mirror of
https://github.com/ysoftdevs/DependencyCheck.git
synced 2026-03-13 05:35:36 +01:00
Compare commits
4058 Commits
v1.0.3
...
issue690_t
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d2a8645dd4 | ||
|
|
4543835a0d | ||
|
|
c0f41c461b | ||
|
|
116ef264e1 | ||
|
|
1371dacdaa | ||
|
|
d252d0f29f | ||
|
|
3786f6ebc7 | ||
|
|
6813427867 | ||
|
|
f94cf106a6 | ||
|
|
a67e421a5d | ||
|
|
865db1b6c3 | ||
|
|
31d7379a39 | ||
|
|
f473e63a61 | ||
|
|
238a96184a | ||
|
|
44ddad8101 | ||
|
|
afa47f7dfc | ||
|
|
f289bcd285 | ||
|
|
c7adb1bb65 | ||
|
|
4bbc5e27b5 | ||
|
|
c877ade004 | ||
|
|
ebd8996ad5 | ||
|
|
f31313d021 | ||
|
|
6936dac9b4 | ||
|
|
4b2f6832fe | ||
|
|
35d0f21c47 | ||
|
|
3066d286c5 | ||
|
|
18564e8e86 | ||
|
|
832cbabc7d | ||
|
|
8b764d5e17 | ||
|
|
e2a1a59543 | ||
|
|
cedb8d3db1 | ||
|
|
539bd754df | ||
|
|
109f5c22e9 | ||
|
|
a23d127c62 | ||
|
|
6825304100 | ||
|
|
947499726a | ||
|
|
97b2e1a4da | ||
|
|
3bb6553111 | ||
|
|
371dba948d | ||
|
|
675349c06f | ||
|
|
7a88981aa4 | ||
|
|
626f6c3de2 | ||
|
|
5540397456 | ||
|
|
69c6dd40a1 | ||
|
|
5ed6e838fc | ||
|
|
1d32a6012a | ||
|
|
b157049a7e | ||
|
|
8ea6b08a0a | ||
|
|
8856ff04ec | ||
|
|
8bfbd11a51 | ||
|
|
abd843d281 | ||
|
|
c54f9b1144 | ||
|
|
318f3e14dd | ||
|
|
46f227e92e | ||
|
|
a7b6f37503 | ||
|
|
a61bba2f72 | ||
|
|
dfc6d952bd | ||
|
|
046f4605f9 | ||
|
|
32590ab7ff | ||
|
|
efeb084e57 | ||
|
|
03ec3142c3 | ||
|
|
679df936e7 | ||
|
|
5ed5764ab5 | ||
|
|
d588092727 | ||
|
|
295ba0679d | ||
|
|
bcdf26c88d | ||
|
|
d6e092bfa2 | ||
|
|
388c1b5af1 | ||
|
|
717aea9a03 | ||
|
|
4951ee5a62 | ||
|
|
666150cf7f | ||
|
|
d8290c0c45 | ||
|
|
e363e8109b | ||
|
|
b228d08843 | ||
|
|
3e08437808 | ||
|
|
e0d5651b75 | ||
|
|
59e29b7afe | ||
|
|
d180208e34 | ||
|
|
0ce1ef596c | ||
|
|
5f7486f851 | ||
|
|
03559fd106 | ||
|
|
d08357a1c2 | ||
|
|
c1cb87ebde | ||
|
|
82fd1cf4d7 | ||
|
|
a87391e609 | ||
|
|
3071cfd7be | ||
|
|
583c2d34d3 | ||
|
|
c9640fbf04 | ||
|
|
192d1de944 | ||
|
|
aa0314c840 | ||
|
|
0171b859c6 | ||
|
|
d267e14b73 | ||
|
|
79e63f4067 | ||
|
|
72d7af5291 | ||
|
|
0e313d1910 | ||
|
|
6841f9a009 | ||
|
|
caeec68999 | ||
|
|
541915a5a7 | ||
|
|
cb75ab8cca | ||
|
|
0f3845b16d | ||
|
|
dd7128095e | ||
|
|
1367be510c | ||
|
|
2ea0eb3c64 | ||
|
|
a5990ea6f3 | ||
|
|
67921f5f3d | ||
|
|
d31e0453bd | ||
|
|
ae21424a30 | ||
|
|
3577949425 | ||
|
|
0d72471502 | ||
|
|
17590a6d38 | ||
|
|
d9dcc8cc2d | ||
|
|
df1ee5e8c6 | ||
|
|
3c68ebece7 | ||
|
|
c9e8e6cf0e | ||
|
|
36945fb84d | ||
|
|
960a2e27ab | ||
|
|
71724461a9 | ||
|
|
ae5a95bfb3 | ||
|
|
d6c9fea354 | ||
|
|
d6f1351f6b | ||
|
|
373488adb4 | ||
|
|
59401cc9f8 | ||
|
|
eca0e7a852 | ||
|
|
563dc24854 | ||
|
|
3a70e25983 | ||
|
|
a9fc6bf02c | ||
|
|
cd4f09dc86 | ||
|
|
4193718571 | ||
|
|
0464626e2b | ||
|
|
a0198e34e7 | ||
|
|
0b329bd40e | ||
|
|
3d33f24f09 | ||
|
|
886c02fad2 | ||
|
|
3a11504153 | ||
|
|
3a082ae00a | ||
|
|
780201845b | ||
|
|
0e0a4bb0b4 | ||
|
|
5333083a78 | ||
|
|
b8c6c86330 | ||
|
|
e246757f47 | ||
|
|
4172300799 | ||
|
|
f39f754b7b | ||
|
|
c59615f452 | ||
|
|
847bed2fa0 | ||
|
|
a9af15f6f8 | ||
|
|
92519ae955 | ||
|
|
2d90aca1f2 | ||
|
|
f29ed38c34 | ||
|
|
df8d4fd77c | ||
|
|
baa2e2c6ff | ||
|
|
9d5769bb69 | ||
|
|
4cdfa804ee | ||
|
|
523cd23b6b | ||
|
|
61866e9e76 | ||
|
|
ff7fbdc98d | ||
|
|
b625d642ea | ||
|
|
8733a85ebb | ||
|
|
5ab5a7b72b | ||
|
|
3cb8b9fa9e | ||
|
|
429039bf1c | ||
|
|
29d28c3408 | ||
|
|
372d484440 | ||
|
|
eac47800a3 | ||
|
|
86a85db12b | ||
|
|
4ab6cd278c | ||
|
|
233a068c8b | ||
|
|
d9f0ffa742 | ||
|
|
8d63ee19ed | ||
|
|
1fb74e1a27 | ||
|
|
c94ab6108c | ||
|
|
bf285e19ab | ||
|
|
b1ceca73e4 | ||
|
|
f3aca63b61 | ||
|
|
fca107d287 | ||
|
|
64b6964fff | ||
|
|
6af0842838 | ||
|
|
4c49adf1ba | ||
|
|
5f4e4fab56 | ||
|
|
146d7e3fbf | ||
|
|
4d22800747 | ||
|
|
541a7f8180 | ||
|
|
f205cf79c9 | ||
|
|
d8bb6488b7 | ||
|
|
4324563c0a | ||
|
|
bad03660b1 | ||
|
|
20b1ff38f9 | ||
|
|
def78a3cfd | ||
|
|
a41158a716 | ||
|
|
63ad13ff7a | ||
|
|
dd92ec675f | ||
|
|
6e1512f7d9 | ||
|
|
287b1df3fd | ||
|
|
38bf9b4ddb | ||
|
|
f9d3a9d8d8 | ||
|
|
309a5d9bcb | ||
|
|
60e661d3a4 | ||
|
|
c33257d266 | ||
|
|
1dbc183567 | ||
|
|
bf258146da | ||
|
|
bb927b447e | ||
|
|
d91b4c3151 | ||
|
|
91dbb39f18 | ||
|
|
35ae8fd660 | ||
|
|
d854917090 | ||
|
|
32ebf6c8ed | ||
|
|
edd4191d47 | ||
|
|
0cce49506a | ||
|
|
1c053469e9 | ||
|
|
610e97ef7f | ||
|
|
5a678d2ccb | ||
|
|
8db61a4d1e | ||
|
|
f47c6b07f4 | ||
|
|
bd3af45db9 | ||
|
|
a271d422f6 | ||
|
|
4dd6dedaa4 | ||
|
|
10ee569096 | ||
|
|
1474855305 | ||
|
|
0202bc11d4 | ||
|
|
e7072ea04c | ||
|
|
8f2c755f21 | ||
|
|
e513a79bd2 | ||
|
|
dd17f7393f | ||
|
|
32f38bf892 | ||
|
|
d5c3eeaf28 | ||
|
|
bfa67fcba7 | ||
|
|
37a556dcc0 | ||
|
|
fe61f298f0 | ||
|
|
9786c9bf82 | ||
|
|
668161081a | ||
|
|
4978f9dcba | ||
|
|
a6ca2e3895 | ||
|
|
6ecf55be91 | ||
|
|
13bd63dac8 | ||
|
|
db5ff1bfca | ||
|
|
42f2385bb2 | ||
|
|
e9556bbbf0 | ||
|
|
316b936326 | ||
|
|
6838b9b950 | ||
|
|
cdfe5d0c9a | ||
|
|
1610f14c47 | ||
|
|
85ab894b94 | ||
|
|
ddbca24f33 | ||
|
|
6b9acac8c4 | ||
|
|
2333bee5fd | ||
|
|
2ad08d2367 | ||
|
|
1337686013 | ||
|
|
41041bfd18 | ||
|
|
e693e53630 | ||
|
|
b99e13a337 | ||
|
|
3bbc485968 | ||
|
|
e0b549e427 | ||
|
|
75207169e3 | ||
|
|
e07f568237 | ||
|
|
e2cd99d40d | ||
|
|
27f2682a98 | ||
|
|
34a2110e9a | ||
|
|
96ba51db4f | ||
|
|
9c6053a60a | ||
|
|
358367ef9e | ||
|
|
a12bc44ecd | ||
|
|
773ac019f8 | ||
|
|
e751b7b814 | ||
|
|
824aa23b9b | ||
|
|
b7b97960a6 | ||
|
|
40f0e907e1 | ||
|
|
5ff0dc885d | ||
|
|
e70a0ee238 | ||
|
|
9338697079 | ||
|
|
4018a4e1de | ||
|
|
e8788dd2a4 | ||
|
|
e70c2f2b05 | ||
|
|
5ed0583039 | ||
|
|
f76d7295f9 | ||
|
|
6e280c4958 | ||
|
|
48b4ef1944 | ||
|
|
9150df964f | ||
|
|
b2237394e1 | ||
|
|
b3a0f7ad26 | ||
|
|
782ba42abc | ||
|
|
74b93ce602 | ||
|
|
e907c40f17 | ||
|
|
13a9dedb1e | ||
|
|
b37698f245 | ||
|
|
d30d000346 | ||
|
|
446239a5bd | ||
|
|
ac25aa795b | ||
|
|
f117a9ded0 | ||
|
|
947d38ccd2 | ||
|
|
23f7996db8 | ||
|
|
9fdff51f26 | ||
|
|
9b43bf004a | ||
|
|
5d73faa1f0 | ||
|
|
9e70279b31 | ||
|
|
9e671d1065 | ||
|
|
7e2c4af0b3 | ||
|
|
11f9092a65 | ||
|
|
6017e5c217 | ||
|
|
b2149ff4b9 | ||
|
|
1a5177c576 | ||
|
|
7020c9931a | ||
|
|
9bc43e2e8e | ||
|
|
26a4e7451e | ||
|
|
3470d33bdc | ||
|
|
51c96894b4 | ||
|
|
7fc2be6a0a | ||
|
|
110c97bc15 | ||
|
|
8d51d8fa1f | ||
|
|
4b02a567e0 | ||
|
|
5a939ec108 | ||
|
|
d9c4480627 | ||
|
|
9388340e23 | ||
|
|
2285d2ef4b | ||
|
|
f84aea0040 | ||
|
|
452969cc92 | ||
|
|
128a600f18 | ||
|
|
7dd9a52e78 | ||
|
|
ff341b7228 | ||
|
|
92a8b4ca85 | ||
|
|
384199b28d | ||
|
|
44edcabe15 | ||
|
|
1a5e9884fc | ||
|
|
cda81315d2 | ||
|
|
d7100e54d1 | ||
|
|
989caead9c | ||
|
|
a9d3b627f1 | ||
|
|
99a1606df1 | ||
|
|
6326513c63 | ||
|
|
f6cfae595a | ||
|
|
0794efcf41 | ||
|
|
b9ea82f2c1 | ||
|
|
8b705b3370 | ||
|
|
c684607a4d | ||
|
|
b00833c2de | ||
|
|
0ca6bc6ab6 | ||
|
|
60faddff9b | ||
|
|
b35da8ad4b | ||
|
|
79887c148a | ||
|
|
1ae3457ee6 | ||
|
|
d2154c9d29 | ||
|
|
40ede24a99 | ||
|
|
5960ba919d | ||
|
|
f6aaaa8815 | ||
|
|
6f1b20c936 | ||
|
|
7734a50427 | ||
|
|
aef118d375 | ||
|
|
22cae71999 | ||
|
|
29d127303c | ||
|
|
5574f1c24f | ||
|
|
9457744571 | ||
|
|
19243c479c | ||
|
|
e868ce8328 | ||
|
|
ffa846c05a | ||
|
|
dde1791476 | ||
|
|
45438a7f06 | ||
|
|
c980e77ea3 | ||
|
|
176d3ddefa | ||
|
|
98d783d448 | ||
|
|
bcd6634d8a | ||
|
|
0b260cef2a | ||
|
|
6a68abbd67 | ||
|
|
9fcf23c802 | ||
|
|
5c2c08e051 | ||
|
|
1f254997e1 | ||
|
|
4f95af0864 | ||
|
|
6ff39be9d2 | ||
|
|
6cf5a47971 | ||
|
|
56da53c700 | ||
|
|
7091e10795 | ||
|
|
34765c5741 | ||
|
|
36c139872a | ||
|
|
1e77cec677 | ||
|
|
e95e3fb2d0 | ||
|
|
39c2234e38 | ||
|
|
f4fff5d9cb | ||
|
|
659785f972 | ||
|
|
85c04f6e3e | ||
|
|
bef117cbe8 | ||
|
|
46dd7cf86e | ||
|
|
9ed5a97267 | ||
|
|
cc2da70db2 | ||
|
|
cedd93e774 | ||
|
|
632e1692eb | ||
|
|
4861592d2a | ||
|
|
22e6d4edf3 | ||
|
|
e9bd7ff72f | ||
|
|
e7228fb489 | ||
|
|
96c03a68f2 | ||
|
|
4f6f248421 | ||
|
|
a8f14c86fd | ||
|
|
36de3d1e25 | ||
|
|
48bc4570e1 | ||
|
|
94b272dbae | ||
|
|
c093edf459 | ||
|
|
0164feffcc | ||
|
|
8cd377b99f | ||
|
|
74282c8ac5 | ||
|
|
d2158e5e44 | ||
|
|
9ea16ad1d1 | ||
|
|
45941adb71 | ||
|
|
c4d662fd2b | ||
|
|
d9ce3cda66 | ||
|
|
6bd7d6b078 | ||
|
|
84c6dd5dfa | ||
|
|
71e7412f15 | ||
|
|
d22c920b35 | ||
|
|
f7a0982ca0 | ||
|
|
bed04150e1 | ||
|
|
ba15de2218 | ||
|
|
e9ec89dc9c | ||
|
|
d09f75658c | ||
|
|
62f92db181 | ||
|
|
27a98f4244 | ||
|
|
f0a3482eda | ||
|
|
5f76843c4a | ||
|
|
c6ea92cff9 | ||
|
|
c253308284 | ||
|
|
9ae9c111e3 | ||
|
|
4894372eee | ||
|
|
7cf040653f | ||
|
|
034bd4dba0 | ||
|
|
af12a2161c | ||
|
|
57fcf6fde3 | ||
|
|
c5757dc5f4 | ||
|
|
6d5d5ceb7b | ||
|
|
2fa8507d69 | ||
|
|
f23003ead3 | ||
|
|
c996f6b436 | ||
|
|
d2ee66a1c4 | ||
|
|
26b0dd5ef5 | ||
|
|
ad4149a259 | ||
|
|
9611c3b478 | ||
|
|
cead88d221 | ||
|
|
c1e1a6bb4f | ||
|
|
6212a5f740 | ||
|
|
b3d9ea3c47 | ||
|
|
cd51989354 | ||
|
|
b705ae5f0c | ||
|
|
13b53537fa | ||
|
|
7d05aa6073 | ||
|
|
85de173086 | ||
|
|
d264d804c8 | ||
|
|
8272da615e | ||
|
|
857b993d51 | ||
|
|
a71edf584e | ||
|
|
461d7fec0e | ||
|
|
5e3da035dd | ||
|
|
ebb52995a5 | ||
|
|
519b82c620 | ||
|
|
84682d07c6 | ||
|
|
960eeb19af | ||
|
|
ab3920f8f1 | ||
|
|
f5f5857897 | ||
|
|
1c400b410e | ||
|
|
cc751aa224 | ||
|
|
c20892ee3e | ||
|
|
32ab53c9e1 | ||
|
|
d0a7d9eb42 | ||
|
|
a1a9602509 | ||
|
|
cf97c89fe0 | ||
|
|
8895bc85ea | ||
|
|
1a9976c6ca | ||
|
|
f47ebf6145 | ||
|
|
0380715311 | ||
|
|
80ad16c7fa | ||
|
|
e56e9035b6 | ||
|
|
73f22d32d2 | ||
|
|
c3bc56eebc | ||
|
|
35cc14815e | ||
|
|
9be91474f6 | ||
|
|
adf949bf08 | ||
|
|
c6bf41b8ba | ||
|
|
bc656c6218 | ||
|
|
f46226d055 | ||
|
|
00d4ee47de | ||
|
|
c5ffc21660 | ||
|
|
d89b1fdc6a | ||
|
|
8324287bd6 | ||
|
|
6be161a546 | ||
|
|
027350e1ba | ||
|
|
a2309e1c2e | ||
|
|
c34dc97bd4 | ||
|
|
7e8749146e | ||
|
|
8680ecd033 | ||
|
|
4e4417c7af | ||
|
|
7909bbbbe9 | ||
|
|
6fd831e688 | ||
|
|
59a4825c70 | ||
|
|
1ba3681457 | ||
|
|
78becffb2e | ||
|
|
e7efd7070b | ||
|
|
ec6471e8c7 | ||
|
|
b01ae2c6d3 | ||
|
|
ef4a260615 | ||
|
|
f6b80630dd | ||
|
|
f43589589d | ||
|
|
06b59cf79b | ||
|
|
a2187205e0 | ||
|
|
52f269a289 | ||
|
|
310ca967a1 | ||
|
|
c4b423cb0f | ||
|
|
8a6c940aaf | ||
|
|
b295e927b7 | ||
|
|
63d24737dd | ||
|
|
60ce02ba28 | ||
|
|
95939ed66c | ||
|
|
7f609a35be | ||
|
|
f7b534f1ee | ||
|
|
cd5f9e2f13 | ||
|
|
e79da72711 | ||
|
|
1ba081959b | ||
|
|
578dc63652 | ||
|
|
fccd683b50 | ||
|
|
f3d3a25856 | ||
|
|
6d70c92795 | ||
|
|
3c525d8e3a | ||
|
|
a6b47c7c43 | ||
|
|
5b52f01f3d | ||
|
|
d13bbd43f3 | ||
|
|
0394d1a24f | ||
|
|
446222e127 | ||
|
|
05d7aa898d | ||
|
|
73f7fc1d51 | ||
|
|
f0262466d4 | ||
|
|
1ecde9bbc1 | ||
|
|
ae5a766092 | ||
|
|
6a807bc002 | ||
|
|
c0384bb0ee | ||
|
|
2906b315b3 | ||
|
|
425fd65bd8 | ||
|
|
7d83362a85 | ||
|
|
0b26894112 | ||
|
|
17f810a720 | ||
|
|
71ef8061f9 | ||
|
|
353b17690f | ||
|
|
6790727260 | ||
|
|
e129f7db85 | ||
|
|
ea942398e3 | ||
|
|
5ad72cae3f | ||
|
|
5f945bc696 | ||
|
|
6f451736ba | ||
|
|
30856f4a4f | ||
|
|
413c71eb0a | ||
|
|
9d1408be20 | ||
|
|
f21f371751 | ||
|
|
2b761279e4 | ||
|
|
d5e8f54214 | ||
|
|
83f83d4eee | ||
|
|
b0f4ab9ba5 | ||
|
|
06dad8f79c | ||
|
|
83ab122ddf | ||
|
|
8a42fe4ae1 | ||
|
|
94c6778b89 | ||
|
|
c0e5973517 | ||
|
|
1e7bbfa7c1 | ||
|
|
dc7245ff6e | ||
|
|
ffaf7b40e9 | ||
|
|
4de3fb1f2a | ||
|
|
99355d993a | ||
|
|
d25f6e813c | ||
|
|
043f8e0523 | ||
|
|
5fcf2a2623 | ||
|
|
ee77fccffd | ||
|
|
f1422adf75 | ||
|
|
189da08885 | ||
|
|
c2b1742582 | ||
|
|
9e63ac6d5b | ||
|
|
4d7ab8b187 | ||
|
|
4de9818bee | ||
|
|
7a2e1fd221 | ||
|
|
d0ca800a23 | ||
|
|
35ffd56ea9 | ||
|
|
84b992d3a1 | ||
|
|
9e46364759 | ||
|
|
0f37c2b59c | ||
|
|
33852ea7e3 | ||
|
|
4fbed1cdac | ||
|
|
42c61ab457 | ||
|
|
8c6b9f9c68 | ||
|
|
abebecac4a | ||
|
|
87efe429da | ||
|
|
35128b0bd4 | ||
|
|
186cb2270f | ||
|
|
deda02f879 | ||
|
|
bcc2478ef7 | ||
|
|
8d54654482 | ||
|
|
08318107c1 | ||
|
|
a5e77c85a6 | ||
|
|
1e8d2aff75 | ||
|
|
bc0a0f9902 | ||
|
|
da82f975e4 | ||
|
|
48af120db8 | ||
|
|
8722eae766 | ||
|
|
53776936ca | ||
|
|
dca465b801 | ||
|
|
43cd115dc7 | ||
|
|
e7ba08e52c | ||
|
|
9df12e6ff2 | ||
|
|
b5c7fb747c | ||
|
|
a40a4afe80 | ||
|
|
739f595f13 | ||
|
|
e07e892969 | ||
|
|
d4a6c58cc8 | ||
|
|
d644431a4e | ||
|
|
33bbb50b43 | ||
|
|
f89d7df305 | ||
|
|
3b02cd0e39 | ||
|
|
52cd50e0a8 | ||
|
|
996a970081 | ||
|
|
6c0b65acd4 | ||
|
|
f4df263dfe | ||
|
|
8c659acc82 | ||
|
|
7aba2429af | ||
|
|
ab48d2c2ff | ||
|
|
0b699d45bf | ||
|
|
54beafa262 | ||
|
|
531d4923eb | ||
|
|
b160a4d1dd | ||
|
|
ca54daf456 | ||
|
|
a22fc550b3 | ||
|
|
0650d93953 | ||
|
|
5633258fa7 | ||
|
|
12278cda58 | ||
|
|
84d1f08fda | ||
|
|
c184292a57 | ||
|
|
4cdfcb9f9d | ||
|
|
343a78917c | ||
|
|
ff7d0fdb9d | ||
|
|
db26b46be0 | ||
|
|
d77a70c360 | ||
|
|
42f4ae65d1 | ||
|
|
88daac31d2 | ||
|
|
ac04c173a8 | ||
|
|
8401494fbc | ||
|
|
97af118cb9 | ||
|
|
091e6026bc | ||
|
|
c798ede7bf | ||
|
|
225851f067 | ||
|
|
9dd65ecf70 | ||
|
|
1a9cc4b6be | ||
|
|
a612f206bf | ||
|
|
e51031c62a | ||
|
|
e30c29ef50 | ||
|
|
91ddcadbcd | ||
|
|
8c145860e5 | ||
|
|
a19dd7687e | ||
|
|
550d6ca083 | ||
|
|
b425411357 | ||
|
|
a1f0cf749d | ||
|
|
22e0d1c74e | ||
|
|
cdc07047aa | ||
|
|
c832c2da28 | ||
|
|
8daa713639 | ||
|
|
e0a2966706 | ||
|
|
354bfa14f9 | ||
|
|
46b91702ba | ||
|
|
de9516e368 | ||
|
|
3924e07e5c | ||
|
|
76bcbb5a7e | ||
|
|
8022381d1c | ||
|
|
feb1233081 | ||
|
|
36eefd0836 | ||
|
|
0e31e59759 | ||
|
|
4a4c1e75da | ||
|
|
b0bfd2292a | ||
|
|
7214b24357 | ||
|
|
24637f496f | ||
|
|
d8ecde5265 | ||
|
|
28840c6209 | ||
|
|
1696213406 | ||
|
|
6f315ac765 | ||
|
|
a485307d92 | ||
|
|
3d3b861ba0 | ||
|
|
4b33ed25d5 | ||
|
|
e264880c7b | ||
|
|
ef8212701f | ||
|
|
492157a502 | ||
|
|
2605bc182e | ||
|
|
fe8dfdd804 | ||
|
|
bd917bc990 | ||
|
|
c5c32f683f | ||
|
|
5506e58c98 | ||
|
|
5af2d49b18 | ||
|
|
0fd35a4925 | ||
|
|
7ed20b1244 | ||
|
|
efa6a78255 | ||
|
|
8b58df3b34 | ||
|
|
0d2a090e1f | ||
|
|
7860d635a9 | ||
|
|
ba91c9fa9b | ||
|
|
b3630e0d5e | ||
|
|
f752285912 | ||
|
|
5a150d9b0e | ||
|
|
f0aa185832 | ||
|
|
9592f058d4 | ||
|
|
f630794e22 | ||
|
|
93636e89c5 | ||
|
|
585002c25c | ||
|
|
412ccc1be1 | ||
|
|
8b1306a36c | ||
|
|
81026e8dca | ||
|
|
dd440c8f9f | ||
|
|
76f3e4b27e | ||
|
|
5f5d3fdb66 | ||
|
|
853c92b87d | ||
|
|
00080f2abc | ||
|
|
55414208a3 | ||
|
|
5091499563 | ||
|
|
944b54d920 | ||
|
|
d023b2b2ff | ||
|
|
b45f9f514b | ||
|
|
239a9383e0 | ||
|
|
2190c0229c | ||
|
|
01ef14dc92 | ||
|
|
7b0784843c | ||
|
|
6fc805369e | ||
|
|
9e29939cd3 | ||
|
|
d750abca22 | ||
|
|
31df2fa131 | ||
|
|
6355a29a7a | ||
|
|
86a2b38340 | ||
|
|
9cb2b58557 | ||
|
|
2b0e2e8d0d | ||
|
|
cf46767196 | ||
|
|
ffc1034b5a | ||
|
|
46bb19de9b | ||
|
|
70bc7a6d01 | ||
|
|
3164505273 | ||
|
|
3d84fcd037 | ||
|
|
578fa32243 | ||
|
|
fc00b7d1cc | ||
|
|
d7351bd3e5 | ||
|
|
e7224c8f05 | ||
|
|
b97622f45b | ||
|
|
0e15f3b703 | ||
|
|
6604c0da89 | ||
|
|
e0b8be20b3 | ||
|
|
46965d8c96 | ||
|
|
66e92f00ee | ||
|
|
4a137b4e8e | ||
|
|
9d5ff28098 | ||
|
|
313b114da5 | ||
|
|
1b6bfc6338 | ||
|
|
49fd89f34a | ||
|
|
a2e862886e | ||
|
|
62f6c7c5a9 | ||
|
|
2294ed1ce1 | ||
|
|
c8a1c6a318 | ||
|
|
600ed66d5b | ||
|
|
512b17555c | ||
|
|
dc7849c9e8 | ||
|
|
6a99a51b91 | ||
|
|
8c7fa022a0 | ||
|
|
cca694a580 | ||
|
|
3a7f95b9b1 | ||
|
|
3a84dc3962 | ||
|
|
5961a96a4c | ||
|
|
a22382505f | ||
|
|
5faef75415 | ||
|
|
fed60907dc | ||
|
|
ce7e360b70 | ||
|
|
0b3def38b8 | ||
|
|
25a15dea8c | ||
|
|
e204971a6c | ||
|
|
d5b3a118bc | ||
|
|
3396cb2887 | ||
|
|
3c5beea218 | ||
|
|
e544384dd5 | ||
|
|
0e90f460f4 | ||
|
|
921efc4d2b | ||
|
|
1b3b4a5906 | ||
|
|
5c8b374352 | ||
|
|
e05cef6886 | ||
|
|
cb39ecacf9 | ||
|
|
e6816f94eb | ||
|
|
8b5dbeab44 | ||
|
|
29c21c3611 | ||
|
|
e05bed8d65 | ||
|
|
1b2210aba0 | ||
|
|
7fb1b1d57b | ||
|
|
a3adf71a1d | ||
|
|
51d81fab5d | ||
|
|
2ed5dc153a | ||
|
|
5f8f156bee | ||
|
|
eb03c90d7a | ||
|
|
fc05471086 | ||
|
|
b9db2dd89f | ||
|
|
de7fe21a4f | ||
|
|
56f9a7c4f9 | ||
|
|
df569a5ae2 | ||
|
|
acb9d04c51 | ||
|
|
09c4708a22 | ||
|
|
b346dfe0a3 | ||
|
|
5f259cb88c | ||
|
|
fb2aff3310 | ||
|
|
3c4c65c28c | ||
|
|
15885e3e8c | ||
|
|
5508c60e85 | ||
|
|
ffc341e4b9 | ||
|
|
41a68f7b25 | ||
|
|
041d3c5312 | ||
|
|
8e8b462bc8 | ||
|
|
efbc76e06f | ||
|
|
67a44d2adc | ||
|
|
92a35b929a | ||
|
|
e5744dd63f | ||
|
|
f2f3d050bd | ||
|
|
0cbecbe3a0 | ||
|
|
51a8b5a058 | ||
|
|
aaf716e54b | ||
|
|
209fcc7946 | ||
|
|
a5cb131806 | ||
|
|
8fbeb5f5d5 | ||
|
|
a92bdfe30d | ||
|
|
7f130ff036 | ||
|
|
b704f72854 | ||
|
|
e21f8a97ac | ||
|
|
a8ff403809 | ||
|
|
22097c0a25 | ||
|
|
92e7d9cf80 | ||
|
|
54d921f275 | ||
|
|
08d7b3dbce | ||
|
|
6949b3c229 | ||
|
|
b0ca38bd29 | ||
|
|
cf173ee9e7 | ||
|
|
aa9908b34a | ||
|
|
640674ef72 | ||
|
|
0c69ab80bb | ||
|
|
662557c2f3 | ||
|
|
346b2c31d2 | ||
|
|
62dbf99557 | ||
|
|
99b140adaa | ||
|
|
387d577d4f | ||
|
|
ab7eee7db9 | ||
|
|
487a45f01b | ||
|
|
60665c6bd8 | ||
|
|
8fc9a3d6d1 | ||
|
|
05a05f7e88 | ||
|
|
0c5bdfd7b7 | ||
|
|
626e93c7e3 | ||
|
|
b588c4c900 | ||
|
|
c52a0d88df | ||
|
|
84838d19d9 | ||
|
|
faf335a181 | ||
|
|
5c25351884 | ||
|
|
520f3cb09a | ||
|
|
e234246618 | ||
|
|
5d1d378f61 | ||
|
|
cef3bb7424 | ||
|
|
ccb03f2763 | ||
|
|
1f6168366b | ||
|
|
cd5bf85245 | ||
|
|
f2778e5d28 | ||
|
|
c2e6065ed7 | ||
|
|
fccba5f7fd | ||
|
|
3f230c5a05 | ||
|
|
dc849c3891 | ||
|
|
2770b58a20 | ||
|
|
37519acfb8 | ||
|
|
ad8c7b3cd2 | ||
|
|
04db8d3208 | ||
|
|
666e3b1e30 | ||
|
|
dc68781c06 | ||
|
|
a7f50d147e | ||
|
|
7e639db5de | ||
|
|
19a97a1706 | ||
|
|
cd66a9ef61 | ||
|
|
f121430a5d | ||
|
|
2f518dacfc | ||
|
|
fded8b6cd3 | ||
|
|
3b6c64dc9d | ||
|
|
d742985640 | ||
|
|
a13dd58989 | ||
|
|
622b3210ae | ||
|
|
90c97ed6aa | ||
|
|
53a4dfbf88 | ||
|
|
f488c57363 | ||
|
|
0ce830ca9d | ||
|
|
30ae418c2c | ||
|
|
3b976d211f | ||
|
|
cca49b5dc2 | ||
|
|
8c2b2070c6 | ||
|
|
24b8ff26db | ||
|
|
f0d93538ae | ||
|
|
02eab65c4e | ||
|
|
d941aa7df3 | ||
|
|
b5026a45f6 | ||
|
|
79fde3ebc9 | ||
|
|
031d648585 | ||
|
|
762b2fe7d6 | ||
|
|
5db377923e | ||
|
|
c3177df739 | ||
|
|
0dc36765f1 | ||
|
|
38e61ebd8d | ||
|
|
529b9739b5 | ||
|
|
a014ca7d8a | ||
|
|
83701f7d0d | ||
|
|
b2500939f3 | ||
|
|
1852b9dbb2 | ||
|
|
069474fc71 | ||
|
|
e7f518264a | ||
|
|
b0b096c3f5 | ||
|
|
bfa9d04d42 | ||
|
|
7dbe58469a | ||
|
|
41b36dabc2 | ||
|
|
4a685557d9 | ||
|
|
e7ef4b6906 | ||
|
|
67502fb9d3 | ||
|
|
960283bdcf | ||
|
|
39f30eab7a | ||
|
|
24b4741aaf | ||
|
|
64f373fb43 | ||
|
|
bc1830d8eb | ||
|
|
f2a2a91682 | ||
|
|
274ac339ad | ||
|
|
1d916286ee | ||
|
|
832d54300a | ||
|
|
ba6d3bbe15 | ||
|
|
c1d0789ac7 | ||
|
|
0573d0083e | ||
|
|
e57d62b682 | ||
|
|
bb6f27b322 | ||
|
|
86f424ad37 | ||
|
|
ad81bbc761 | ||
|
|
07e868e6f6 | ||
|
|
b45700df03 | ||
|
|
93ce2a8e3a | ||
|
|
fbc4d46962 | ||
|
|
d73d138b3f | ||
|
|
14ea21d53d | ||
|
|
2b3791b83e | ||
|
|
e04809f96b | ||
|
|
9203acff9c | ||
|
|
afc1a9f077 | ||
|
|
fc57851113 | ||
|
|
1f1d3f843f | ||
|
|
b389260dec | ||
|
|
1f37a5ff8f | ||
|
|
815d60eca2 | ||
|
|
877a584a26 | ||
|
|
0c60c9ff75 | ||
|
|
6a7a868b71 | ||
|
|
b5a070b228 | ||
|
|
39f13c6e5b | ||
|
|
8c98da09f0 | ||
|
|
ed70a7200c | ||
|
|
ea4410cd16 | ||
|
|
9d9b1cbcd5 | ||
|
|
f17d8f38fb | ||
|
|
0efc9d1cd2 | ||
|
|
4f5d5f1afd | ||
|
|
c4d8d7abf4 | ||
|
|
3fad29a709 | ||
|
|
665f204c1f | ||
|
|
362b651823 | ||
|
|
49b56588b8 | ||
|
|
c7a763ffdc | ||
|
|
5435ddad9f | ||
|
|
0ecd466c4c | ||
|
|
6117e25b97 | ||
|
|
ee10f09bc6 | ||
|
|
58512e302f | ||
|
|
ce564c209b | ||
|
|
7296d49693 | ||
|
|
290fdc4c0f | ||
|
|
1fa5ae695d | ||
|
|
b2ba6d38b8 | ||
|
|
620f1b94bc | ||
|
|
c8fb5d1a9a | ||
|
|
1f763aeb72 | ||
|
|
fcfb019555 | ||
|
|
d4c1acb126 | ||
|
|
862bf43685 | ||
|
|
f83139a9ee | ||
|
|
3d938b3edf | ||
|
|
6c6ae66e36 | ||
|
|
813e423bec | ||
|
|
a9a235fc87 | ||
|
|
6e1c6b4bed | ||
|
|
2214059a63 | ||
|
|
424cfcfa0c | ||
|
|
ce871dfa3e | ||
|
|
48a6eb1f86 | ||
|
|
fb85fb5b76 | ||
|
|
c39c3cfdae | ||
|
|
e2fa7c666a | ||
|
|
f49cc6fb1f | ||
|
|
69bef59473 | ||
|
|
9e931b9eb0 | ||
|
|
b26d9ea1e0 | ||
|
|
ca5607d79e | ||
|
|
903eaed250 | ||
|
|
0859eab2dc | ||
|
|
f0f84722ba | ||
|
|
17b8ba7069 | ||
|
|
eb91152cfa | ||
|
|
08c1b6879e | ||
|
|
0077a8f67c | ||
|
|
a89cc67bd2 | ||
|
|
388415ecc2 | ||
|
|
44c5ba208d | ||
|
|
d3a51857cb | ||
|
|
11a3db5d64 | ||
|
|
f3be8ae608 | ||
|
|
0577c9121c | ||
|
|
058f51e8c1 | ||
|
|
698444caec | ||
|
|
d575df4b19 | ||
|
|
bee98513a2 | ||
|
|
3746df49ee | ||
|
|
d98f67eab9 | ||
|
|
fde415e251 | ||
|
|
5702f39181 | ||
|
|
45658afd89 | ||
|
|
ece4a51b94 | ||
|
|
837d4918f2 | ||
|
|
57ae0f1676 | ||
|
|
48e644e007 | ||
|
|
49a04fa913 | ||
|
|
df943bcf75 | ||
|
|
fdbec176fa | ||
|
|
4b2b4e5482 | ||
|
|
96768d8529 | ||
|
|
2689a08026 | ||
|
|
54be70672e | ||
|
|
480fa50af5 | ||
|
|
b51731d15f | ||
|
|
c09650a136 | ||
|
|
769fcb20d8 | ||
|
|
537c4b3a50 | ||
|
|
a75c17ac5e | ||
|
|
85604e8afa | ||
|
|
9a45c9aa7c | ||
|
|
01450bacc2 | ||
|
|
af0255ee09 | ||
|
|
df25bbb6d2 | ||
|
|
444685bc05 | ||
|
|
115f63c330 | ||
|
|
f9dbc4f7bf | ||
|
|
83263f8dee | ||
|
|
a452ade957 | ||
|
|
1f48af024e | ||
|
|
0a643d7195 | ||
|
|
c3835b9da7 | ||
|
|
bb1a96cf7a | ||
|
|
56360301d7 | ||
|
|
435cccdeae | ||
|
|
b11b472933 | ||
|
|
514f8398e2 | ||
|
|
90935fef25 | ||
|
|
9b5ce1c3a6 | ||
|
|
8ad1639b02 | ||
|
|
6d70332cd6 | ||
|
|
717f6240e3 | ||
|
|
ab782054a1 | ||
|
|
b481f01217 | ||
|
|
d0f884f5b2 | ||
|
|
51e66354b0 | ||
|
|
1efe90f445 | ||
|
|
7b47b7549d | ||
|
|
7ccb77fb57 | ||
|
|
a32fa69823 | ||
|
|
ece4cb03ad | ||
|
|
5c53b6528f | ||
|
|
9b92007eff | ||
|
|
e433809f4d | ||
|
|
d74218004a | ||
|
|
c35276e3df | ||
|
|
064236ed5b | ||
|
|
2a50dcba9d | ||
|
|
f7974b324b | ||
|
|
3bb716b060 | ||
|
|
39e465261f | ||
|
|
784b78b17c | ||
|
|
22c68ed8ef | ||
|
|
c4c670a3b1 | ||
|
|
17a05cc1d4 | ||
|
|
d452c5fabb | ||
|
|
2cf974ef02 | ||
|
|
1f0e789575 | ||
|
|
92e1fd3f28 | ||
|
|
49736a87aa | ||
|
|
d009e39842 | ||
|
|
c2b8901537 | ||
|
|
dd910cb5ec | ||
|
|
4632753f02 | ||
|
|
3fdcd12b4f | ||
|
|
94d1d611c7 | ||
|
|
27b54a0bfa | ||
|
|
1b1ecd0748 | ||
|
|
1e29d2e751 | ||
|
|
a0437bf933 | ||
|
|
73e0292a4b | ||
|
|
c393e74160 | ||
|
|
80c4666198 | ||
|
|
ea7bd1f700 | ||
|
|
b3a55cc85d | ||
|
|
036200350d | ||
|
|
e630c484ff | ||
|
|
713e9658c5 | ||
|
|
782039810e | ||
|
|
b473d8ab9c | ||
|
|
2eb6918fb3 | ||
|
|
29626666a7 | ||
|
|
dc41c9a671 | ||
|
|
83af70bb59 | ||
|
|
b293873640 | ||
|
|
8bb92815cb | ||
|
|
7a8f7199c8 | ||
|
|
6f4ce34840 | ||
|
|
8853552161 | ||
|
|
95d3d17d83 | ||
|
|
3594280b04 | ||
|
|
1e447c6e3e | ||
|
|
c41a288280 | ||
|
|
a0492fe944 | ||
|
|
1fffebd497 | ||
|
|
62c05049a7 | ||
|
|
0fdf377d45 | ||
|
|
6ca8e2644a | ||
|
|
4a3061db6d | ||
|
|
61ac81518a | ||
|
|
acd4b4371d | ||
|
|
1d20291d44 | ||
|
|
c60245ea2b | ||
|
|
9e25480baa | ||
|
|
facd803943 | ||
|
|
05c8a6282d | ||
|
|
3f9ae34203 | ||
|
|
afb85309a2 | ||
|
|
2c5e64d0d5 | ||
|
|
ddb8c432be | ||
|
|
054be314f6 | ||
|
|
e484c5754e | ||
|
|
b36c4f65e5 | ||
|
|
4bdfbcc916 | ||
|
|
519198bb61 | ||
|
|
9a7c342f91 | ||
|
|
761a5ed3dd | ||
|
|
481e753ad4 | ||
|
|
271016f0fa | ||
|
|
4493f895c6 | ||
|
|
5c32ecd8e1 | ||
|
|
0b5244d321 | ||
|
|
b6f9715174 | ||
|
|
2db1f8d2b6 | ||
|
|
4c5957ae40 | ||
|
|
38cd19de15 | ||
|
|
f66ffbdd63 | ||
|
|
8d3f08e529 | ||
|
|
4209c1c406 | ||
|
|
1cd12d0a0c | ||
|
|
7eb18e1931 | ||
|
|
d308e50e1e | ||
|
|
88569cb369 | ||
|
|
235869fc79 | ||
|
|
89166e81fb | ||
|
|
2d109b81cf | ||
|
|
5c02b4dccb | ||
|
|
e7f154b58d | ||
|
|
c0752575c6 | ||
|
|
7eb2c89f39 | ||
|
|
bf4eb07342 | ||
|
|
c856d01b52 | ||
|
|
7a535b2576 | ||
|
|
4b17fd88a3 | ||
|
|
8d1f3f723f | ||
|
|
a543fbbec9 | ||
|
|
37f50db00e | ||
|
|
ccb87f43b7 | ||
|
|
d569f39f53 | ||
|
|
fb3951772f | ||
|
|
2c00bf4040 | ||
|
|
4f8772bd77 | ||
|
|
b4c3046ab5 | ||
|
|
2441b92bc6 | ||
|
|
c39eec32f2 | ||
|
|
7837718d04 | ||
|
|
7069671471 | ||
|
|
d1dbde2890 | ||
|
|
0472471ac9 | ||
|
|
62a0b8da90 | ||
|
|
810530fabd | ||
|
|
707de56612 | ||
|
|
921b0eb229 | ||
|
|
9afb92f0ed | ||
|
|
1ded88e089 | ||
|
|
1f074ff400 | ||
|
|
4764f61b48 | ||
|
|
56424924bb | ||
|
|
4c3831ec74 | ||
|
|
ba564a6aed | ||
|
|
d529e88242 | ||
|
|
5d6ad8bc6c | ||
|
|
01769a6f38 | ||
|
|
a43cc38739 | ||
|
|
085069c2c7 | ||
|
|
816a6d057a | ||
|
|
19ab099f98 | ||
|
|
99a1097953 | ||
|
|
673cf7018b | ||
|
|
624f52882e | ||
|
|
654ab4a289 | ||
|
|
ec86dc5734 | ||
|
|
44f37c12c3 | ||
|
|
d0b704d7f4 | ||
|
|
7452942091 | ||
|
|
ea4ea680a2 | ||
|
|
ac7ae3d8df | ||
|
|
4fa5f2ac72 | ||
|
|
8b1a44fe42 | ||
|
|
c4d26f9194 | ||
|
|
79b59f2aae | ||
|
|
1eecd13ea7 | ||
|
|
1ae3a63f5c | ||
|
|
561694a991 | ||
|
|
096af016ef | ||
|
|
498835015a | ||
|
|
cafa0d6578 | ||
|
|
5444253ed6 | ||
|
|
d0ae12a167 | ||
|
|
e323c7f810 | ||
|
|
dd3758af43 | ||
|
|
94ae6e76f1 | ||
|
|
ee969a5ed9 | ||
|
|
a547a219a4 | ||
|
|
d4eba634ea | ||
|
|
0927897451 | ||
|
|
63e5a2c5ba | ||
|
|
a7f3f1d806 | ||
|
|
97d3a2986c | ||
|
|
d3b20757ef | ||
|
|
d99804f14e | ||
|
|
1b8dc71980 | ||
|
|
dc466f1480 | ||
|
|
ba6a783834 | ||
|
|
b2edf5683c | ||
|
|
dacb91b9a8 | ||
|
|
7ac71a7b2a | ||
|
|
4b44bb5426 | ||
|
|
8cd68c7c16 | ||
|
|
0ae228d6f8 | ||
|
|
6a2ed23822 | ||
|
|
fe0035fe0e | ||
|
|
aeabaf8513 | ||
|
|
43907e07c2 | ||
|
|
2413dc9a41 | ||
|
|
2d92c9d240 | ||
|
|
a24813b678 | ||
|
|
dffb2887d6 | ||
|
|
68f1c1a54c | ||
|
|
726aa7b894 | ||
|
|
44c795cd4f | ||
|
|
4d5d46d08a | ||
|
|
52cdff14bd | ||
|
|
0372167f25 | ||
|
|
005e401c7f | ||
|
|
479212dd60 | ||
|
|
0af9239906 | ||
|
|
13d871ab21 | ||
|
|
136830ce22 | ||
|
|
afe8e343b1 | ||
|
|
f7c2cdff9b | ||
|
|
a7abe97ca0 | ||
|
|
5354137c76 | ||
|
|
433c2e5916 | ||
|
|
e5fdda60fc | ||
|
|
b227cf890b | ||
|
|
0a4c3102dd | ||
|
|
54094ebc21 | ||
|
|
bf3fe6404a | ||
|
|
58888ac389 | ||
|
|
07df8ecc02 | ||
|
|
c86becb169 | ||
|
|
98a43606ce | ||
|
|
5b2353e612 | ||
|
|
a3ad598004 | ||
|
|
c02d1d73b8 | ||
|
|
77c99e1d7c | ||
|
|
055d34818a | ||
|
|
3a06503b74 | ||
|
|
cae15a8d7a | ||
|
|
70554d1158 | ||
|
|
db42da14d1 | ||
|
|
9daa9b6cca | ||
|
|
30087b5e79 | ||
|
|
c214b70459 | ||
|
|
ad0b6c28ba | ||
|
|
8127dc2620 | ||
|
|
fed5d3efc0 | ||
|
|
ed3c806869 | ||
|
|
b8a32eb086 | ||
|
|
e537ce155e | ||
|
|
be506964b0 | ||
|
|
df39b490f5 | ||
|
|
e3256e4bb9 | ||
|
|
4d01d636cc | ||
|
|
1bf07036e8 | ||
|
|
da058fcaf5 | ||
|
|
7203c91c70 | ||
|
|
44893a2a2c | ||
|
|
bdf2ca6e1d | ||
|
|
621ac3b6ec | ||
|
|
9fbf8b58a1 | ||
|
|
70ac55f983 | ||
|
|
890bb4a2c3 | ||
|
|
888f2aed97 | ||
|
|
e6707c65a5 | ||
|
|
414912de67 | ||
|
|
723ba740e0 | ||
|
|
e2389b4992 | ||
|
|
39e587085f | ||
|
|
42e77c77a9 | ||
|
|
e8353089f3 | ||
|
|
d76799cfd0 | ||
|
|
4907c20ba6 | ||
|
|
fa16a960a5 | ||
|
|
aa66e5ab15 | ||
|
|
802e4fc238 | ||
|
|
2494fec2a7 | ||
|
|
13db27854b | ||
|
|
190e17e6b9 | ||
|
|
02acd3162e | ||
|
|
47fa6e67d9 | ||
|
|
aba7b47fa8 | ||
|
|
c1ae4f8cc2 | ||
|
|
4f43793e17 | ||
|
|
8fd32ebd5e | ||
|
|
0b2059462b | ||
|
|
b0df41213a | ||
|
|
f421f30122 | ||
|
|
358ac46393 | ||
|
|
ebd98b9094 | ||
|
|
c713bb0353 | ||
|
|
d61a7b090d | ||
|
|
9f1a894b86 | ||
|
|
cc86d73719 | ||
|
|
86b1802d16 | ||
|
|
3cdf66a0a4 | ||
|
|
faeee200d3 | ||
|
|
4b34734919 | ||
|
|
765c1b8875 | ||
|
|
f89cefd9ae | ||
|
|
23dfa8645c | ||
|
|
9556e7bf51 | ||
|
|
7fa306dd9a | ||
|
|
d9a322b533 | ||
|
|
fde1b21d1f | ||
|
|
124249a35d | ||
|
|
6d6e9a6df7 | ||
|
|
77ae9dfbef | ||
|
|
4ed642ed5d | ||
|
|
556be02696 | ||
|
|
572418a2f5 | ||
|
|
fce742910e | ||
|
|
370b0cb049 | ||
|
|
76333b8647 | ||
|
|
ce7d12e850 | ||
|
|
63d92c62a5 | ||
|
|
7e2720e673 | ||
|
|
a7c0ea3602 | ||
|
|
374829ecd5 | ||
|
|
6a67c04ca2 | ||
|
|
f4ce087649 | ||
|
|
4566ce7de8 | ||
|
|
a898e61a7a | ||
|
|
6d524bdc99 | ||
|
|
1ba21f7f71 | ||
|
|
7f710e0782 | ||
|
|
acb78c18bf | ||
|
|
5b1f632035 | ||
|
|
8aca739f54 | ||
|
|
efdfcee7fc | ||
|
|
1b4cb1379a | ||
|
|
820d7f18c4 | ||
|
|
7a5a5e0211 | ||
|
|
07dda233ec | ||
|
|
02209fc039 | ||
|
|
a372882c18 | ||
|
|
91c05598b2 | ||
|
|
0130ab6356 | ||
|
|
581a3f8388 | ||
|
|
2587ad21c0 | ||
|
|
8b56349daa | ||
|
|
25f2eb69b9 | ||
|
|
46b4761f1a | ||
|
|
4d3f96f979 | ||
|
|
084371a1e3 | ||
|
|
f5aaaf1c63 | ||
|
|
316bab6fff | ||
|
|
65a5d38fc6 | ||
|
|
aa927e9168 | ||
|
|
7b0a120e66 | ||
|
|
143ce58cb3 | ||
|
|
9244b44ce6 | ||
|
|
4720312b26 | ||
|
|
d43610701b | ||
|
|
243b0b2c21 | ||
|
|
930894ced5 | ||
|
|
63ce7850e1 | ||
|
|
984a38ce91 | ||
|
|
12ce2275e0 | ||
|
|
214b88ea1c | ||
|
|
980e00e824 | ||
|
|
80276d5e4d | ||
|
|
28c2db9edc | ||
|
|
5e66f70cf0 | ||
|
|
4e41187bf3 | ||
|
|
0a09760aec | ||
|
|
500ad62470 | ||
|
|
1204d98e8d | ||
|
|
ae3596ac99 | ||
|
|
d662c693f1 | ||
|
|
1820cd0ae8 | ||
|
|
c5e144d211 | ||
|
|
e1c041a250 | ||
|
|
82dff86802 | ||
|
|
b2019d7633 | ||
|
|
f6afea0004 | ||
|
|
309eb502cd | ||
|
|
712252eb6b | ||
|
|
c3baf36eb5 | ||
|
|
771fd77088 | ||
|
|
7d3ac21e42 | ||
|
|
cc3a72f4fd | ||
|
|
d87fa374ec | ||
|
|
154a576388 | ||
|
|
29fe71b82c | ||
|
|
e960fd31fa | ||
|
|
132fb87c2c | ||
|
|
6e281e0b66 | ||
|
|
a86ff9dfd1 | ||
|
|
3ea33f1dd6 | ||
|
|
b645fd495f | ||
|
|
5e635224e2 | ||
|
|
54d8becd74 | ||
|
|
87243537e7 | ||
|
|
0604361d4e | ||
|
|
399c052129 | ||
|
|
362c7e9c04 | ||
|
|
c4843253c0 | ||
|
|
928d8dbb15 | ||
|
|
7f528d8d4a | ||
|
|
8ddf4a0e72 | ||
|
|
5c589136e5 | ||
|
|
00f10771d9 | ||
|
|
583a5cda61 | ||
|
|
f9e5ebccfd | ||
|
|
77eebb6c1b | ||
|
|
53d01e5fe1 | ||
|
|
3d08e8db06 | ||
|
|
50a3ce2036 | ||
|
|
a127948c4c | ||
|
|
36b406f7ec | ||
|
|
3c50e9f784 | ||
|
|
51e2af148e | ||
|
|
d7351f97fe | ||
|
|
1a042fab4b | ||
|
|
c3f000c5ef | ||
|
|
e848dd5bee | ||
|
|
566e11f755 | ||
|
|
13aa00e465 | ||
|
|
e9df060e0c | ||
|
|
c4724e8020 | ||
|
|
9c36087dae | ||
|
|
51c3ebcdb8 | ||
|
|
f29e4a5d36 | ||
|
|
99dd04a1c1 | ||
|
|
29c47e3e96 | ||
|
|
659248ff22 | ||
|
|
71a7e8d2dc | ||
|
|
caabdc6584 | ||
|
|
0b92d2ec17 | ||
|
|
db8bcd8fd6 | ||
|
|
17cb96ef41 | ||
|
|
2248380c90 | ||
|
|
ffe64d2f8f | ||
|
|
a0c624fca6 | ||
|
|
31022ea8de | ||
|
|
0d0de4d5b3 | ||
|
|
1fdb4c4627 | ||
|
|
76665c54e2 | ||
|
|
04166766da | ||
|
|
aa7f903210 | ||
|
|
c4ca53cdf9 | ||
|
|
d5885acd6e | ||
|
|
550b3332a3 | ||
|
|
93b98576b8 | ||
|
|
e6f2c25167 | ||
|
|
0b207c6141 | ||
|
|
3ed5e85646 | ||
|
|
4068da33c8 | ||
|
|
d1d53ee65b | ||
|
|
38413c4f64 | ||
|
|
a6bb6cd170 | ||
|
|
145bf70420 | ||
|
|
e2c92c57e6 | ||
|
|
1fa59270c1 | ||
|
|
d5c1fda958 | ||
|
|
b0e34fd062 | ||
|
|
8fbf8df0bd | ||
|
|
bcc2173768 | ||
|
|
aa1df53ab0 | ||
|
|
fb6a2a2c37 | ||
|
|
f403fc732c | ||
|
|
03aa7c56a2 | ||
|
|
547d6d4bcc | ||
|
|
2cba8f906d | ||
|
|
bb5ee6a347 | ||
|
|
34604efde4 | ||
|
|
c232a4fbad | ||
|
|
0c5dfdbe24 | ||
|
|
c0f9a382b3 | ||
|
|
8ca32fcace | ||
|
|
0461a9fc89 | ||
|
|
2b600290ae | ||
|
|
56fd3f2566 | ||
|
|
142e06e752 | ||
|
|
cbf2a047be | ||
|
|
1880e22d22 | ||
|
|
963b1eae1c | ||
|
|
d173573e6c | ||
|
|
b6c0426c1c | ||
|
|
4f18e9ee7f | ||
|
|
e227b90370 | ||
|
|
360b112bd2 | ||
|
|
ff7027439d | ||
|
|
a5ed91611a | ||
|
|
168b1c3684 | ||
|
|
7e1141ff16 | ||
|
|
168d55c54c | ||
|
|
d5ed2bc765 | ||
|
|
940a4613ee | ||
|
|
4f6d96e16b | ||
|
|
707d9925a8 | ||
|
|
657340c912 | ||
|
|
3e220704a1 | ||
|
|
4a2309a3f8 | ||
|
|
09122be7be | ||
|
|
e26ec47ad7 | ||
|
|
05ae73eea2 | ||
|
|
511d2b9457 | ||
|
|
bf96c24ec3 | ||
|
|
e328ec990c | ||
|
|
a5dee0cb27 | ||
|
|
7fb5d5bde5 | ||
|
|
5a329b4a6d | ||
|
|
500f6c5b6f | ||
|
|
29f76ba62a | ||
|
|
70e0c84a20 | ||
|
|
3dd95180e0 | ||
|
|
dcd8fc0320 | ||
|
|
bcd9fb0be9 | ||
|
|
a088d20612 | ||
|
|
29fb347bbb | ||
|
|
b2a436b3bc | ||
|
|
d288912df1 | ||
|
|
7bde6baaac | ||
|
|
26ca6d9b77 | ||
|
|
961626a136 | ||
|
|
641a311537 | ||
|
|
995ba02357 | ||
|
|
fb3e6e4208 | ||
|
|
e5363f7c8f | ||
|
|
d1a128b897 | ||
|
|
2b5fb4d75a | ||
|
|
6439ddde23 | ||
|
|
f2994ed4ff | ||
|
|
019bf67f93 | ||
|
|
78c1dcd0d0 | ||
|
|
e07b30df85 | ||
|
|
96cd517c36 | ||
|
|
2cb8e00c99 | ||
|
|
92f093009e | ||
|
|
27256a1854 | ||
|
|
ba782ca56f | ||
|
|
3f3e33a366 | ||
|
|
343fd75477 | ||
|
|
7bcfb6ff49 | ||
|
|
78ec08792f | ||
|
|
461b41f300 | ||
|
|
5b246424fb | ||
|
|
6af4b4cd5e | ||
|
|
6d348eb5a7 | ||
|
|
b26f6b697a | ||
|
|
554510bb78 | ||
|
|
3f2e5b7c69 | ||
|
|
3c4989f5ca | ||
|
|
d33c649be6 | ||
|
|
c55954e5e8 | ||
|
|
678311e65b | ||
|
|
ab1d3075e8 | ||
|
|
0a6f8b7ac1 | ||
|
|
422a1f78fc | ||
|
|
f21af8bd1e | ||
|
|
924278e387 | ||
|
|
c6ea4466fb | ||
|
|
318cc7a8fb | ||
|
|
9554a30286 | ||
|
|
5336da52d9 | ||
|
|
bd0c2e4ee4 | ||
|
|
64aad66adc | ||
|
|
587bf131db | ||
|
|
fc96c727ec | ||
|
|
d17bd5bd9e | ||
|
|
b22a935a6c | ||
|
|
a7c1d594dc | ||
|
|
dd20a9c7cc | ||
|
|
e0994e0e54 | ||
|
|
0f8ce09646 | ||
|
|
871e27d19f | ||
|
|
c429df3280 | ||
|
|
13f355c385 | ||
|
|
d33ddefb2d | ||
|
|
75b3f4b3c8 | ||
|
|
03ce1d2ea8 | ||
|
|
08eae2b09c | ||
|
|
c94f9e2d2b | ||
|
|
520370688c | ||
|
|
725949db2f | ||
|
|
5d647155b6 | ||
|
|
c152bd0517 | ||
|
|
f35146d93d | ||
|
|
e8e58555d0 | ||
|
|
7190dcc04e | ||
|
|
b623e3b3c8 | ||
|
|
d78e82bd56 | ||
|
|
ff478253e3 | ||
|
|
85c3368cda | ||
|
|
a4095cec8d | ||
|
|
c840ce249f | ||
|
|
b70812fc3d | ||
|
|
3ccf06321d | ||
|
|
1d5dd5ea11 | ||
|
|
0cadd88769 | ||
|
|
75499a3321 | ||
|
|
5096027523 | ||
|
|
5c8c07794d | ||
|
|
18a72bbb59 | ||
|
|
7b3c4475da | ||
|
|
419c446f01 | ||
|
|
735c16cc11 | ||
|
|
ed41abcf9d | ||
|
|
b750a8c802 | ||
|
|
1ee75dd8cb | ||
|
|
396efad518 | ||
|
|
8f33be262a | ||
|
|
9daa111f9c | ||
|
|
889bf22840 | ||
|
|
f46e96c7de | ||
|
|
9be6dc2935 | ||
|
|
6188f6d74a | ||
|
|
8837fab9fa | ||
|
|
316339011b | ||
|
|
fe7121e057 | ||
|
|
bc09bfd3ba | ||
|
|
26f19cead1 | ||
|
|
777b35f412 | ||
|
|
9e94ffb422 | ||
|
|
b6a38bf4d1 | ||
|
|
92d12ec68e | ||
|
|
93dd5e4b31 | ||
|
|
79e325e2ab | ||
|
|
0e095018a4 | ||
|
|
7040071ab9 | ||
|
|
e157350d03 | ||
|
|
28f6ef5eec | ||
|
|
15bcee3d10 | ||
|
|
67dbf70f5b | ||
|
|
c75b99837f | ||
|
|
cbc951be62 | ||
|
|
f5b38852a7 | ||
|
|
45b5fd3762 | ||
|
|
04c14f3a27 | ||
|
|
a55d89cc93 | ||
|
|
888801ab0c | ||
|
|
731528ef6e | ||
|
|
d7fbd0df47 | ||
|
|
6f95e6d499 | ||
|
|
79e6a13b29 | ||
|
|
b9a53775b6 | ||
|
|
1b15603227 | ||
|
|
a7ffeb7016 | ||
|
|
13b1c0fe0c | ||
|
|
1d259c510f | ||
|
|
56783bbf4d | ||
|
|
e63c296b16 | ||
|
|
57450a65cf | ||
|
|
716b52ef90 | ||
|
|
6ab8552f44 | ||
|
|
9880483690 | ||
|
|
7b9b459b74 | ||
|
|
0723606120 | ||
|
|
4261e9eb29 | ||
|
|
a322556c66 | ||
|
|
b6d3efa042 | ||
|
|
4019a0615c | ||
|
|
376e486c47 | ||
|
|
5b7c47682b | ||
|
|
741a803ea7 | ||
|
|
8a886f5434 | ||
|
|
01514af188 | ||
|
|
c5d5dccc57 | ||
|
|
5e58304448 | ||
|
|
dd9c4bfa42 | ||
|
|
e6a559f0d1 | ||
|
|
f1c860f68c | ||
|
|
cd175816e2 | ||
|
|
1d74d2e241 | ||
|
|
c4479a36a9 | ||
|
|
cc2c18243e | ||
|
|
211d34fcef | ||
|
|
dc60c24d89 | ||
|
|
922e6437cf | ||
|
|
1058157827 | ||
|
|
33b38e686a | ||
|
|
a6014f30dd | ||
|
|
3fc75df55d | ||
|
|
2bcd9d78e8 | ||
|
|
723b9e9cea | ||
|
|
efb7088cd8 | ||
|
|
f2131102f5 | ||
|
|
eae04bb156 | ||
|
|
11716128df | ||
|
|
5122808189 | ||
|
|
3c1905f941 | ||
|
|
3348086c00 | ||
|
|
919efc5037 | ||
|
|
04ab0e09d5 | ||
|
|
c8862cb927 | ||
|
|
ac135ec2b6 | ||
|
|
0257000d1a | ||
|
|
608b95e941 | ||
|
|
e6a2c5b5b4 | ||
|
|
a546aadba1 | ||
|
|
5934588b2c | ||
|
|
3ad5482a30 | ||
|
|
c3902447af | ||
|
|
764aa466f4 | ||
|
|
9ffda6cd17 | ||
|
|
8281fb09fc | ||
|
|
b6988f96fb | ||
|
|
4597c13d9a | ||
|
|
acf7297c8d | ||
|
|
bbdc8298d9 | ||
|
|
4d9f102033 | ||
|
|
0056e1052c | ||
|
|
7b729e078b | ||
|
|
6a0623f1e7 | ||
|
|
542c871152 | ||
|
|
77189eeeb1 | ||
|
|
340172ab56 | ||
|
|
afcfed1c67 | ||
|
|
59ce3bb64d | ||
|
|
81c5aa73d2 | ||
|
|
12ff05208c | ||
|
|
dc0ef70699 | ||
|
|
6ce735dcc7 | ||
|
|
faf3298f7a | ||
|
|
4f1b6b4bf1 | ||
|
|
99702fdb67 | ||
|
|
7bce7691e4 | ||
|
|
7f90160936 | ||
|
|
f367ad7185 | ||
|
|
29a31476b1 | ||
|
|
b844b66614 | ||
|
|
3e6fa1ed1f | ||
|
|
e141b4eb9f | ||
|
|
c794194bb5 | ||
|
|
3a31902e78 | ||
|
|
fedafe55c3 | ||
|
|
1c0b885267 | ||
|
|
8e4791048b | ||
|
|
e28be6f2b7 | ||
|
|
55271b8e83 | ||
|
|
8b5d8679f7 | ||
|
|
51d8ced8ce | ||
|
|
1cc94dd60b | ||
|
|
6d107e79b6 | ||
|
|
6f44b4dce1 | ||
|
|
1600492780 | ||
|
|
5f396cc647 | ||
|
|
49bd45d88c | ||
|
|
c41e673346 | ||
|
|
cf8d1a490c | ||
|
|
962f20296c | ||
|
|
e9c1ae1893 | ||
|
|
5db51a2abf | ||
|
|
63be1efed9 | ||
|
|
7fe3c659e0 | ||
|
|
4d76c7685c | ||
|
|
b50bcde028 | ||
|
|
9a8b61ae47 | ||
|
|
c31880d8de | ||
|
|
1496dc8e7d | ||
|
|
cdbd513e42 | ||
|
|
653bf1764e | ||
|
|
df08acfe9e | ||
|
|
e7a5287bb4 | ||
|
|
656f26cc9d | ||
|
|
52385ddac4 | ||
|
|
50c58667ba | ||
|
|
9cc6ca5ebe | ||
|
|
34b82a3f84 | ||
|
|
d0401f3f8d | ||
|
|
f247978d12 | ||
|
|
999116c75e | ||
|
|
04e9f5b15b | ||
|
|
78b0f7798f | ||
|
|
b0727ef3cf | ||
|
|
01fb31fc15 | ||
|
|
a1187acc31 | ||
|
|
fe4a24a651 | ||
|
|
3dcce572d3 | ||
|
|
ece69014ce | ||
|
|
fc6bb67e56 | ||
|
|
968de2947b | ||
|
|
6f9ba0033f | ||
|
|
4d4672fc4d | ||
|
|
70859eb719 | ||
|
|
ae9daf7f33 | ||
|
|
ff0daa8d66 | ||
|
|
09f1a0ac92 | ||
|
|
e562be77f6 | ||
|
|
af7c6bc2a0 | ||
|
|
e49cbcf345 | ||
|
|
b4218ff0e8 | ||
|
|
4af174d27b | ||
|
|
203a7da23a | ||
|
|
9833ff20d1 | ||
|
|
638b3c0695 | ||
|
|
01ef2e1061 | ||
|
|
56aea8ad24 | ||
|
|
d530eddc57 | ||
|
|
1eab76aab8 | ||
|
|
167dbd7368 | ||
|
|
2594fb1c5f | ||
|
|
c57d21e9bc | ||
|
|
9c15bdfe41 | ||
|
|
64dedf892d | ||
|
|
d6fc456039 | ||
|
|
df606674db | ||
|
|
1e3a7ff4ba | ||
|
|
b53de8c69b | ||
|
|
0f3ffaf270 | ||
|
|
25238d5fb5 | ||
|
|
cf677bd70e | ||
|
|
42939e4922 | ||
|
|
7c4cc1334b | ||
|
|
ff4a1e0ac6 | ||
|
|
069e22049d | ||
|
|
135ed5c614 | ||
|
|
13d7d29630 | ||
|
|
889f315c0a | ||
|
|
5a0e280899 | ||
|
|
ccb5e234b3 | ||
|
|
2caccab85f | ||
|
|
085ab48f3f | ||
|
|
a28c2819fa | ||
|
|
40beec2e40 | ||
|
|
d136aeda84 | ||
|
|
fdd6c47cd5 | ||
|
|
c5a2b5b3d8 | ||
|
|
babe4739c5 | ||
|
|
49e8ee443c | ||
|
|
a5d8ce07d8 | ||
|
|
babc016b48 | ||
|
|
a5f378d755 | ||
|
|
ebf995537e | ||
|
|
49edb6c2e1 | ||
|
|
423f26852f | ||
|
|
f931412bee | ||
|
|
bef0657801 | ||
|
|
d79d5b5f33 | ||
|
|
4c5489efd3 | ||
|
|
d5753b9589 | ||
|
|
a841027d48 | ||
|
|
73bea8e63f | ||
|
|
bbc8bab4da | ||
|
|
019f6dfb8b | ||
|
|
3b6a2a2908 | ||
|
|
c2b757ad6f | ||
|
|
efeba40f2b | ||
|
|
018e4bc382 | ||
|
|
88924ea520 | ||
|
|
4461c2e4a4 | ||
|
|
1c4aceb0fb | ||
|
|
a5b396a60d | ||
|
|
efd96ed892 | ||
|
|
fe88785846 | ||
|
|
0dcb0fb325 | ||
|
|
0825843d0f | ||
|
|
8c4df134e4 | ||
|
|
dfed5067f3 | ||
|
|
2b78e8fdc1 | ||
|
|
63c7a9d926 | ||
|
|
6609481cc1 | ||
|
|
a37853def6 | ||
|
|
9f348cfa16 | ||
|
|
52293f2596 | ||
|
|
54d3a73282 | ||
|
|
ab2d3b70cb | ||
|
|
451df460f6 | ||
|
|
b4afa01887 | ||
|
|
2ea95f5bf9 | ||
|
|
22602f42f2 | ||
|
|
b2c5183043 | ||
|
|
9f6559c7fb | ||
|
|
ef04c16237 | ||
|
|
dd85bfd2ab | ||
|
|
7152a05bfd | ||
|
|
754c2fc9bf | ||
|
|
85ad0b881f | ||
|
|
db6c471cc6 | ||
|
|
300d990276 | ||
|
|
9c55b889cb | ||
|
|
735f76cc0b | ||
|
|
d1c27a4298 | ||
|
|
650f09bbc5 | ||
|
|
08bf16971a | ||
|
|
ccb149240e | ||
|
|
ae22719985 | ||
|
|
55c4d729bb | ||
|
|
429f0966f0 | ||
|
|
7a246b90b9 | ||
|
|
d2e7de5505 | ||
|
|
a9eab16502 | ||
|
|
d59cce8080 | ||
|
|
9390e71dd9 | ||
|
|
65992243fa | ||
|
|
c81b8b0171 | ||
|
|
0671d12628 | ||
|
|
a892c5e7b7 | ||
|
|
b5c21ffbf0 | ||
|
|
bb2b25cca5 | ||
|
|
b3867244ba | ||
|
|
6bf8d396e0 | ||
|
|
6394c1a7b4 | ||
|
|
ccd656845d | ||
|
|
2931e8454c | ||
|
|
112b158795 | ||
|
|
921001000f | ||
|
|
3e3a8e9f98 | ||
|
|
7440a039fd | ||
|
|
e73f9ab02f | ||
|
|
59815b858e | ||
|
|
7df7f59d93 | ||
|
|
e971bc1991 | ||
|
|
a3f0f12779 | ||
|
|
2a9c214593 | ||
|
|
3fc37f3e5e | ||
|
|
ebe4423e25 | ||
|
|
cfafb4a101 | ||
|
|
8d538a9977 | ||
|
|
cc2953d6a3 | ||
|
|
c888019068 | ||
|
|
56639d3965 | ||
|
|
09ff99823e | ||
|
|
5078e32dc7 | ||
|
|
ecaadff0d8 | ||
|
|
f2ad8cc7d1 | ||
|
|
c8d77eb213 | ||
|
|
fe3d9e8bf6 | ||
|
|
6c4171be75 | ||
|
|
4bbb466e43 | ||
|
|
c478415667 | ||
|
|
fc832b67c5 | ||
|
|
943a9ea97e | ||
|
|
2c7ab297d7 | ||
|
|
d8299f7db1 | ||
|
|
4deeb33f08 | ||
|
|
3bf4cf8c85 | ||
|
|
e0217fc6c3 | ||
|
|
62a3efa23a | ||
|
|
cc7ebe6d52 | ||
|
|
5d920e4b44 | ||
|
|
1264ea54a1 | ||
|
|
caa1d77d23 | ||
|
|
20a55b3342 | ||
|
|
8bfe67fc60 | ||
|
|
d42a1c6ab1 | ||
|
|
80a89ef6d1 | ||
|
|
1a0e605f0c | ||
|
|
573c8eb509 | ||
|
|
e676e3a14b | ||
|
|
af8c807ee0 | ||
|
|
dfaa5df965 | ||
|
|
32055ecdcc | ||
|
|
9db71c5f0c | ||
|
|
99856bf285 | ||
|
|
4d006b3e05 | ||
|
|
4e37165ba6 | ||
|
|
38a5834785 | ||
|
|
d6e1352869 | ||
|
|
bf1b7bd7a2 | ||
|
|
2306327057 | ||
|
|
2d389ba73f | ||
|
|
ce8d5bc635 | ||
|
|
8fdc2007e0 | ||
|
|
88a97769de | ||
|
|
589c761cb0 | ||
|
|
3e6787fd61 | ||
|
|
aff52ee3f5 | ||
|
|
4555b02592 | ||
|
|
e1d4599a93 | ||
|
|
1a1e141cb8 | ||
|
|
33218f41e8 | ||
|
|
8772cda47a | ||
|
|
512eb713e4 | ||
|
|
0f90d48c62 | ||
|
|
658860e396 | ||
|
|
7522dae557 | ||
|
|
e34e65a3ba | ||
|
|
5a001a2c32 | ||
|
|
13a03eb250 | ||
|
|
cd863b6cca | ||
|
|
83b182dda5 | ||
|
|
3b90d1a564 | ||
|
|
d724855dfc | ||
|
|
78008330fe | ||
|
|
e716aad224 | ||
|
|
aa0d7cb4e9 | ||
|
|
0cd43ce35c | ||
|
|
ac98c8e395 | ||
|
|
70a8fc09c6 | ||
|
|
5b00d05e2e | ||
|
|
28c1730a02 | ||
|
|
c54483d36f | ||
|
|
2dd02ff8cb | ||
|
|
46c5501b7a | ||
|
|
f154826749 | ||
|
|
96383ef985 | ||
|
|
ab4b19dbab | ||
|
|
cdc53ac570 | ||
|
|
143cc1912e | ||
|
|
0d90b676bc | ||
|
|
5fadbb3d25 | ||
|
|
0ec99a3e12 | ||
|
|
1efbc44cc4 | ||
|
|
735fcfeee2 | ||
|
|
4a77150566 | ||
|
|
180a420219 | ||
|
|
d12ba8f3ef | ||
|
|
f333ef76d9 | ||
|
|
af5ba6854e | ||
|
|
8b7ce06793 | ||
|
|
297a5e516f | ||
|
|
92b11526be | ||
|
|
299350f655 | ||
|
|
127eafc9b3 | ||
|
|
ad1ad3a997 | ||
|
|
82151c5b3f | ||
|
|
90457c89ff | ||
|
|
3f3ac86d38 | ||
|
|
aa126039e5 | ||
|
|
662815b1ee | ||
|
|
243c36849c | ||
|
|
52d5baaf3f | ||
|
|
89217f778e | ||
|
|
9bc9bc9169 | ||
|
|
6b73430473 | ||
|
|
5ca5bca3df | ||
|
|
89ab382a18 | ||
|
|
bad425c0d7 | ||
|
|
cdbbb1b94c | ||
|
|
0a9d8a9b22 | ||
|
|
e662041d06 | ||
|
|
155464bc87 | ||
|
|
06cd811ae4 | ||
|
|
1b2cd354db | ||
|
|
1b31268f59 | ||
|
|
b57ef7291f | ||
|
|
c3bf6aa3f8 | ||
|
|
d2fa14bbe2 | ||
|
|
9b6e55e90c | ||
|
|
afb07b651f | ||
|
|
e6806fdf2b | ||
|
|
e5ff2cff4e | ||
|
|
17d7d47b9a | ||
|
|
64e32061ab | ||
|
|
931110ba6c | ||
|
|
d90e7820cd | ||
|
|
824898dba5 | ||
|
|
761dd61ed4 | ||
|
|
89c63e6d87 | ||
|
|
a2361f9327 | ||
|
|
ea15205be8 | ||
|
|
0a45048535 | ||
|
|
1c51655ce3 | ||
|
|
7749f0da7c | ||
|
|
5695238f95 | ||
|
|
e1feeb7e21 | ||
|
|
84fecaf040 | ||
|
|
da77727673 | ||
|
|
f8c913a3e8 | ||
|
|
2024881ee1 | ||
|
|
35ed3a51e5 | ||
|
|
24b1c4d0a4 | ||
|
|
7ec2458fb5 | ||
|
|
175feaea23 | ||
|
|
dda6cf728b | ||
|
|
a7fd410b01 | ||
|
|
d281c36733 | ||
|
|
dc91e44c0a | ||
|
|
7967a858f4 | ||
|
|
2081407e38 | ||
|
|
976eabd527 | ||
|
|
b6d6a5de2b | ||
|
|
2d58cfe0ce | ||
|
|
9df8bdff5f | ||
|
|
c86b821951 | ||
|
|
4def086bf9 | ||
|
|
885c890d7d | ||
|
|
06060a6694 | ||
|
|
70667814f6 | ||
|
|
766b7a940c | ||
|
|
0c37586357 | ||
|
|
b4aa55ce1f | ||
|
|
109443ce77 | ||
|
|
5f38741831 | ||
|
|
c6f391501d | ||
|
|
d1f3105fbd | ||
|
|
8f88ca9d3d | ||
|
|
f9e4ca0cc2 | ||
|
|
5caf023677 | ||
|
|
35c2f4873c | ||
|
|
1ed7bab375 | ||
|
|
f0d1bfb777 | ||
|
|
42519ac843 | ||
|
|
8869e13385 | ||
|
|
8f9cbfe806 | ||
|
|
6481938626 | ||
|
|
9c7cc2acbf | ||
|
|
89a57d4ed3 | ||
|
|
732378592b | ||
|
|
19dc46660b | ||
|
|
4aad3471af | ||
|
|
533b455356 | ||
|
|
92bd305b00 | ||
|
|
f71eb09f74 | ||
|
|
83d4a7bc18 | ||
|
|
58807d9021 | ||
|
|
29595324c4 | ||
|
|
f9064e526f | ||
|
|
93ec2e8639 | ||
|
|
0e2a31709a | ||
|
|
c785b39eda | ||
|
|
8fab2f58da | ||
|
|
e44ee3bfe1 | ||
|
|
62065c9d28 | ||
|
|
c76275275f | ||
|
|
257f78879d | ||
|
|
894263809c | ||
|
|
bc9458101c | ||
|
|
c503935d6a | ||
|
|
d4756c9eb8 | ||
|
|
0004767775 | ||
|
|
74908642c7 | ||
|
|
aadfb71c98 | ||
|
|
1244af649d | ||
|
|
7bd48cc811 | ||
|
|
8f3ce38418 | ||
|
|
1b2d9b4245 | ||
|
|
c6b2b34fde | ||
|
|
e58fc13fdb | ||
|
|
922d53d2e4 | ||
|
|
fec53b3951 | ||
|
|
e72e2c6a02 | ||
|
|
08d001ee05 | ||
|
|
99d8a07f4a | ||
|
|
eef565134b | ||
|
|
9d78293437 | ||
|
|
fc0a556e5f | ||
|
|
b6b070584f | ||
|
|
e13225eee6 | ||
|
|
da20fb2922 | ||
|
|
459c2beb12 | ||
|
|
f1cc44dead | ||
|
|
d24cfdc382 | ||
|
|
ae4cc543f6 | ||
|
|
abdb3d17f9 | ||
|
|
4095c5da38 | ||
|
|
78fab728e4 | ||
|
|
52097a6867 | ||
|
|
cb990b55b5 | ||
|
|
5070fe303a | ||
|
|
b4405ebf3e | ||
|
|
d9e6bf5068 | ||
|
|
6822188f52 | ||
|
|
15858d03ff | ||
|
|
814a733258 | ||
|
|
3ce85d8ca9 | ||
|
|
d3bff2f39d | ||
|
|
f2272730ac | ||
|
|
fe19c97d86 | ||
|
|
d49556bf3d | ||
|
|
56b447493e | ||
|
|
e45b68eda7 | ||
|
|
8df1ef5986 | ||
|
|
dac34cda82 | ||
|
|
9925e30c8b | ||
|
|
dc5566b5ae | ||
|
|
8132ee651a | ||
|
|
f49a134a3d | ||
|
|
bd955cda06 | ||
|
|
c6dbc01912 | ||
|
|
fabe1aa940 | ||
|
|
ba5dbb94b8 | ||
|
|
6ccc053d7e | ||
|
|
cf21dfaa3a | ||
|
|
54ceb630de | ||
|
|
0a0c302cb2 | ||
|
|
f6eef54566 | ||
|
|
a69804f84d | ||
|
|
0b06b194b0 | ||
|
|
73f6ce304c | ||
|
|
195818a432 | ||
|
|
47c817de1c | ||
|
|
8b3894f213 | ||
|
|
a411252f07 | ||
|
|
d7626aeb3f | ||
|
|
3565098650 | ||
|
|
803fcf146b | ||
|
|
d9d646c5fb | ||
|
|
034a274b07 | ||
|
|
718d7af8bc | ||
|
|
860d3d9c8b | ||
|
|
f28b566992 | ||
|
|
1c261c7463 | ||
|
|
226b2482b1 | ||
|
|
ff346dc429 | ||
|
|
2dcef25175 | ||
|
|
46702bbb5c | ||
|
|
5600c9bc69 | ||
|
|
d7e46b1693 | ||
|
|
fe8c60ade1 | ||
|
|
288892441f | ||
|
|
e1179a8e22 | ||
|
|
4b06d0fd87 | ||
|
|
464d91f45a | ||
|
|
5cc7aa25cc | ||
|
|
20ec224070 | ||
|
|
9cbcc29ddb | ||
|
|
0badbfc4a0 | ||
|
|
e042148c62 | ||
|
|
d8ba04ae7f | ||
|
|
314d5fdad2 | ||
|
|
5c874cafd1 | ||
|
|
8cafc14d09 | ||
|
|
25ac5033fc | ||
|
|
848be0db6c | ||
|
|
0f9da0731e | ||
|
|
8bc2364cce | ||
|
|
b64916ce3f | ||
|
|
452955667c | ||
|
|
f38bbf4cc7 | ||
|
|
25eaa11a52 | ||
|
|
4b4da8d467 | ||
|
|
13116c5381 | ||
|
|
d2cd406a62 | ||
|
|
acbce05fbf | ||
|
|
bee4d3a338 | ||
|
|
b9003a2f02 | ||
|
|
bce226002b | ||
|
|
a417db7c7a | ||
|
|
0ffef12a8b | ||
|
|
4539b040e0 | ||
|
|
f85014a86d | ||
|
|
d90d07c68b | ||
|
|
ce292b84fa | ||
|
|
01690860db | ||
|
|
89fb2d4915 | ||
|
|
5cc3a42832 | ||
|
|
6b303410d1 | ||
|
|
60b0145e04 | ||
|
|
8cae2f24b1 | ||
|
|
ce48823d38 | ||
|
|
0a04d753ea | ||
|
|
d43fee5585 | ||
|
|
35402c7bd3 | ||
|
|
5dc9e51dd4 | ||
|
|
847a97f61c | ||
|
|
235fcccbd7 | ||
|
|
fac27a6120 | ||
|
|
91c971b8fd | ||
|
|
2e24eda00d | ||
|
|
e43003cadc | ||
|
|
7a653abf22 | ||
|
|
9a96165655 | ||
|
|
ae09229107 | ||
|
|
994aef411c | ||
|
|
be35f48bdd | ||
|
|
094a180935 | ||
|
|
846173844e | ||
|
|
74e9de6370 | ||
|
|
59c28d8e51 | ||
|
|
c7f31b3d79 | ||
|
|
abdfa3ccf6 | ||
|
|
98d0239d03 | ||
|
|
99ad6634c4 | ||
|
|
ffeab147ce | ||
|
|
84556fb055 | ||
|
|
90bdbd6b84 | ||
|
|
26e14e0151 | ||
|
|
e29dd3cd33 | ||
|
|
3df2daa5cb | ||
|
|
23b95178ff | ||
|
|
c55efddc81 | ||
|
|
9bde80357f | ||
|
|
a59c8908f0 | ||
|
|
1485733715 | ||
|
|
a421c5f952 | ||
|
|
d125a7f09d | ||
|
|
37b0612d45 | ||
|
|
77486dffd4 | ||
|
|
07bc94f9f6 | ||
|
|
c84bcb433f | ||
|
|
82511880ac | ||
|
|
f1e5221257 | ||
|
|
2f5cc6a8a4 | ||
|
|
b8bf01acc3 | ||
|
|
f9a0f5e7a1 | ||
|
|
65aa7bd1de | ||
|
|
47b083eaca | ||
|
|
6f511444a7 | ||
|
|
8fcf5ee760 | ||
|
|
ef5174d89f | ||
|
|
f2006206d3 | ||
|
|
e2a97e75d8 | ||
|
|
c32361a428 | ||
|
|
9fc6e265eb | ||
|
|
ac83c2bc3c | ||
|
|
f81c42b1fd | ||
|
|
32808c16e7 | ||
|
|
8594e146eb | ||
|
|
e4e2433396 | ||
|
|
cda0dfdafe | ||
|
|
8196b6e69e | ||
|
|
363568b02c | ||
|
|
8dd49b6156 | ||
|
|
443ab02788 | ||
|
|
c4ab83a801 | ||
|
|
65784d6dc4 | ||
|
|
2c51b7b835 | ||
|
|
da805d037f | ||
|
|
bab49d04b7 | ||
|
|
d383776245 | ||
|
|
6963d66240 | ||
|
|
51eba8da73 | ||
|
|
8cbf3ffc6b | ||
|
|
14b4d64244 | ||
|
|
2a4693f6ed | ||
|
|
7cb7f68cda | ||
|
|
217256746c | ||
|
|
83300d028b | ||
|
|
6c90225024 | ||
|
|
e891ce39c0 | ||
|
|
92d8a894e3 | ||
|
|
e58b7782ac | ||
|
|
c89d619808 | ||
|
|
1ddb468a08 | ||
|
|
31dd4f6305 | ||
|
|
95e3f0e0d9 | ||
|
|
ff9715ede7 | ||
|
|
0edf017ddc | ||
|
|
ffd1e383c2 | ||
|
|
ad601fd1ee | ||
|
|
2cc4f8c2fe | ||
|
|
e7eaccb5e0 | ||
|
|
6f513eb359 | ||
|
|
6b201da3ff | ||
|
|
b235a5bb49 | ||
|
|
a85a47bc20 | ||
|
|
25f1912573 | ||
|
|
69b8f51319 | ||
|
|
d24d6f6b52 | ||
|
|
0d943ba805 | ||
|
|
afdb156c84 | ||
|
|
56fe3b5892 | ||
|
|
643d3600b8 | ||
|
|
c177f12e1d | ||
|
|
9c51bff55b | ||
|
|
72f9564757 | ||
|
|
81c91b3877 | ||
|
|
ab1a80152d | ||
|
|
3d365eb258 | ||
|
|
a87c677a35 | ||
|
|
6857f6d8f8 | ||
|
|
9e0ed57cec | ||
|
|
81bd9991bb | ||
|
|
767f4797b0 | ||
|
|
056fa9ded2 | ||
|
|
8f8c9c4582 | ||
|
|
a3792c474b | ||
|
|
9acfe3afdb | ||
|
|
ec233dbb46 | ||
|
|
9c03962c26 | ||
|
|
d89cd789ac | ||
|
|
a135460caa | ||
|
|
69088e162d | ||
|
|
7f72ef88e0 | ||
|
|
ec53bd4125 | ||
|
|
fa1adc5294 | ||
|
|
35a264d21c | ||
|
|
579b526196 | ||
|
|
0372c2eccc | ||
|
|
654e6942cb | ||
|
|
08c7ffc6d9 | ||
|
|
b7ed1429de | ||
|
|
e386f6ac20 | ||
|
|
6642c23761 | ||
|
|
60ab893888 | ||
|
|
f2b908c859 | ||
|
|
f2d960c3eb | ||
|
|
709840ca02 | ||
|
|
fb88aeaeb9 | ||
|
|
9fe596f3de | ||
|
|
94561de719 | ||
|
|
228bb2fc86 | ||
|
|
89ed18cea3 | ||
|
|
d07947f712 | ||
|
|
b996fa234b | ||
|
|
70022088fb | ||
|
|
f6cd5cb4b2 | ||
|
|
9143564d41 | ||
|
|
6ac8caaf5f | ||
|
|
55440ae32b | ||
|
|
e5a4145e37 | ||
|
|
db65c0b422 | ||
|
|
2c8b408bfb | ||
|
|
f0297938b6 | ||
|
|
58c5c04feb | ||
|
|
4d390b65fe | ||
|
|
b0d6070d28 | ||
|
|
294df359d5 | ||
|
|
3728594f73 | ||
|
|
a855d53542 | ||
|
|
dc2f1eabb2 | ||
|
|
57a0c48293 | ||
|
|
eda08e7454 | ||
|
|
bbc82d827e | ||
|
|
1bf4b6daa9 | ||
|
|
742b49e302 | ||
|
|
f757266282 | ||
|
|
8716f14941 | ||
|
|
0321823125 | ||
|
|
8b7b41de47 | ||
|
|
33d190afaa | ||
|
|
36fd4dbcf4 | ||
|
|
ff16c4f127 | ||
|
|
291a8c2bfb | ||
|
|
134728438e | ||
|
|
a1db394d93 | ||
|
|
754bd68a87 | ||
|
|
0933d96954 | ||
|
|
bd32eeeaa2 | ||
|
|
c4fcb6c88c | ||
|
|
1b9a3bd4bd | ||
|
|
2390b20e68 | ||
|
|
584d369b0b | ||
|
|
a6fd0434de | ||
|
|
0ebe052752 | ||
|
|
53b36472a0 | ||
|
|
535863bc52 | ||
|
|
ccefea6b59 | ||
|
|
dd925cd92b | ||
|
|
b24c63cb49 | ||
|
|
5529de3d95 | ||
|
|
38f69fd7cc | ||
|
|
ce6b65adb8 | ||
|
|
6a9ea3bc0f | ||
|
|
9897109332 | ||
|
|
d1b4e93f9e | ||
|
|
cfc851a99b | ||
|
|
9a6a61151d | ||
|
|
380178ccc8 | ||
|
|
497d0f0c74 | ||
|
|
3227ddd9f9 | ||
|
|
ecf1c90c22 | ||
|
|
336be63237 | ||
|
|
1aa13c1c8c | ||
|
|
37c9b9e1f5 | ||
|
|
251ad23a9e | ||
|
|
ebb3e02dcc | ||
|
|
22876e5a25 | ||
|
|
352505c54f | ||
|
|
12162e2aae | ||
|
|
0c7998712e | ||
|
|
2af09fb49d | ||
|
|
b9a20e7ac5 | ||
|
|
c58589026c | ||
|
|
7ab89b900c | ||
|
|
5b83919eb2 | ||
|
|
9620956727 | ||
|
|
f26f02c986 | ||
|
|
9b85768b7e | ||
|
|
c5d16a49d0 | ||
|
|
5276e1863d | ||
|
|
260b2c3532 | ||
|
|
0fc1a30a2c | ||
|
|
420da8f476 | ||
|
|
8609b98b1c | ||
|
|
c2a39d3296 | ||
|
|
c85514a17a | ||
|
|
6cd4bf337e | ||
|
|
d00bef5546 | ||
|
|
095c48a942 | ||
|
|
b905f46f98 | ||
|
|
e61ef1ae85 | ||
|
|
cdd4765d38 | ||
|
|
886b21af68 | ||
|
|
d62793f4ad | ||
|
|
7bba66737f | ||
|
|
d83d325a49 | ||
|
|
52fd2772cf | ||
|
|
e5baf99814 | ||
|
|
48043b5ec4 | ||
|
|
b4aeab3501 | ||
|
|
1f67ae82bd | ||
|
|
039bfd372d | ||
|
|
e7749c161d | ||
|
|
1a92de71d1 | ||
|
|
144f913aa9 | ||
|
|
d8279e11aa | ||
|
|
e28b6b9f73 | ||
|
|
b1b8584641 | ||
|
|
691636de7b | ||
|
|
11e75df1a9 | ||
|
|
6f2b1b8f06 | ||
|
|
25fc2bfbea | ||
|
|
139640e768 | ||
|
|
a93c84ff64 | ||
|
|
ae2fa19c0e | ||
|
|
986a4182d9 | ||
|
|
f8867abe49 | ||
|
|
d38a8b109b | ||
|
|
fd83e72177 | ||
|
|
711d8c8c6b | ||
|
|
1ff45c8e02 | ||
|
|
0d1d22aeff | ||
|
|
608c338403 | ||
|
|
ac2231f0f3 | ||
|
|
f23da0dd5a | ||
|
|
21344dacfc | ||
|
|
8c3f887cac | ||
|
|
ca22ba5bbc | ||
|
|
6e6f16d6ee | ||
|
|
fc64c34214 | ||
|
|
8a83385c7f | ||
|
|
c35bc2476d | ||
|
|
147bc797a2 | ||
|
|
222826af95 | ||
|
|
1735f36b82 | ||
|
|
db28db0bc7 | ||
|
|
a782354874 | ||
|
|
931f7d47ea | ||
|
|
21a709cf89 | ||
|
|
987ed1cefc | ||
|
|
76a0c1d96e | ||
|
|
3e9a77abfa | ||
|
|
1c30e555dc | ||
|
|
3879eb6b3a | ||
|
|
9bdff89833 | ||
|
|
5e5a2040fc | ||
|
|
08105eee48 | ||
|
|
eea44d7de2 | ||
|
|
40e13184ca | ||
|
|
3fcbf075fb | ||
|
|
b5a65c5e43 | ||
|
|
b2641494cc | ||
|
|
7eac65fec2 | ||
|
|
c48a794aee | ||
|
|
9bc974661c | ||
|
|
e53906aea8 | ||
|
|
b8c41a91e1 | ||
|
|
05a4a1670f | ||
|
|
3264becdc2 | ||
|
|
4bd35852a5 | ||
|
|
845bf6ada1 | ||
|
|
be4d56f8d2 | ||
|
|
865ef2beb3 | ||
|
|
dfbcd616f2 | ||
|
|
ace5353595 | ||
|
|
dc0106348d | ||
|
|
56a43fe17b | ||
|
|
f2666d4a30 | ||
|
|
46f36dc7ab | ||
|
|
4220e58d26 | ||
|
|
db0ac70b71 | ||
|
|
07de43981a | ||
|
|
6cfcc903df | ||
|
|
fa352c1a8f | ||
|
|
2ccae9f434 | ||
|
|
e5d582b30b | ||
|
|
139bf0ee35 | ||
|
|
8fb14ffdf3 | ||
|
|
1ce6e37e78 | ||
|
|
c16e85e7db | ||
|
|
462026e7e9 | ||
|
|
25a72e3508 | ||
|
|
2f180510b8 | ||
|
|
20411da67b | ||
|
|
53e67dfb27 | ||
|
|
81bfdc69dd | ||
|
|
ff951130b6 | ||
|
|
5e2829fe49 | ||
|
|
69ebb53a05 | ||
|
|
2aba09f090 | ||
|
|
1a2a3d1945 | ||
|
|
38e27309fb | ||
|
|
c8b967ba37 | ||
|
|
6b586684e6 | ||
|
|
83b713a781 | ||
|
|
773e280339 | ||
|
|
c930568df7 | ||
|
|
297a67cd00 | ||
|
|
95e2c6179f | ||
|
|
ceb61ebe74 | ||
|
|
dfdf690575 | ||
|
|
6c85e3502e | ||
|
|
db30517516 | ||
|
|
690192300f | ||
|
|
534b2e59a0 | ||
|
|
3ba963f474 | ||
|
|
5028216058 | ||
|
|
9b2cacc3a0 | ||
|
|
173947fd7d | ||
|
|
315a616293 | ||
|
|
9aa6ad216d | ||
|
|
3c56cd6738 | ||
|
|
b2a5963f5a | ||
|
|
a48ac013e8 | ||
|
|
c80fdee99b | ||
|
|
258602ce1a | ||
|
|
270db7829d | ||
|
|
c85b547502 | ||
|
|
5ff9ec9942 | ||
|
|
d6266c36bf | ||
|
|
2fc554e1d4 | ||
|
|
fdd7f30e9a | ||
|
|
7a35c1638b | ||
|
|
3994ef3619 | ||
|
|
916243468f | ||
|
|
633028a63f | ||
|
|
cb56bbc122 | ||
|
|
013374e9db | ||
|
|
d1b2d5cb27 | ||
|
|
4358b47e91 | ||
|
|
884b56a4ef | ||
|
|
6decc1ce30 | ||
|
|
eeb8d9cdf5 | ||
|
|
8a3dba3064 | ||
|
|
e8d7bbd280 | ||
|
|
27bcead1bc | ||
|
|
277ee4c4b2 | ||
|
|
acb9c01776 | ||
|
|
efa6c8135d | ||
|
|
79fd23d51b | ||
|
|
cbb705c367 | ||
|
|
776614d211 | ||
|
|
44326cd8c1 | ||
|
|
b03a498cd7 | ||
|
|
4592ab4bf5 | ||
|
|
b612926fb6 | ||
|
|
870849f01a | ||
|
|
b67377f505 | ||
|
|
a00bcc3df2 | ||
|
|
2033acbe2a | ||
|
|
122dc5baf4 | ||
|
|
e435cfc489 | ||
|
|
a276d2da4f | ||
|
|
a3199a52af | ||
|
|
6f04d4d43b | ||
|
|
99be870ab9 | ||
|
|
a966f263a2 | ||
|
|
9b2ecb4701 | ||
|
|
ac5a23ef29 | ||
|
|
be7443a0a0 | ||
|
|
b82804018d | ||
|
|
0de6557872 | ||
|
|
35b0b684df | ||
|
|
258e890056 | ||
|
|
a627ca2127 | ||
|
|
d84bbad79a | ||
|
|
05a1096e25 | ||
|
|
07e6477686 | ||
|
|
9600e56344 | ||
|
|
acde161412 | ||
|
|
1bb0871948 | ||
|
|
8d8f9c6d26 | ||
|
|
6ff50689e1 | ||
|
|
c7507d9743 | ||
|
|
9b025ddece | ||
|
|
ff970fde56 | ||
|
|
12fd77f0b2 | ||
|
|
2c4a997c64 | ||
|
|
0e60883b3d | ||
|
|
5c787e0b69 | ||
|
|
33b6bfe5be | ||
|
|
41da8435cc | ||
|
|
8167146372 | ||
|
|
84ecc4c664 | ||
|
|
21bbedaf04 | ||
|
|
d18a36af22 | ||
|
|
998aedde33 | ||
|
|
b3e766aa50 | ||
|
|
25050da2c9 | ||
|
|
0cee54c51b | ||
|
|
a74cf8ec4d | ||
|
|
41e436a183 | ||
|
|
e06f0a5d49 | ||
|
|
743fc19fa3 | ||
|
|
9d1ea4b551 | ||
|
|
76e8c66b1b | ||
|
|
e0410783be | ||
|
|
4379ea63f0 | ||
|
|
d064337c15 | ||
|
|
00ae54b4b2 | ||
|
|
6379bfb8b8 | ||
|
|
3a7fd7d271 | ||
|
|
220539e51a | ||
|
|
94a0c98bfe | ||
|
|
95cd215e9e | ||
|
|
c2b2b2698d | ||
|
|
88c04714f8 | ||
|
|
9bb630bae6 | ||
|
|
6d47e32cac | ||
|
|
c47b2f5b18 | ||
|
|
fc34b40c0a | ||
|
|
ecdc9a968d | ||
|
|
d95fa8a893 | ||
|
|
c041ff66e2 | ||
|
|
b48f83ff49 | ||
|
|
fe0e2d5c2d | ||
|
|
c189b258b4 | ||
|
|
2cf3bca8de | ||
|
|
06fc5e71c3 | ||
|
|
b2a817e17b | ||
|
|
8093927579 | ||
|
|
d1ca951ffa | ||
|
|
d9eed4a460 | ||
|
|
b3932ae8c5 | ||
|
|
9d609b6085 | ||
|
|
35223d5737 | ||
|
|
ef97f9c088 | ||
|
|
9d263f11e5 | ||
|
|
bb8aa0fe6f | ||
|
|
3f28b30e95 | ||
|
|
be441d2aa5 | ||
|
|
d797abdb1f | ||
|
|
73e089d330 | ||
|
|
3b3a940ee4 | ||
|
|
0a24fb57aa | ||
|
|
1b5b61b25e | ||
|
|
7f2c51f337 | ||
|
|
00d29b88df | ||
|
|
537e490f0f | ||
|
|
ab9bc9da74 | ||
|
|
4340368e49 | ||
|
|
b79f7b7ab8 | ||
|
|
a85fb3a871 | ||
|
|
9b34b5ca89 | ||
|
|
05a49ff5db | ||
|
|
b486788993 | ||
|
|
0bec242b2e | ||
|
|
563e9c51e1 | ||
|
|
831624897b | ||
|
|
6ab5e3ed4f | ||
|
|
ca8a0e9a88 | ||
|
|
43a6c81151 | ||
|
|
865ff7911a | ||
|
|
887a5d50a4 | ||
|
|
eefc6a5567 | ||
|
|
be68f8c3f7 | ||
|
|
bf3bc83fd8 | ||
|
|
86a4923157 | ||
|
|
03b06eee67 | ||
|
|
f80ff31412 | ||
|
|
3bc17e7b83 | ||
|
|
94acc82bf5 | ||
|
|
458297bf56 | ||
|
|
3c1a1fcca1 | ||
|
|
9673b2aa7c | ||
|
|
b3d08e4cb8 | ||
|
|
a55710df7b | ||
|
|
ab766ce85b | ||
|
|
73edd3bc40 | ||
|
|
bcb8245c61 | ||
|
|
f2ee243628 | ||
|
|
c9e60d5c3a | ||
|
|
88b1e668ee | ||
|
|
eb7c74eea7 | ||
|
|
1c92a47d75 | ||
|
|
40f5911ceb | ||
|
|
d2a9f0583a | ||
|
|
2a8809adbb | ||
|
|
2621d2e1dc | ||
|
|
39524c4064 | ||
|
|
1ce683a95a | ||
|
|
c1cc2d6350 | ||
|
|
3d5f725004 | ||
|
|
acb857f433 | ||
|
|
655bc4bee3 | ||
|
|
d343d92b17 | ||
|
|
c67d372667 | ||
|
|
43cb4716a9 | ||
|
|
54e45dac51 | ||
|
|
6222561431 | ||
|
|
5b0b594761 | ||
|
|
07b10e9e23 | ||
|
|
cdf6e3b456 | ||
|
|
dffe8cef7a | ||
|
|
cf46afea94 | ||
|
|
bb26626fd5 | ||
|
|
ea6cca588c | ||
|
|
2f207de1a0 | ||
|
|
1f9996fe62 | ||
|
|
a69419ed04 | ||
|
|
e0be6c746c | ||
|
|
be7c1ba914 | ||
|
|
2b62bf0337 | ||
|
|
461f6ad2c1 | ||
|
|
845825c0bf | ||
|
|
aff85cbfb8 | ||
|
|
f9b09e5b61 | ||
|
|
c0ce4523fa | ||
|
|
1403aa18eb | ||
|
|
65f8b3978d | ||
|
|
ba2fff249d | ||
|
|
80ca3e114e | ||
|
|
17447d3cdc | ||
|
|
330e803675 | ||
|
|
3f4c1e7029 | ||
|
|
337e9ac3ef | ||
|
|
543bbf34c2 | ||
|
|
dfb78788f9 | ||
|
|
5394151e42 | ||
|
|
2dc560f583 | ||
|
|
9349e9cd99 | ||
|
|
7355400548 | ||
|
|
594aa03c5a | ||
|
|
50b4630436 | ||
|
|
ff1328dbdd | ||
|
|
132d43f999 | ||
|
|
9ba44e32fb | ||
|
|
0627f20f5e | ||
|
|
245becdc8c | ||
|
|
40f329512b | ||
|
|
56f77e88a8 | ||
|
|
c196c08ada | ||
|
|
695e35634c | ||
|
|
8f1e0d57bf | ||
|
|
1f408dd7a7 | ||
|
|
c30c455a9f | ||
|
|
303a3ac376 | ||
|
|
cd0e8e1c6b | ||
|
|
221537601f | ||
|
|
cbeb91f9a9 | ||
|
|
f08919a829 | ||
|
|
a3830989ba | ||
|
|
cfb1f8c767 | ||
|
|
86427e2042 | ||
|
|
39d3e447ab | ||
|
|
8f079de0aa | ||
|
|
bb76242632 | ||
|
|
651727c697 | ||
|
|
6bfb709233 | ||
|
|
5c55f4d4bb | ||
|
|
ab9ec7145d | ||
|
|
c8502d3b7b | ||
|
|
6ec931fcd7 | ||
|
|
22e3b9b544 | ||
|
|
ae76a7f7d4 | ||
|
|
f16db8298b | ||
|
|
2f20bf1bee | ||
|
|
cf4a32b260 | ||
|
|
f9d01d2fad | ||
|
|
b8d83c37d9 | ||
|
|
1eb1329f68 | ||
|
|
617f6bb8ef | ||
|
|
51a3e60913 | ||
|
|
0c9f2bf5d2 | ||
|
|
30c88a2fe7 | ||
|
|
eb9afecd66 | ||
|
|
4ffd336c72 | ||
|
|
2c1f2ae589 | ||
|
|
7cbc047b41 | ||
|
|
9387b09a19 | ||
|
|
adf4222b24 | ||
|
|
f17f04f00a | ||
|
|
c095118e98 | ||
|
|
07f0192088 | ||
|
|
11d7d25037 | ||
|
|
0fd19f0de8 | ||
|
|
c45ff40250 | ||
|
|
e954fa6478 | ||
|
|
2f8c2b05bd | ||
|
|
a0fdfc0f39 | ||
|
|
a4c17bb308 | ||
|
|
57a4372b65 | ||
|
|
75eff7f083 | ||
|
|
c11cb38269 | ||
|
|
a5b9a707a4 | ||
|
|
e4fd446946 | ||
|
|
1b013db312 | ||
|
|
714d8ac3ba | ||
|
|
158250e98d | ||
|
|
f09293e077 | ||
|
|
f9f4be181d | ||
|
|
389e8bc325 | ||
|
|
3bea99c000 | ||
|
|
367f763ce5 | ||
|
|
05e52ca236 | ||
|
|
3febed82f1 | ||
|
|
f268a48a16 | ||
|
|
8a6371fe68 | ||
|
|
96bb9a2f8e | ||
|
|
93937feb13 | ||
|
|
f9b977d266 | ||
|
|
21e62d8597 | ||
|
|
7fca2a9cc6 | ||
|
|
88e8019858 | ||
|
|
e473ef36b1 | ||
|
|
cbe562a204 | ||
|
|
3b5b832bbc | ||
|
|
4dc40389a3 | ||
|
|
4cfb451755 | ||
|
|
0552f10c38 | ||
|
|
368d1ad354 | ||
|
|
c9ac7401e8 | ||
|
|
9a8f7ccba8 | ||
|
|
60625b9978 | ||
|
|
032c8e9fac | ||
|
|
b4b53cfa4c | ||
|
|
20d1abd2e1 | ||
|
|
f1e1d67f4e | ||
|
|
73903cbd1f | ||
|
|
982641752f | ||
|
|
bff22a4e4e | ||
|
|
ba66cbbc95 | ||
|
|
daaaed4118 | ||
|
|
750d13a300 | ||
|
|
c2c9db66e2 | ||
|
|
3c69a87fc2 | ||
|
|
09308083a9 | ||
|
|
dbaddab07b | ||
|
|
cf492355b4 | ||
|
|
1d58811680 | ||
|
|
1cd1b1cb08 | ||
|
|
4d78fe9ca4 | ||
|
|
91a137ab95 | ||
|
|
56d3082696 | ||
|
|
efd4b8ec11 | ||
|
|
8f573aba2f | ||
|
|
9803c75fbd | ||
|
|
96633360d0 | ||
|
|
509bbc7743 | ||
|
|
8ae7935cee | ||
|
|
f7a2428ba9 | ||
|
|
68e860baad | ||
|
|
c79a9f2ce3 | ||
|
|
38ead3133f | ||
|
|
685569e131 | ||
|
|
553d1f85c4 | ||
|
|
ca44e3062e | ||
|
|
d9a985ff38 | ||
|
|
3d919f1836 | ||
|
|
d3a2d2b248 | ||
|
|
f4fa2150b5 | ||
|
|
575b8e5f62 | ||
|
|
0e28c8e0d5 | ||
|
|
37ff924c74 | ||
|
|
cb25fc03f9 | ||
|
|
7ccbc4c77c | ||
|
|
7a64b84c5f | ||
|
|
27b7a60a8d | ||
|
|
1cac8a857d | ||
|
|
dca731ffb8 | ||
|
|
f6e02aec2a | ||
|
|
0d56de99a7 | ||
|
|
78f7152f6c | ||
|
|
ac5e11d327 | ||
|
|
1f4746c90a | ||
|
|
9d315b0ff9 | ||
|
|
c5f95e79d6 | ||
|
|
038fe84498 | ||
|
|
bd4cbc54fb | ||
|
|
4fd59f2a19 | ||
|
|
2f83c2ee89 | ||
|
|
f77c3bfdf7 | ||
|
|
11edce737b | ||
|
|
dc7d941316 | ||
|
|
9e22068a78 | ||
|
|
433cc1e32c | ||
|
|
c9461a8e63 | ||
|
|
c066a03683 | ||
|
|
70bbb54563 | ||
|
|
562a8036bc | ||
|
|
de2a47c741 | ||
|
|
53ac703f09 | ||
|
|
8038f18209 | ||
|
|
a2891d97d0 | ||
|
|
98b0500c98 | ||
|
|
2bd5169f20 | ||
|
|
3743988fd8 | ||
|
|
b3fd6d8c92 | ||
|
|
fb13e5ec8f | ||
|
|
cea281b1d3 | ||
|
|
aed044dcc6 | ||
|
|
e85b2a8961 | ||
|
|
17e3e51607 | ||
|
|
77b879d6bb | ||
|
|
6badd51b69 | ||
|
|
9de3ae5cf2 | ||
|
|
82e4677b0d | ||
|
|
b3a0dc3506 | ||
|
|
95c824f401 | ||
|
|
383731da4d | ||
|
|
f6650a95cf | ||
|
|
67abb42652 | ||
|
|
9256341c70 | ||
|
|
edcc24bc12 | ||
|
|
696c7d0e21 | ||
|
|
a6836cab15 | ||
|
|
be3fa7b940 | ||
|
|
8f985737b0 | ||
|
|
9f1aac5138 | ||
|
|
6e2f102177 | ||
|
|
310a6003fd | ||
|
|
46a768339a | ||
|
|
0e58388d77 | ||
|
|
f1dbbd62e9 | ||
|
|
c90e1d5c11 | ||
|
|
8bb94889e0 | ||
|
|
819d6719c3 | ||
|
|
da38e4e00c | ||
|
|
2b16072d6e | ||
|
|
d8e8156b1c | ||
|
|
8af35d4c2b | ||
|
|
77a1b18673 | ||
|
|
a4c37b3b9f | ||
|
|
9abd51f318 | ||
|
|
8a8241dd1f | ||
|
|
c7d51a29ac | ||
|
|
b2222d368a | ||
|
|
ac453ef32a | ||
|
|
04077ec6eb | ||
|
|
db25493c04 | ||
|
|
96582ff622 | ||
|
|
8d4b4d3cd9 | ||
|
|
d4d193fe9d | ||
|
|
b05f13d82b | ||
|
|
3516d804a4 | ||
|
|
438622d450 | ||
|
|
5b1fe811c3 | ||
|
|
4f79efedc9 | ||
|
|
cde8f50659 | ||
|
|
845fa89d0f | ||
|
|
8fb97ed04e | ||
|
|
29768576c8 | ||
|
|
7e438df89f | ||
|
|
4e659d799d | ||
|
|
f39548d6a0 | ||
|
|
10596bcb54 | ||
|
|
67a18188c7 | ||
|
|
5ac6f4f7b3 | ||
|
|
bc1f4e3cf2 | ||
|
|
957bb46e5c | ||
|
|
04c217f72e | ||
|
|
1042a537c1 | ||
|
|
f537cc1b6a | ||
|
|
2159b4b691 | ||
|
|
3a698abf45 | ||
|
|
ce48e07e18 | ||
|
|
0d6a72d364 | ||
|
|
48dded02c6 | ||
|
|
b9f5799c1b | ||
|
|
b7d77042bf | ||
|
|
8b6e9b7f76 | ||
|
|
b4ea2569e3 | ||
|
|
4a02c87c27 | ||
|
|
42a9f864eb | ||
|
|
b1a5af187c | ||
|
|
22e6de19c4 | ||
|
|
5c781987a3 | ||
|
|
572a65d661 | ||
|
|
45e2215575 | ||
|
|
108ecb7e12 | ||
|
|
be6d590254 | ||
|
|
9c87d61528 | ||
|
|
248f4ca856 | ||
|
|
dd903dd7e5 | ||
|
|
67284737f1 | ||
|
|
ae13cb2513 | ||
|
|
9e2e2e9375 | ||
|
|
40f47ccd4e | ||
|
|
7fb7d4209f | ||
|
|
c344cd2a2b | ||
|
|
1a1ea33142 | ||
|
|
7601af24f0 | ||
|
|
f996a25f6b | ||
|
|
0197eb0d08 | ||
|
|
035c876fe3 | ||
|
|
a248967ae8 | ||
|
|
78ba72aa65 | ||
|
|
a4beb58b54 | ||
|
|
9c50b23906 | ||
|
|
922cc942a4 | ||
|
|
16b2b52252 | ||
|
|
f11b086381 | ||
|
|
4b9d3b5090 | ||
|
|
e5eab69f65 | ||
|
|
e9ea13cdff | ||
|
|
961884ef12 | ||
|
|
4780f23e1f | ||
|
|
5dbbf643a4 | ||
|
|
be5a6f7e7d | ||
|
|
f937458c25 | ||
|
|
1c3b5e75d2 | ||
|
|
c617e62a16 | ||
|
|
ae80cc8984 | ||
|
|
343c886d54 | ||
|
|
14992c8e23 | ||
|
|
824d85b2a0 | ||
|
|
c24ffd3914 | ||
|
|
0289fc5ce2 | ||
|
|
bc9fa35fa2 | ||
|
|
914a886bfe | ||
|
|
dbebab3f91 | ||
|
|
f65c30e975 | ||
|
|
be1f047ca3 | ||
|
|
48ac0049aa | ||
|
|
df07a5ebb6 | ||
|
|
fea1117eae | ||
|
|
96f7ca7598 | ||
|
|
ace1a060db | ||
|
|
4674a0dcca | ||
|
|
be6ad9c5e3 | ||
|
|
4fb61d4048 | ||
|
|
b2d51a2a9b | ||
|
|
7e36ad9701 | ||
|
|
74411d8656 | ||
|
|
3b81dd4082 | ||
|
|
332392b7ba | ||
|
|
04f6e9ffc2 | ||
|
|
e441414854 | ||
|
|
7b7b9385e8 | ||
|
|
4b1d79e7f7 | ||
|
|
646ce9492f | ||
|
|
d7889e27e5 | ||
|
|
4411c7643d | ||
|
|
e65a68ce78 | ||
|
|
b10af5fb3b | ||
|
|
990f6d3730 | ||
|
|
09f6f4bc66 | ||
|
|
84a62b3707 | ||
|
|
60b946eb28 | ||
|
|
e18789b8d3 | ||
|
|
c65dd1e854 | ||
|
|
cb7be0e460 | ||
|
|
0b703f2ad4 | ||
|
|
df825d0109 | ||
|
|
1b73572e22 | ||
|
|
ce4baecb4b | ||
|
|
0994af86fc | ||
|
|
48907517e9 | ||
|
|
1608cb7cd1 | ||
|
|
dde1d96058 | ||
|
|
19e882a0d7 | ||
|
|
b2f688a032 | ||
|
|
77b1c74c83 | ||
|
|
b4664f85f0 | ||
|
|
269ae95318 | ||
|
|
2725d32c33 | ||
|
|
59fefd5ad9 | ||
|
|
c9f80db3c6 | ||
|
|
b60340f03a | ||
|
|
cb53ddf8a8 | ||
|
|
93250f2b60 | ||
|
|
fdca41a71b | ||
|
|
dc37ba740b | ||
|
|
d59ceee0f7 | ||
|
|
b7fa63bf15 | ||
|
|
38b08835c2 | ||
|
|
6379665360 | ||
|
|
dbbdb1bcbe | ||
|
|
ea6e30e7a7 | ||
|
|
b408e5d0d3 | ||
|
|
ceda50bc60 | ||
|
|
30f00508f5 | ||
|
|
fa0f2ccc4d | ||
|
|
75bb6aa966 | ||
|
|
84f68a7460 | ||
|
|
eff206fb2b | ||
|
|
1c9d15892e | ||
|
|
98da419c96 | ||
|
|
ab91313f4f | ||
|
|
efe226045d | ||
|
|
55045e15b8 | ||
|
|
35ba1532f4 | ||
|
|
25a8fa7d11 | ||
|
|
476d732a3c | ||
|
|
d0a7757b75 | ||
|
|
21efc0c4a5 | ||
|
|
c20c6665fd | ||
|
|
c9132de1ea | ||
|
|
cd497bfe9b | ||
|
|
690d52bf2d | ||
|
|
25c42bee6d | ||
|
|
5b2a3af850 | ||
|
|
6d639385da | ||
|
|
4ae9c03caf | ||
|
|
fd1c0efedf | ||
|
|
d92d832804 | ||
|
|
5d2010aa73 | ||
|
|
db12565dcf | ||
|
|
d9333b2e93 | ||
|
|
6df73257b1 | ||
|
|
3034306fcc | ||
|
|
b79e69af77 | ||
|
|
0c7bae6fd7 | ||
|
|
78ea0779d7 | ||
|
|
855233f498 | ||
|
|
3002c9e430 | ||
|
|
6b859a0478 | ||
|
|
749d70ca94 | ||
|
|
2f37b658f1 | ||
|
|
70b4adeda0 | ||
|
|
3bd952e5c5 | ||
|
|
7eb86d0a58 | ||
|
|
ae58c1fa99 | ||
|
|
5545d43417 | ||
|
|
dfb411cb6a | ||
|
|
2e3f68bd2c | ||
|
|
449e3f5cc6 | ||
|
|
539babed18 | ||
|
|
1b1fe17fca | ||
|
|
300752ab47 | ||
|
|
f3c457745e | ||
|
|
2c34c10c7e | ||
|
|
26f2e2b223 | ||
|
|
e2fb261e5b | ||
|
|
fcdd399eea | ||
|
|
6399978168 | ||
|
|
c1d16782ab | ||
|
|
4f94765156 | ||
|
|
860434a1d5 | ||
|
|
d58e2aa701 | ||
|
|
38b493ee9d | ||
|
|
000f382143 | ||
|
|
19dc560d56 | ||
|
|
cede2e8843 | ||
|
|
bb10214db0 | ||
|
|
66c3450d46 | ||
|
|
6a871c51a1 | ||
|
|
9e6e6701be | ||
|
|
d7ff3050c2 | ||
|
|
e60ec5df3c | ||
|
|
8e0a0379d5 | ||
|
|
3eae185ae2 | ||
|
|
b7ceb90e61 | ||
|
|
053057fdd2 | ||
|
|
c1935c83f6 | ||
|
|
0af856d566 | ||
|
|
62f08a2105 | ||
|
|
76f2b39ce6 | ||
|
|
38d7f6e671 | ||
|
|
7b646c04d5 | ||
|
|
3c2c99c236 | ||
|
|
45ae3209b6 | ||
|
|
7694402ae4 | ||
|
|
9b04ceedf1 | ||
|
|
7ed1d13221 | ||
|
|
41a31cdf4c | ||
|
|
47e89e35b2 | ||
|
|
fe072cd2e3 | ||
|
|
3633759295 | ||
|
|
525933be99 | ||
|
|
98bdb0479b | ||
|
|
98792fde85 | ||
|
|
1e40df227d | ||
|
|
caf0a709b8 | ||
|
|
81733d9f81 | ||
|
|
daef951e59 | ||
|
|
03a753b82c | ||
|
|
73eab87dd9 | ||
|
|
6938b0f4ae | ||
|
|
1a2720649b | ||
|
|
a50c61e5c5 | ||
|
|
1083cdb743 | ||
|
|
5450bdbc55 | ||
|
|
06eb8f9c10 | ||
|
|
11a634b9be | ||
|
|
31af15d267 | ||
|
|
801102d379 | ||
|
|
12938df375 | ||
|
|
8eaba18e91 | ||
|
|
24d8dbcf64 | ||
|
|
d1cb88b5c5 | ||
|
|
2b7585357f | ||
|
|
940889f96f | ||
|
|
5b659966c8 | ||
|
|
3d5b934f54 | ||
|
|
2834d6cac7 | ||
|
|
155f62fd22 | ||
|
|
65dd4c873f | ||
|
|
6c3025c487 | ||
|
|
8c834e634b | ||
|
|
4e62a2ee4f | ||
|
|
f92430d092 | ||
|
|
712a076be8 | ||
|
|
b110e944c3 | ||
|
|
97f1ff02a0 | ||
|
|
77eb5b5147 | ||
|
|
2b36eb42a8 | ||
|
|
1fabdb9e2d | ||
|
|
ada2972669 | ||
|
|
e8682ac058 | ||
|
|
5822dcccec | ||
|
|
08603ad905 | ||
|
|
843fd4abec | ||
|
|
224b867737 | ||
|
|
8d840bfe0e | ||
|
|
0eb4ac5bcc | ||
|
|
a2d0c335d0 | ||
|
|
876ca5927d | ||
|
|
645735a048 | ||
|
|
98b4509014 | ||
|
|
c58d27fe2d | ||
|
|
c0013a0ba5 | ||
|
|
b9a2bcb0bf | ||
|
|
cc915e39c5 | ||
|
|
8eb2f738ef | ||
|
|
b569ad4ef5 | ||
|
|
af77ab01c2 | ||
|
|
6ab5388075 | ||
|
|
6022b13285 | ||
|
|
ded3079390 | ||
|
|
735660c830 | ||
|
|
44fe358766 | ||
|
|
27daccfc35 | ||
|
|
cee4b089c6 | ||
|
|
2a54077ab1 | ||
|
|
ba8bd4f95c | ||
|
|
8e2e258518 | ||
|
|
c602072e5b | ||
|
|
a4771090ed | ||
|
|
76061c84aa | ||
|
|
133a18b70c | ||
|
|
cd01d3e923 | ||
|
|
4286c79173 | ||
|
|
ff23e7aba7 | ||
|
|
97238b764f | ||
|
|
e61fb6f206 | ||
|
|
b9f3c41a9d | ||
|
|
a6cab8fddc | ||
|
|
e8e951e7ff | ||
|
|
ec16d9abfc | ||
|
|
f4928dd0b4 | ||
|
|
b5c67a47d1 | ||
|
|
8e14a54815 | ||
|
|
a4c1e3b0bc | ||
|
|
52b2bfcd41 | ||
|
|
b160d58d1b | ||
|
|
a383fe09f6 | ||
|
|
b6a4dfb424 | ||
|
|
00446f7093 | ||
|
|
5837718cf4 | ||
|
|
7b0d04ef72 | ||
|
|
962e579434 | ||
|
|
66996ec1d3 | ||
|
|
63a249ecb0 | ||
|
|
71f40856dc | ||
|
|
3f40ca65f5 | ||
|
|
57668fc618 | ||
|
|
2c19cc3dff | ||
|
|
e82d14c973 | ||
|
|
40a1b6fde0 | ||
|
|
8e9aa23c3c | ||
|
|
ca5ce25dee | ||
|
|
4687c7dcda | ||
|
|
ca08887dca | ||
|
|
5d857c731f | ||
|
|
b7804a4c83 | ||
|
|
eaec1205a1 | ||
|
|
5460645d4a | ||
|
|
e3d03c3d78 | ||
|
|
0fbfbfb8f7 | ||
|
|
927fb013ff | ||
|
|
998f916cdc | ||
|
|
4deb14ccfb | ||
|
|
1895af9f39 | ||
|
|
e04dba610b | ||
|
|
720870675c | ||
|
|
99a5dfee31 | ||
|
|
a58eba37a9 | ||
|
|
66842fca8e | ||
|
|
9a2ec6b110 | ||
|
|
a47280f47b | ||
|
|
389852c979 | ||
|
|
2808ca139c | ||
|
|
bbee8e7d81 | ||
|
|
d87467aa88 | ||
|
|
161cd1ee13 | ||
|
|
382aad5119 | ||
|
|
3adc6a646f | ||
|
|
93f94b65f1 | ||
|
|
13ba54183a | ||
|
|
bc66d4b0e7 | ||
|
|
8be331ddcb | ||
|
|
ff044c831f | ||
|
|
a896566a14 | ||
|
|
cb85292f99 | ||
|
|
58ebcbce3d | ||
|
|
7c7722e8fc | ||
|
|
06cff0b2a6 | ||
|
|
78cc6764bf | ||
|
|
74c0e3a659 | ||
|
|
0b540d6406 | ||
|
|
076ad8ef7e | ||
|
|
f1e0b7a94f | ||
|
|
64ebc35dbd | ||
|
|
611635a9a2 | ||
|
|
ee5146273e | ||
|
|
26c30b013b | ||
|
|
2c82711476 | ||
|
|
899f5231b5 | ||
|
|
897650cf27 | ||
|
|
0cfeee18c9 | ||
|
|
8e4a3c705a | ||
|
|
3e44835687 | ||
|
|
01bf6a7eee | ||
|
|
d5ac67071f | ||
|
|
4ea9445a8f | ||
|
|
6aee9ce92e | ||
|
|
b3980acbf5 | ||
|
|
6a268bfb68 | ||
|
|
d3a1f73d3e | ||
|
|
63848e815f | ||
|
|
7faa9adf79 | ||
|
|
6640df18ac | ||
|
|
1a5ce8f2e9 | ||
|
|
b9436c0cab | ||
|
|
fc98d646a0 | ||
|
|
c730f7931f | ||
|
|
573866feee | ||
|
|
ef6035b5be | ||
|
|
ebf855f2a4 | ||
|
|
8502c0f048 | ||
|
|
595452cf82 | ||
|
|
acc4d5201a | ||
|
|
1439fd6104 | ||
|
|
8248f31b20 | ||
|
|
f8771adbe7 | ||
|
|
39c1624d42 | ||
|
|
4eb76e6da3 | ||
|
|
7eb82f2e84 | ||
|
|
a84b624fa5 | ||
|
|
df0d0d820a | ||
|
|
9ca198ee41 | ||
|
|
e0c0d8bc04 | ||
|
|
d509523743 | ||
|
|
97619d8ba1 | ||
|
|
338c70c289 | ||
|
|
80df96fd0d | ||
|
|
e899ad8caa | ||
|
|
579e76430d | ||
|
|
c8c6e0350a | ||
|
|
36dd7269e2 | ||
|
|
8faaf6a469 | ||
|
|
6596cb014f | ||
|
|
1a0bd89c9d | ||
|
|
62ac63fd77 | ||
|
|
6a9308b514 | ||
|
|
e6e8d96f12 | ||
|
|
1b1f5203f1 | ||
|
|
f80464ea31 | ||
|
|
e2c78e546d | ||
|
|
75b0c6f7a3 | ||
|
|
dc02757bc3 | ||
|
|
f95ce8c7b5 | ||
|
|
19a2265792 | ||
|
|
c991a3ccfd | ||
|
|
7666ed070a | ||
|
|
a1d612b1f6 | ||
|
|
d088e4574e | ||
|
|
d3cbd20c5e | ||
|
|
dd8798e52b | ||
|
|
cff4f29ba4 | ||
|
|
623d992e34 | ||
|
|
dc08363360 | ||
|
|
420f9a068d | ||
|
|
a2aa8d9336 | ||
|
|
864807196c | ||
|
|
ab2bfa951c | ||
|
|
a71c8cef83 | ||
|
|
e871d37044 | ||
|
|
f34a3e421d | ||
|
|
e32ee71bea | ||
|
|
0440a4aa7e | ||
|
|
3bc8823e54 | ||
|
|
0faa49d0e5 | ||
|
|
a4b9dfaf1c | ||
|
|
9dfc25559e | ||
|
|
c7c85ac676 | ||
|
|
ee6dd0e794 | ||
|
|
1af445a390 | ||
|
|
10824e9731 | ||
|
|
4236a2e6f7 | ||
|
|
edcf708945 | ||
|
|
47e58942f8 | ||
|
|
c96375a16c | ||
|
|
f854ed50d6 | ||
|
|
5cbf49a3dd | ||
|
|
2933a173a2 | ||
|
|
eebd0491a3 | ||
|
|
39c45cd329 | ||
|
|
8c38a0e6cc | ||
|
|
93e6473828 | ||
|
|
5b9fe065d7 | ||
|
|
2cf96bef52 | ||
|
|
8567610ddc | ||
|
|
3850ef4355 | ||
|
|
52c186868e | ||
|
|
d29f989c22 | ||
|
|
2699f8ee85 | ||
|
|
0e31d503d0 | ||
|
|
ebaf33a36f | ||
|
|
8c2d552238 | ||
|
|
b0f3c76f76 | ||
|
|
1b6cb61f8a | ||
|
|
acd118a58c | ||
|
|
b6e0fa9085 | ||
|
|
dff0b497b0 | ||
|
|
1f983d502e | ||
|
|
e34f51a1b0 | ||
|
|
13637be1aa | ||
|
|
e82e996fe5 | ||
|
|
8f22740e07 | ||
|
|
238abd009d | ||
|
|
03d5cc7521 | ||
|
|
c9f9e2b97d | ||
|
|
25e929c10e | ||
|
|
8ca4ede403 | ||
|
|
0e9f5978e1 | ||
|
|
b50be86615 | ||
|
|
1024b11eeb | ||
|
|
fe1a8f4425 | ||
|
|
a390418f83 | ||
|
|
dd472c1322 | ||
|
|
182c131ee0 | ||
|
|
a636adec10 | ||
|
|
1d5d104bbc | ||
|
|
e3960445ae | ||
|
|
53cf0863d0 | ||
|
|
c631b7cd8a | ||
|
|
5bc64c6925 | ||
|
|
bb2bf12808 | ||
|
|
c2f9d3f455 | ||
|
|
db95dfe208 | ||
|
|
ddd93f518d | ||
|
|
86d052e51e | ||
|
|
6d7de79fa9 | ||
|
|
fb55b9db17 | ||
|
|
df0f05197a | ||
|
|
ad3ad81c1e | ||
|
|
e3186e6c4c | ||
|
|
dccb84ded8 | ||
|
|
18bca6352d | ||
|
|
510c693871 | ||
|
|
fd7299c86f | ||
|
|
8696df12ac | ||
|
|
f572d32f5b | ||
|
|
d56e0b0eba | ||
|
|
e534d41d81 | ||
|
|
29d77b2f2c | ||
|
|
a641c9858c | ||
|
|
4e131cd059 | ||
|
|
c8e339a58d | ||
|
|
4c1f3948a3 | ||
|
|
5cfb83a912 | ||
|
|
c40ff67704 | ||
|
|
85540e6fe3 | ||
|
|
af6ac8bd4f | ||
|
|
eda770570c | ||
|
|
70211a8407 | ||
|
|
41476943ef | ||
|
|
4d6b83425b | ||
|
|
68857fea24 | ||
|
|
985396aaf9 | ||
|
|
98911eca05 | ||
|
|
d86c14d3a6 | ||
|
|
d71e61df8b | ||
|
|
3bdb3a6b87 | ||
|
|
3188b0f6cb | ||
|
|
8dac57d4cf | ||
|
|
9885b8d117 | ||
|
|
a91e7b9ed0 | ||
|
|
f868c3d172 | ||
|
|
220b2c9a2a | ||
|
|
a169183783 | ||
|
|
06bc8ed4a4 | ||
|
|
415edd2265 | ||
|
|
648863d21b | ||
|
|
255c80953d | ||
|
|
3232e60467 | ||
|
|
bf08aeeaad | ||
|
|
da81ea4e57 | ||
|
|
45143ba8d4 | ||
|
|
42baec7c72 | ||
|
|
ffeac233c2 | ||
|
|
1accdfe2e6 | ||
|
|
6903ecbeb4 | ||
|
|
f625653b30 | ||
|
|
64f0c37251 | ||
|
|
2682187fa3 | ||
|
|
2331c569df | ||
|
|
090f3fafa9 | ||
|
|
34ae6fd089 | ||
|
|
de81ed0c61 | ||
|
|
5b58894b02 | ||
|
|
49465888b2 | ||
|
|
ed5e8e2666 | ||
|
|
1555185d60 | ||
|
|
f903d91dca | ||
|
|
e5235bd714 | ||
|
|
58cfdd6d05 | ||
|
|
1b4fe6135f | ||
|
|
28523c356c | ||
|
|
9481b29d6b | ||
|
|
3553489f2e | ||
|
|
20115e6557 | ||
|
|
f74efd5b96 | ||
|
|
ee47136fb4 | ||
|
|
ba887fdf21 | ||
|
|
83dece68fc | ||
|
|
3995cd64da | ||
|
|
fce7083e28 | ||
|
|
9fdf22a475 | ||
|
|
5268375153 | ||
|
|
5980d0a6fa | ||
|
|
3598f59123 | ||
|
|
21f8b0b553 | ||
|
|
557f491a7e | ||
|
|
d98ca9d21f | ||
|
|
5aa876da72 | ||
|
|
fe2cdfe81a | ||
|
|
7e7a66595b | ||
|
|
878d9ad8d9 | ||
|
|
c429bdf139 | ||
|
|
e25961f40c | ||
|
|
22d22f3afa | ||
|
|
7987800567 | ||
|
|
f5845908b9 | ||
|
|
daec4c2e4e | ||
|
|
138ce1c69a | ||
|
|
5ea52b47ab | ||
|
|
8366ec5831 | ||
|
|
383f0a7f43 | ||
|
|
22e5a5cafd | ||
|
|
8d6255aa55 | ||
|
|
8fd6f7add9 | ||
|
|
623c2cb9f1 | ||
|
|
259e87442d | ||
|
|
8655e025a2 | ||
|
|
aba2a9f504 | ||
|
|
9aa76bd088 | ||
|
|
10faef62fa | ||
|
|
6b291a5ce5 | ||
|
|
164f1dcfd4 | ||
|
|
b7d6d027d3 | ||
|
|
c4869f1917 | ||
|
|
79c31b5f54 | ||
|
|
89e99219d7 | ||
|
|
a9b6c68ce3 | ||
|
|
0563077fb9 | ||
|
|
e2f174e92e | ||
|
|
861bdb47ed | ||
|
|
9f9e2d12c4 | ||
|
|
03f504cadc | ||
|
|
182c7e827b | ||
|
|
61e0cfc979 | ||
|
|
3ea3f01394 | ||
|
|
fc5b8ca1e5 | ||
|
|
5d67b2f9dc | ||
|
|
bcf4fd9e93 | ||
|
|
5b5faad553 | ||
|
|
5299261d18 | ||
|
|
f852851886 | ||
|
|
20a4d9adb8 | ||
|
|
13997cd282 | ||
|
|
965429296b | ||
|
|
d9750ce4dc | ||
|
|
d0fb41e582 | ||
|
|
f7a83d5a60 | ||
|
|
fc52462df4 | ||
|
|
119804794f | ||
|
|
f23bd0b268 | ||
|
|
d6f61b4faf | ||
|
|
4e4b7a1c39 | ||
|
|
376bfb6799 | ||
|
|
12bdba9a9c | ||
|
|
33fa1e1350 | ||
|
|
94e1a4f793 | ||
|
|
2603d960b7 | ||
|
|
b8433c4ea7 | ||
|
|
fc30aeea61 | ||
|
|
01d6e1f14d | ||
|
|
3b4a65deaa | ||
|
|
2ec5ec78a9 | ||
|
|
6b416b8494 | ||
|
|
eac470e081 | ||
|
|
34ce50b7b5 | ||
|
|
6d85e7cdf7 | ||
|
|
23a47a6f63 | ||
|
|
d2bfcc6f0e | ||
|
|
7495392aa2 | ||
|
|
c4ddf84ba8 | ||
|
|
aad6c28e4d | ||
|
|
2bd03dada4 | ||
|
|
5fab16ad06 | ||
|
|
6a4d1ed44d | ||
|
|
db22159a89 | ||
|
|
029e0e5044 | ||
|
|
3f1ee0b1b8 | ||
|
|
8009794cca | ||
|
|
12ce96d802 | ||
|
|
53bd62b236 | ||
|
|
cd7362c654 | ||
|
|
788b5633cb | ||
|
|
46d106e6e2 | ||
|
|
8ffb91022e | ||
|
|
57c09d1772 | ||
|
|
0731ed2c7a | ||
|
|
19ecb67f2d | ||
|
|
d16123c276 | ||
|
|
f90b168fdd | ||
|
|
09f416efdf | ||
|
|
05f40f3451 | ||
|
|
d81206fe2e | ||
|
|
f166ef9313 | ||
|
|
14704f9b4d | ||
|
|
8381daeeb7 | ||
|
|
164ed75af2 | ||
|
|
1f7c64e279 | ||
|
|
a76bf03bc9 | ||
|
|
e50d7f7b95 | ||
|
|
45b1327c58 | ||
|
|
fe60421731 | ||
|
|
0404fe9044 | ||
|
|
8cf6c59ec7 | ||
|
|
7b817ff866 | ||
|
|
f087f70a2c | ||
|
|
b05752f430 | ||
|
|
c4cde366e8 | ||
|
|
33249fad21 | ||
|
|
f0dd28d4db | ||
|
|
c0e35aa9fa | ||
|
|
1fd633a23b | ||
|
|
9a65e26e71 | ||
|
|
f22cabc32a | ||
|
|
b97d57f00b | ||
|
|
5db3544683 | ||
|
|
96eee95596 | ||
|
|
ffb3243bb6 | ||
|
|
09f07902ef | ||
|
|
43583bbc2e | ||
|
|
2ebc713cbb | ||
|
|
65ecc0f3bb | ||
|
|
ebabc1117e | ||
|
|
672e59e657 | ||
|
|
882e11f558 | ||
|
|
1cd5acb972 | ||
|
|
464a6efd28 | ||
|
|
18c3c1f475 | ||
|
|
52de46aeb3 | ||
|
|
b80d088254 | ||
|
|
7d0d85aeb7 | ||
|
|
d19ef8322e | ||
|
|
840b4d7619 | ||
|
|
e4a36545d7 | ||
|
|
31fbc7389b | ||
|
|
19ec936d38 | ||
|
|
939c67d41c | ||
|
|
9614e4f115 | ||
|
|
c48150a792 | ||
|
|
60687502d1 | ||
|
|
2fab58759e | ||
|
|
a42c586bb2 | ||
|
|
a6b76b3494 | ||
|
|
a6eaf7fc84 | ||
|
|
97ba9b42eb | ||
|
|
e0a71f0373 | ||
|
|
b8875d7f1c | ||
|
|
67dfd9a942 | ||
|
|
db46b03d0c | ||
|
|
5672c86905 | ||
|
|
d5406270a5 | ||
|
|
0b3f5e408b | ||
|
|
2ce432ac77 | ||
|
|
6cb26b3fbb | ||
|
|
a9b5949191 | ||
|
|
6016370515 | ||
|
|
f3c026f278 | ||
|
|
8f218bd6d6 | ||
|
|
59fd89bf68 | ||
|
|
d27a6235f0 | ||
|
|
c23febbcf0 | ||
|
|
81e85a4d0d | ||
|
|
44ba1bc85b | ||
|
|
6244fe5a93 | ||
|
|
973335db56 | ||
|
|
4b2c4f88d3 | ||
|
|
bbd2ca0d68 | ||
|
|
a82c225841 | ||
|
|
f9a6852aaa | ||
|
|
fad704b692 | ||
|
|
e362632477 | ||
|
|
4558b49c1b | ||
|
|
4357d8788a | ||
|
|
78b7c24c15 | ||
|
|
127e9e9f74 | ||
|
|
1951ae1cce | ||
|
|
79e2fd4b52 | ||
|
|
2265a2c43d | ||
|
|
1e7e543ab0 | ||
|
|
9671a73bd6 | ||
|
|
5bbee94d68 | ||
|
|
9d7122d69c | ||
|
|
6b1270a4f9 | ||
|
|
3c8de2be3f | ||
|
|
5afb5f0e83 | ||
|
|
7f42d0df40 | ||
|
|
0df54c9021 | ||
|
|
41bc33f4ba | ||
|
|
dcc883fa27 | ||
|
|
492c5d01bf | ||
|
|
49eaca1290 | ||
|
|
ce43b586ad | ||
|
|
ae49cd6a26 | ||
|
|
6ad3897af8 | ||
|
|
53ddb067ea | ||
|
|
a9762170bc | ||
|
|
4d91403fd2 | ||
|
|
e1cd4a63d0 | ||
|
|
18f3874dab | ||
|
|
6efcee500d | ||
|
|
8c0532f363 | ||
|
|
fdb0d07ab8 | ||
|
|
58e30649a3 | ||
|
|
85feef3a60 | ||
|
|
fccd913a8a | ||
|
|
dd119edafe | ||
|
|
f6633fb16c | ||
|
|
d243bf4f48 | ||
|
|
92d306f777 | ||
|
|
0ea29b3d7c | ||
|
|
c8e6e8eb32 | ||
|
|
a6aae6292e | ||
|
|
e33100b075 | ||
|
|
84a229d286 | ||
|
|
ab32c42487 | ||
|
|
0dc3744859 | ||
|
|
d22eab4155 | ||
|
|
ea9bfec3c9 | ||
|
|
02b43a5d66 | ||
|
|
e0fc7952f4 | ||
|
|
66ec2c5d27 | ||
|
|
f5a78402a6 | ||
|
|
29bfd7325d | ||
|
|
318962c01f | ||
|
|
8ca49fafa1 | ||
|
|
656e783894 | ||
|
|
18c6d60a85 | ||
|
|
b202121c21 | ||
|
|
ea3672dd08 | ||
|
|
88037af7ef | ||
|
|
4bda5b619d | ||
|
|
a0645ea30f | ||
|
|
a3e4adb0af | ||
|
|
e18aedfabf | ||
|
|
44529a78d2 | ||
|
|
bb9025364b | ||
|
|
7c78283b46 | ||
|
|
f7d6ca5c11 | ||
|
|
172a341b40 | ||
|
|
09aef67808 | ||
|
|
a400312d3a | ||
|
|
1b01b35b03 | ||
|
|
2d0acaa8ae | ||
|
|
a31a73320b | ||
|
|
75da352806 | ||
|
|
61b0c9b1c1 | ||
|
|
2185fe0f4c | ||
|
|
4ee0977aa1 | ||
|
|
1ba44771bb | ||
|
|
9966eec1df | ||
|
|
dd444f5f76 | ||
|
|
a0a6089057 | ||
|
|
4be72fc989 | ||
|
|
033cbf696a | ||
|
|
805bc85ea9 | ||
|
|
0d057d500e | ||
|
|
7462500e20 | ||
|
|
3e06a4a7c5 | ||
|
|
e0684ab086 | ||
|
|
e7be883e2e | ||
|
|
8fe80a4507 | ||
|
|
68084c4567 | ||
|
|
9c27545f5f | ||
|
|
6da8af7680 | ||
|
|
1b7ce93623 | ||
|
|
5f6480527e | ||
|
|
4d7b4ce877 | ||
|
|
fd61f7d363 | ||
|
|
47cc3d7358 | ||
|
|
d180618634 | ||
|
|
b2b96426d7 | ||
|
|
5796d4b969 | ||
|
|
37957613df | ||
|
|
cb82f02eb4 | ||
|
|
3feccefee8 | ||
|
|
910b1dca85 | ||
|
|
d71c6f055b | ||
|
|
536f373b91 | ||
|
|
6987845228 | ||
|
|
2edd2bf763 | ||
|
|
2605761d76 | ||
|
|
391d261ca1 | ||
|
|
6a7531f1e6 | ||
|
|
fb294e8bea | ||
|
|
a1046488c3 | ||
|
|
8cef56265c | ||
|
|
ec30851247 | ||
|
|
7420c12b89 | ||
|
|
895c770c24 | ||
|
|
606070f449 | ||
|
|
ec41493d91 | ||
|
|
d551093199 | ||
|
|
f7f8b2da62 | ||
|
|
1378b630a6 | ||
|
|
9726d86ab0 | ||
|
|
c9364e7b94 | ||
|
|
1e6780a2e3 | ||
|
|
72855d4d7a | ||
|
|
c0359da930 | ||
|
|
b4f39b0bfc | ||
|
|
d7af145f3b | ||
|
|
b078d8477e | ||
|
|
02b64e1a4b | ||
|
|
f444825e42 | ||
|
|
9fa62ef388 | ||
|
|
e73ad07836 | ||
|
|
a680e79686 | ||
|
|
728c05262c | ||
|
|
23e08c1ca1 | ||
|
|
198d73acfa | ||
|
|
71e210b66c | ||
|
|
2f31c53fd4 | ||
|
|
9f661535e0 | ||
|
|
5b0d4bf8e6 | ||
|
|
a639264149 | ||
|
|
91ab257eb6 | ||
|
|
e24a62d621 | ||
|
|
ec9f4b2b61 | ||
|
|
b66c7da4b3 | ||
|
|
6544cc98d5 | ||
|
|
2dbef9e1fa | ||
|
|
a924e81adb | ||
|
|
1ded1b603e | ||
|
|
a3012a29c2 | ||
|
|
8fcd800aff | ||
|
|
4d414ea082 | ||
|
|
d5b2380bc2 | ||
|
|
d2853fafa9 | ||
|
|
0e5a207c44 | ||
|
|
d7744537ae | ||
|
|
9e79e9efb6 | ||
|
|
a04338d184 | ||
|
|
772b0ca2b0 | ||
|
|
13eb2b75d5 | ||
|
|
c800440e44 | ||
|
|
05f822380c | ||
|
|
7896c81e98 | ||
|
|
ea50569b2a | ||
|
|
7bce07aa0e | ||
|
|
5ef02290dd | ||
|
|
34d5ba7d35 | ||
|
|
55004e7832 | ||
|
|
4945446171 | ||
|
|
0e2d2408ca | ||
|
|
8b8707c36e | ||
|
|
3bd9caf113 | ||
|
|
f713a83abf | ||
|
|
b0e0f8c8bf | ||
|
|
c8623fd3a2 | ||
|
|
c6aad2c2d4 | ||
|
|
7ede87753b | ||
|
|
59bed5a0fa | ||
|
|
e59377d9a3 | ||
|
|
6274cfce4b | ||
|
|
9d624702f6 | ||
|
|
f9d8ff3f74 | ||
|
|
6c837f0639 | ||
|
|
03c9ce3589 | ||
|
|
1ac7cdacb0 | ||
|
|
ba93be1814 | ||
|
|
1404bbab9f | ||
|
|
a5f8ed6378 | ||
|
|
1b59212003 | ||
|
|
4142901dc6 | ||
|
|
4ba9431e6f | ||
|
|
5da83517a8 | ||
|
|
a7e95c2a4d | ||
|
|
ae7fbbb04f | ||
|
|
cc18ef9aa8 | ||
|
|
4202e8a7ba | ||
|
|
882ff8a325 | ||
|
|
1b29957731 | ||
|
|
5702543bc5 | ||
|
|
c810f0647a | ||
|
|
d366b67bee | ||
|
|
85286b3cf9 | ||
|
|
ae4b5464c7 | ||
|
|
dec2536e3e | ||
|
|
30ea512dcc | ||
|
|
f6cdf34b25 | ||
|
|
99818d038b | ||
|
|
c35ce8e195 | ||
|
|
2ae856b0dd | ||
|
|
e592598990 | ||
|
|
07af34fbd0 | ||
|
|
0b3e313260 | ||
|
|
21947de4e0 | ||
|
|
3cdd0baabb | ||
|
|
f851e62330 | ||
|
|
bea19ad8ce | ||
|
|
f5b48f5390 | ||
|
|
cc712b86d5 | ||
|
|
0cf6cfc2b0 | ||
|
|
6f19360da5 | ||
|
|
f216b4716f | ||
|
|
3bf638f7c6 | ||
|
|
5ec9a24c99 | ||
|
|
23caa1d0b5 | ||
|
|
36ecf7c7fd | ||
|
|
0027e75a45 | ||
|
|
4cd759bfa6 | ||
|
|
0f2752220a | ||
|
|
ce1ed46851 | ||
|
|
aa795ee7eb | ||
|
|
5c83671739 | ||
|
|
3fb9390040 | ||
|
|
965687186c | ||
|
|
83742437d6 | ||
|
|
a37e53769c | ||
|
|
084a389a02 | ||
|
|
7971c42814 | ||
|
|
c694461abc |
2
.gitattributes
vendored
Normal file
2
.gitattributes
vendored
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
*.html linguist-documentation
|
||||||
|
(^|/)site/) linguist-documentation
|
||||||
34
.github/contributing.md
vendored
Normal file
34
.github/contributing.md
vendored
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
# Contributing to OWASP dependency-check
|
||||||
|
|
||||||
|
## Reporting Bugs
|
||||||
|
|
||||||
|
- Ensure you're running the latest version of dependency-check.
|
||||||
|
- Ensure the bug has not [already been reported](https://github.com/jeremylong/DependencyCheck/issues).
|
||||||
|
- If you're unable to find an open issue addressing the problem, please [submit a new issue](https://github.com/jeremylong/DependencyCheck/issues/new).
|
||||||
|
- Please fill out the appropriate section of the bug report template provided. Please delete any sections not needed in the template.
|
||||||
|
|
||||||
|
## Reporting Vulnerabilities
|
||||||
|
|
||||||
|
- If you believe you have found a vulnerability in dependency-check itself (not that dependency-check found a vulnerability); please email jeremy.long@owasp.org.
|
||||||
|
|
||||||
|
## Asking Questions
|
||||||
|
|
||||||
|
- Your question may be answered by taking a look at the [documentataion](https://jeremylong.github.io/DependencyCheck/).
|
||||||
|
- If you still have a question consider:
|
||||||
|
- posting to the [Google Group](https://groups.google.com/forum/#!forum/dependency-check)
|
||||||
|
- opening a [new issue](https://github.com/jeremylong/DependencyCheck/issues/new)
|
||||||
|
|
||||||
|
## Enhancement Requests
|
||||||
|
|
||||||
|
- Suggest changes by [submitting a new issue](https://github.com/jeremylong/DependencyCheck/issues/new) and begin coding.
|
||||||
|
|
||||||
|
## Contributing Code
|
||||||
|
|
||||||
|
- If you have written a new feature or have fixed a bug please open a new pull request with the patch.
|
||||||
|
- Ensure the PR description clearly describes the problem and solution. Include any related issue number(s) if applicable.
|
||||||
|
- Please ensure the PR passes the automated checks performed (travis-ci, codacy, etc.)
|
||||||
|
- Please consider adding test cases for any new functionality
|
||||||
|
|
||||||
|
## Thank you for your contributions
|
||||||
|
|
||||||
|
OWASP dependency-check team
|
||||||
20
.github/issue_template.md
vendored
Normal file
20
.github/issue_template.md
vendored
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
Please delete any un-needed section from the following issue template:
|
||||||
|
|
||||||
|
### Reporting Bugs/Errors
|
||||||
|
When reporting errors, 99% of the time log file output is required. Please post the log file as a [gist](https://gist.github.com/) and provide a link in the new issue.
|
||||||
|
|
||||||
|
### Reporting False Positives
|
||||||
|
When reporting a false positive please include:
|
||||||
|
- The location of the dependency (Maven GAV, URL to download the dependency, etc.)
|
||||||
|
- The CPE that is believed to be false positive
|
||||||
|
- Please report the CPE not the CVE
|
||||||
|
|
||||||
|
#### Example
|
||||||
|
False positive on library foo.jar - reported as cpe:/a:apache:tomcat:7.0
|
||||||
|
```xml
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.sample</groupId>
|
||||||
|
<artifactId>foo</artifactId>
|
||||||
|
<version>1.0</version>
|
||||||
|
</dependency>
|
||||||
|
```
|
||||||
9
.github/pull_request_template.md
vendored
Normal file
9
.github/pull_request_template.md
vendored
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
## Fixes Issue #
|
||||||
|
|
||||||
|
## Description of Change
|
||||||
|
|
||||||
|
*Please add a description of the proposed change*
|
||||||
|
|
||||||
|
## Have test cases been added to cover the new functionality?
|
||||||
|
|
||||||
|
*yes/no*
|
||||||
16
.gitignore
vendored
16
.gitignore
vendored
@@ -1,4 +1,6 @@
|
|||||||
*/target/**
|
*/target/**
|
||||||
|
# IntelliJ test run side-effects
|
||||||
|
dependency-check-core/data/
|
||||||
# Intellij project files
|
# Intellij project files
|
||||||
*.iml
|
*.iml
|
||||||
*.ipr
|
*.ipr
|
||||||
@@ -7,8 +9,22 @@
|
|||||||
# Eclipse project files
|
# Eclipse project files
|
||||||
.classpath
|
.classpath
|
||||||
.project
|
.project
|
||||||
|
.settings
|
||||||
|
maven-eclipse.xml
|
||||||
|
.externalToolBuilders
|
||||||
|
.pmd
|
||||||
# Netbeans configuration
|
# Netbeans configuration
|
||||||
nb-configuration.xml
|
nb-configuration.xml
|
||||||
/target/
|
/target/
|
||||||
#maven-shade-plugin generated pom
|
#maven-shade-plugin generated pom
|
||||||
dependency-reduced-pom.xml
|
dependency-reduced-pom.xml
|
||||||
|
#ruby Gemfile, etc. This is a java project, Gemfile is here to check site problem with Jekyll
|
||||||
|
Gemfile
|
||||||
|
Gemfile.lock
|
||||||
|
_site/**
|
||||||
|
#unknown as to why these are showing up... but need to be ignored.
|
||||||
|
.LCKpom.xml~
|
||||||
|
#coverity
|
||||||
|
/cov-int/
|
||||||
|
/dependency-check-core/nbproject/
|
||||||
|
cov-scan.bat
|
||||||
3
.travis.yml
Normal file
3
.travis.yml
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
language: java
|
||||||
|
jdk: oraclejdk7
|
||||||
|
script: mvn install -DreleaseTesting
|
||||||
14
Dockerfile
Normal file
14
Dockerfile
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
FROM java:8
|
||||||
|
|
||||||
|
MAINTAINER Timo Pagel <dependencycheckmaintainer@timo-pagel.de>
|
||||||
|
|
||||||
|
RUN wget -O /tmp/current.txt http://jeremylong.github.io/DependencyCheck/current.txt && current=$(cat /tmp/current.txt) && wget https://dl.bintray.com/jeremy-long/owasp/dependency-check-$current-release.zip && unzip dependency-check-$current-release.zip && mv dependency-check /usr/share/
|
||||||
|
|
||||||
|
RUN useradd -ms /bin/bash dockeruser && chown -R dockeruser:dockeruser /usr/share/dependency-check && mkdir /report && chown -R dockeruser:dockeruser /report
|
||||||
|
USER dockeruser
|
||||||
|
|
||||||
|
VOLUME "/src /usr/share/dependency-check/data /report"
|
||||||
|
|
||||||
|
WORKDIR /report
|
||||||
|
|
||||||
|
ENTRYPOINT ["/usr/share/dependency-check/bin/dependency-check.sh", "--scan", "/src"]
|
||||||
858
LICENSE.txt
858
LICENSE.txt
@@ -1,674 +1,202 @@
|
|||||||
GNU GENERAL PUBLIC LICENSE
|
|
||||||
Version 3, 29 June 2007
|
|
||||||
|
|
||||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
Apache License
|
||||||
Everyone is permitted to copy and distribute verbatim copies
|
Version 2.0, January 2004
|
||||||
of this license document, but changing it is not allowed.
|
http://www.apache.org/licenses/
|
||||||
|
|
||||||
Preamble
|
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||||
|
|
||||||
The GNU General Public License is a free, copyleft license for
|
1. Definitions.
|
||||||
software and other kinds of works.
|
|
||||||
|
"License" shall mean the terms and conditions for use, reproduction,
|
||||||
The licenses for most software and other practical works are designed
|
and distribution as defined by Sections 1 through 9 of this document.
|
||||||
to take away your freedom to share and change the works. By contrast,
|
|
||||||
the GNU General Public License is intended to guarantee your freedom to
|
"Licensor" shall mean the copyright owner or entity authorized by
|
||||||
share and change all versions of a program--to make sure it remains free
|
the copyright owner that is granting the License.
|
||||||
software for all its users. We, the Free Software Foundation, use the
|
|
||||||
GNU General Public License for most of our software; it applies also to
|
"Legal Entity" shall mean the union of the acting entity and all
|
||||||
any other work released this way by its authors. You can apply it to
|
other entities that control, are controlled by, or are under common
|
||||||
your programs, too.
|
control with that entity. For the purposes of this definition,
|
||||||
|
"control" means (i) the power, direct or indirect, to cause the
|
||||||
When we speak of free software, we are referring to freedom, not
|
direction or management of such entity, whether by contract or
|
||||||
price. Our General Public Licenses are designed to make sure that you
|
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||||
have the freedom to distribute copies of free software (and charge for
|
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||||
them if you wish), that you receive source code or can get it if you
|
|
||||||
want it, that you can change the software or use pieces of it in new
|
"You" (or "Your") shall mean an individual or Legal Entity
|
||||||
free programs, and that you know you can do these things.
|
exercising permissions granted by this License.
|
||||||
|
|
||||||
To protect your rights, we need to prevent others from denying you
|
"Source" form shall mean the preferred form for making modifications,
|
||||||
these rights or asking you to surrender the rights. Therefore, you have
|
including but not limited to software source code, documentation
|
||||||
certain responsibilities if you distribute copies of the software, or if
|
source, and configuration files.
|
||||||
you modify it: responsibilities to respect the freedom of others.
|
|
||||||
|
"Object" form shall mean any form resulting from mechanical
|
||||||
For example, if you distribute copies of such a program, whether
|
transformation or translation of a Source form, including but
|
||||||
gratis or for a fee, you must pass on to the recipients the same
|
not limited to compiled object code, generated documentation,
|
||||||
freedoms that you received. You must make sure that they, too, receive
|
and conversions to other media types.
|
||||||
or can get the source code. And you must show them these terms so they
|
|
||||||
know their rights.
|
"Work" shall mean the work of authorship, whether in Source or
|
||||||
|
Object form, made available under the License, as indicated by a
|
||||||
Developers that use the GNU GPL protect your rights with two steps:
|
copyright notice that is included in or attached to the work
|
||||||
(1) assert copyright on the software, and (2) offer you this License
|
(an example is provided in the Appendix below).
|
||||||
giving you legal permission to copy, distribute and/or modify it.
|
|
||||||
|
"Derivative Works" shall mean any work, whether in Source or Object
|
||||||
For the developers' and authors' protection, the GPL clearly explains
|
form, that is based on (or derived from) the Work and for which the
|
||||||
that there is no warranty for this free software. For both users' and
|
editorial revisions, annotations, elaborations, or other modifications
|
||||||
authors' sake, the GPL requires that modified versions be marked as
|
represent, as a whole, an original work of authorship. For the purposes
|
||||||
changed, so that their problems will not be attributed erroneously to
|
of this License, Derivative Works shall not include works that remain
|
||||||
authors of previous versions.
|
separable from, or merely link (or bind by name) to the interfaces of,
|
||||||
|
the Work and Derivative Works thereof.
|
||||||
Some devices are designed to deny users access to install or run
|
|
||||||
modified versions of the software inside them, although the manufacturer
|
"Contribution" shall mean any work of authorship, including
|
||||||
can do so. This is fundamentally incompatible with the aim of
|
the original version of the Work and any modifications or additions
|
||||||
protecting users' freedom to change the software. The systematic
|
to that Work or Derivative Works thereof, that is intentionally
|
||||||
pattern of such abuse occurs in the area of products for individuals to
|
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||||
use, which is precisely where it is most unacceptable. Therefore, we
|
or by an individual or Legal Entity authorized to submit on behalf of
|
||||||
have designed this version of the GPL to prohibit the practice for those
|
the copyright owner. For the purposes of this definition, "submitted"
|
||||||
products. If such problems arise substantially in other domains, we
|
means any form of electronic, verbal, or written communication sent
|
||||||
stand ready to extend this provision to those domains in future versions
|
to the Licensor or its representatives, including but not limited to
|
||||||
of the GPL, as needed to protect the freedom of users.
|
communication on electronic mailing lists, source code control systems,
|
||||||
|
and issue tracking systems that are managed by, or on behalf of, the
|
||||||
Finally, every program is threatened constantly by software patents.
|
Licensor for the purpose of discussing and improving the Work, but
|
||||||
States should not allow patents to restrict development and use of
|
excluding communication that is conspicuously marked or otherwise
|
||||||
software on general-purpose computers, but in those that do, we wish to
|
designated in writing by the copyright owner as "Not a Contribution."
|
||||||
avoid the special danger that patents applied to a free program could
|
|
||||||
make it effectively proprietary. To prevent this, the GPL assures that
|
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||||
patents cannot be used to render the program non-free.
|
on behalf of whom a Contribution has been received by Licensor and
|
||||||
|
subsequently incorporated within the Work.
|
||||||
The precise terms and conditions for copying, distribution and
|
|
||||||
modification follow.
|
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
TERMS AND CONDITIONS
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
copyright license to reproduce, prepare Derivative Works of,
|
||||||
0. Definitions.
|
publicly display, publicly perform, sublicense, and distribute the
|
||||||
|
Work and such Derivative Works in Source or Object form.
|
||||||
"This License" refers to version 3 of the GNU General Public License.
|
|
||||||
|
3. Grant of Patent License. Subject to the terms and conditions of
|
||||||
"Copyright" also means copyright-like laws that apply to other kinds of
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
works, such as semiconductor masks.
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
(except as stated in this section) patent license to make, have made,
|
||||||
"The Program" refers to any copyrightable work licensed under this
|
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||||
License. Each licensee is addressed as "you". "Licensees" and
|
where such license applies only to those patent claims licensable
|
||||||
"recipients" may be individuals or organizations.
|
by such Contributor that are necessarily infringed by their
|
||||||
|
Contribution(s) alone or by combination of their Contribution(s)
|
||||||
To "modify" a work means to copy from or adapt all or part of the work
|
with the Work to which such Contribution(s) was submitted. If You
|
||||||
in a fashion requiring copyright permission, other than the making of an
|
institute patent litigation against any entity (including a
|
||||||
exact copy. The resulting work is called a "modified version" of the
|
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||||
earlier work or a work "based on" the earlier work.
|
or a Contribution incorporated within the Work constitutes direct
|
||||||
|
or contributory patent infringement, then any patent licenses
|
||||||
A "covered work" means either the unmodified Program or a work based
|
granted to You under this License for that Work shall terminate
|
||||||
on the Program.
|
as of the date such litigation is filed.
|
||||||
|
|
||||||
To "propagate" a work means to do anything with it that, without
|
4. Redistribution. You may reproduce and distribute copies of the
|
||||||
permission, would make you directly or secondarily liable for
|
Work or Derivative Works thereof in any medium, with or without
|
||||||
infringement under applicable copyright law, except executing it on a
|
modifications, and in Source or Object form, provided that You
|
||||||
computer or modifying a private copy. Propagation includes copying,
|
meet the following conditions:
|
||||||
distribution (with or without modification), making available to the
|
|
||||||
public, and in some countries other activities as well.
|
(a) You must give any other recipients of the Work or
|
||||||
|
Derivative Works a copy of this License; and
|
||||||
To "convey" a work means any kind of propagation that enables other
|
|
||||||
parties to make or receive copies. Mere interaction with a user through
|
(b) You must cause any modified files to carry prominent notices
|
||||||
a computer network, with no transfer of a copy, is not conveying.
|
stating that You changed the files; and
|
||||||
|
|
||||||
An interactive user interface displays "Appropriate Legal Notices"
|
(c) You must retain, in the Source form of any Derivative Works
|
||||||
to the extent that it includes a convenient and prominently visible
|
that You distribute, all copyright, patent, trademark, and
|
||||||
feature that (1) displays an appropriate copyright notice, and (2)
|
attribution notices from the Source form of the Work,
|
||||||
tells the user that there is no warranty for the work (except to the
|
excluding those notices that do not pertain to any part of
|
||||||
extent that warranties are provided), that licensees may convey the
|
the Derivative Works; and
|
||||||
work under this License, and how to view a copy of this License. If
|
|
||||||
the interface presents a list of user commands or options, such as a
|
(d) If the Work includes a "NOTICE" text file as part of its
|
||||||
menu, a prominent item in the list meets this criterion.
|
distribution, then any Derivative Works that You distribute must
|
||||||
|
include a readable copy of the attribution notices contained
|
||||||
1. Source Code.
|
within such NOTICE file, excluding those notices that do not
|
||||||
|
pertain to any part of the Derivative Works, in at least one
|
||||||
The "source code" for a work means the preferred form of the work
|
of the following places: within a NOTICE text file distributed
|
||||||
for making modifications to it. "Object code" means any non-source
|
as part of the Derivative Works; within the Source form or
|
||||||
form of a work.
|
documentation, if provided along with the Derivative Works; or,
|
||||||
|
within a display generated by the Derivative Works, if and
|
||||||
A "Standard Interface" means an interface that either is an official
|
wherever such third-party notices normally appear. The contents
|
||||||
standard defined by a recognized standards body, or, in the case of
|
of the NOTICE file are for informational purposes only and
|
||||||
interfaces specified for a particular programming language, one that
|
do not modify the License. You may add Your own attribution
|
||||||
is widely used among developers working in that language.
|
notices within Derivative Works that You distribute, alongside
|
||||||
|
or as an addendum to the NOTICE text from the Work, provided
|
||||||
The "System Libraries" of an executable work include anything, other
|
that such additional attribution notices cannot be construed
|
||||||
than the work as a whole, that (a) is included in the normal form of
|
as modifying the License.
|
||||||
packaging a Major Component, but which is not part of that Major
|
|
||||||
Component, and (b) serves only to enable use of the work with that
|
You may add Your own copyright statement to Your modifications and
|
||||||
Major Component, or to implement a Standard Interface for which an
|
may provide additional or different license terms and conditions
|
||||||
implementation is available to the public in source code form. A
|
for use, reproduction, or distribution of Your modifications, or
|
||||||
"Major Component", in this context, means a major essential component
|
for any such Derivative Works as a whole, provided Your use,
|
||||||
(kernel, window system, and so on) of the specific operating system
|
reproduction, and distribution of the Work otherwise complies with
|
||||||
(if any) on which the executable work runs, or a compiler used to
|
the conditions stated in this License.
|
||||||
produce the work, or an object code interpreter used to run it.
|
|
||||||
|
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||||
The "Corresponding Source" for a work in object code form means all
|
any Contribution intentionally submitted for inclusion in the Work
|
||||||
the source code needed to generate, install, and (for an executable
|
by You to the Licensor shall be under the terms and conditions of
|
||||||
work) run the object code and to modify the work, including scripts to
|
this License, without any additional terms or conditions.
|
||||||
control those activities. However, it does not include the work's
|
Notwithstanding the above, nothing herein shall supersede or modify
|
||||||
System Libraries, or general-purpose tools or generally available free
|
the terms of any separate license agreement you may have executed
|
||||||
programs which are used unmodified in performing those activities but
|
with Licensor regarding such Contributions.
|
||||||
which are not part of the work. For example, Corresponding Source
|
|
||||||
includes interface definition files associated with source files for
|
6. Trademarks. This License does not grant permission to use the trade
|
||||||
the work, and the source code for shared libraries and dynamically
|
names, trademarks, service marks, or product names of the Licensor,
|
||||||
linked subprograms that the work is specifically designed to require,
|
except as required for reasonable and customary use in describing the
|
||||||
such as by intimate data communication or control flow between those
|
origin of the Work and reproducing the content of the NOTICE file.
|
||||||
subprograms and other parts of the work.
|
|
||||||
|
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||||
The Corresponding Source need not include anything that users
|
agreed to in writing, Licensor provides the Work (and each
|
||||||
can regenerate automatically from other parts of the Corresponding
|
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||||
Source.
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||||
|
implied, including, without limitation, any warranties or conditions
|
||||||
The Corresponding Source for a work in source code form is that
|
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||||
same work.
|
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||||
|
appropriateness of using or redistributing the Work and assume any
|
||||||
2. Basic Permissions.
|
risks associated with Your exercise of permissions under this License.
|
||||||
|
|
||||||
All rights granted under this License are granted for the term of
|
8. Limitation of Liability. In no event and under no legal theory,
|
||||||
copyright on the Program, and are irrevocable provided the stated
|
whether in tort (including negligence), contract, or otherwise,
|
||||||
conditions are met. This License explicitly affirms your unlimited
|
unless required by applicable law (such as deliberate and grossly
|
||||||
permission to run the unmodified Program. The output from running a
|
negligent acts) or agreed to in writing, shall any Contributor be
|
||||||
covered work is covered by this License only if the output, given its
|
liable to You for damages, including any direct, indirect, special,
|
||||||
content, constitutes a covered work. This License acknowledges your
|
incidental, or consequential damages of any character arising as a
|
||||||
rights of fair use or other equivalent, as provided by copyright law.
|
result of this License or out of the use or inability to use the
|
||||||
|
Work (including but not limited to damages for loss of goodwill,
|
||||||
You may make, run and propagate covered works that you do not
|
work stoppage, computer failure or malfunction, or any and all
|
||||||
convey, without conditions so long as your license otherwise remains
|
other commercial damages or losses), even if such Contributor
|
||||||
in force. You may convey covered works to others for the sole purpose
|
has been advised of the possibility of such damages.
|
||||||
of having them make modifications exclusively for you, or provide you
|
|
||||||
with facilities for running those works, provided that you comply with
|
9. Accepting Warranty or Additional Liability. While redistributing
|
||||||
the terms of this License in conveying all material for which you do
|
the Work or Derivative Works thereof, You may choose to offer,
|
||||||
not control copyright. Those thus making or running the covered works
|
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||||
for you must do so exclusively on your behalf, under your direction
|
or other liability obligations and/or rights consistent with this
|
||||||
and control, on terms that prohibit them from making any copies of
|
License. However, in accepting such obligations, You may act only
|
||||||
your copyrighted material outside their relationship with you.
|
on Your own behalf and on Your sole responsibility, not on behalf
|
||||||
|
of any other Contributor, and only if You agree to indemnify,
|
||||||
Conveying under any other circumstances is permitted solely under
|
defend, and hold each Contributor harmless for any liability
|
||||||
the conditions stated below. Sublicensing is not allowed; section 10
|
incurred by, or claims asserted against, such Contributor by reason
|
||||||
makes it unnecessary.
|
of your accepting any such warranty or additional liability.
|
||||||
|
|
||||||
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
|
||||||
|
|
||||||
No covered work shall be deemed part of an effective technological
|
|
||||||
measure under any applicable law fulfilling obligations under article
|
|
||||||
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
|
||||||
similar laws prohibiting or restricting circumvention of such
|
|
||||||
measures.
|
|
||||||
|
|
||||||
When you convey a covered work, you waive any legal power to forbid
|
|
||||||
circumvention of technological measures to the extent such circumvention
|
|
||||||
is effected by exercising rights under this License with respect to
|
|
||||||
the covered work, and you disclaim any intention to limit operation or
|
|
||||||
modification of the work as a means of enforcing, against the work's
|
|
||||||
users, your or third parties' legal rights to forbid circumvention of
|
|
||||||
technological measures.
|
|
||||||
|
|
||||||
4. Conveying Verbatim Copies.
|
|
||||||
|
|
||||||
You may convey verbatim copies of the Program's source code as you
|
|
||||||
receive it, in any medium, provided that you conspicuously and
|
|
||||||
appropriately publish on each copy an appropriate copyright notice;
|
|
||||||
keep intact all notices stating that this License and any
|
|
||||||
non-permissive terms added in accord with section 7 apply to the code;
|
|
||||||
keep intact all notices of the absence of any warranty; and give all
|
|
||||||
recipients a copy of this License along with the Program.
|
|
||||||
|
|
||||||
You may charge any price or no price for each copy that you convey,
|
|
||||||
and you may offer support or warranty protection for a fee.
|
|
||||||
|
|
||||||
5. Conveying Modified Source Versions.
|
|
||||||
|
|
||||||
You may convey a work based on the Program, or the modifications to
|
|
||||||
produce it from the Program, in the form of source code under the
|
|
||||||
terms of section 4, provided that you also meet all of these conditions:
|
|
||||||
|
|
||||||
a) The work must carry prominent notices stating that you modified
|
|
||||||
it, and giving a relevant date.
|
|
||||||
|
|
||||||
b) The work must carry prominent notices stating that it is
|
|
||||||
released under this License and any conditions added under section
|
|
||||||
7. This requirement modifies the requirement in section 4 to
|
|
||||||
"keep intact all notices".
|
|
||||||
|
|
||||||
c) You must license the entire work, as a whole, under this
|
|
||||||
License to anyone who comes into possession of a copy. This
|
|
||||||
License will therefore apply, along with any applicable section 7
|
|
||||||
additional terms, to the whole of the work, and all its parts,
|
|
||||||
regardless of how they are packaged. This License gives no
|
|
||||||
permission to license the work in any other way, but it does not
|
|
||||||
invalidate such permission if you have separately received it.
|
|
||||||
|
|
||||||
d) If the work has interactive user interfaces, each must display
|
|
||||||
Appropriate Legal Notices; however, if the Program has interactive
|
|
||||||
interfaces that do not display Appropriate Legal Notices, your
|
|
||||||
work need not make them do so.
|
|
||||||
|
|
||||||
A compilation of a covered work with other separate and independent
|
|
||||||
works, which are not by their nature extensions of the covered work,
|
|
||||||
and which are not combined with it such as to form a larger program,
|
|
||||||
in or on a volume of a storage or distribution medium, is called an
|
|
||||||
"aggregate" if the compilation and its resulting copyright are not
|
|
||||||
used to limit the access or legal rights of the compilation's users
|
|
||||||
beyond what the individual works permit. Inclusion of a covered work
|
|
||||||
in an aggregate does not cause this License to apply to the other
|
|
||||||
parts of the aggregate.
|
|
||||||
|
|
||||||
6. Conveying Non-Source Forms.
|
|
||||||
|
|
||||||
You may convey a covered work in object code form under the terms
|
|
||||||
of sections 4 and 5, provided that you also convey the
|
|
||||||
machine-readable Corresponding Source under the terms of this License,
|
|
||||||
in one of these ways:
|
|
||||||
|
|
||||||
a) Convey the object code in, or embodied in, a physical product
|
|
||||||
(including a physical distribution medium), accompanied by the
|
|
||||||
Corresponding Source fixed on a durable physical medium
|
|
||||||
customarily used for software interchange.
|
|
||||||
|
|
||||||
b) Convey the object code in, or embodied in, a physical product
|
|
||||||
(including a physical distribution medium), accompanied by a
|
|
||||||
written offer, valid for at least three years and valid for as
|
|
||||||
long as you offer spare parts or customer support for that product
|
|
||||||
model, to give anyone who possesses the object code either (1) a
|
|
||||||
copy of the Corresponding Source for all the software in the
|
|
||||||
product that is covered by this License, on a durable physical
|
|
||||||
medium customarily used for software interchange, for a price no
|
|
||||||
more than your reasonable cost of physically performing this
|
|
||||||
conveying of source, or (2) access to copy the
|
|
||||||
Corresponding Source from a network server at no charge.
|
|
||||||
|
|
||||||
c) Convey individual copies of the object code with a copy of the
|
|
||||||
written offer to provide the Corresponding Source. This
|
|
||||||
alternative is allowed only occasionally and noncommercially, and
|
|
||||||
only if you received the object code with such an offer, in accord
|
|
||||||
with subsection 6b.
|
|
||||||
|
|
||||||
d) Convey the object code by offering access from a designated
|
|
||||||
place (gratis or for a charge), and offer equivalent access to the
|
|
||||||
Corresponding Source in the same way through the same place at no
|
|
||||||
further charge. You need not require recipients to copy the
|
|
||||||
Corresponding Source along with the object code. If the place to
|
|
||||||
copy the object code is a network server, the Corresponding Source
|
|
||||||
may be on a different server (operated by you or a third party)
|
|
||||||
that supports equivalent copying facilities, provided you maintain
|
|
||||||
clear directions next to the object code saying where to find the
|
|
||||||
Corresponding Source. Regardless of what server hosts the
|
|
||||||
Corresponding Source, you remain obligated to ensure that it is
|
|
||||||
available for as long as needed to satisfy these requirements.
|
|
||||||
|
|
||||||
e) Convey the object code using peer-to-peer transmission, provided
|
|
||||||
you inform other peers where the object code and Corresponding
|
|
||||||
Source of the work are being offered to the general public at no
|
|
||||||
charge under subsection 6d.
|
|
||||||
|
|
||||||
A separable portion of the object code, whose source code is excluded
|
|
||||||
from the Corresponding Source as a System Library, need not be
|
|
||||||
included in conveying the object code work.
|
|
||||||
|
|
||||||
A "User Product" is either (1) a "consumer product", which means any
|
|
||||||
tangible personal property which is normally used for personal, family,
|
|
||||||
or household purposes, or (2) anything designed or sold for incorporation
|
|
||||||
into a dwelling. In determining whether a product is a consumer product,
|
|
||||||
doubtful cases shall be resolved in favor of coverage. For a particular
|
|
||||||
product received by a particular user, "normally used" refers to a
|
|
||||||
typical or common use of that class of product, regardless of the status
|
|
||||||
of the particular user or of the way in which the particular user
|
|
||||||
actually uses, or expects or is expected to use, the product. A product
|
|
||||||
is a consumer product regardless of whether the product has substantial
|
|
||||||
commercial, industrial or non-consumer uses, unless such uses represent
|
|
||||||
the only significant mode of use of the product.
|
|
||||||
|
|
||||||
"Installation Information" for a User Product means any methods,
|
|
||||||
procedures, authorization keys, or other information required to install
|
|
||||||
and execute modified versions of a covered work in that User Product from
|
|
||||||
a modified version of its Corresponding Source. The information must
|
|
||||||
suffice to ensure that the continued functioning of the modified object
|
|
||||||
code is in no case prevented or interfered with solely because
|
|
||||||
modification has been made.
|
|
||||||
|
|
||||||
If you convey an object code work under this section in, or with, or
|
|
||||||
specifically for use in, a User Product, and the conveying occurs as
|
|
||||||
part of a transaction in which the right of possession and use of the
|
|
||||||
User Product is transferred to the recipient in perpetuity or for a
|
|
||||||
fixed term (regardless of how the transaction is characterized), the
|
|
||||||
Corresponding Source conveyed under this section must be accompanied
|
|
||||||
by the Installation Information. But this requirement does not apply
|
|
||||||
if neither you nor any third party retains the ability to install
|
|
||||||
modified object code on the User Product (for example, the work has
|
|
||||||
been installed in ROM).
|
|
||||||
|
|
||||||
The requirement to provide Installation Information does not include a
|
|
||||||
requirement to continue to provide support service, warranty, or updates
|
|
||||||
for a work that has been modified or installed by the recipient, or for
|
|
||||||
the User Product in which it has been modified or installed. Access to a
|
|
||||||
network may be denied when the modification itself materially and
|
|
||||||
adversely affects the operation of the network or violates the rules and
|
|
||||||
protocols for communication across the network.
|
|
||||||
|
|
||||||
Corresponding Source conveyed, and Installation Information provided,
|
|
||||||
in accord with this section must be in a format that is publicly
|
|
||||||
documented (and with an implementation available to the public in
|
|
||||||
source code form), and must require no special password or key for
|
|
||||||
unpacking, reading or copying.
|
|
||||||
|
|
||||||
7. Additional Terms.
|
|
||||||
|
|
||||||
"Additional permissions" are terms that supplement the terms of this
|
|
||||||
License by making exceptions from one or more of its conditions.
|
|
||||||
Additional permissions that are applicable to the entire Program shall
|
|
||||||
be treated as though they were included in this License, to the extent
|
|
||||||
that they are valid under applicable law. If additional permissions
|
|
||||||
apply only to part of the Program, that part may be used separately
|
|
||||||
under those permissions, but the entire Program remains governed by
|
|
||||||
this License without regard to the additional permissions.
|
|
||||||
|
|
||||||
When you convey a copy of a covered work, you may at your option
|
|
||||||
remove any additional permissions from that copy, or from any part of
|
|
||||||
it. (Additional permissions may be written to require their own
|
|
||||||
removal in certain cases when you modify the work.) You may place
|
|
||||||
additional permissions on material, added by you to a covered work,
|
|
||||||
for which you have or can give appropriate copyright permission.
|
|
||||||
|
|
||||||
Notwithstanding any other provision of this License, for material you
|
|
||||||
add to a covered work, you may (if authorized by the copyright holders of
|
|
||||||
that material) supplement the terms of this License with terms:
|
|
||||||
|
|
||||||
a) Disclaiming warranty or limiting liability differently from the
|
|
||||||
terms of sections 15 and 16 of this License; or
|
|
||||||
|
|
||||||
b) Requiring preservation of specified reasonable legal notices or
|
|
||||||
author attributions in that material or in the Appropriate Legal
|
|
||||||
Notices displayed by works containing it; or
|
|
||||||
|
|
||||||
c) Prohibiting misrepresentation of the origin of that material, or
|
|
||||||
requiring that modified versions of such material be marked in
|
|
||||||
reasonable ways as different from the original version; or
|
|
||||||
|
|
||||||
d) Limiting the use for publicity purposes of names of licensors or
|
|
||||||
authors of the material; or
|
|
||||||
|
|
||||||
e) Declining to grant rights under trademark law for use of some
|
|
||||||
trade names, trademarks, or service marks; or
|
|
||||||
|
|
||||||
f) Requiring indemnification of licensors and authors of that
|
|
||||||
material by anyone who conveys the material (or modified versions of
|
|
||||||
it) with contractual assumptions of liability to the recipient, for
|
|
||||||
any liability that these contractual assumptions directly impose on
|
|
||||||
those licensors and authors.
|
|
||||||
|
|
||||||
All other non-permissive additional terms are considered "further
|
|
||||||
restrictions" within the meaning of section 10. If the Program as you
|
|
||||||
received it, or any part of it, contains a notice stating that it is
|
|
||||||
governed by this License along with a term that is a further
|
|
||||||
restriction, you may remove that term. If a license document contains
|
|
||||||
a further restriction but permits relicensing or conveying under this
|
|
||||||
License, you may add to a covered work material governed by the terms
|
|
||||||
of that license document, provided that the further restriction does
|
|
||||||
not survive such relicensing or conveying.
|
|
||||||
|
|
||||||
If you add terms to a covered work in accord with this section, you
|
|
||||||
must place, in the relevant source files, a statement of the
|
|
||||||
additional terms that apply to those files, or a notice indicating
|
|
||||||
where to find the applicable terms.
|
|
||||||
|
|
||||||
Additional terms, permissive or non-permissive, may be stated in the
|
|
||||||
form of a separately written license, or stated as exceptions;
|
|
||||||
the above requirements apply either way.
|
|
||||||
|
|
||||||
8. Termination.
|
|
||||||
|
|
||||||
You may not propagate or modify a covered work except as expressly
|
|
||||||
provided under this License. Any attempt otherwise to propagate or
|
|
||||||
modify it is void, and will automatically terminate your rights under
|
|
||||||
this License (including any patent licenses granted under the third
|
|
||||||
paragraph of section 11).
|
|
||||||
|
|
||||||
However, if you cease all violation of this License, then your
|
|
||||||
license from a particular copyright holder is reinstated (a)
|
|
||||||
provisionally, unless and until the copyright holder explicitly and
|
|
||||||
finally terminates your license, and (b) permanently, if the copyright
|
|
||||||
holder fails to notify you of the violation by some reasonable means
|
|
||||||
prior to 60 days after the cessation.
|
|
||||||
|
|
||||||
Moreover, your license from a particular copyright holder is
|
|
||||||
reinstated permanently if the copyright holder notifies you of the
|
|
||||||
violation by some reasonable means, this is the first time you have
|
|
||||||
received notice of violation of this License (for any work) from that
|
|
||||||
copyright holder, and you cure the violation prior to 30 days after
|
|
||||||
your receipt of the notice.
|
|
||||||
|
|
||||||
Termination of your rights under this section does not terminate the
|
|
||||||
licenses of parties who have received copies or rights from you under
|
|
||||||
this License. If your rights have been terminated and not permanently
|
|
||||||
reinstated, you do not qualify to receive new licenses for the same
|
|
||||||
material under section 10.
|
|
||||||
|
|
||||||
9. Acceptance Not Required for Having Copies.
|
|
||||||
|
|
||||||
You are not required to accept this License in order to receive or
|
|
||||||
run a copy of the Program. Ancillary propagation of a covered work
|
|
||||||
occurring solely as a consequence of using peer-to-peer transmission
|
|
||||||
to receive a copy likewise does not require acceptance. However,
|
|
||||||
nothing other than this License grants you permission to propagate or
|
|
||||||
modify any covered work. These actions infringe copyright if you do
|
|
||||||
not accept this License. Therefore, by modifying or propagating a
|
|
||||||
covered work, you indicate your acceptance of this License to do so.
|
|
||||||
|
|
||||||
10. Automatic Licensing of Downstream Recipients.
|
|
||||||
|
|
||||||
Each time you convey a covered work, the recipient automatically
|
|
||||||
receives a license from the original licensors, to run, modify and
|
|
||||||
propagate that work, subject to this License. You are not responsible
|
|
||||||
for enforcing compliance by third parties with this License.
|
|
||||||
|
|
||||||
An "entity transaction" is a transaction transferring control of an
|
|
||||||
organization, or substantially all assets of one, or subdividing an
|
|
||||||
organization, or merging organizations. If propagation of a covered
|
|
||||||
work results from an entity transaction, each party to that
|
|
||||||
transaction who receives a copy of the work also receives whatever
|
|
||||||
licenses to the work the party's predecessor in interest had or could
|
|
||||||
give under the previous paragraph, plus a right to possession of the
|
|
||||||
Corresponding Source of the work from the predecessor in interest, if
|
|
||||||
the predecessor has it or can get it with reasonable efforts.
|
|
||||||
|
|
||||||
You may not impose any further restrictions on the exercise of the
|
|
||||||
rights granted or affirmed under this License. For example, you may
|
|
||||||
not impose a license fee, royalty, or other charge for exercise of
|
|
||||||
rights granted under this License, and you may not initiate litigation
|
|
||||||
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
|
||||||
any patent claim is infringed by making, using, selling, offering for
|
|
||||||
sale, or importing the Program or any portion of it.
|
|
||||||
|
|
||||||
11. Patents.
|
|
||||||
|
|
||||||
A "contributor" is a copyright holder who authorizes use under this
|
|
||||||
License of the Program or a work on which the Program is based. The
|
|
||||||
work thus licensed is called the contributor's "contributor version".
|
|
||||||
|
|
||||||
A contributor's "essential patent claims" are all patent claims
|
|
||||||
owned or controlled by the contributor, whether already acquired or
|
|
||||||
hereafter acquired, that would be infringed by some manner, permitted
|
|
||||||
by this License, of making, using, or selling its contributor version,
|
|
||||||
but do not include claims that would be infringed only as a
|
|
||||||
consequence of further modification of the contributor version. For
|
|
||||||
purposes of this definition, "control" includes the right to grant
|
|
||||||
patent sublicenses in a manner consistent with the requirements of
|
|
||||||
this License.
|
|
||||||
|
|
||||||
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
|
||||||
patent license under the contributor's essential patent claims, to
|
|
||||||
make, use, sell, offer for sale, import and otherwise run, modify and
|
|
||||||
propagate the contents of its contributor version.
|
|
||||||
|
|
||||||
In the following three paragraphs, a "patent license" is any express
|
|
||||||
agreement or commitment, however denominated, not to enforce a patent
|
|
||||||
(such as an express permission to practice a patent or covenant not to
|
|
||||||
sue for patent infringement). To "grant" such a patent license to a
|
|
||||||
party means to make such an agreement or commitment not to enforce a
|
|
||||||
patent against the party.
|
|
||||||
|
|
||||||
If you convey a covered work, knowingly relying on a patent license,
|
|
||||||
and the Corresponding Source of the work is not available for anyone
|
|
||||||
to copy, free of charge and under the terms of this License, through a
|
|
||||||
publicly available network server or other readily accessible means,
|
|
||||||
then you must either (1) cause the Corresponding Source to be so
|
|
||||||
available, or (2) arrange to deprive yourself of the benefit of the
|
|
||||||
patent license for this particular work, or (3) arrange, in a manner
|
|
||||||
consistent with the requirements of this License, to extend the patent
|
|
||||||
license to downstream recipients. "Knowingly relying" means you have
|
|
||||||
actual knowledge that, but for the patent license, your conveying the
|
|
||||||
covered work in a country, or your recipient's use of the covered work
|
|
||||||
in a country, would infringe one or more identifiable patents in that
|
|
||||||
country that you have reason to believe are valid.
|
|
||||||
|
|
||||||
If, pursuant to or in connection with a single transaction or
|
|
||||||
arrangement, you convey, or propagate by procuring conveyance of, a
|
|
||||||
covered work, and grant a patent license to some of the parties
|
|
||||||
receiving the covered work authorizing them to use, propagate, modify
|
|
||||||
or convey a specific copy of the covered work, then the patent license
|
|
||||||
you grant is automatically extended to all recipients of the covered
|
|
||||||
work and works based on it.
|
|
||||||
|
|
||||||
A patent license is "discriminatory" if it does not include within
|
|
||||||
the scope of its coverage, prohibits the exercise of, or is
|
|
||||||
conditioned on the non-exercise of one or more of the rights that are
|
|
||||||
specifically granted under this License. You may not convey a covered
|
|
||||||
work if you are a party to an arrangement with a third party that is
|
|
||||||
in the business of distributing software, under which you make payment
|
|
||||||
to the third party based on the extent of your activity of conveying
|
|
||||||
the work, and under which the third party grants, to any of the
|
|
||||||
parties who would receive the covered work from you, a discriminatory
|
|
||||||
patent license (a) in connection with copies of the covered work
|
|
||||||
conveyed by you (or copies made from those copies), or (b) primarily
|
|
||||||
for and in connection with specific products or compilations that
|
|
||||||
contain the covered work, unless you entered into that arrangement,
|
|
||||||
or that patent license was granted, prior to 28 March 2007.
|
|
||||||
|
|
||||||
Nothing in this License shall be construed as excluding or limiting
|
|
||||||
any implied license or other defenses to infringement that may
|
|
||||||
otherwise be available to you under applicable patent law.
|
|
||||||
|
|
||||||
12. No Surrender of Others' Freedom.
|
|
||||||
|
|
||||||
If conditions are imposed on you (whether by court order, agreement or
|
|
||||||
otherwise) that contradict the conditions of this License, they do not
|
|
||||||
excuse you from the conditions of this License. If you cannot convey a
|
|
||||||
covered work so as to satisfy simultaneously your obligations under this
|
|
||||||
License and any other pertinent obligations, then as a consequence you may
|
|
||||||
not convey it at all. For example, if you agree to terms that obligate you
|
|
||||||
to collect a royalty for further conveying from those to whom you convey
|
|
||||||
the Program, the only way you could satisfy both those terms and this
|
|
||||||
License would be to refrain entirely from conveying the Program.
|
|
||||||
|
|
||||||
13. Use with the GNU Affero General Public License.
|
|
||||||
|
|
||||||
Notwithstanding any other provision of this License, you have
|
|
||||||
permission to link or combine any covered work with a work licensed
|
|
||||||
under version 3 of the GNU Affero General Public License into a single
|
|
||||||
combined work, and to convey the resulting work. The terms of this
|
|
||||||
License will continue to apply to the part which is the covered work,
|
|
||||||
but the special requirements of the GNU Affero General Public License,
|
|
||||||
section 13, concerning interaction through a network will apply to the
|
|
||||||
combination as such.
|
|
||||||
|
|
||||||
14. Revised Versions of this License.
|
|
||||||
|
|
||||||
The Free Software Foundation may publish revised and/or new versions of
|
|
||||||
the GNU General Public License from time to time. Such new versions will
|
|
||||||
be similar in spirit to the present version, but may differ in detail to
|
|
||||||
address new problems or concerns.
|
|
||||||
|
|
||||||
Each version is given a distinguishing version number. If the
|
|
||||||
Program specifies that a certain numbered version of the GNU General
|
|
||||||
Public License "or any later version" applies to it, you have the
|
|
||||||
option of following the terms and conditions either of that numbered
|
|
||||||
version or of any later version published by the Free Software
|
|
||||||
Foundation. If the Program does not specify a version number of the
|
|
||||||
GNU General Public License, you may choose any version ever published
|
|
||||||
by the Free Software Foundation.
|
|
||||||
|
|
||||||
If the Program specifies that a proxy can decide which future
|
|
||||||
versions of the GNU General Public License can be used, that proxy's
|
|
||||||
public statement of acceptance of a version permanently authorizes you
|
|
||||||
to choose that version for the Program.
|
|
||||||
|
|
||||||
Later license versions may give you additional or different
|
|
||||||
permissions. However, no additional obligations are imposed on any
|
|
||||||
author or copyright holder as a result of your choosing to follow a
|
|
||||||
later version.
|
|
||||||
|
|
||||||
15. Disclaimer of Warranty.
|
|
||||||
|
|
||||||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
|
||||||
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
|
||||||
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
|
||||||
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
|
||||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
|
||||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
|
||||||
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
|
||||||
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
|
||||||
|
|
||||||
16. Limitation of Liability.
|
|
||||||
|
|
||||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
|
||||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
|
||||||
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
|
||||||
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
|
||||||
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
|
||||||
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
|
||||||
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
|
||||||
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
|
||||||
SUCH DAMAGES.
|
|
||||||
|
|
||||||
17. Interpretation of Sections 15 and 16.
|
|
||||||
|
|
||||||
If the disclaimer of warranty and limitation of liability provided
|
|
||||||
above cannot be given local legal effect according to their terms,
|
|
||||||
reviewing courts shall apply local law that most closely approximates
|
|
||||||
an absolute waiver of all civil liability in connection with the
|
|
||||||
Program, unless a warranty or assumption of liability accompanies a
|
|
||||||
copy of the Program in return for a fee.
|
|
||||||
|
|
||||||
END OF TERMS AND CONDITIONS
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
How to Apply These Terms to Your New Programs
|
APPENDIX: How to apply the Apache License to your work.
|
||||||
|
|
||||||
If you develop a new program, and you want it to be of the greatest
|
To apply the Apache License to your work, attach the following
|
||||||
possible use to the public, the best way to achieve this is to make it
|
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||||
free software which everyone can redistribute and change under these terms.
|
replaced with your own identifying information. (Don't include
|
||||||
|
the brackets!) The text should be enclosed in the appropriate
|
||||||
|
comment syntax for the file format. We also recommend that a
|
||||||
|
file or class name and description of purpose be included on the
|
||||||
|
same "printed page" as the copyright notice for easier
|
||||||
|
identification within third-party archives.
|
||||||
|
|
||||||
To do so, attach the following notices to the program. It is safest
|
Copyright [yyyy] [name of copyright owner]
|
||||||
to attach them to the start of each source file to most effectively
|
|
||||||
state the exclusion of warranty; and each file should have at least
|
|
||||||
the "copyright" line and a pointer to where the full notice is found.
|
|
||||||
|
|
||||||
<one line to give the program's name and a brief idea of what it does.>
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
Copyright (C) <year> <name of author>
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
Unless required by applicable law or agreed to in writing, software
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
GNU General Public License for more details.
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
Also add information on how to contact you by electronic and paper mail.
|
|
||||||
|
|
||||||
If the program does terminal interaction, make it output a short
|
|
||||||
notice like this when it starts in an interactive mode:
|
|
||||||
|
|
||||||
<program> Copyright (C) <year> <name of author>
|
|
||||||
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
|
||||||
This is free software, and you are welcome to redistribute it
|
|
||||||
under certain conditions; type `show c' for details.
|
|
||||||
|
|
||||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
|
||||||
parts of the General Public License. Of course, your program's commands
|
|
||||||
might be different; for a GUI interface, you would use an "about box".
|
|
||||||
|
|
||||||
You should also get your employer (if you work as a programmer) or school,
|
|
||||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
|
||||||
For more information on this, and how to apply and follow the GNU GPL, see
|
|
||||||
<http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
The GNU General Public License does not permit incorporating your program
|
|
||||||
into proprietary programs. If your program is a subroutine library, you
|
|
||||||
may consider it more useful to permit linking proprietary applications with
|
|
||||||
the library. If this is what you want to do, use the GNU Lesser General
|
|
||||||
Public License instead of this License. But first, please read
|
|
||||||
<http://www.gnu.org/philosophy/why-not-lgpl.html>.
|
|
||||||
|
|||||||
79
README.md
79
README.md
@@ -1,3 +1,7 @@
|
|||||||
|
[](https://travis-ci.org/jeremylong/DependencyCheck) [](https://scan.coverity.com/projects/dependencycheck) [](https://www.codacy.com/app/jeremylong/DependencyCheck?utm_source=github.com&utm_medium=referral&utm_content=jeremylong/DependencyCheck&utm_campaign=Badge_Grade) [](https://www.apache.org/licenses/LICENSE-2.0.txt)
|
||||||
|
|
||||||
|
[](https://www.toolswatch.org/2015/06/black-hat-arsenal-usa-2015-speakers-lineup/) [](https://www.toolswatch.org/2014/06/black-hat-usa-2014-arsenal-tools-speaker-list/) [](https://www.toolswatch.org/2013/06/announcement-blackhat-arsenal-usa-2013-selected-tools/)
|
||||||
|
|
||||||
Dependency-Check
|
Dependency-Check
|
||||||
================
|
================
|
||||||
|
|
||||||
@@ -9,27 +13,35 @@ Current Releases
|
|||||||
-------------
|
-------------
|
||||||
### Jenkins Plugin
|
### Jenkins Plugin
|
||||||
|
|
||||||
For instructions on the use of the Jenkins plugin please see the [Jenkins dependency-check page](http://wiki.jenkins-ci.org/x/CwDgAQ).
|
For instructions on the use of the Jenkins plugin please see the [OWASP Dependency-Check Plugin page](https://wiki.jenkins-ci.org/display/JENKINS/OWASP+Dependency-Check+Plugin).
|
||||||
|
|
||||||
### Command Line
|
### Command Line
|
||||||
|
|
||||||
More detailed instructions can be found on the [dependency-check github pages](http://jeremylong.github.io/DependencyCheck/dependency-check-cli/installation.html).
|
More detailed instructions can be found on the
|
||||||
The latest CLI can be downloaded from bintray's [dependency-check page](https://bintray.com/jeremy-long/owasp/dependency-check).
|
[dependency-check github pages](http://jeremylong.github.io/DependencyCheck/dependency-check-cli/).
|
||||||
|
The latest CLI can be downloaded from bintray's
|
||||||
|
[dependency-check page](https://bintray.com/jeremy-long/owasp/dependency-check).
|
||||||
|
|
||||||
On *nix
|
On *nix
|
||||||
```
|
```
|
||||||
$ ./bin/dependency-check.sh -h
|
$ ./bin/dependency-check.sh -h
|
||||||
$ ./bin/dependency-check.sh --app Testing --out . --scan [path to jar files to be scanned]
|
$ ./bin/dependency-check.sh --project Testing --out . --scan [path to jar files to be scanned]
|
||||||
```
|
```
|
||||||
On Windows
|
On Windows
|
||||||
```
|
```
|
||||||
> bin/dependency-check.bat -h
|
> bin/dependency-check.bat -h
|
||||||
> bin/dependency-check.bat --app Testing --out . --scan [path to jar files to be scanned]
|
> bin/dependency-check.bat --project Testing --out . --scan [path to jar files to be scanned]
|
||||||
|
```
|
||||||
|
On Mac with [Homebrew](http://brew.sh)
|
||||||
|
```
|
||||||
|
$ brew update && brew install dependency-check
|
||||||
|
$ dependency-check -h
|
||||||
|
$ dependency-check --project Testing --out . --scan [path to jar files to be scanned]
|
||||||
```
|
```
|
||||||
|
|
||||||
### Maven Plugin
|
### Maven Plugin
|
||||||
|
|
||||||
More detailed instructions can be found on the [dependency-check-maven github pages](http://jeremylong.github.io/DependencyCheck/dependency-check-maven/installation.html).
|
More detailed instructions can be found on the [dependency-check-maven github pages](http://jeremylong.github.io/DependencyCheck/dependency-check-maven).
|
||||||
The plugin can be configured using the following:
|
The plugin can be configured using the following:
|
||||||
|
|
||||||
```xml
|
```xml
|
||||||
@@ -40,7 +52,6 @@ The plugin can be configured using the following:
|
|||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.owasp</groupId>
|
<groupId>org.owasp</groupId>
|
||||||
<artifactId>dependency-check-maven</artifactId>
|
<artifactId>dependency-check-maven</artifactId>
|
||||||
<version>1.0.2</version>
|
|
||||||
<executions>
|
<executions>
|
||||||
<execution>
|
<execution>
|
||||||
<goals>
|
<goals>
|
||||||
@@ -59,30 +70,65 @@ The plugin can be configured using the following:
|
|||||||
|
|
||||||
### Ant Task
|
### Ant Task
|
||||||
|
|
||||||
For instructions on the use of the Ant Task, please see the [dependency-check-ant github page](http://jeremylong.github.io/DependencyCheck/dependency-check-maven/installation.html).
|
For instructions on the use of the Ant Task, please see the [dependency-check-ant github page](http://jeremylong.github.io/DependencyCheck/dependency-check-ant).
|
||||||
|
|
||||||
Development Usage
|
Development Usage
|
||||||
-------------
|
-------------
|
||||||
The following instructions outline how to compile and use the current snapshot. While every intention is to maintain a stable snapshot it is recommended
|
The following instructions outline how to compile and use the current snapshot. While every intention is to maintain a stable snapshot it is recommended
|
||||||
that the release versions listed above be used.
|
that the release versions listed above be used.
|
||||||
|
|
||||||
Note, currently the install goal may take a long time to execute the integration tests. However, if this takes more then 30 minutes it is likely that the
|
The repository has some large files due to test resources. The team has tried to cleanup the history as much as possible.
|
||||||
download of data from the NVD is having an issue. This issue is still being researched and a solution should be published soon.
|
However, it is recommended that you perform a shallow clone to save yourself time:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git clone --depth 1 git@github.com:jeremylong/DependencyCheck.git
|
||||||
|
```
|
||||||
|
|
||||||
On *nix
|
On *nix
|
||||||
```
|
```
|
||||||
$ mvn install
|
$ mvn install
|
||||||
$ ./dependency-check-cli/target/release/bin/dependency-check.sh -h
|
$ ./dependency-check-cli/target/release/bin/dependency-check.sh -h
|
||||||
$ ./dependency-check-cli/target/release/bin/dependency-check.sh --app Testing --out . --scan ./src/test/resources
|
$ ./dependency-check-cli/target/release/bin/dependency-check.sh --project Testing --out . --scan ./src/test/resources
|
||||||
```
|
```
|
||||||
On Windows
|
On Windows
|
||||||
```
|
```
|
||||||
> mvn install
|
> mvn install
|
||||||
> dependency-check-cli/target/release/bin/dependency-check.bat -h
|
> dependency-check-cli/target/release/bin/dependency-check.bat -h
|
||||||
> dependency-check-cli/target/release/bin/dependency-check.bat --app Testing --out . --scan ./src/test/resources
|
> dependency-check-cli/target/release/bin/dependency-check.bat --project Testing --out . --scan ./src/test/resources
|
||||||
|
```
|
||||||
|
|
||||||
|
Then load the resulting 'DependencyCheck-Report.html' into your favorite browser.
|
||||||
|
|
||||||
|
### Docker
|
||||||
|
|
||||||
|
In the following example it is assumed that the source to be checked is in the actual directory. A persistent data directory and a persistent report directory is used so that the container can be destroyed after running it to make sure that you use the newest version, always.
|
||||||
|
```
|
||||||
|
# After the first run, feel free to change the owner of the directories to the owner of the created files and the permissions to 744
|
||||||
|
DATA_DIRECTORY=$HOME/OWASP-Dependency-Check/data
|
||||||
|
REPORT_DIRECTORY=/$HOME/OWASP-Dependency-Check/reports
|
||||||
|
|
||||||
|
if [ ! -d $DATA_DIRECTORY ]; then
|
||||||
|
echo "Initially creating persistent directories"
|
||||||
|
mkdir -p $DATA_DIRECTORY
|
||||||
|
chmod -R 777 $DATA_DIRECTORY
|
||||||
|
|
||||||
|
mkdir -p $REPORT_DIRECTORY
|
||||||
|
chmod -R 777 $REPORT_DIRECTORY
|
||||||
|
fi
|
||||||
|
|
||||||
|
docker pull owasp/dependency-check # Make sure it is the actual version
|
||||||
|
|
||||||
|
docker run --rm \
|
||||||
|
--volume $(pwd):/src \
|
||||||
|
--volume $DATA_DIRECTORY:/usr/share/dependency-check/data \
|
||||||
|
--volume $REPORT_DIRECTORY:/report \
|
||||||
|
--name dependency-check \
|
||||||
|
dc \
|
||||||
|
--suppression "/src/security/dependency-check-suppression.xml"\
|
||||||
|
--format "ALL" \
|
||||||
|
--project "My OWASP Dependency Check Project" \
|
||||||
```
|
```
|
||||||
|
|
||||||
Then load the resulting 'DependencyCheck-Report.html' into your favourite browser.
|
|
||||||
|
|
||||||
Mailing List
|
Mailing List
|
||||||
------------
|
------------
|
||||||
@@ -96,9 +142,9 @@ Archive: [google group](https://groups.google.com/forum/#!forum/dependency-check
|
|||||||
Copyright & License
|
Copyright & License
|
||||||
-
|
-
|
||||||
|
|
||||||
Dependency-Check is Copyright (c) 2012-2013 Jeremy Long. All Rights Reserved.
|
Dependency-Check is Copyright (c) 2012-2016 Jeremy Long. All Rights Reserved.
|
||||||
|
|
||||||
Permission to modify and redistribute is granted under the terms of the GPLv3 license. See the [LICENSE.txt] [GPLv3] file for the full license.
|
Permission to modify and redistribute is granted under the terms of the Apache 2.0 license. See the [LICENSE.txt](https://raw.githubusercontent.com/jeremylong/DependencyCheck/master/LICENSE.txt) file for the full license.
|
||||||
|
|
||||||
Dependency-Check makes use of several other open source libraries. Please see the [NOTICE.txt][notices] file for more information.
|
Dependency-Check makes use of several other open source libraries. Please see the [NOTICE.txt][notices] file for more information.
|
||||||
|
|
||||||
@@ -106,5 +152,4 @@ Dependency-Check makes use of several other open source libraries. Please see th
|
|||||||
[wiki]: https://github.com/jeremylong/DependencyCheck/wiki
|
[wiki]: https://github.com/jeremylong/DependencyCheck/wiki
|
||||||
[subscribe]: mailto:dependency-check+subscribe@googlegroups.com
|
[subscribe]: mailto:dependency-check+subscribe@googlegroups.com
|
||||||
[post]: mailto:dependency-check@googlegroups.com
|
[post]: mailto:dependency-check@googlegroups.com
|
||||||
[GPLv3]: https://github.com/jeremylong/DependencyCheck/blob/master/LICENSE.txt
|
[notices]: https://github.com/jeremylong/DependencyCheck/blob/master/NOTICE.txt
|
||||||
[notices]: https://github.com/jeremylong/DependencyCheck/blob/master/NOTICES.txt
|
|
||||||
|
|||||||
@@ -1,674 +1,202 @@
|
|||||||
GNU GENERAL PUBLIC LICENSE
|
|
||||||
Version 3, 29 June 2007
|
|
||||||
|
|
||||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
Apache License
|
||||||
Everyone is permitted to copy and distribute verbatim copies
|
Version 2.0, January 2004
|
||||||
of this license document, but changing it is not allowed.
|
http://www.apache.org/licenses/
|
||||||
|
|
||||||
Preamble
|
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||||
|
|
||||||
The GNU General Public License is a free, copyleft license for
|
1. Definitions.
|
||||||
software and other kinds of works.
|
|
||||||
|
"License" shall mean the terms and conditions for use, reproduction,
|
||||||
The licenses for most software and other practical works are designed
|
and distribution as defined by Sections 1 through 9 of this document.
|
||||||
to take away your freedom to share and change the works. By contrast,
|
|
||||||
the GNU General Public License is intended to guarantee your freedom to
|
"Licensor" shall mean the copyright owner or entity authorized by
|
||||||
share and change all versions of a program--to make sure it remains free
|
the copyright owner that is granting the License.
|
||||||
software for all its users. We, the Free Software Foundation, use the
|
|
||||||
GNU General Public License for most of our software; it applies also to
|
"Legal Entity" shall mean the union of the acting entity and all
|
||||||
any other work released this way by its authors. You can apply it to
|
other entities that control, are controlled by, or are under common
|
||||||
your programs, too.
|
control with that entity. For the purposes of this definition,
|
||||||
|
"control" means (i) the power, direct or indirect, to cause the
|
||||||
When we speak of free software, we are referring to freedom, not
|
direction or management of such entity, whether by contract or
|
||||||
price. Our General Public Licenses are designed to make sure that you
|
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||||
have the freedom to distribute copies of free software (and charge for
|
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||||
them if you wish), that you receive source code or can get it if you
|
|
||||||
want it, that you can change the software or use pieces of it in new
|
"You" (or "Your") shall mean an individual or Legal Entity
|
||||||
free programs, and that you know you can do these things.
|
exercising permissions granted by this License.
|
||||||
|
|
||||||
To protect your rights, we need to prevent others from denying you
|
"Source" form shall mean the preferred form for making modifications,
|
||||||
these rights or asking you to surrender the rights. Therefore, you have
|
including but not limited to software source code, documentation
|
||||||
certain responsibilities if you distribute copies of the software, or if
|
source, and configuration files.
|
||||||
you modify it: responsibilities to respect the freedom of others.
|
|
||||||
|
"Object" form shall mean any form resulting from mechanical
|
||||||
For example, if you distribute copies of such a program, whether
|
transformation or translation of a Source form, including but
|
||||||
gratis or for a fee, you must pass on to the recipients the same
|
not limited to compiled object code, generated documentation,
|
||||||
freedoms that you received. You must make sure that they, too, receive
|
and conversions to other media types.
|
||||||
or can get the source code. And you must show them these terms so they
|
|
||||||
know their rights.
|
"Work" shall mean the work of authorship, whether in Source or
|
||||||
|
Object form, made available under the License, as indicated by a
|
||||||
Developers that use the GNU GPL protect your rights with two steps:
|
copyright notice that is included in or attached to the work
|
||||||
(1) assert copyright on the software, and (2) offer you this License
|
(an example is provided in the Appendix below).
|
||||||
giving you legal permission to copy, distribute and/or modify it.
|
|
||||||
|
"Derivative Works" shall mean any work, whether in Source or Object
|
||||||
For the developers' and authors' protection, the GPL clearly explains
|
form, that is based on (or derived from) the Work and for which the
|
||||||
that there is no warranty for this free software. For both users' and
|
editorial revisions, annotations, elaborations, or other modifications
|
||||||
authors' sake, the GPL requires that modified versions be marked as
|
represent, as a whole, an original work of authorship. For the purposes
|
||||||
changed, so that their problems will not be attributed erroneously to
|
of this License, Derivative Works shall not include works that remain
|
||||||
authors of previous versions.
|
separable from, or merely link (or bind by name) to the interfaces of,
|
||||||
|
the Work and Derivative Works thereof.
|
||||||
Some devices are designed to deny users access to install or run
|
|
||||||
modified versions of the software inside them, although the manufacturer
|
"Contribution" shall mean any work of authorship, including
|
||||||
can do so. This is fundamentally incompatible with the aim of
|
the original version of the Work and any modifications or additions
|
||||||
protecting users' freedom to change the software. The systematic
|
to that Work or Derivative Works thereof, that is intentionally
|
||||||
pattern of such abuse occurs in the area of products for individuals to
|
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||||
use, which is precisely where it is most unacceptable. Therefore, we
|
or by an individual or Legal Entity authorized to submit on behalf of
|
||||||
have designed this version of the GPL to prohibit the practice for those
|
the copyright owner. For the purposes of this definition, "submitted"
|
||||||
products. If such problems arise substantially in other domains, we
|
means any form of electronic, verbal, or written communication sent
|
||||||
stand ready to extend this provision to those domains in future versions
|
to the Licensor or its representatives, including but not limited to
|
||||||
of the GPL, as needed to protect the freedom of users.
|
communication on electronic mailing lists, source code control systems,
|
||||||
|
and issue tracking systems that are managed by, or on behalf of, the
|
||||||
Finally, every program is threatened constantly by software patents.
|
Licensor for the purpose of discussing and improving the Work, but
|
||||||
States should not allow patents to restrict development and use of
|
excluding communication that is conspicuously marked or otherwise
|
||||||
software on general-purpose computers, but in those that do, we wish to
|
designated in writing by the copyright owner as "Not a Contribution."
|
||||||
avoid the special danger that patents applied to a free program could
|
|
||||||
make it effectively proprietary. To prevent this, the GPL assures that
|
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||||
patents cannot be used to render the program non-free.
|
on behalf of whom a Contribution has been received by Licensor and
|
||||||
|
subsequently incorporated within the Work.
|
||||||
The precise terms and conditions for copying, distribution and
|
|
||||||
modification follow.
|
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
TERMS AND CONDITIONS
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
copyright license to reproduce, prepare Derivative Works of,
|
||||||
0. Definitions.
|
publicly display, publicly perform, sublicense, and distribute the
|
||||||
|
Work and such Derivative Works in Source or Object form.
|
||||||
"This License" refers to version 3 of the GNU General Public License.
|
|
||||||
|
3. Grant of Patent License. Subject to the terms and conditions of
|
||||||
"Copyright" also means copyright-like laws that apply to other kinds of
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
works, such as semiconductor masks.
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
(except as stated in this section) patent license to make, have made,
|
||||||
"The Program" refers to any copyrightable work licensed under this
|
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||||
License. Each licensee is addressed as "you". "Licensees" and
|
where such license applies only to those patent claims licensable
|
||||||
"recipients" may be individuals or organizations.
|
by such Contributor that are necessarily infringed by their
|
||||||
|
Contribution(s) alone or by combination of their Contribution(s)
|
||||||
To "modify" a work means to copy from or adapt all or part of the work
|
with the Work to which such Contribution(s) was submitted. If You
|
||||||
in a fashion requiring copyright permission, other than the making of an
|
institute patent litigation against any entity (including a
|
||||||
exact copy. The resulting work is called a "modified version" of the
|
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||||
earlier work or a work "based on" the earlier work.
|
or a Contribution incorporated within the Work constitutes direct
|
||||||
|
or contributory patent infringement, then any patent licenses
|
||||||
A "covered work" means either the unmodified Program or a work based
|
granted to You under this License for that Work shall terminate
|
||||||
on the Program.
|
as of the date such litigation is filed.
|
||||||
|
|
||||||
To "propagate" a work means to do anything with it that, without
|
4. Redistribution. You may reproduce and distribute copies of the
|
||||||
permission, would make you directly or secondarily liable for
|
Work or Derivative Works thereof in any medium, with or without
|
||||||
infringement under applicable copyright law, except executing it on a
|
modifications, and in Source or Object form, provided that You
|
||||||
computer or modifying a private copy. Propagation includes copying,
|
meet the following conditions:
|
||||||
distribution (with or without modification), making available to the
|
|
||||||
public, and in some countries other activities as well.
|
(a) You must give any other recipients of the Work or
|
||||||
|
Derivative Works a copy of this License; and
|
||||||
To "convey" a work means any kind of propagation that enables other
|
|
||||||
parties to make or receive copies. Mere interaction with a user through
|
(b) You must cause any modified files to carry prominent notices
|
||||||
a computer network, with no transfer of a copy, is not conveying.
|
stating that You changed the files; and
|
||||||
|
|
||||||
An interactive user interface displays "Appropriate Legal Notices"
|
(c) You must retain, in the Source form of any Derivative Works
|
||||||
to the extent that it includes a convenient and prominently visible
|
that You distribute, all copyright, patent, trademark, and
|
||||||
feature that (1) displays an appropriate copyright notice, and (2)
|
attribution notices from the Source form of the Work,
|
||||||
tells the user that there is no warranty for the work (except to the
|
excluding those notices that do not pertain to any part of
|
||||||
extent that warranties are provided), that licensees may convey the
|
the Derivative Works; and
|
||||||
work under this License, and how to view a copy of this License. If
|
|
||||||
the interface presents a list of user commands or options, such as a
|
(d) If the Work includes a "NOTICE" text file as part of its
|
||||||
menu, a prominent item in the list meets this criterion.
|
distribution, then any Derivative Works that You distribute must
|
||||||
|
include a readable copy of the attribution notices contained
|
||||||
1. Source Code.
|
within such NOTICE file, excluding those notices that do not
|
||||||
|
pertain to any part of the Derivative Works, in at least one
|
||||||
The "source code" for a work means the preferred form of the work
|
of the following places: within a NOTICE text file distributed
|
||||||
for making modifications to it. "Object code" means any non-source
|
as part of the Derivative Works; within the Source form or
|
||||||
form of a work.
|
documentation, if provided along with the Derivative Works; or,
|
||||||
|
within a display generated by the Derivative Works, if and
|
||||||
A "Standard Interface" means an interface that either is an official
|
wherever such third-party notices normally appear. The contents
|
||||||
standard defined by a recognized standards body, or, in the case of
|
of the NOTICE file are for informational purposes only and
|
||||||
interfaces specified for a particular programming language, one that
|
do not modify the License. You may add Your own attribution
|
||||||
is widely used among developers working in that language.
|
notices within Derivative Works that You distribute, alongside
|
||||||
|
or as an addendum to the NOTICE text from the Work, provided
|
||||||
The "System Libraries" of an executable work include anything, other
|
that such additional attribution notices cannot be construed
|
||||||
than the work as a whole, that (a) is included in the normal form of
|
as modifying the License.
|
||||||
packaging a Major Component, but which is not part of that Major
|
|
||||||
Component, and (b) serves only to enable use of the work with that
|
You may add Your own copyright statement to Your modifications and
|
||||||
Major Component, or to implement a Standard Interface for which an
|
may provide additional or different license terms and conditions
|
||||||
implementation is available to the public in source code form. A
|
for use, reproduction, or distribution of Your modifications, or
|
||||||
"Major Component", in this context, means a major essential component
|
for any such Derivative Works as a whole, provided Your use,
|
||||||
(kernel, window system, and so on) of the specific operating system
|
reproduction, and distribution of the Work otherwise complies with
|
||||||
(if any) on which the executable work runs, or a compiler used to
|
the conditions stated in this License.
|
||||||
produce the work, or an object code interpreter used to run it.
|
|
||||||
|
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||||
The "Corresponding Source" for a work in object code form means all
|
any Contribution intentionally submitted for inclusion in the Work
|
||||||
the source code needed to generate, install, and (for an executable
|
by You to the Licensor shall be under the terms and conditions of
|
||||||
work) run the object code and to modify the work, including scripts to
|
this License, without any additional terms or conditions.
|
||||||
control those activities. However, it does not include the work's
|
Notwithstanding the above, nothing herein shall supersede or modify
|
||||||
System Libraries, or general-purpose tools or generally available free
|
the terms of any separate license agreement you may have executed
|
||||||
programs which are used unmodified in performing those activities but
|
with Licensor regarding such Contributions.
|
||||||
which are not part of the work. For example, Corresponding Source
|
|
||||||
includes interface definition files associated with source files for
|
6. Trademarks. This License does not grant permission to use the trade
|
||||||
the work, and the source code for shared libraries and dynamically
|
names, trademarks, service marks, or product names of the Licensor,
|
||||||
linked subprograms that the work is specifically designed to require,
|
except as required for reasonable and customary use in describing the
|
||||||
such as by intimate data communication or control flow between those
|
origin of the Work and reproducing the content of the NOTICE file.
|
||||||
subprograms and other parts of the work.
|
|
||||||
|
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||||
The Corresponding Source need not include anything that users
|
agreed to in writing, Licensor provides the Work (and each
|
||||||
can regenerate automatically from other parts of the Corresponding
|
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||||
Source.
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||||
|
implied, including, without limitation, any warranties or conditions
|
||||||
The Corresponding Source for a work in source code form is that
|
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||||
same work.
|
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||||
|
appropriateness of using or redistributing the Work and assume any
|
||||||
2. Basic Permissions.
|
risks associated with Your exercise of permissions under this License.
|
||||||
|
|
||||||
All rights granted under this License are granted for the term of
|
8. Limitation of Liability. In no event and under no legal theory,
|
||||||
copyright on the Program, and are irrevocable provided the stated
|
whether in tort (including negligence), contract, or otherwise,
|
||||||
conditions are met. This License explicitly affirms your unlimited
|
unless required by applicable law (such as deliberate and grossly
|
||||||
permission to run the unmodified Program. The output from running a
|
negligent acts) or agreed to in writing, shall any Contributor be
|
||||||
covered work is covered by this License only if the output, given its
|
liable to You for damages, including any direct, indirect, special,
|
||||||
content, constitutes a covered work. This License acknowledges your
|
incidental, or consequential damages of any character arising as a
|
||||||
rights of fair use or other equivalent, as provided by copyright law.
|
result of this License or out of the use or inability to use the
|
||||||
|
Work (including but not limited to damages for loss of goodwill,
|
||||||
You may make, run and propagate covered works that you do not
|
work stoppage, computer failure or malfunction, or any and all
|
||||||
convey, without conditions so long as your license otherwise remains
|
other commercial damages or losses), even if such Contributor
|
||||||
in force. You may convey covered works to others for the sole purpose
|
has been advised of the possibility of such damages.
|
||||||
of having them make modifications exclusively for you, or provide you
|
|
||||||
with facilities for running those works, provided that you comply with
|
9. Accepting Warranty or Additional Liability. While redistributing
|
||||||
the terms of this License in conveying all material for which you do
|
the Work or Derivative Works thereof, You may choose to offer,
|
||||||
not control copyright. Those thus making or running the covered works
|
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||||
for you must do so exclusively on your behalf, under your direction
|
or other liability obligations and/or rights consistent with this
|
||||||
and control, on terms that prohibit them from making any copies of
|
License. However, in accepting such obligations, You may act only
|
||||||
your copyrighted material outside their relationship with you.
|
on Your own behalf and on Your sole responsibility, not on behalf
|
||||||
|
of any other Contributor, and only if You agree to indemnify,
|
||||||
Conveying under any other circumstances is permitted solely under
|
defend, and hold each Contributor harmless for any liability
|
||||||
the conditions stated below. Sublicensing is not allowed; section 10
|
incurred by, or claims asserted against, such Contributor by reason
|
||||||
makes it unnecessary.
|
of your accepting any such warranty or additional liability.
|
||||||
|
|
||||||
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
|
||||||
|
|
||||||
No covered work shall be deemed part of an effective technological
|
|
||||||
measure under any applicable law fulfilling obligations under article
|
|
||||||
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
|
||||||
similar laws prohibiting or restricting circumvention of such
|
|
||||||
measures.
|
|
||||||
|
|
||||||
When you convey a covered work, you waive any legal power to forbid
|
|
||||||
circumvention of technological measures to the extent such circumvention
|
|
||||||
is effected by exercising rights under this License with respect to
|
|
||||||
the covered work, and you disclaim any intention to limit operation or
|
|
||||||
modification of the work as a means of enforcing, against the work's
|
|
||||||
users, your or third parties' legal rights to forbid circumvention of
|
|
||||||
technological measures.
|
|
||||||
|
|
||||||
4. Conveying Verbatim Copies.
|
|
||||||
|
|
||||||
You may convey verbatim copies of the Program's source code as you
|
|
||||||
receive it, in any medium, provided that you conspicuously and
|
|
||||||
appropriately publish on each copy an appropriate copyright notice;
|
|
||||||
keep intact all notices stating that this License and any
|
|
||||||
non-permissive terms added in accord with section 7 apply to the code;
|
|
||||||
keep intact all notices of the absence of any warranty; and give all
|
|
||||||
recipients a copy of this License along with the Program.
|
|
||||||
|
|
||||||
You may charge any price or no price for each copy that you convey,
|
|
||||||
and you may offer support or warranty protection for a fee.
|
|
||||||
|
|
||||||
5. Conveying Modified Source Versions.
|
|
||||||
|
|
||||||
You may convey a work based on the Program, or the modifications to
|
|
||||||
produce it from the Program, in the form of source code under the
|
|
||||||
terms of section 4, provided that you also meet all of these conditions:
|
|
||||||
|
|
||||||
a) The work must carry prominent notices stating that you modified
|
|
||||||
it, and giving a relevant date.
|
|
||||||
|
|
||||||
b) The work must carry prominent notices stating that it is
|
|
||||||
released under this License and any conditions added under section
|
|
||||||
7. This requirement modifies the requirement in section 4 to
|
|
||||||
"keep intact all notices".
|
|
||||||
|
|
||||||
c) You must license the entire work, as a whole, under this
|
|
||||||
License to anyone who comes into possession of a copy. This
|
|
||||||
License will therefore apply, along with any applicable section 7
|
|
||||||
additional terms, to the whole of the work, and all its parts,
|
|
||||||
regardless of how they are packaged. This License gives no
|
|
||||||
permission to license the work in any other way, but it does not
|
|
||||||
invalidate such permission if you have separately received it.
|
|
||||||
|
|
||||||
d) If the work has interactive user interfaces, each must display
|
|
||||||
Appropriate Legal Notices; however, if the Program has interactive
|
|
||||||
interfaces that do not display Appropriate Legal Notices, your
|
|
||||||
work need not make them do so.
|
|
||||||
|
|
||||||
A compilation of a covered work with other separate and independent
|
|
||||||
works, which are not by their nature extensions of the covered work,
|
|
||||||
and which are not combined with it such as to form a larger program,
|
|
||||||
in or on a volume of a storage or distribution medium, is called an
|
|
||||||
"aggregate" if the compilation and its resulting copyright are not
|
|
||||||
used to limit the access or legal rights of the compilation's users
|
|
||||||
beyond what the individual works permit. Inclusion of a covered work
|
|
||||||
in an aggregate does not cause this License to apply to the other
|
|
||||||
parts of the aggregate.
|
|
||||||
|
|
||||||
6. Conveying Non-Source Forms.
|
|
||||||
|
|
||||||
You may convey a covered work in object code form under the terms
|
|
||||||
of sections 4 and 5, provided that you also convey the
|
|
||||||
machine-readable Corresponding Source under the terms of this License,
|
|
||||||
in one of these ways:
|
|
||||||
|
|
||||||
a) Convey the object code in, or embodied in, a physical product
|
|
||||||
(including a physical distribution medium), accompanied by the
|
|
||||||
Corresponding Source fixed on a durable physical medium
|
|
||||||
customarily used for software interchange.
|
|
||||||
|
|
||||||
b) Convey the object code in, or embodied in, a physical product
|
|
||||||
(including a physical distribution medium), accompanied by a
|
|
||||||
written offer, valid for at least three years and valid for as
|
|
||||||
long as you offer spare parts or customer support for that product
|
|
||||||
model, to give anyone who possesses the object code either (1) a
|
|
||||||
copy of the Corresponding Source for all the software in the
|
|
||||||
product that is covered by this License, on a durable physical
|
|
||||||
medium customarily used for software interchange, for a price no
|
|
||||||
more than your reasonable cost of physically performing this
|
|
||||||
conveying of source, or (2) access to copy the
|
|
||||||
Corresponding Source from a network server at no charge.
|
|
||||||
|
|
||||||
c) Convey individual copies of the object code with a copy of the
|
|
||||||
written offer to provide the Corresponding Source. This
|
|
||||||
alternative is allowed only occasionally and noncommercially, and
|
|
||||||
only if you received the object code with such an offer, in accord
|
|
||||||
with subsection 6b.
|
|
||||||
|
|
||||||
d) Convey the object code by offering access from a designated
|
|
||||||
place (gratis or for a charge), and offer equivalent access to the
|
|
||||||
Corresponding Source in the same way through the same place at no
|
|
||||||
further charge. You need not require recipients to copy the
|
|
||||||
Corresponding Source along with the object code. If the place to
|
|
||||||
copy the object code is a network server, the Corresponding Source
|
|
||||||
may be on a different server (operated by you or a third party)
|
|
||||||
that supports equivalent copying facilities, provided you maintain
|
|
||||||
clear directions next to the object code saying where to find the
|
|
||||||
Corresponding Source. Regardless of what server hosts the
|
|
||||||
Corresponding Source, you remain obligated to ensure that it is
|
|
||||||
available for as long as needed to satisfy these requirements.
|
|
||||||
|
|
||||||
e) Convey the object code using peer-to-peer transmission, provided
|
|
||||||
you inform other peers where the object code and Corresponding
|
|
||||||
Source of the work are being offered to the general public at no
|
|
||||||
charge under subsection 6d.
|
|
||||||
|
|
||||||
A separable portion of the object code, whose source code is excluded
|
|
||||||
from the Corresponding Source as a System Library, need not be
|
|
||||||
included in conveying the object code work.
|
|
||||||
|
|
||||||
A "User Product" is either (1) a "consumer product", which means any
|
|
||||||
tangible personal property which is normally used for personal, family,
|
|
||||||
or household purposes, or (2) anything designed or sold for incorporation
|
|
||||||
into a dwelling. In determining whether a product is a consumer product,
|
|
||||||
doubtful cases shall be resolved in favor of coverage. For a particular
|
|
||||||
product received by a particular user, "normally used" refers to a
|
|
||||||
typical or common use of that class of product, regardless of the status
|
|
||||||
of the particular user or of the way in which the particular user
|
|
||||||
actually uses, or expects or is expected to use, the product. A product
|
|
||||||
is a consumer product regardless of whether the product has substantial
|
|
||||||
commercial, industrial or non-consumer uses, unless such uses represent
|
|
||||||
the only significant mode of use of the product.
|
|
||||||
|
|
||||||
"Installation Information" for a User Product means any methods,
|
|
||||||
procedures, authorization keys, or other information required to install
|
|
||||||
and execute modified versions of a covered work in that User Product from
|
|
||||||
a modified version of its Corresponding Source. The information must
|
|
||||||
suffice to ensure that the continued functioning of the modified object
|
|
||||||
code is in no case prevented or interfered with solely because
|
|
||||||
modification has been made.
|
|
||||||
|
|
||||||
If you convey an object code work under this section in, or with, or
|
|
||||||
specifically for use in, a User Product, and the conveying occurs as
|
|
||||||
part of a transaction in which the right of possession and use of the
|
|
||||||
User Product is transferred to the recipient in perpetuity or for a
|
|
||||||
fixed term (regardless of how the transaction is characterized), the
|
|
||||||
Corresponding Source conveyed under this section must be accompanied
|
|
||||||
by the Installation Information. But this requirement does not apply
|
|
||||||
if neither you nor any third party retains the ability to install
|
|
||||||
modified object code on the User Product (for example, the work has
|
|
||||||
been installed in ROM).
|
|
||||||
|
|
||||||
The requirement to provide Installation Information does not include a
|
|
||||||
requirement to continue to provide support service, warranty, or updates
|
|
||||||
for a work that has been modified or installed by the recipient, or for
|
|
||||||
the User Product in which it has been modified or installed. Access to a
|
|
||||||
network may be denied when the modification itself materially and
|
|
||||||
adversely affects the operation of the network or violates the rules and
|
|
||||||
protocols for communication across the network.
|
|
||||||
|
|
||||||
Corresponding Source conveyed, and Installation Information provided,
|
|
||||||
in accord with this section must be in a format that is publicly
|
|
||||||
documented (and with an implementation available to the public in
|
|
||||||
source code form), and must require no special password or key for
|
|
||||||
unpacking, reading or copying.
|
|
||||||
|
|
||||||
7. Additional Terms.
|
|
||||||
|
|
||||||
"Additional permissions" are terms that supplement the terms of this
|
|
||||||
License by making exceptions from one or more of its conditions.
|
|
||||||
Additional permissions that are applicable to the entire Program shall
|
|
||||||
be treated as though they were included in this License, to the extent
|
|
||||||
that they are valid under applicable law. If additional permissions
|
|
||||||
apply only to part of the Program, that part may be used separately
|
|
||||||
under those permissions, but the entire Program remains governed by
|
|
||||||
this License without regard to the additional permissions.
|
|
||||||
|
|
||||||
When you convey a copy of a covered work, you may at your option
|
|
||||||
remove any additional permissions from that copy, or from any part of
|
|
||||||
it. (Additional permissions may be written to require their own
|
|
||||||
removal in certain cases when you modify the work.) You may place
|
|
||||||
additional permissions on material, added by you to a covered work,
|
|
||||||
for which you have or can give appropriate copyright permission.
|
|
||||||
|
|
||||||
Notwithstanding any other provision of this License, for material you
|
|
||||||
add to a covered work, you may (if authorized by the copyright holders of
|
|
||||||
that material) supplement the terms of this License with terms:
|
|
||||||
|
|
||||||
a) Disclaiming warranty or limiting liability differently from the
|
|
||||||
terms of sections 15 and 16 of this License; or
|
|
||||||
|
|
||||||
b) Requiring preservation of specified reasonable legal notices or
|
|
||||||
author attributions in that material or in the Appropriate Legal
|
|
||||||
Notices displayed by works containing it; or
|
|
||||||
|
|
||||||
c) Prohibiting misrepresentation of the origin of that material, or
|
|
||||||
requiring that modified versions of such material be marked in
|
|
||||||
reasonable ways as different from the original version; or
|
|
||||||
|
|
||||||
d) Limiting the use for publicity purposes of names of licensors or
|
|
||||||
authors of the material; or
|
|
||||||
|
|
||||||
e) Declining to grant rights under trademark law for use of some
|
|
||||||
trade names, trademarks, or service marks; or
|
|
||||||
|
|
||||||
f) Requiring indemnification of licensors and authors of that
|
|
||||||
material by anyone who conveys the material (or modified versions of
|
|
||||||
it) with contractual assumptions of liability to the recipient, for
|
|
||||||
any liability that these contractual assumptions directly impose on
|
|
||||||
those licensors and authors.
|
|
||||||
|
|
||||||
All other non-permissive additional terms are considered "further
|
|
||||||
restrictions" within the meaning of section 10. If the Program as you
|
|
||||||
received it, or any part of it, contains a notice stating that it is
|
|
||||||
governed by this License along with a term that is a further
|
|
||||||
restriction, you may remove that term. If a license document contains
|
|
||||||
a further restriction but permits relicensing or conveying under this
|
|
||||||
License, you may add to a covered work material governed by the terms
|
|
||||||
of that license document, provided that the further restriction does
|
|
||||||
not survive such relicensing or conveying.
|
|
||||||
|
|
||||||
If you add terms to a covered work in accord with this section, you
|
|
||||||
must place, in the relevant source files, a statement of the
|
|
||||||
additional terms that apply to those files, or a notice indicating
|
|
||||||
where to find the applicable terms.
|
|
||||||
|
|
||||||
Additional terms, permissive or non-permissive, may be stated in the
|
|
||||||
form of a separately written license, or stated as exceptions;
|
|
||||||
the above requirements apply either way.
|
|
||||||
|
|
||||||
8. Termination.
|
|
||||||
|
|
||||||
You may not propagate or modify a covered work except as expressly
|
|
||||||
provided under this License. Any attempt otherwise to propagate or
|
|
||||||
modify it is void, and will automatically terminate your rights under
|
|
||||||
this License (including any patent licenses granted under the third
|
|
||||||
paragraph of section 11).
|
|
||||||
|
|
||||||
However, if you cease all violation of this License, then your
|
|
||||||
license from a particular copyright holder is reinstated (a)
|
|
||||||
provisionally, unless and until the copyright holder explicitly and
|
|
||||||
finally terminates your license, and (b) permanently, if the copyright
|
|
||||||
holder fails to notify you of the violation by some reasonable means
|
|
||||||
prior to 60 days after the cessation.
|
|
||||||
|
|
||||||
Moreover, your license from a particular copyright holder is
|
|
||||||
reinstated permanently if the copyright holder notifies you of the
|
|
||||||
violation by some reasonable means, this is the first time you have
|
|
||||||
received notice of violation of this License (for any work) from that
|
|
||||||
copyright holder, and you cure the violation prior to 30 days after
|
|
||||||
your receipt of the notice.
|
|
||||||
|
|
||||||
Termination of your rights under this section does not terminate the
|
|
||||||
licenses of parties who have received copies or rights from you under
|
|
||||||
this License. If your rights have been terminated and not permanently
|
|
||||||
reinstated, you do not qualify to receive new licenses for the same
|
|
||||||
material under section 10.
|
|
||||||
|
|
||||||
9. Acceptance Not Required for Having Copies.
|
|
||||||
|
|
||||||
You are not required to accept this License in order to receive or
|
|
||||||
run a copy of the Program. Ancillary propagation of a covered work
|
|
||||||
occurring solely as a consequence of using peer-to-peer transmission
|
|
||||||
to receive a copy likewise does not require acceptance. However,
|
|
||||||
nothing other than this License grants you permission to propagate or
|
|
||||||
modify any covered work. These actions infringe copyright if you do
|
|
||||||
not accept this License. Therefore, by modifying or propagating a
|
|
||||||
covered work, you indicate your acceptance of this License to do so.
|
|
||||||
|
|
||||||
10. Automatic Licensing of Downstream Recipients.
|
|
||||||
|
|
||||||
Each time you convey a covered work, the recipient automatically
|
|
||||||
receives a license from the original licensors, to run, modify and
|
|
||||||
propagate that work, subject to this License. You are not responsible
|
|
||||||
for enforcing compliance by third parties with this License.
|
|
||||||
|
|
||||||
An "entity transaction" is a transaction transferring control of an
|
|
||||||
organization, or substantially all assets of one, or subdividing an
|
|
||||||
organization, or merging organizations. If propagation of a covered
|
|
||||||
work results from an entity transaction, each party to that
|
|
||||||
transaction who receives a copy of the work also receives whatever
|
|
||||||
licenses to the work the party's predecessor in interest had or could
|
|
||||||
give under the previous paragraph, plus a right to possession of the
|
|
||||||
Corresponding Source of the work from the predecessor in interest, if
|
|
||||||
the predecessor has it or can get it with reasonable efforts.
|
|
||||||
|
|
||||||
You may not impose any further restrictions on the exercise of the
|
|
||||||
rights granted or affirmed under this License. For example, you may
|
|
||||||
not impose a license fee, royalty, or other charge for exercise of
|
|
||||||
rights granted under this License, and you may not initiate litigation
|
|
||||||
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
|
||||||
any patent claim is infringed by making, using, selling, offering for
|
|
||||||
sale, or importing the Program or any portion of it.
|
|
||||||
|
|
||||||
11. Patents.
|
|
||||||
|
|
||||||
A "contributor" is a copyright holder who authorizes use under this
|
|
||||||
License of the Program or a work on which the Program is based. The
|
|
||||||
work thus licensed is called the contributor's "contributor version".
|
|
||||||
|
|
||||||
A contributor's "essential patent claims" are all patent claims
|
|
||||||
owned or controlled by the contributor, whether already acquired or
|
|
||||||
hereafter acquired, that would be infringed by some manner, permitted
|
|
||||||
by this License, of making, using, or selling its contributor version,
|
|
||||||
but do not include claims that would be infringed only as a
|
|
||||||
consequence of further modification of the contributor version. For
|
|
||||||
purposes of this definition, "control" includes the right to grant
|
|
||||||
patent sublicenses in a manner consistent with the requirements of
|
|
||||||
this License.
|
|
||||||
|
|
||||||
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
|
||||||
patent license under the contributor's essential patent claims, to
|
|
||||||
make, use, sell, offer for sale, import and otherwise run, modify and
|
|
||||||
propagate the contents of its contributor version.
|
|
||||||
|
|
||||||
In the following three paragraphs, a "patent license" is any express
|
|
||||||
agreement or commitment, however denominated, not to enforce a patent
|
|
||||||
(such as an express permission to practice a patent or covenant not to
|
|
||||||
sue for patent infringement). To "grant" such a patent license to a
|
|
||||||
party means to make such an agreement or commitment not to enforce a
|
|
||||||
patent against the party.
|
|
||||||
|
|
||||||
If you convey a covered work, knowingly relying on a patent license,
|
|
||||||
and the Corresponding Source of the work is not available for anyone
|
|
||||||
to copy, free of charge and under the terms of this License, through a
|
|
||||||
publicly available network server or other readily accessible means,
|
|
||||||
then you must either (1) cause the Corresponding Source to be so
|
|
||||||
available, or (2) arrange to deprive yourself of the benefit of the
|
|
||||||
patent license for this particular work, or (3) arrange, in a manner
|
|
||||||
consistent with the requirements of this License, to extend the patent
|
|
||||||
license to downstream recipients. "Knowingly relying" means you have
|
|
||||||
actual knowledge that, but for the patent license, your conveying the
|
|
||||||
covered work in a country, or your recipient's use of the covered work
|
|
||||||
in a country, would infringe one or more identifiable patents in that
|
|
||||||
country that you have reason to believe are valid.
|
|
||||||
|
|
||||||
If, pursuant to or in connection with a single transaction or
|
|
||||||
arrangement, you convey, or propagate by procuring conveyance of, a
|
|
||||||
covered work, and grant a patent license to some of the parties
|
|
||||||
receiving the covered work authorizing them to use, propagate, modify
|
|
||||||
or convey a specific copy of the covered work, then the patent license
|
|
||||||
you grant is automatically extended to all recipients of the covered
|
|
||||||
work and works based on it.
|
|
||||||
|
|
||||||
A patent license is "discriminatory" if it does not include within
|
|
||||||
the scope of its coverage, prohibits the exercise of, or is
|
|
||||||
conditioned on the non-exercise of one or more of the rights that are
|
|
||||||
specifically granted under this License. You may not convey a covered
|
|
||||||
work if you are a party to an arrangement with a third party that is
|
|
||||||
in the business of distributing software, under which you make payment
|
|
||||||
to the third party based on the extent of your activity of conveying
|
|
||||||
the work, and under which the third party grants, to any of the
|
|
||||||
parties who would receive the covered work from you, a discriminatory
|
|
||||||
patent license (a) in connection with copies of the covered work
|
|
||||||
conveyed by you (or copies made from those copies), or (b) primarily
|
|
||||||
for and in connection with specific products or compilations that
|
|
||||||
contain the covered work, unless you entered into that arrangement,
|
|
||||||
or that patent license was granted, prior to 28 March 2007.
|
|
||||||
|
|
||||||
Nothing in this License shall be construed as excluding or limiting
|
|
||||||
any implied license or other defenses to infringement that may
|
|
||||||
otherwise be available to you under applicable patent law.
|
|
||||||
|
|
||||||
12. No Surrender of Others' Freedom.
|
|
||||||
|
|
||||||
If conditions are imposed on you (whether by court order, agreement or
|
|
||||||
otherwise) that contradict the conditions of this License, they do not
|
|
||||||
excuse you from the conditions of this License. If you cannot convey a
|
|
||||||
covered work so as to satisfy simultaneously your obligations under this
|
|
||||||
License and any other pertinent obligations, then as a consequence you may
|
|
||||||
not convey it at all. For example, if you agree to terms that obligate you
|
|
||||||
to collect a royalty for further conveying from those to whom you convey
|
|
||||||
the Program, the only way you could satisfy both those terms and this
|
|
||||||
License would be to refrain entirely from conveying the Program.
|
|
||||||
|
|
||||||
13. Use with the GNU Affero General Public License.
|
|
||||||
|
|
||||||
Notwithstanding any other provision of this License, you have
|
|
||||||
permission to link or combine any covered work with a work licensed
|
|
||||||
under version 3 of the GNU Affero General Public License into a single
|
|
||||||
combined work, and to convey the resulting work. The terms of this
|
|
||||||
License will continue to apply to the part which is the covered work,
|
|
||||||
but the special requirements of the GNU Affero General Public License,
|
|
||||||
section 13, concerning interaction through a network will apply to the
|
|
||||||
combination as such.
|
|
||||||
|
|
||||||
14. Revised Versions of this License.
|
|
||||||
|
|
||||||
The Free Software Foundation may publish revised and/or new versions of
|
|
||||||
the GNU General Public License from time to time. Such new versions will
|
|
||||||
be similar in spirit to the present version, but may differ in detail to
|
|
||||||
address new problems or concerns.
|
|
||||||
|
|
||||||
Each version is given a distinguishing version number. If the
|
|
||||||
Program specifies that a certain numbered version of the GNU General
|
|
||||||
Public License "or any later version" applies to it, you have the
|
|
||||||
option of following the terms and conditions either of that numbered
|
|
||||||
version or of any later version published by the Free Software
|
|
||||||
Foundation. If the Program does not specify a version number of the
|
|
||||||
GNU General Public License, you may choose any version ever published
|
|
||||||
by the Free Software Foundation.
|
|
||||||
|
|
||||||
If the Program specifies that a proxy can decide which future
|
|
||||||
versions of the GNU General Public License can be used, that proxy's
|
|
||||||
public statement of acceptance of a version permanently authorizes you
|
|
||||||
to choose that version for the Program.
|
|
||||||
|
|
||||||
Later license versions may give you additional or different
|
|
||||||
permissions. However, no additional obligations are imposed on any
|
|
||||||
author or copyright holder as a result of your choosing to follow a
|
|
||||||
later version.
|
|
||||||
|
|
||||||
15. Disclaimer of Warranty.
|
|
||||||
|
|
||||||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
|
||||||
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
|
||||||
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
|
||||||
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
|
||||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
|
||||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
|
||||||
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
|
||||||
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
|
||||||
|
|
||||||
16. Limitation of Liability.
|
|
||||||
|
|
||||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
|
||||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
|
||||||
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
|
||||||
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
|
||||||
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
|
||||||
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
|
||||||
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
|
||||||
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
|
||||||
SUCH DAMAGES.
|
|
||||||
|
|
||||||
17. Interpretation of Sections 15 and 16.
|
|
||||||
|
|
||||||
If the disclaimer of warranty and limitation of liability provided
|
|
||||||
above cannot be given local legal effect according to their terms,
|
|
||||||
reviewing courts shall apply local law that most closely approximates
|
|
||||||
an absolute waiver of all civil liability in connection with the
|
|
||||||
Program, unless a warranty or assumption of liability accompanies a
|
|
||||||
copy of the Program in return for a fee.
|
|
||||||
|
|
||||||
END OF TERMS AND CONDITIONS
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
How to Apply These Terms to Your New Programs
|
APPENDIX: How to apply the Apache License to your work.
|
||||||
|
|
||||||
If you develop a new program, and you want it to be of the greatest
|
To apply the Apache License to your work, attach the following
|
||||||
possible use to the public, the best way to achieve this is to make it
|
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||||
free software which everyone can redistribute and change under these terms.
|
replaced with your own identifying information. (Don't include
|
||||||
|
the brackets!) The text should be enclosed in the appropriate
|
||||||
|
comment syntax for the file format. We also recommend that a
|
||||||
|
file or class name and description of purpose be included on the
|
||||||
|
same "printed page" as the copyright notice for easier
|
||||||
|
identification within third-party archives.
|
||||||
|
|
||||||
To do so, attach the following notices to the program. It is safest
|
Copyright [yyyy] [name of copyright owner]
|
||||||
to attach them to the start of each source file to most effectively
|
|
||||||
state the exclusion of warranty; and each file should have at least
|
|
||||||
the "copyright" line and a pointer to where the full notice is found.
|
|
||||||
|
|
||||||
<one line to give the program's name and a brief idea of what it does.>
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
Copyright (C) <year> <name of author>
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
Unless required by applicable law or agreed to in writing, software
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
GNU General Public License for more details.
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
Also add information on how to contact you by electronic and paper mail.
|
|
||||||
|
|
||||||
If the program does terminal interaction, make it output a short
|
|
||||||
notice like this when it starts in an interactive mode:
|
|
||||||
|
|
||||||
<program> Copyright (C) <year> <name of author>
|
|
||||||
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
|
||||||
This is free software, and you are welcome to redistribute it
|
|
||||||
under certain conditions; type `show c' for details.
|
|
||||||
|
|
||||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
|
||||||
parts of the General Public License. Of course, your program's commands
|
|
||||||
might be different; for a GUI interface, you would use an "about box".
|
|
||||||
|
|
||||||
You should also get your employer (if you work as a programmer) or school,
|
|
||||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
|
||||||
For more information on this, and how to apply and follow the GNU GPL, see
|
|
||||||
<http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
The GNU General Public License does not permit incorporating your program
|
|
||||||
into proprietary programs. If your program is a subroutine library, you
|
|
||||||
may consider it more useful to permit linking proprietary applications with
|
|
||||||
the library. If this is what you want to do, use the GNU Lesser General
|
|
||||||
Public License instead of this License. But first, please read
|
|
||||||
<http://www.gnu.org/philosophy/why-not-lgpl.html>.
|
|
||||||
|
|||||||
@@ -1,9 +1,6 @@
|
|||||||
-----------------------------
|
OWASP dependency-check
|
||||||
---begin dependency-check----
|
|
||||||
-----------------------------
|
|
||||||
dependency-check
|
|
||||||
|
|
||||||
Copyright (c) 2012-2013 Jeremy Long. All Rights Reserved.
|
Copyright (c) 2012-2015 Jeremy Long. All Rights Reserved.
|
||||||
|
|
||||||
The licenses for the software listed below can be found in the META-INF/licenses/[dependency name].
|
The licenses for the software listed below can be found in the META-INF/licenses/[dependency name].
|
||||||
|
|
||||||
@@ -19,11 +16,3 @@ An original copy of the license agreement can be found at: http://www.h2database
|
|||||||
This product includes data from the Common Weakness Enumeration (CWE): http://cwe.mitre.org/
|
This product includes data from the Common Weakness Enumeration (CWE): http://cwe.mitre.org/
|
||||||
|
|
||||||
This product downloads and utilizes data from the National Vulnerability Database hosted by NIST: http://nvd.nist.gov/download.cfm
|
This product downloads and utilizes data from the National Vulnerability Database hosted by NIST: http://nvd.nist.gov/download.cfm
|
||||||
|
|
||||||
-----------------------------
|
|
||||||
---end dependency-check------
|
|
||||||
-----------------------------
|
|
||||||
|
|
||||||
Notices below are from dependent libraries and have been included via maven-shade-plugin.
|
|
||||||
|
|
||||||
-----------------------------
|
|
||||||
@@ -6,7 +6,7 @@ performed are a "best effort" and as such, there could be false positives as wel
|
|||||||
vulnerabilities in 3rd party components is a well-known problem and is currently documented in the 2013 OWASP
|
vulnerabilities in 3rd party components is a well-known problem and is currently documented in the 2013 OWASP
|
||||||
Top 10 as [A9 - Using Components with Known Vulnerabilities](https://www.owasp.org/index.php/Top_10_2013-A9-Using_Components_with_Known_Vulnerabilities).
|
Top 10 as [A9 - Using Components with Known Vulnerabilities](https://www.owasp.org/index.php/Top_10_2013-A9-Using_Components_with_Known_Vulnerabilities).
|
||||||
|
|
||||||
Documentation and links to production binary releases can be found on the [github pages](http://jeremylong.github.io/DependencyCheck/dependency-check-ant/installation.html).
|
Documentation and links to production binary releases can be found on the [github pages](http://jeremylong.github.io/DependencyCheck/dependency-check-ant/index.html).
|
||||||
|
|
||||||
Mailing List
|
Mailing List
|
||||||
------------
|
------------
|
||||||
@@ -18,8 +18,8 @@ Post: [dependency-check@googlegroups.com](mailto:dependency-check@googlegroups.c
|
|||||||
Copyright & License
|
Copyright & License
|
||||||
-------------------
|
-------------------
|
||||||
|
|
||||||
Dependency-Check is Copyright (c) 2012-2013 Jeremy Long. All Rights Reserved.
|
Dependency-Check is Copyright (c) 2012-2014 Jeremy Long. All Rights Reserved.
|
||||||
|
|
||||||
Permission to modify and redistribute is granted under the terms of the GPLv3 license. See the [LICENSE.txt](https://github.com/jeremylong/DependencyCheck/dependency-check-ant/blob/master/LICENSE.txt) file for the full license.
|
Permission to modify and redistribute is granted under the terms of the Apache 2.0 license. See the [LICENSE.txt](https://raw.githubusercontent.com/jeremylong/DependencyCheck/master/LICENSE.txt) file for the full license.
|
||||||
|
|
||||||
Dependency-Check-Ant makes use of other open source libraries. Please see the [NOTICE.txt](https://github.com/jeremylong/DependencyCheck/dependency-check-ant/blob/master/NOTICES.txt) file for more information.
|
Dependency-Check-Ant makes use of other open source libraries. Please see the [NOTICE.txt](https://raw.githubusercontent.com/jeremylong/DependencyCheck/master/dependency-check-ant/NOTICE.txt) file for more information.
|
||||||
|
|||||||
@@ -1,223 +0,0 @@
|
|||||||
<?xml version="1.0"?>
|
|
||||||
<!DOCTYPE module PUBLIC
|
|
||||||
"-//Puppy Crawl//DTD Check Configuration 1.3//EN"
|
|
||||||
"http://www.puppycrawl.com/dtds/configuration_1_3.dtd">
|
|
||||||
|
|
||||||
<module name="Checker">
|
|
||||||
<!--
|
|
||||||
If you set the basedir property below, then all reported file
|
|
||||||
names will be relative to the specified directory. See
|
|
||||||
http://checkstyle.sourceforge.net/5.x/config.html#Checker
|
|
||||||
|
|
||||||
<property name="basedir" value="${basedir}"/>
|
|
||||||
-->
|
|
||||||
|
|
||||||
<property name="severity" value="error"/>
|
|
||||||
|
|
||||||
<module name="SuppressionFilter">
|
|
||||||
<property name="file" value="${checkstyle.suppressions.file}"/>
|
|
||||||
</module>
|
|
||||||
|
|
||||||
<module name="JavadocPackage">
|
|
||||||
<property name="allowLegacy" value="false"/>
|
|
||||||
</module>
|
|
||||||
|
|
||||||
<module name="Translation">
|
|
||||||
<property name="severity" value="warning"/>
|
|
||||||
</module>
|
|
||||||
|
|
||||||
<module name="FileTabCharacter">
|
|
||||||
<property name="eachLine" value="false"/>
|
|
||||||
</module>
|
|
||||||
|
|
||||||
<module name="FileLength">
|
|
||||||
<property name="fileExtensions" value="java"/>
|
|
||||||
</module>
|
|
||||||
|
|
||||||
<module name="NewlineAtEndOfFile">
|
|
||||||
<property name="fileExtensions" value="java"/>
|
|
||||||
<property name="lineSeparator" value="lf"/>
|
|
||||||
</module>
|
|
||||||
|
|
||||||
<module name="RegexpHeader">
|
|
||||||
<property name="headerFile" value="${checkstyle.header.file}"/>
|
|
||||||
<property name="fileExtensions" value="java"/>
|
|
||||||
<property name="id" value="header"/>
|
|
||||||
</module>
|
|
||||||
|
|
||||||
<module name="RegexpSingleline">
|
|
||||||
<property name="format" value="\s+$"/>
|
|
||||||
<property name="minimum" value="0"/>
|
|
||||||
<property name="maximum" value="0"/>
|
|
||||||
</module>
|
|
||||||
|
|
||||||
<module name="TreeWalker">
|
|
||||||
<property name="tabWidth" value="4"/>
|
|
||||||
|
|
||||||
<module name="AvoidStarImport"/>
|
|
||||||
<module name="ConstantName"/>
|
|
||||||
<module name="EmptyBlock"/>
|
|
||||||
<module name="EmptyForIteratorPad"/>
|
|
||||||
<module name="EqualsHashCode"/>
|
|
||||||
<module name="OneStatementPerLine"/>
|
|
||||||
|
|
||||||
<!-- module name="IllegalCatch"/ -->
|
|
||||||
<!--module name="ImportControl">
|
|
||||||
<property name="file" value="${checkstyle.importcontrol.file}"/>
|
|
||||||
</module-->
|
|
||||||
<module name="IllegalImport"/>
|
|
||||||
<module name="IllegalInstantiation"/>
|
|
||||||
<module name="IllegalThrows"/>
|
|
||||||
<module name="InnerAssignment"/>
|
|
||||||
<module name="JavadocType">
|
|
||||||
<property name="authorFormat" value="\S"/>
|
|
||||||
</module>
|
|
||||||
<module name="JavadocMethod">
|
|
||||||
<property name="allowUndeclaredRTE" value="true"/>
|
|
||||||
<property name="allowThrowsTagsForSubclasses" value="true"/>
|
|
||||||
<property name="allowMissingPropertyJavadoc" value="true"/>
|
|
||||||
</module>
|
|
||||||
<module name="JavadocVariable"/>
|
|
||||||
<module name="JavadocStyle">
|
|
||||||
<property name="scope" value="public"/>
|
|
||||||
</module>
|
|
||||||
|
|
||||||
<module name="LeftCurly">
|
|
||||||
<property name="option" value="eol"/>
|
|
||||||
<property name="tokens" value="CLASS_DEF"/>
|
|
||||||
<property name="tokens" value="CTOR_DEF"/>
|
|
||||||
<property name="tokens" value="INTERFACE_DEF"/>
|
|
||||||
<property name="tokens" value="METHOD_DEF"/>
|
|
||||||
<property name="tokens" value="LITERAL_CATCH"/>
|
|
||||||
<property name="tokens" value="LITERAL_DO"/>
|
|
||||||
<property name="tokens" value="LITERAL_ELSE"/>
|
|
||||||
<property name="tokens" value="LITERAL_FINALLY"/>
|
|
||||||
<property name="tokens" value="LITERAL_FOR"/>
|
|
||||||
<property name="tokens" value="LITERAL_IF"/>
|
|
||||||
<property name="tokens" value="LITERAL_SWITCH"/>
|
|
||||||
<property name="tokens" value="LITERAL_SYNCHRONIZED"/>
|
|
||||||
<property name="tokens" value="LITERAL_TRY"/>
|
|
||||||
<property name="tokens" value="LITERAL_WHILE"/>
|
|
||||||
</module>
|
|
||||||
|
|
||||||
<module name="OuterTypeNumber"/>
|
|
||||||
<module name="LineLength">
|
|
||||||
<property name="ignorePattern" value="^ *\* *[^ ]+$"/>
|
|
||||||
<property name="max" value="150"/>
|
|
||||||
</module>
|
|
||||||
|
|
||||||
<module name="MethodCount">
|
|
||||||
<property name="maxTotal" value="40"/>
|
|
||||||
</module>
|
|
||||||
|
|
||||||
<module name="LocalFinalVariableName"/>
|
|
||||||
<module name="LocalVariableName"/>
|
|
||||||
<module name="MemberName">
|
|
||||||
<property name="format" value="^[a-z][a-zA-Z0-9]*$"/>
|
|
||||||
</module>
|
|
||||||
<module name="MethodLength">
|
|
||||||
<property name="max" value="160"/>
|
|
||||||
<property name="countEmpty" value="false"/>
|
|
||||||
</module>
|
|
||||||
<module name="MethodName"/>
|
|
||||||
<module name="MethodParamPad"/>
|
|
||||||
<module name="ModifierOrder"/>
|
|
||||||
<module name="NeedBraces"/>
|
|
||||||
<module name="NoWhitespaceAfter">
|
|
||||||
<property name="tokens" value="ARRAY_INIT"/>
|
|
||||||
<property name="tokens" value="BNOT"/>
|
|
||||||
<property name="tokens" value="DEC"/>
|
|
||||||
<property name="tokens" value="DOT"/>
|
|
||||||
<property name="tokens" value="INC"/>
|
|
||||||
<property name="tokens" value="LNOT"/>
|
|
||||||
<property name="tokens" value="UNARY_MINUS"/>
|
|
||||||
<property name="tokens" value="UNARY_PLUS"/>
|
|
||||||
</module>
|
|
||||||
|
|
||||||
<module name="NoWhitespaceBefore"/>
|
|
||||||
<module name="NoWhitespaceBefore">
|
|
||||||
<property name="tokens" value="DOT"/>
|
|
||||||
<property name="allowLineBreaks" value="true"/>
|
|
||||||
</module>
|
|
||||||
|
|
||||||
<module name="OperatorWrap"/>
|
|
||||||
<module name="OperatorWrap">
|
|
||||||
<property name="tokens" value="ASSIGN"/>
|
|
||||||
<property name="tokens" value="DIV_ASSIGN"/>
|
|
||||||
<property name="tokens" value="PLUS_ASSIGN"/>
|
|
||||||
<property name="tokens" value="MINUS_ASSIGN"/>
|
|
||||||
<property name="tokens" value="STAR_ASSIGN"/>
|
|
||||||
<property name="tokens" value="MOD_ASSIGN"/>
|
|
||||||
<property name="tokens" value="SR_ASSIGN"/>
|
|
||||||
<property name="tokens" value="BSR_ASSIGN"/>
|
|
||||||
<property name="tokens" value="SL_ASSIGN"/>
|
|
||||||
<property name="tokens" value="BXOR_ASSIGN"/>
|
|
||||||
<property name="tokens" value="BOR_ASSIGN"/>
|
|
||||||
<property name="tokens" value="BAND_ASSIGN"/>
|
|
||||||
<property name="option" value="eol"/>
|
|
||||||
</module>
|
|
||||||
<module name="PackageName"/>
|
|
||||||
<module name="ParameterName">
|
|
||||||
<property name="format" value="^[a-z][a-zA-Z0-9]*$"/>
|
|
||||||
</module>
|
|
||||||
<module name="ParameterNumber">
|
|
||||||
<property name="id" value="paramNum"/>
|
|
||||||
</module>
|
|
||||||
<module name="ParenPad"/>
|
|
||||||
<module name="TypecastParenPad"/>
|
|
||||||
<module name="RedundantImport"/>
|
|
||||||
<module name="RedundantModifier"/>
|
|
||||||
<module name="RightCurly">
|
|
||||||
<property name="option" value="same"/>
|
|
||||||
</module>
|
|
||||||
<module name="SimplifyBooleanExpression"/>
|
|
||||||
<module name="SimplifyBooleanReturn"/>
|
|
||||||
<module name="StaticVariableName">
|
|
||||||
<property name="format" value="^[a-z][a-zA-Z0-9]*$"/>
|
|
||||||
</module>
|
|
||||||
<module name="TypeName"/>
|
|
||||||
<module name="UnusedImports"/>
|
|
||||||
<module name="UpperEll"/>
|
|
||||||
<module name="VisibilityModifier"/>
|
|
||||||
<module name="WhitespaceAfter"/>
|
|
||||||
<module name="WhitespaceAround"/>
|
|
||||||
<module name="GenericWhitespace"/>
|
|
||||||
<module name="FinalClass"/>
|
|
||||||
<module name="MissingSwitchDefault"/>
|
|
||||||
<!--module name="MagicNumber"/-->
|
|
||||||
<!--module name="Indentation">
|
|
||||||
<property name="basicOffset" value="4"/>
|
|
||||||
<property name="braceAdjustment" value="0"/>
|
|
||||||
<property name="caseIndent" value="0"/>
|
|
||||||
</module-->
|
|
||||||
<module name="ArrayTrailingComma"/>
|
|
||||||
<module name="FinalLocalVariable"/>
|
|
||||||
<module name="EqualsAvoidNull"/>
|
|
||||||
<module name="ParameterAssignment"/>
|
|
||||||
|
|
||||||
<!-- Generates quite a few errors -->
|
|
||||||
<module name="CyclomaticComplexity">
|
|
||||||
<property name="severity" value="ignore"/>
|
|
||||||
</module>
|
|
||||||
|
|
||||||
<module name="NestedForDepth">
|
|
||||||
<property name="max" value="2"/>
|
|
||||||
</module>
|
|
||||||
<module name="NestedIfDepth">
|
|
||||||
<property name="max" value="4"/>
|
|
||||||
</module>
|
|
||||||
<module name="NestedTryDepth">
|
|
||||||
<property name="max" value="2"/>
|
|
||||||
</module>
|
|
||||||
<!--module name="ExplicitInitialization"/-->
|
|
||||||
<module name="AnnotationUseStyle"/>
|
|
||||||
<module name="MissingDeprecated"/>
|
|
||||||
<module name="MissingOverride">
|
|
||||||
<property name="javaFiveCompatibility" value="true"/>
|
|
||||||
</module>
|
|
||||||
<module name="PackageAnnotation"/>
|
|
||||||
<module name="SuppressWarnings"/>
|
|
||||||
<module name="OuterTypeFilename"/>
|
|
||||||
<module name="HideUtilityClassConstructor"/>
|
|
||||||
</module>
|
|
||||||
</module>
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
^/\*\s*$
|
|
||||||
^ \* This file is part of dependency-check-ant\.\s*$
|
|
||||||
^ \*\s*$
|
|
||||||
^ \* Dependency-check-ant is free software\: you can redistribute it and/or modify it\s*$
|
|
||||||
^ \* under the terms of the GNU General Public License as published by the Free\s*$
|
|
||||||
^ \* Software Foundation, either version 3 of the License, or \(at your option\) any\s*$
|
|
||||||
^ \* later version\.
|
|
||||||
^ \*\s*$
|
|
||||||
^ \* Dependency-check-ant is distributed in the hope that it will be useful, but\s*$
|
|
||||||
^ \* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\s*$
|
|
||||||
^ \* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more\s*$
|
|
||||||
^ \* details\.\s*$
|
|
||||||
^ \*\s*$
|
|
||||||
^ \* You should have received a copy of the GNU General Public License along with\s*$
|
|
||||||
^ \* dependency-check-ant\. If not, see http://www.gnu.org/licenses/\.\s*$
|
|
||||||
^ \*\s*$
|
|
||||||
^ \* Copyright \(c\) 2013 (Jeremy Long|Steve Springett)\. All Rights Reserved\.\s*$
|
|
||||||
^ \*/\s*$
|
|
||||||
^package
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
<?xml version="1.0"?>
|
|
||||||
|
|
||||||
<!DOCTYPE suppressions PUBLIC
|
|
||||||
"-//Puppy Crawl//DTD Suppressions 1.0//EN"
|
|
||||||
"http://www.puppycrawl.com/dtds/suppressions_1_0.dtd">
|
|
||||||
|
|
||||||
<suppressions>
|
|
||||||
<suppress checks=".*" files=".*[\\/]package-info\.java" />
|
|
||||||
</suppressions>
|
|
||||||
@@ -1,35 +1,33 @@
|
|||||||
<!--
|
<!--
|
||||||
This file is part of dependency-check-ant.
|
This file is part of dependency-check-ant.
|
||||||
|
|
||||||
Dependency-check-ant is free software: you can redistribute it and/or modify
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
it under the terms of the GNU General Public License as published by
|
you may not use this file except in compliance with the License.
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
You may obtain a copy of the License at
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
Dependency-check is distributed in the hope that it will be useful,
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
Unless required by applicable law or agreed to in writing, software
|
||||||
along with dependency-check-ant. If not, see <http://www.gnu.org/licenses />.
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
|
||||||
Copyright (c) 2013 - Jeremy Long. All Rights Reserved.
|
Copyright (c) 2013 - Jeremy Long. All Rights Reserved.
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>org.owasp</groupId>
|
<groupId>org.owasp</groupId>
|
||||||
<artifactId>dependency-check-parent</artifactId>
|
<artifactId>dependency-check-parent</artifactId>
|
||||||
<version>1.0.3</version>
|
<version>1.4.6-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>dependency-check-ant</artifactId>
|
<artifactId>dependency-check-ant</artifactId>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
<name>Dependency-Check Ant Task</name>
|
<name>Dependency-Check Ant Task</name>
|
||||||
<description>Dependency-check is a utility that attempts to detect publicly disclosed vulnerabilities contained within project dependencies. It does this by determining if there is a Common Platform Enumeration (CPE) identifier for a given dependency. If found, it will generate a report linking to the associated CVE entries.</description>
|
<description>dependency-check-ant is an Ant Task that uses dependency-check-core to detect publicly disclosed vulnerabilities associated with the project's dependencies. The task will generate a report listing the dependency, any identified Common Platform Enumeration (CPE) identifiers, and the associated Common Vulnerability and Exposure (CVE) entries.</description>
|
||||||
<!-- begin copy from http://minds.coremedia.com/2012/09/11/problem-solved-deploy-multi-module-maven-project-site-as-github-pages/ -->
|
<!-- begin copy from http://minds.coremedia.com/2012/09/11/problem-solved-deploy-multi-module-maven-project-site-as-github-pages/ -->
|
||||||
<distributionManagement>
|
<distributionManagement>
|
||||||
<site>
|
<site>
|
||||||
@@ -70,7 +68,6 @@ Copyright (c) 2013 - Jeremy Long. All Rights Reserved.
|
|||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-resources-plugin</artifactId>
|
<artifactId>maven-resources-plugin</artifactId>
|
||||||
<version>2.6</version>
|
|
||||||
<configuration>
|
<configuration>
|
||||||
<escapeWindowsPaths>false</escapeWindowsPaths>
|
<escapeWindowsPaths>false</escapeWindowsPaths>
|
||||||
</configuration>
|
</configuration>
|
||||||
@@ -195,50 +192,40 @@ Copyright (c) 2013 - Jeremy Long. All Rights Reserved.
|
|||||||
</plugin>
|
</plugin>
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-shade-plugin</artifactId>
|
<artifactId>maven-jar-plugin</artifactId>
|
||||||
<version>2.1</version>
|
|
||||||
<configuration>
|
<configuration>
|
||||||
<transformers>
|
<archive>
|
||||||
<transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer" />
|
<manifest>
|
||||||
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
|
<addClasspath>true</addClasspath>
|
||||||
<resource>META-INF/NOTICE.txt</resource>
|
<classpathPrefix>lib/</classpathPrefix>
|
||||||
</transformer>
|
</manifest>
|
||||||
<transformer implementation="org.apache.maven.plugins.shade.resource.DontIncludeResourceTransformer">
|
</archive>
|
||||||
<resource>META-INF/NOTICE</resource>
|
</configuration>
|
||||||
</transformer>
|
</plugin>
|
||||||
<transformer implementation="org.apache.maven.plugins.shade.resource.DontIncludeResourceTransformer">
|
<plugin>
|
||||||
<resource>META-INF/LICENSE</resource>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
</transformer>
|
<artifactId>maven-assembly-plugin</artifactId>
|
||||||
</transformers>
|
<configuration>
|
||||||
|
<attach>false</attach> <!-- don't install/deploy this archive -->
|
||||||
</configuration>
|
</configuration>
|
||||||
<executions>
|
<executions>
|
||||||
<execution>
|
<execution>
|
||||||
|
<id>create-distribution</id>
|
||||||
<phase>package</phase>
|
<phase>package</phase>
|
||||||
<goals>
|
<goals>
|
||||||
<goal>shade</goal>
|
<goal>single</goal>
|
||||||
</goals>
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<descriptors>
|
||||||
|
<descriptor>src/main/assembly/release.xml</descriptor>
|
||||||
|
</descriptors>
|
||||||
|
</configuration>
|
||||||
</execution>
|
</execution>
|
||||||
</executions>
|
</executions>
|
||||||
</plugin>
|
</plugin>
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-jar-plugin</artifactId>
|
|
||||||
<version>2.4</version>
|
|
||||||
<configuration>
|
|
||||||
<archive>
|
|
||||||
<manifest>
|
|
||||||
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
|
|
||||||
</manifest>
|
|
||||||
</archive>
|
|
||||||
<excludes>
|
|
||||||
<exclude>**/checkstyle*</exclude>
|
|
||||||
</excludes>
|
|
||||||
</configuration>
|
|
||||||
</plugin>
|
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.codehaus.mojo</groupId>
|
<groupId>org.codehaus.mojo</groupId>
|
||||||
<artifactId>cobertura-maven-plugin</artifactId>
|
<artifactId>cobertura-maven-plugin</artifactId>
|
||||||
<version>2.5.2</version>
|
|
||||||
<configuration>
|
<configuration>
|
||||||
<check>
|
<check>
|
||||||
<branchRate>85</branchRate>
|
<branchRate>85</branchRate>
|
||||||
@@ -268,14 +255,9 @@ Copyright (c) 2013 - Jeremy Long. All Rights Reserved.
|
|||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-surefire-plugin</artifactId>
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
<version>2.14</version>
|
|
||||||
<configuration>
|
<configuration>
|
||||||
|
<argLine>-Dfile.encoding=UTF-8</argLine>
|
||||||
<systemProperties>
|
<systemProperties>
|
||||||
<property>
|
|
||||||
<name>net.sourceforge.cobertura.datafile</name>
|
|
||||||
<value>${project.build.directory}/cobertura/cobertura.ser</value>
|
|
||||||
<workingDirectory>target</workingDirectory>
|
|
||||||
</property>
|
|
||||||
<property>
|
<property>
|
||||||
<name>data.directory</name>
|
<name>data.directory</name>
|
||||||
<value>${project.build.directory}/dependency-check-data</value>
|
<value>${project.build.directory}/dependency-check-data</value>
|
||||||
@@ -283,154 +265,55 @@ Copyright (c) 2013 - Jeremy Long. All Rights Reserved.
|
|||||||
</systemProperties>
|
</systemProperties>
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
<plugin>
|
</plugins>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
</build>
|
||||||
<artifactId>maven-compiler-plugin</artifactId>
|
<reporting>
|
||||||
<version>2.3.2</version>
|
<plugins>
|
||||||
<configuration>
|
|
||||||
<showDeprecation>false</showDeprecation>
|
|
||||||
</configuration>
|
|
||||||
</plugin>
|
|
||||||
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-site-plugin</artifactId>
|
|
||||||
<version>3.3</version>
|
|
||||||
<dependencies>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.apache.maven.doxia</groupId>
|
|
||||||
<artifactId>doxia-module-markdown</artifactId>
|
|
||||||
<version>1.4</version>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
|
||||||
<configuration>
|
|
||||||
<skipDeploy>true</skipDeploy>
|
|
||||||
<reportPlugins>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-project-info-reports-plugin</artifactId>
|
|
||||||
<version>2.6</version>
|
|
||||||
<reportSets>
|
|
||||||
<reportSet>
|
|
||||||
<reports>
|
|
||||||
<report>index</report>
|
|
||||||
<report>summary</report>
|
|
||||||
<report>license</report>
|
|
||||||
<report>help</report>
|
|
||||||
</reports>
|
|
||||||
</reportSet>
|
|
||||||
</reportSets>
|
|
||||||
</plugin>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-javadoc-plugin</artifactId>
|
|
||||||
<version>2.9</version>
|
|
||||||
<reportSets>
|
|
||||||
<reportSet>
|
|
||||||
<id>default</id>
|
|
||||||
<reports>
|
|
||||||
<report>javadoc</report>
|
|
||||||
</reports>
|
|
||||||
</reportSet>
|
|
||||||
</reportSets>
|
|
||||||
</plugin>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.codehaus.mojo</groupId>
|
|
||||||
<artifactId>versions-maven-plugin</artifactId>
|
|
||||||
<version>2.0</version>
|
|
||||||
<reportSets>
|
|
||||||
<reportSet>
|
|
||||||
<reports>
|
|
||||||
<report>dependency-updates-report</report>
|
|
||||||
<report>plugin-updates-report</report>
|
|
||||||
</reports>
|
|
||||||
</reportSet>
|
|
||||||
</reportSets>
|
|
||||||
</plugin>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-jxr-plugin</artifactId>
|
|
||||||
<version>2.3</version>
|
|
||||||
</plugin>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.codehaus.mojo</groupId>
|
|
||||||
<artifactId>cobertura-maven-plugin</artifactId>
|
|
||||||
<version>2.5.2</version>
|
|
||||||
</plugin>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-surefire-report-plugin</artifactId>
|
|
||||||
<version>2.14</version>
|
|
||||||
<reportSets>
|
|
||||||
<reportSet>
|
|
||||||
<reports>
|
|
||||||
<report>report-only</report>
|
|
||||||
</reports>
|
|
||||||
</reportSet>
|
|
||||||
</reportSets>
|
|
||||||
</plugin>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.codehaus.mojo</groupId>
|
|
||||||
<artifactId>taglist-maven-plugin</artifactId>
|
|
||||||
<version>2.4</version>
|
|
||||||
<configuration>
|
|
||||||
<tagListOptions>
|
|
||||||
<tagClasses>
|
|
||||||
<tagClass>
|
|
||||||
<displayName>Todo Work</displayName>
|
|
||||||
<tags>
|
|
||||||
<tag>
|
|
||||||
<matchString>todo</matchString>
|
|
||||||
<matchType>ignoreCase</matchType>
|
|
||||||
</tag>
|
|
||||||
<tag>
|
|
||||||
<matchString>FIXME</matchString>
|
|
||||||
<matchType>exact</matchType>
|
|
||||||
</tag>
|
|
||||||
</tags>
|
|
||||||
</tagClass>
|
|
||||||
</tagClasses>
|
|
||||||
</tagListOptions>
|
|
||||||
</configuration>
|
|
||||||
</plugin>
|
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-checkstyle-plugin</artifactId>
|
<artifactId>maven-checkstyle-plugin</artifactId>
|
||||||
<version>2.10</version>
|
<version>${reporting.checkstyle-plugin.version}</version>
|
||||||
<configuration>
|
<configuration>
|
||||||
<enableRulesSummary>false</enableRulesSummary>
|
<enableRulesSummary>false</enableRulesSummary>
|
||||||
<configLocation>${basedir}/config/checkstyle-checks.xml</configLocation>
|
<enableFilesSummary>false</enableFilesSummary>
|
||||||
<headerLocation>${basedir}/config/checkstyle-header.txt</headerLocation>
|
<configLocation>${basedir}/../src/main/config/checkstyle-checks.xml</configLocation>
|
||||||
<suppressionsLocation>${basedir}/config/checkstyle-suppressions.xml</suppressionsLocation>
|
<headerLocation>${basedir}/../src/main/config/checkstyle-header.txt</headerLocation>
|
||||||
|
<suppressionsLocation>${basedir}/../src/main/config/checkstyle-suppressions.xml</suppressionsLocation>
|
||||||
<suppressionsFileExpression>checkstyle.suppressions.file</suppressionsFileExpression>
|
<suppressionsFileExpression>checkstyle.suppressions.file</suppressionsFileExpression>
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-pmd-plugin</artifactId>
|
<artifactId>maven-pmd-plugin</artifactId>
|
||||||
<version>3.0.1</version>
|
<version>${reporting.pmd-plugin.version}</version>
|
||||||
<configuration>
|
<configuration>
|
||||||
<targetJdk>1.6</targetJdk>
|
<targetJdk>1.6</targetJdk>
|
||||||
<linkXref>true</linkXref>
|
<linkXRef>true</linkXRef>
|
||||||
<sourceEncoding>utf-8</sourceEncoding>
|
<sourceEncoding>utf-8</sourceEncoding>
|
||||||
</configuration>
|
<excludes>
|
||||||
</plugin>
|
<exclude>**/generated/*.java</exclude>
|
||||||
<plugin>
|
</excludes>
|
||||||
<groupId>org.codehaus.mojo</groupId>
|
<rulesets>
|
||||||
<artifactId>findbugs-maven-plugin</artifactId>
|
<ruleset>../src/main/config/dcrules.xml</ruleset>
|
||||||
<version>2.5.2</version>
|
<ruleset>/rulesets/java/basic.xml</ruleset>
|
||||||
</plugin>
|
<ruleset>/rulesets/java/imports.xml</ruleset>
|
||||||
</reportPlugins>
|
<ruleset>/rulesets/java/unusedcode.xml</ruleset>
|
||||||
|
</rulesets>
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
</plugins>
|
</plugins>
|
||||||
</build>
|
</reporting>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.owasp</groupId>
|
<groupId>org.owasp</groupId>
|
||||||
<artifactId>dependency-check-core</artifactId>
|
<artifactId>dependency-check-core</artifactId>
|
||||||
<version>${project.parent.version}</version>
|
<version>${project.parent.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.owasp</groupId>
|
||||||
|
<artifactId>dependency-check-utils</artifactId>
|
||||||
|
<version>${project.parent.version}</version>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.owasp</groupId>
|
<groupId>org.owasp</groupId>
|
||||||
<artifactId>dependency-check-core</artifactId>
|
<artifactId>dependency-check-core</artifactId>
|
||||||
@@ -441,12 +324,11 @@ Copyright (c) 2013 - Jeremy Long. All Rights Reserved.
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.ant</groupId>
|
<groupId>org.apache.ant</groupId>
|
||||||
<artifactId>ant</artifactId>
|
<artifactId>ant</artifactId>
|
||||||
<version>1.9.1</version>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.ant</groupId>
|
<groupId>org.apache.ant</groupId>
|
||||||
<artifactId>ant-testutil</artifactId>
|
<artifactId>ant-testutil</artifactId>
|
||||||
<version>1.9.1</version>
|
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|||||||
@@ -12,18 +12,25 @@
|
|||||||
<format>zip</format>
|
<format>zip</format>
|
||||||
</formats>
|
</formats>
|
||||||
<includeBaseDirectory>false</includeBaseDirectory>
|
<includeBaseDirectory>false</includeBaseDirectory>
|
||||||
<fileSets>
|
<!--fileSets>
|
||||||
<fileSet>
|
<fileSet>
|
||||||
<outputDirectory>/</outputDirectory>
|
<outputDirectory>dependency-check</outputDirectory>
|
||||||
<directory>${project.build.directory}</directory>
|
<directory>${project.build.directory}</directory>
|
||||||
<includes>
|
<includes>
|
||||||
<include>dependency-check*.jar</include>
|
<include>dependency-check*.jar</include>
|
||||||
</includes>
|
</includes>
|
||||||
</fileSet>
|
</fileSet>
|
||||||
</fileSets>
|
</fileSets-->
|
||||||
|
<files>
|
||||||
|
<file>
|
||||||
|
<source>${project.build.directory}/${project.artifactId}-${project.version}.jar</source>
|
||||||
|
<outputDirectory>dependency-check-ant</outputDirectory>
|
||||||
|
<destName>dependency-check-ant.jar</destName>
|
||||||
|
</file>
|
||||||
|
</files>
|
||||||
<dependencySets>
|
<dependencySets>
|
||||||
<dependencySet>
|
<dependencySet>
|
||||||
<outputDirectory>/lib</outputDirectory>
|
<outputDirectory>dependency-check-ant/lib</outputDirectory>
|
||||||
<scope>runtime</scope>
|
<scope>runtime</scope>
|
||||||
</dependencySet>
|
</dependencySet>
|
||||||
</dependencySets>
|
</dependencySets>
|
||||||
|
|||||||
@@ -0,0 +1,278 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of dependency-check-ant.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
* Copyright (c) 2015 The OWASP Foundation. All Rights Reserved.
|
||||||
|
*/
|
||||||
|
package org.owasp.dependencycheck.ant.logging;
|
||||||
|
|
||||||
|
import org.apache.tools.ant.Project;
|
||||||
|
import org.apache.tools.ant.Task;
|
||||||
|
import org.slf4j.helpers.FormattingTuple;
|
||||||
|
import org.slf4j.helpers.MarkerIgnoringBase;
|
||||||
|
import org.slf4j.helpers.MessageFormatter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An instance of {@link org.slf4j.Logger} which simply calls the log method on
|
||||||
|
* the delegate Ant task.
|
||||||
|
*
|
||||||
|
* @author colezlaw
|
||||||
|
*/
|
||||||
|
public class AntLoggerAdapter extends MarkerIgnoringBase {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* serialization UID.
|
||||||
|
*/
|
||||||
|
private static final long serialVersionUID = -1337;
|
||||||
|
/**
|
||||||
|
* A reference to the Ant task used for logging.
|
||||||
|
*/
|
||||||
|
private transient Task task;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs an Ant Logger Adapter.
|
||||||
|
*
|
||||||
|
* @param task the Ant Task to use for logging
|
||||||
|
*/
|
||||||
|
public AntLoggerAdapter(Task task) {
|
||||||
|
super();
|
||||||
|
this.task = task;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the current Ant task to use for logging.
|
||||||
|
*
|
||||||
|
* @param task the Ant task to use for logging
|
||||||
|
*/
|
||||||
|
public void setTask(Task task) {
|
||||||
|
this.task = task;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isTraceEnabled() {
|
||||||
|
// Might be a more efficient way to do this, but Ant doesn't enable or disable
|
||||||
|
// various levels globally - it just fires things at registered Listeners.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void trace(String msg) {
|
||||||
|
if (task != null) {
|
||||||
|
task.log(msg, Project.MSG_VERBOSE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void trace(String format, Object arg) {
|
||||||
|
if (task != null) {
|
||||||
|
final FormattingTuple tp = MessageFormatter.format(format, arg);
|
||||||
|
task.log(tp.getMessage(), Project.MSG_VERBOSE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void trace(String format, Object arg1, Object arg2) {
|
||||||
|
if (task != null) {
|
||||||
|
final FormattingTuple tp = MessageFormatter.format(format, arg1, arg2);
|
||||||
|
task.log(tp.getMessage(), Project.MSG_VERBOSE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void trace(String format, Object... arguments) {
|
||||||
|
if (task != null) {
|
||||||
|
final FormattingTuple tp = MessageFormatter.format(format, arguments);
|
||||||
|
task.log(tp.getMessage(), Project.MSG_VERBOSE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void trace(String msg, Throwable t) {
|
||||||
|
if (task != null) {
|
||||||
|
task.log(msg, t, Project.MSG_VERBOSE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isDebugEnabled() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void debug(String msg) {
|
||||||
|
if (task != null) {
|
||||||
|
task.log(msg, Project.MSG_DEBUG);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void debug(String format, Object arg) {
|
||||||
|
if (task != null) {
|
||||||
|
final FormattingTuple tp = MessageFormatter.format(format, arg);
|
||||||
|
task.log(tp.getMessage(), Project.MSG_DEBUG);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void debug(String format, Object arg1, Object arg2) {
|
||||||
|
if (task != null) {
|
||||||
|
final FormattingTuple tp = MessageFormatter.format(format, arg1, arg2);
|
||||||
|
task.log(tp.getMessage(), Project.MSG_DEBUG);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void debug(String format, Object... arguments) {
|
||||||
|
if (task != null) {
|
||||||
|
final FormattingTuple tp = MessageFormatter.format(format, arguments);
|
||||||
|
task.log(tp.getMessage(), Project.MSG_DEBUG);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void debug(String msg, Throwable t) {
|
||||||
|
if (task != null) {
|
||||||
|
task.log(msg, t, Project.MSG_DEBUG);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isInfoEnabled() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void info(String msg) {
|
||||||
|
if (task != null) {
|
||||||
|
task.log(msg, Project.MSG_INFO);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void info(String format, Object arg) {
|
||||||
|
if (task != null) {
|
||||||
|
final FormattingTuple tp = MessageFormatter.format(format, arg);
|
||||||
|
task.log(tp.getMessage(), Project.MSG_INFO);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void info(String format, Object arg1, Object arg2) {
|
||||||
|
if (task != null) {
|
||||||
|
final FormattingTuple tp = MessageFormatter.format(format, arg1, arg2);
|
||||||
|
task.log(tp.getMessage(), Project.MSG_INFO);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void info(String format, Object... arguments) {
|
||||||
|
if (task != null) {
|
||||||
|
final FormattingTuple tp = MessageFormatter.format(format, arguments);
|
||||||
|
task.log(tp.getMessage(), Project.MSG_INFO);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void info(String msg, Throwable t) {
|
||||||
|
if (task != null) {
|
||||||
|
task.log(msg, t, Project.MSG_INFO);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isWarnEnabled() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void warn(String msg) {
|
||||||
|
if (task != null) {
|
||||||
|
task.log(msg, Project.MSG_WARN);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void warn(String format, Object arg) {
|
||||||
|
if (task != null) {
|
||||||
|
final FormattingTuple tp = MessageFormatter.format(format, arg);
|
||||||
|
task.log(tp.getMessage(), Project.MSG_WARN);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void warn(String format, Object... arguments) {
|
||||||
|
if (task != null) {
|
||||||
|
final FormattingTuple tp = MessageFormatter.format(format, arguments);
|
||||||
|
task.log(tp.getMessage(), Project.MSG_WARN);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void warn(String format, Object arg1, Object arg2) {
|
||||||
|
if (task != null) {
|
||||||
|
final FormattingTuple tp = MessageFormatter.format(format, arg1, arg2);
|
||||||
|
task.log(tp.getMessage(), Project.MSG_WARN);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void warn(String msg, Throwable t) {
|
||||||
|
if (task != null) {
|
||||||
|
task.log(msg, t, Project.MSG_WARN);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isErrorEnabled() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void error(String msg) {
|
||||||
|
if (task != null) {
|
||||||
|
task.log(msg, Project.MSG_ERR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void error(String format, Object arg) {
|
||||||
|
if (task != null) {
|
||||||
|
final FormattingTuple tp = MessageFormatter.format(format, arg);
|
||||||
|
task.log(tp.getMessage(), Project.MSG_ERR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void error(String format, Object arg1, Object arg2) {
|
||||||
|
if (task != null) {
|
||||||
|
final FormattingTuple tp = MessageFormatter.format(format, arg1, arg2);
|
||||||
|
task.log(tp.getMessage(), Project.MSG_ERR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void error(String format, Object... arguments) {
|
||||||
|
if (task != null) {
|
||||||
|
final FormattingTuple tp = MessageFormatter.format(format, arguments);
|
||||||
|
task.log(tp.getMessage(), Project.MSG_ERR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void error(String msg, Throwable t) {
|
||||||
|
if (task != null) {
|
||||||
|
task.log(msg, t, Project.MSG_ERR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of dependency-check-ant.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
* Copyright (c) 2015 The OWASP Foundation. All Rights Reserved.
|
||||||
|
*/
|
||||||
|
package org.owasp.dependencycheck.ant.logging;
|
||||||
|
|
||||||
|
import org.apache.tools.ant.Task;
|
||||||
|
import org.slf4j.ILoggerFactory;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An implementation of {@link org.slf4j.ILoggerFactory} which always returns {@link AntLoggerAdapter} instances.
|
||||||
|
*
|
||||||
|
* @author colezlaw
|
||||||
|
*/
|
||||||
|
public class AntLoggerFactory implements ILoggerFactory {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A reference to the Ant logger Adapter.
|
||||||
|
*/
|
||||||
|
private final AntLoggerAdapter antLoggerAdapter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a new Ant Logger Factory.
|
||||||
|
*
|
||||||
|
* @param task the Ant task to use for logging
|
||||||
|
*/
|
||||||
|
public AntLoggerFactory(Task task) {
|
||||||
|
super();
|
||||||
|
this.antLoggerAdapter = new AntLoggerAdapter(task);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the Ant logger adapter.
|
||||||
|
*
|
||||||
|
* @param name ignored in this implementation
|
||||||
|
* @return the Ant logger adapter
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Logger getLogger(String name) {
|
||||||
|
return antLoggerAdapter;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
/**
|
||||||
|
* This package includes the Ant task definitions.
|
||||||
|
*/
|
||||||
|
package org.owasp.dependencycheck.ant.logging;
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,525 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of dependency-check-ant.
|
|
||||||
*
|
|
||||||
* Dependency-check-ant is free software: you can redistribute it and/or modify it
|
|
||||||
* under the terms of the GNU General Public License as published by the Free
|
|
||||||
* Software Foundation, either version 3 of the License, or (at your option) any
|
|
||||||
* later version.
|
|
||||||
*
|
|
||||||
* Dependency-check-ant is distributed in the hope that it will be useful, but
|
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
|
||||||
* details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License along with
|
|
||||||
* dependency-check-ant. If not, see http://www.gnu.org/licenses/.
|
|
||||||
*
|
|
||||||
* Copyright (c) 2013 Jeremy Long. All Rights Reserved.
|
|
||||||
*/
|
|
||||||
package org.owasp.dependencycheck.taskdefs;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.logging.Level;
|
|
||||||
import java.util.logging.LogManager;
|
|
||||||
import java.util.logging.Logger;
|
|
||||||
import org.apache.tools.ant.BuildException;
|
|
||||||
import org.apache.tools.ant.Task;
|
|
||||||
import org.apache.tools.ant.types.EnumeratedAttribute;
|
|
||||||
import org.apache.tools.ant.types.Reference;
|
|
||||||
import org.apache.tools.ant.types.Resource;
|
|
||||||
import org.apache.tools.ant.types.ResourceCollection;
|
|
||||||
import org.apache.tools.ant.types.resources.FileProvider;
|
|
||||||
import org.apache.tools.ant.types.resources.Resources;
|
|
||||||
import org.owasp.dependencycheck.Engine;
|
|
||||||
import org.owasp.dependencycheck.dependency.Dependency;
|
|
||||||
import org.owasp.dependencycheck.dependency.Vulnerability;
|
|
||||||
import org.owasp.dependencycheck.reporting.ReportGenerator;
|
|
||||||
import org.owasp.dependencycheck.reporting.ReportGenerator.Format;
|
|
||||||
import org.owasp.dependencycheck.utils.Settings;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An Ant task definition to execute dependency-check during an Ant build.
|
|
||||||
*
|
|
||||||
* @author Jeremy Long (jeremy.long@owasp.org)
|
|
||||||
*/
|
|
||||||
public class DependencyCheckTask extends Task {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The properties file location.
|
|
||||||
*/
|
|
||||||
private static final String PROPERTIES_FILE = "task.properties";
|
|
||||||
/**
|
|
||||||
* Name of the logging properties file.
|
|
||||||
*/
|
|
||||||
private static final String LOG_PROPERTIES_FILE = "log.properties";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Construct a new DependencyCheckTask.
|
|
||||||
*/
|
|
||||||
public DependencyCheckTask() {
|
|
||||||
super();
|
|
||||||
}
|
|
||||||
//The following code was copied Apache Ant PathConvert
|
|
||||||
//BEGIN COPY from org.apache.tools.ant.taskdefs.PathConvert
|
|
||||||
/**
|
|
||||||
* Path to be converted
|
|
||||||
*/
|
|
||||||
private Resources path = null;
|
|
||||||
/**
|
|
||||||
* Reference to path/fileset to convert
|
|
||||||
*/
|
|
||||||
private Reference refid = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add an arbitrary ResourceCollection.
|
|
||||||
*
|
|
||||||
* @param rc the ResourceCollection to add.
|
|
||||||
* @since Ant 1.7
|
|
||||||
*/
|
|
||||||
public void add(ResourceCollection rc) {
|
|
||||||
if (isReference()) {
|
|
||||||
throw new BuildException("Nested elements are not allowed when using the refid attribute.");
|
|
||||||
}
|
|
||||||
getPath().add(rc);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the path. If the path has not been initialized yet, this class is
|
|
||||||
* synchronized, and will instantiate the path object.
|
|
||||||
*
|
|
||||||
* @return the path
|
|
||||||
*/
|
|
||||||
private synchronized Resources getPath() {
|
|
||||||
if (path == null) {
|
|
||||||
path = new Resources(getProject());
|
|
||||||
path.setCache(true);
|
|
||||||
}
|
|
||||||
return path;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Learn whether the refid attribute of this element been set.
|
|
||||||
*
|
|
||||||
* @return true if refid is valid.
|
|
||||||
*/
|
|
||||||
public boolean isReference() {
|
|
||||||
return refid != null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add a reference to a Path, FileSet, DirSet, or FileList defined
|
|
||||||
* elsewhere.
|
|
||||||
*
|
|
||||||
* @param r the reference to a path, fileset, dirset or filelist.
|
|
||||||
*/
|
|
||||||
public void setRefid(Reference r) {
|
|
||||||
if (path != null) {
|
|
||||||
throw new BuildException("Nested elements are not allowed when using the refid attribute.");
|
|
||||||
}
|
|
||||||
refid = r;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* If this is a reference, this method will add the referenced resource
|
|
||||||
* collection to the collection of paths.
|
|
||||||
*
|
|
||||||
* @throws BuildException if the reference is not to a resource collection
|
|
||||||
*/
|
|
||||||
private void dealWithReferences() throws BuildException {
|
|
||||||
if (isReference()) {
|
|
||||||
final Object o = refid.getReferencedObject(getProject());
|
|
||||||
if (!(o instanceof ResourceCollection)) {
|
|
||||||
throw new BuildException("refid '" + refid.getRefId()
|
|
||||||
+ "' does not refer to a resource collection.");
|
|
||||||
}
|
|
||||||
getPath().add((ResourceCollection) o);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// END COPY from org.apache.tools.ant.taskdefs
|
|
||||||
/**
|
|
||||||
* The application name for the report.
|
|
||||||
*/
|
|
||||||
private String applicationName = "Dependency-Check";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the value of applicationName.
|
|
||||||
*
|
|
||||||
* @return the value of applicationName
|
|
||||||
*/
|
|
||||||
public String getApplicationName() {
|
|
||||||
return applicationName;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the value of applicationName.
|
|
||||||
*
|
|
||||||
* @param applicationName new value of applicationName
|
|
||||||
*/
|
|
||||||
public void setApplicationName(String applicationName) {
|
|
||||||
this.applicationName = applicationName;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* The location of the data directory that contains
|
|
||||||
*/
|
|
||||||
private String dataDirectory = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the value of dataDirectory.
|
|
||||||
*
|
|
||||||
* @return the value of dataDirectory
|
|
||||||
*/
|
|
||||||
public String getDataDirectory() {
|
|
||||||
return dataDirectory;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the value of dataDirectory.
|
|
||||||
*
|
|
||||||
* @param dataDirectory new value of dataDirectory
|
|
||||||
*/
|
|
||||||
public void setDataDirectory(String dataDirectory) {
|
|
||||||
this.dataDirectory = dataDirectory;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Specifies the destination directory for the generated Dependency-Check
|
|
||||||
* report.
|
|
||||||
*/
|
|
||||||
private String reportOutputDirectory = ".";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the value of reportOutputDirectory.
|
|
||||||
*
|
|
||||||
* @return the value of reportOutputDirectory
|
|
||||||
*/
|
|
||||||
public String getReportOutputDirectory() {
|
|
||||||
return reportOutputDirectory;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the value of reportOutputDirectory.
|
|
||||||
*
|
|
||||||
* @param reportOutputDirectory new value of reportOutputDirectory
|
|
||||||
*/
|
|
||||||
public void setReportOutputDirectory(String reportOutputDirectory) {
|
|
||||||
this.reportOutputDirectory = reportOutputDirectory;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Specifies if the build should be failed if a CVSS score above a specified
|
|
||||||
* level is identified. The default is 11 which means since the CVSS scores
|
|
||||||
* are 0-10, by default the build will never fail and the CVSS score is set
|
|
||||||
* to 11. The valid range for the fail build on CVSS is 0 to 11, where
|
|
||||||
* anything above 10 will not cause the build to fail.
|
|
||||||
*/
|
|
||||||
private float failBuildOnCVSS = 11;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the value of failBuildOnCVSS.
|
|
||||||
*
|
|
||||||
* @return the value of failBuildOnCVSS
|
|
||||||
*/
|
|
||||||
public float getFailBuildOnCVSS() {
|
|
||||||
return failBuildOnCVSS;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the value of failBuildOnCVSS.
|
|
||||||
*
|
|
||||||
* @param failBuildOnCVSS new value of failBuildOnCVSS
|
|
||||||
*/
|
|
||||||
public void setFailBuildOnCVSS(float failBuildOnCVSS) {
|
|
||||||
this.failBuildOnCVSS = failBuildOnCVSS;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Sets whether auto-updating of the NVD CVE/CPE data is enabled. It is not
|
|
||||||
* recommended that this be turned to false. Default is true.
|
|
||||||
*/
|
|
||||||
private boolean autoUpdate = true;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the value of autoUpdate.
|
|
||||||
*
|
|
||||||
* @return the value of autoUpdate
|
|
||||||
*/
|
|
||||||
public boolean isAutoUpdate() {
|
|
||||||
return autoUpdate;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the value of autoUpdate.
|
|
||||||
*
|
|
||||||
* @param autoUpdate new value of autoUpdate
|
|
||||||
*/
|
|
||||||
public void setAutoUpdate(boolean autoUpdate) {
|
|
||||||
this.autoUpdate = autoUpdate;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* The report format to be generated (HTML, XML, VULN, ALL). This
|
|
||||||
* configuration option has no affect if using this within the Site plugin
|
|
||||||
* unless the externalReport is set to true. Default is HTML.
|
|
||||||
*/
|
|
||||||
private String reportFormat = "HTML";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the value of reportFormat.
|
|
||||||
*
|
|
||||||
* @return the value of reportFormat
|
|
||||||
*/
|
|
||||||
public String getReportFormat() {
|
|
||||||
return reportFormat;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the value of reportFormat.
|
|
||||||
*
|
|
||||||
* @param reportFormat new value of reportFormat
|
|
||||||
*/
|
|
||||||
public void setReportFormat(ReportFormats reportFormat) {
|
|
||||||
this.reportFormat = reportFormat.getValue();
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* The Proxy URL.
|
|
||||||
*/
|
|
||||||
private String proxyUrl;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the value of proxyUrl.
|
|
||||||
*
|
|
||||||
* @return the value of proxyUrl
|
|
||||||
*/
|
|
||||||
public String getProxyUrl() {
|
|
||||||
return proxyUrl;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the value of proxyUrl.
|
|
||||||
*
|
|
||||||
* @param proxyUrl new value of proxyUrl
|
|
||||||
*/
|
|
||||||
public void setProxyUrl(String proxyUrl) {
|
|
||||||
this.proxyUrl = proxyUrl;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* The Proxy Port.
|
|
||||||
*/
|
|
||||||
private String proxyPort;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the value of proxyPort.
|
|
||||||
*
|
|
||||||
* @return the value of proxyPort
|
|
||||||
*/
|
|
||||||
public String getProxyPort() {
|
|
||||||
return proxyPort;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the value of proxyPort.
|
|
||||||
*
|
|
||||||
* @param proxyPort new value of proxyPort
|
|
||||||
*/
|
|
||||||
public void setProxyPort(String proxyPort) {
|
|
||||||
this.proxyPort = proxyPort;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* The Connection Timeout.
|
|
||||||
*/
|
|
||||||
private String connectionTimeout;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the value of connectionTimeout.
|
|
||||||
*
|
|
||||||
* @return the value of connectionTimeout
|
|
||||||
*/
|
|
||||||
public String getConnectionTimeout() {
|
|
||||||
return connectionTimeout;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the value of connectionTimeout.
|
|
||||||
*
|
|
||||||
* @param connectionTimeout new value of connectionTimeout
|
|
||||||
*/
|
|
||||||
public void setConnectionTimeout(String connectionTimeout) {
|
|
||||||
this.connectionTimeout = connectionTimeout;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Configures the logger for use by the application.
|
|
||||||
*/
|
|
||||||
private static void prepareLogger() {
|
|
||||||
InputStream in = null;
|
|
||||||
try {
|
|
||||||
in = DependencyCheckTask.class.getClassLoader().getResourceAsStream(LOG_PROPERTIES_FILE);
|
|
||||||
LogManager.getLogManager().reset();
|
|
||||||
LogManager.getLogManager().readConfiguration(in);
|
|
||||||
//TODO add code to disable fine grained log file.
|
|
||||||
// Logger logger = LogManager.getLogManager().getLogger("");
|
|
||||||
// for (Handler h : logger.getHandlers()) {
|
|
||||||
// if (h.getFormatter(). h.toString());
|
|
||||||
// }
|
|
||||||
} catch (IOException ex) {
|
|
||||||
System.err.println(ex.toString());
|
|
||||||
Logger.getLogger(DependencyCheckTask.class.getName()).log(Level.SEVERE, null, ex);
|
|
||||||
} catch (SecurityException ex) {
|
|
||||||
Logger.getLogger(DependencyCheckTask.class.getName()).log(Level.SEVERE, null, ex);
|
|
||||||
} finally {
|
|
||||||
if (in != null) {
|
|
||||||
try {
|
|
||||||
in.close();
|
|
||||||
} catch (Exception ex) {
|
|
||||||
//noinspection UnusedAssignment
|
|
||||||
in = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void execute() throws BuildException {
|
|
||||||
prepareLogger();
|
|
||||||
|
|
||||||
dealWithReferences();
|
|
||||||
validateConfiguration();
|
|
||||||
populateSettings();
|
|
||||||
|
|
||||||
final Engine engine = new Engine();
|
|
||||||
for (Resource resource : path) {
|
|
||||||
final FileProvider provider = resource.as(FileProvider.class);
|
|
||||||
if (provider != null) {
|
|
||||||
final File file = provider.getFile();
|
|
||||||
if (file != null && file.exists()) {
|
|
||||||
engine.scan(file);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
engine.analyzeDependencies();
|
|
||||||
final ReportGenerator reporter = new ReportGenerator(applicationName, engine.getDependencies(), engine.getAnalyzers());
|
|
||||||
reporter.generateReports(reportOutputDirectory, reportFormat);
|
|
||||||
|
|
||||||
if (this.failBuildOnCVSS <= 10) {
|
|
||||||
checkForFailure(engine.getDependencies());
|
|
||||||
}
|
|
||||||
} catch (IOException ex) {
|
|
||||||
Logger.getLogger(DependencyCheckTask.class.getName()).log(Level.FINE, null, ex);
|
|
||||||
throw new BuildException("Unable to generate dependency-check report", ex);
|
|
||||||
} catch (Exception ex) {
|
|
||||||
Logger.getLogger(DependencyCheckTask.class.getName()).log(Level.SEVERE, null, ex);
|
|
||||||
throw new BuildException("An exception occured; unable to continue task", ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Validate the configuration to ensure the parameters have been properly
|
|
||||||
* configured/initialized.
|
|
||||||
*
|
|
||||||
* @throws BuildException if the task was not configured correctly.
|
|
||||||
*/
|
|
||||||
private void validateConfiguration() throws BuildException {
|
|
||||||
if (path == null) {
|
|
||||||
throw new BuildException("No project dependencies have been defined to analyze.");
|
|
||||||
}
|
|
||||||
if (failBuildOnCVSS < 0 || failBuildOnCVSS > 11) {
|
|
||||||
throw new BuildException("Invalid configuration, failBuildOnCVSS must be between 0 and 11.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Takes the properties supplied and updates the dependency-check settings.
|
|
||||||
* Additionally, this sets the system properties required to change the
|
|
||||||
* proxy url, port, and connection timeout.
|
|
||||||
*/
|
|
||||||
private void populateSettings() {
|
|
||||||
InputStream taskProperties = null;
|
|
||||||
try {
|
|
||||||
taskProperties = this.getClass().getClassLoader().getResourceAsStream(PROPERTIES_FILE);
|
|
||||||
Settings.mergeProperties(taskProperties);
|
|
||||||
} catch (IOException ex) {
|
|
||||||
Logger.getLogger(DependencyCheckTask.class.getName()).log(Level.WARNING, "Unable to load the dependency-check ant task.properties file.");
|
|
||||||
Logger.getLogger(DependencyCheckTask.class.getName()).log(Level.FINE, null, ex);
|
|
||||||
} finally {
|
|
||||||
if (taskProperties != null) {
|
|
||||||
try {
|
|
||||||
taskProperties.close();
|
|
||||||
} catch (IOException ex) {
|
|
||||||
Logger.getLogger(DependencyCheckTask.class.getName()).log(Level.FINEST, null, ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (dataDirectory != null) {
|
|
||||||
Settings.setString(Settings.KEYS.DATA_DIRECTORY, dataDirectory);
|
|
||||||
} else {
|
|
||||||
final File jarPath = new File(DependencyCheckTask.class.getProtectionDomain().getCodeSource().getLocation().getPath());
|
|
||||||
final File base = jarPath.getParentFile();
|
|
||||||
final String sub = Settings.getString(Settings.KEYS.DATA_DIRECTORY);
|
|
||||||
final File dataDir = new File(base, sub);
|
|
||||||
Settings.setString(Settings.KEYS.DATA_DIRECTORY, dataDir.getAbsolutePath());
|
|
||||||
}
|
|
||||||
|
|
||||||
Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, autoUpdate);
|
|
||||||
|
|
||||||
if (proxyUrl != null && !proxyUrl.isEmpty()) {
|
|
||||||
Settings.setString(Settings.KEYS.PROXY_URL, proxyUrl);
|
|
||||||
}
|
|
||||||
if (proxyPort != null && !proxyPort.isEmpty()) {
|
|
||||||
Settings.setString(Settings.KEYS.PROXY_PORT, proxyPort);
|
|
||||||
}
|
|
||||||
if (connectionTimeout != null && !connectionTimeout.isEmpty()) {
|
|
||||||
Settings.setString(Settings.KEYS.CONNECTION_TIMEOUT, connectionTimeout);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks to see if a vulnerability has been identified with a CVSS score
|
|
||||||
* that is above the threshold set in the configuration.
|
|
||||||
*
|
|
||||||
* @param dependencies the list of dependency objects
|
|
||||||
* @throws BuildException thrown if a CVSS score is found that is higher
|
|
||||||
* then the threshold set
|
|
||||||
*/
|
|
||||||
private void checkForFailure(List<Dependency> dependencies) throws BuildException {
|
|
||||||
final StringBuilder ids = new StringBuilder();
|
|
||||||
for (Dependency d : dependencies) {
|
|
||||||
for (Vulnerability v : d.getVulnerabilities()) {
|
|
||||||
if (v.getCvssScore() >= failBuildOnCVSS) {
|
|
||||||
if (ids.length() == 0) {
|
|
||||||
ids.append(v.getName());
|
|
||||||
} else {
|
|
||||||
ids.append(", ").append(v.getName());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (ids.length() > 0) {
|
|
||||||
final String msg = String.format("%n%nDependency-Check Failure:%n"
|
|
||||||
+ "One or more dependencies were identified with vulnerabilities that have a CVSS score greater then '%.1f': %s%n"
|
|
||||||
+ "See the dependency-check report for more details.%n%n", failBuildOnCVSS, ids.toString());
|
|
||||||
throw new BuildException(msg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An enumeration of supported report formats: "ALL", "HTML", "XML", "VULN",
|
|
||||||
* etc..
|
|
||||||
*/
|
|
||||||
public static class ReportFormats extends EnumeratedAttribute {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the list of values for the report format.
|
|
||||||
*
|
|
||||||
* @return the list of values for the report format
|
|
||||||
*/
|
|
||||||
public String[] getValues() {
|
|
||||||
int i = 0;
|
|
||||||
final Format[] formats = Format.values();
|
|
||||||
final String[] values = new String[formats.length];
|
|
||||||
for (Format format : formats) {
|
|
||||||
values[i++] = format.name();
|
|
||||||
}
|
|
||||||
return values;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,166 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of dependency-check-ant.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
* Copyright (c) 2015 Jeremy Long. All Rights Reserved.
|
||||||
|
*/
|
||||||
|
package org.owasp.dependencycheck.taskdefs;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import org.apache.tools.ant.BuildException;
|
||||||
|
import org.apache.tools.ant.Project;
|
||||||
|
import org.apache.tools.ant.Task;
|
||||||
|
import org.owasp.dependencycheck.utils.Settings;
|
||||||
|
import org.slf4j.impl.StaticLoggerBinder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An Ant task definition to execute dependency-check during an Ant build.
|
||||||
|
*
|
||||||
|
* @author Jeremy Long
|
||||||
|
*/
|
||||||
|
public class Purge extends Task {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The properties file location.
|
||||||
|
*/
|
||||||
|
private static final String PROPERTIES_FILE = "task.properties";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct a new DependencyCheckTask.
|
||||||
|
*/
|
||||||
|
public Purge() {
|
||||||
|
super();
|
||||||
|
// Call this before Dependency Check Core starts logging anything - this way, all SLF4J messages from
|
||||||
|
// core end up coming through this tasks logger
|
||||||
|
StaticLoggerBinder.getSingleton().setTask(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The location of the data directory that contains
|
||||||
|
*/
|
||||||
|
private String dataDirectory = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the value of dataDirectory.
|
||||||
|
*
|
||||||
|
* @return the value of dataDirectory
|
||||||
|
*/
|
||||||
|
public String getDataDirectory() {
|
||||||
|
return dataDirectory;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the value of dataDirectory.
|
||||||
|
*
|
||||||
|
* @param dataDirectory new value of dataDirectory
|
||||||
|
*/
|
||||||
|
public void setDataDirectory(String dataDirectory) {
|
||||||
|
this.dataDirectory = dataDirectory;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates if dependency-check should fail the build if an exception
|
||||||
|
* occurs.
|
||||||
|
*/
|
||||||
|
private boolean failOnError = true;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the value of failOnError.
|
||||||
|
*
|
||||||
|
* @return the value of failOnError
|
||||||
|
*/
|
||||||
|
public boolean isFailOnError() {
|
||||||
|
return failOnError;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the value of failOnError.
|
||||||
|
*
|
||||||
|
* @param failOnError new value of failOnError
|
||||||
|
*/
|
||||||
|
public void setFailOnError(boolean failOnError) {
|
||||||
|
this.failOnError = failOnError;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Executes the dependency-check purge to delete the existing local copy of
|
||||||
|
* the NVD CVE data.
|
||||||
|
*
|
||||||
|
* @throws BuildException thrown if there is a problem deleting the file(s)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void execute() throws BuildException {
|
||||||
|
populateSettings();
|
||||||
|
File db;
|
||||||
|
try {
|
||||||
|
db = new File(Settings.getDataDirectory(), "dc.h2.db");
|
||||||
|
if (db.exists()) {
|
||||||
|
if (db.delete()) {
|
||||||
|
log("Database file purged; local copy of the NVD has been removed", Project.MSG_INFO);
|
||||||
|
} else {
|
||||||
|
final String msg = String.format("Unable to delete '%s'; please delete the file manually", db.getAbsolutePath());
|
||||||
|
if (this.failOnError) {
|
||||||
|
throw new BuildException(msg);
|
||||||
|
}
|
||||||
|
log(msg, Project.MSG_ERR);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
final String msg = String.format("Unable to purge database; the database file does not exists: %s", db.getAbsolutePath());
|
||||||
|
if (this.failOnError) {
|
||||||
|
throw new BuildException(msg);
|
||||||
|
}
|
||||||
|
log(msg, Project.MSG_ERR);
|
||||||
|
}
|
||||||
|
} catch (IOException ex) {
|
||||||
|
final String msg = "Unable to delete the database";
|
||||||
|
if (this.failOnError) {
|
||||||
|
throw new BuildException(msg);
|
||||||
|
}
|
||||||
|
log(msg, Project.MSG_ERR);
|
||||||
|
} finally {
|
||||||
|
Settings.cleanup(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Takes the properties supplied and updates the dependency-check settings.
|
||||||
|
* Additionally, this sets the system properties required to change the
|
||||||
|
* proxy server, port, and connection timeout.
|
||||||
|
*
|
||||||
|
* @throws BuildException thrown if the properties file cannot be read.
|
||||||
|
*/
|
||||||
|
protected void populateSettings() throws BuildException {
|
||||||
|
Settings.initialize();
|
||||||
|
try (InputStream taskProperties = this.getClass().getClassLoader().getResourceAsStream(PROPERTIES_FILE)) {
|
||||||
|
Settings.mergeProperties(taskProperties);
|
||||||
|
} catch (IOException ex) {
|
||||||
|
final String msg = "Unable to load the dependency-check ant task.properties file.";
|
||||||
|
if (this.failOnError) {
|
||||||
|
throw new BuildException(msg, ex);
|
||||||
|
}
|
||||||
|
log(msg, ex, Project.MSG_WARN);
|
||||||
|
}
|
||||||
|
if (dataDirectory != null) {
|
||||||
|
Settings.setString(Settings.KEYS.DATA_DIRECTORY, dataDirectory);
|
||||||
|
} else {
|
||||||
|
final File jarPath = new File(Purge.class.getProtectionDomain().getCodeSource().getLocation().getPath());
|
||||||
|
final File base = jarPath.getParentFile();
|
||||||
|
final String sub = Settings.getString(Settings.KEYS.DATA_DIRECTORY);
|
||||||
|
final File dataDir = new File(base, sub);
|
||||||
|
Settings.setString(Settings.KEYS.DATA_DIRECTORY, dataDir.getAbsolutePath());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,445 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of dependency-check-ant.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
* Copyright (c) 2015 Jeremy Long. All Rights Reserved.
|
||||||
|
*/
|
||||||
|
package org.owasp.dependencycheck.taskdefs;
|
||||||
|
|
||||||
|
import org.apache.tools.ant.BuildException;
|
||||||
|
import org.apache.tools.ant.Project;
|
||||||
|
import org.owasp.dependencycheck.Engine;
|
||||||
|
import org.owasp.dependencycheck.data.nvdcve.DatabaseException;
|
||||||
|
import org.owasp.dependencycheck.data.update.exception.UpdateException;
|
||||||
|
import org.owasp.dependencycheck.utils.Settings;
|
||||||
|
import org.slf4j.impl.StaticLoggerBinder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An Ant task definition to execute dependency-check update. This will download
|
||||||
|
* the latest data from the National Vulnerability Database (NVD) and store a
|
||||||
|
* copy in the local database.
|
||||||
|
*
|
||||||
|
* @author Jeremy Long
|
||||||
|
*/
|
||||||
|
public class Update extends Purge {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Proxy Server.
|
||||||
|
*/
|
||||||
|
private String proxyServer;
|
||||||
|
/**
|
||||||
|
* The Proxy Port.
|
||||||
|
*/
|
||||||
|
private String proxyPort;
|
||||||
|
/**
|
||||||
|
* The Proxy username.
|
||||||
|
*/
|
||||||
|
private String proxyUsername;
|
||||||
|
/**
|
||||||
|
* The Proxy password.
|
||||||
|
*/
|
||||||
|
private String proxyPassword;
|
||||||
|
/**
|
||||||
|
* The Connection Timeout.
|
||||||
|
*/
|
||||||
|
private String connectionTimeout;
|
||||||
|
/**
|
||||||
|
* The database driver name; such as org.h2.Driver.
|
||||||
|
*/
|
||||||
|
private String databaseDriverName;
|
||||||
|
/**
|
||||||
|
* The path to the database driver JAR file if it is not on the class path.
|
||||||
|
*/
|
||||||
|
private String databaseDriverPath;
|
||||||
|
/**
|
||||||
|
* The database connection string.
|
||||||
|
*/
|
||||||
|
private String connectionString;
|
||||||
|
/**
|
||||||
|
* The user name for connecting to the database.
|
||||||
|
*/
|
||||||
|
private String databaseUser;
|
||||||
|
/**
|
||||||
|
* The password to use when connecting to the database.
|
||||||
|
*/
|
||||||
|
private String databasePassword;
|
||||||
|
/**
|
||||||
|
* The url for the modified NVD CVE (1.2 schema).
|
||||||
|
*/
|
||||||
|
private String cveUrl12Modified;
|
||||||
|
/**
|
||||||
|
* Base Data Mirror URL for CVE 1.2.
|
||||||
|
*/
|
||||||
|
private String cveUrl12Base;
|
||||||
|
/**
|
||||||
|
* Data Mirror URL for CVE 2.0.
|
||||||
|
*/
|
||||||
|
private String cveUrl20Base;
|
||||||
|
/**
|
||||||
|
* The number of hours to wait before re-checking for updates.
|
||||||
|
*/
|
||||||
|
private Integer cveValidForHours;
|
||||||
|
/**
|
||||||
|
* The url for the modified NVD CVE (2.0 schema).
|
||||||
|
*/
|
||||||
|
private String cveUrl20Modified;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct a new UpdateTask.
|
||||||
|
*/
|
||||||
|
public Update() {
|
||||||
|
super();
|
||||||
|
// Call this before Dependency Check Core starts logging anything - this way, all SLF4J messages from
|
||||||
|
// core end up coming through this tasks logger
|
||||||
|
StaticLoggerBinder.getSingleton().setTask(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the value of proxyServer.
|
||||||
|
*
|
||||||
|
* @return the value of proxyServer
|
||||||
|
*/
|
||||||
|
public String getProxyServer() {
|
||||||
|
return proxyServer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the value of proxyServer.
|
||||||
|
*
|
||||||
|
* @param server new value of proxyServer
|
||||||
|
*/
|
||||||
|
public void setProxyServer(String server) {
|
||||||
|
this.proxyServer = server;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the value of proxyPort.
|
||||||
|
*
|
||||||
|
* @return the value of proxyPort
|
||||||
|
*/
|
||||||
|
public String getProxyPort() {
|
||||||
|
return proxyPort;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the value of proxyPort.
|
||||||
|
*
|
||||||
|
* @param proxyPort new value of proxyPort
|
||||||
|
*/
|
||||||
|
public void setProxyPort(String proxyPort) {
|
||||||
|
this.proxyPort = proxyPort;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the value of proxyUsername.
|
||||||
|
*
|
||||||
|
* @return the value of proxyUsername
|
||||||
|
*/
|
||||||
|
public String getProxyUsername() {
|
||||||
|
return proxyUsername;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the value of proxyUsername.
|
||||||
|
*
|
||||||
|
* @param proxyUsername new value of proxyUsername
|
||||||
|
*/
|
||||||
|
public void setProxyUsername(String proxyUsername) {
|
||||||
|
this.proxyUsername = proxyUsername;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the value of proxyPassword.
|
||||||
|
*
|
||||||
|
* @return the value of proxyPassword
|
||||||
|
*/
|
||||||
|
public String getProxyPassword() {
|
||||||
|
return proxyPassword;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the value of proxyPassword.
|
||||||
|
*
|
||||||
|
* @param proxyPassword new value of proxyPassword
|
||||||
|
*/
|
||||||
|
public void setProxyPassword(String proxyPassword) {
|
||||||
|
this.proxyPassword = proxyPassword;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the value of connectionTimeout.
|
||||||
|
*
|
||||||
|
* @return the value of connectionTimeout
|
||||||
|
*/
|
||||||
|
public String getConnectionTimeout() {
|
||||||
|
return connectionTimeout;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the value of connectionTimeout.
|
||||||
|
*
|
||||||
|
* @param connectionTimeout new value of connectionTimeout
|
||||||
|
*/
|
||||||
|
public void setConnectionTimeout(String connectionTimeout) {
|
||||||
|
this.connectionTimeout = connectionTimeout;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the value of databaseDriverName.
|
||||||
|
*
|
||||||
|
* @return the value of databaseDriverName
|
||||||
|
*/
|
||||||
|
public String getDatabaseDriverName() {
|
||||||
|
return databaseDriverName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the value of databaseDriverName.
|
||||||
|
*
|
||||||
|
* @param databaseDriverName new value of databaseDriverName
|
||||||
|
*/
|
||||||
|
public void setDatabaseDriverName(String databaseDriverName) {
|
||||||
|
this.databaseDriverName = databaseDriverName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the value of databaseDriverPath.
|
||||||
|
*
|
||||||
|
* @return the value of databaseDriverPath
|
||||||
|
*/
|
||||||
|
public String getDatabaseDriverPath() {
|
||||||
|
return databaseDriverPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the value of databaseDriverPath.
|
||||||
|
*
|
||||||
|
* @param databaseDriverPath new value of databaseDriverPath
|
||||||
|
*/
|
||||||
|
public void setDatabaseDriverPath(String databaseDriverPath) {
|
||||||
|
this.databaseDriverPath = databaseDriverPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the value of connectionString.
|
||||||
|
*
|
||||||
|
* @return the value of connectionString
|
||||||
|
*/
|
||||||
|
public String getConnectionString() {
|
||||||
|
return connectionString;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the value of connectionString.
|
||||||
|
*
|
||||||
|
* @param connectionString new value of connectionString
|
||||||
|
*/
|
||||||
|
public void setConnectionString(String connectionString) {
|
||||||
|
this.connectionString = connectionString;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the value of databaseUser.
|
||||||
|
*
|
||||||
|
* @return the value of databaseUser
|
||||||
|
*/
|
||||||
|
public String getDatabaseUser() {
|
||||||
|
return databaseUser;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the value of databaseUser.
|
||||||
|
*
|
||||||
|
* @param databaseUser new value of databaseUser
|
||||||
|
*/
|
||||||
|
public void setDatabaseUser(String databaseUser) {
|
||||||
|
this.databaseUser = databaseUser;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the value of databasePassword.
|
||||||
|
*
|
||||||
|
* @return the value of databasePassword
|
||||||
|
*/
|
||||||
|
public String getDatabasePassword() {
|
||||||
|
return databasePassword;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the value of databasePassword.
|
||||||
|
*
|
||||||
|
* @param databasePassword new value of databasePassword
|
||||||
|
*/
|
||||||
|
public void setDatabasePassword(String databasePassword) {
|
||||||
|
this.databasePassword = databasePassword;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the value of cveUrl12Modified.
|
||||||
|
*
|
||||||
|
* @return the value of cveUrl12Modified
|
||||||
|
*/
|
||||||
|
public String getCveUrl12Modified() {
|
||||||
|
return cveUrl12Modified;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the value of cveUrl12Modified.
|
||||||
|
*
|
||||||
|
* @param cveUrl12Modified new value of cveUrl12Modified
|
||||||
|
*/
|
||||||
|
public void setCveUrl12Modified(String cveUrl12Modified) {
|
||||||
|
this.cveUrl12Modified = cveUrl12Modified;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the value of cveUrl20Modified.
|
||||||
|
*
|
||||||
|
* @return the value of cveUrl20Modified
|
||||||
|
*/
|
||||||
|
public String getCveUrl20Modified() {
|
||||||
|
return cveUrl20Modified;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the value of cveUrl20Modified.
|
||||||
|
*
|
||||||
|
* @param cveUrl20Modified new value of cveUrl20Modified
|
||||||
|
*/
|
||||||
|
public void setCveUrl20Modified(String cveUrl20Modified) {
|
||||||
|
this.cveUrl20Modified = cveUrl20Modified;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the value of cveUrl12Base.
|
||||||
|
*
|
||||||
|
* @return the value of cveUrl12Base
|
||||||
|
*/
|
||||||
|
public String getCveUrl12Base() {
|
||||||
|
return cveUrl12Base;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the value of cveUrl12Base.
|
||||||
|
*
|
||||||
|
* @param cveUrl12Base new value of cveUrl12Base
|
||||||
|
*/
|
||||||
|
public void setCveUrl12Base(String cveUrl12Base) {
|
||||||
|
this.cveUrl12Base = cveUrl12Base;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the value of cveUrl20Base.
|
||||||
|
*
|
||||||
|
* @return the value of cveUrl20Base
|
||||||
|
*/
|
||||||
|
public String getCveUrl20Base() {
|
||||||
|
return cveUrl20Base;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the value of cveUrl20Base.
|
||||||
|
*
|
||||||
|
* @param cveUrl20Base new value of cveUrl20Base
|
||||||
|
*/
|
||||||
|
public void setCveUrl20Base(String cveUrl20Base) {
|
||||||
|
this.cveUrl20Base = cveUrl20Base;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the value of cveValidForHours.
|
||||||
|
*
|
||||||
|
* @return the value of cveValidForHours
|
||||||
|
*/
|
||||||
|
public Integer getCveValidForHours() {
|
||||||
|
return cveValidForHours;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the value of cveValidForHours.
|
||||||
|
*
|
||||||
|
* @param cveValidForHours new value of cveValidForHours
|
||||||
|
*/
|
||||||
|
public void setCveValidForHours(Integer cveValidForHours) {
|
||||||
|
this.cveValidForHours = cveValidForHours;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Executes the update by initializing the settings, downloads the NVD XML
|
||||||
|
* data, and then processes the data storing it in the local database.
|
||||||
|
*
|
||||||
|
* @throws BuildException thrown if a connection to the local database
|
||||||
|
* cannot be made.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void execute() throws BuildException {
|
||||||
|
populateSettings();
|
||||||
|
Engine engine = null;
|
||||||
|
try {
|
||||||
|
engine = new Engine(Update.class.getClassLoader());
|
||||||
|
try {
|
||||||
|
engine.doUpdates();
|
||||||
|
} catch (UpdateException ex) {
|
||||||
|
if (this.isFailOnError()) {
|
||||||
|
throw new BuildException(ex);
|
||||||
|
}
|
||||||
|
log(ex.getMessage(), Project.MSG_ERR);
|
||||||
|
}
|
||||||
|
} catch (DatabaseException ex) {
|
||||||
|
final String msg = "Unable to connect to the dependency-check database; unable to update the NVD data";
|
||||||
|
if (this.isFailOnError()) {
|
||||||
|
throw new BuildException(msg, ex);
|
||||||
|
}
|
||||||
|
log(msg, Project.MSG_ERR);
|
||||||
|
} finally {
|
||||||
|
Settings.cleanup(true);
|
||||||
|
if (engine != null) {
|
||||||
|
engine.cleanup();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Takes the properties supplied and updates the dependency-check settings.
|
||||||
|
* Additionally, this sets the system properties required to change the
|
||||||
|
* proxy server, port, and connection timeout.
|
||||||
|
*
|
||||||
|
* @throws BuildException thrown when an invalid setting is configured.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected void populateSettings() throws BuildException {
|
||||||
|
super.populateSettings();
|
||||||
|
Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_SERVER, proxyServer);
|
||||||
|
Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_PORT, proxyPort);
|
||||||
|
Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_USERNAME, proxyUsername);
|
||||||
|
Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_PASSWORD, proxyPassword);
|
||||||
|
Settings.setStringIfNotEmpty(Settings.KEYS.CONNECTION_TIMEOUT, connectionTimeout);
|
||||||
|
Settings.setStringIfNotEmpty(Settings.KEYS.DB_DRIVER_NAME, databaseDriverName);
|
||||||
|
Settings.setStringIfNotEmpty(Settings.KEYS.DB_DRIVER_PATH, databaseDriverPath);
|
||||||
|
Settings.setStringIfNotEmpty(Settings.KEYS.DB_CONNECTION_STRING, connectionString);
|
||||||
|
Settings.setStringIfNotEmpty(Settings.KEYS.DB_USER, databaseUser);
|
||||||
|
Settings.setStringIfNotEmpty(Settings.KEYS.DB_PASSWORD, databasePassword);
|
||||||
|
Settings.setStringIfNotEmpty(Settings.KEYS.CVE_MODIFIED_12_URL, cveUrl12Modified);
|
||||||
|
Settings.setStringIfNotEmpty(Settings.KEYS.CVE_MODIFIED_20_URL, cveUrl20Modified);
|
||||||
|
Settings.setStringIfNotEmpty(Settings.KEYS.CVE_SCHEMA_1_2, cveUrl12Base);
|
||||||
|
Settings.setStringIfNotEmpty(Settings.KEYS.CVE_SCHEMA_2_0, cveUrl20Base);
|
||||||
|
if (cveValidForHours != null) {
|
||||||
|
if (cveValidForHours >= 0) {
|
||||||
|
Settings.setInt(Settings.KEYS.CVE_CHECK_VALID_FOR_HOURS, cveValidForHours);
|
||||||
|
} else {
|
||||||
|
throw new BuildException("Invalid setting: `cpeValidForHours` must be 0 or greater");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,11 +1,4 @@
|
|||||||
/**
|
/**
|
||||||
* <html>
|
* This package includes the a slf4j logging implementation that wraps the Ant logger.
|
||||||
* <head>
|
|
||||||
* <title>org.owasp.dependencycheck.taskdefs</title>
|
|
||||||
* </head>
|
|
||||||
* <body>
|
|
||||||
* This package includes the Ant task definitions.
|
|
||||||
* </body>
|
|
||||||
* </html>
|
|
||||||
*/
|
*/
|
||||||
package org.owasp.dependencycheck.taskdefs;
|
package org.owasp.dependencycheck.taskdefs;
|
||||||
|
|||||||
@@ -0,0 +1,113 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of dependency-check-ant.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
* Copyright (c) 2015 The OWASP Foundation. All Rights Reserved.
|
||||||
|
*/
|
||||||
|
package org.slf4j.impl;
|
||||||
|
|
||||||
|
import org.apache.tools.ant.Task;
|
||||||
|
import org.owasp.dependencycheck.ant.logging.AntLoggerFactory;
|
||||||
|
import org.slf4j.ILoggerFactory;
|
||||||
|
import org.slf4j.spi.LoggerFactoryBinder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The binding of org.slf4j.LoggerFactory class with an actual instance of
|
||||||
|
* org.slf4j.ILoggerFactory is performed using information returned by this
|
||||||
|
* class.
|
||||||
|
*
|
||||||
|
* @author colezlaw
|
||||||
|
*/
|
||||||
|
//CSOFF: FinalClass
|
||||||
|
public class StaticLoggerBinder implements LoggerFactoryBinder {
|
||||||
|
//CSON: FinalClass
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The unique instance of this class
|
||||||
|
*/
|
||||||
|
private static final StaticLoggerBinder SINGLETON = new StaticLoggerBinder();
|
||||||
|
/**
|
||||||
|
* Ant tasks have the log method we actually want to call. So we hang onto
|
||||||
|
* the task as a delegate
|
||||||
|
*/
|
||||||
|
private Task task = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the singleton of this class.
|
||||||
|
*
|
||||||
|
* @return the StaticLoggerBinder singleton
|
||||||
|
*/
|
||||||
|
public static final StaticLoggerBinder getSingleton() {
|
||||||
|
return SINGLETON;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the Task which will this is to log through.
|
||||||
|
*
|
||||||
|
* @param task the task through which to log
|
||||||
|
*/
|
||||||
|
public void setTask(Task task) {
|
||||||
|
this.task = task;
|
||||||
|
loggerFactory = new AntLoggerFactory(task);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Declare the version of the SLF4J API this implementation is compiled
|
||||||
|
* against. The value of this filed is usually modified with each release.
|
||||||
|
*/
|
||||||
|
// to avoid constant folding by the compiler, this field must *not* be final
|
||||||
|
//CSOFF: StaticVariableName
|
||||||
|
//CSOFF: VisibilityModifier
|
||||||
|
public static String REQUESTED_API_VERSION = "1.7.12"; // final
|
||||||
|
//CSON: VisibilityModifier
|
||||||
|
//CSON: StaticVariableName
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The logger factory class string.
|
||||||
|
*/
|
||||||
|
private static final String LOGGER_FACTORY_CLASS = AntLoggerFactory.class.getName();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The ILoggerFactory instance returned by the {@link #getLoggerFactory}
|
||||||
|
* method should always be the smae object
|
||||||
|
*/
|
||||||
|
private ILoggerFactory loggerFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a new static logger binder.
|
||||||
|
*/
|
||||||
|
private StaticLoggerBinder() {
|
||||||
|
loggerFactory = new AntLoggerFactory(task);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the logger factory.
|
||||||
|
*
|
||||||
|
* @return the logger factory
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public ILoggerFactory getLoggerFactory() {
|
||||||
|
return loggerFactory;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the logger factory class string.
|
||||||
|
*
|
||||||
|
* @return the logger factory class string
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String getLoggerFactoryClassStr() {
|
||||||
|
return LOGGER_FACTORY_CLASS;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
/**
|
||||||
|
* This package contains the static binder for the slf4j-ant logger.
|
||||||
|
*/
|
||||||
|
package org.slf4j.impl;
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
dependency-check=org.owasp.dependencycheck.taskdefs.Check
|
||||||
|
dependency-check-purge=org.owasp.dependencycheck.taskdefs.Purge
|
||||||
|
dependency-check-update=org.owasp.dependencycheck.taskdefs.Update
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
handlers=java.util.logging.ConsoleHandler, java.util.logging.FileHandler
|
|
||||||
|
|
||||||
# logging levels
|
|
||||||
# FINEST, FINER, FINE, CONFIG, INFO, WARNING and SEVERE.
|
|
||||||
|
|
||||||
# Configure the ConsoleHandler.
|
|
||||||
java.util.logging.ConsoleHandler.level=INFO
|
|
||||||
|
|
||||||
#org.owasp.dependencycheck.data.nvdcve.xml
|
|
||||||
|
|
||||||
# Configure the FileHandler.
|
|
||||||
#java.util.logging.FileHandler.formatter=java.util.logging.SimpleFormatter
|
|
||||||
#java.util.logging.FileHandler.level=FINEST
|
|
||||||
|
|
||||||
# The following special tokens can be used in the pattern property
|
|
||||||
# which specifies the location and name of the log file.
|
|
||||||
# / - standard path separator
|
|
||||||
# %t - system temporary directory
|
|
||||||
# %h - value of the user.home system property
|
|
||||||
# %g - generation number for rotating logs
|
|
||||||
# %u - unique number to avoid conflicts
|
|
||||||
# FileHandler writes to %h/demo0.log by default.
|
|
||||||
#java.util.logging.FileHandler.pattern=./target/dependency-check.log
|
|
||||||
@@ -1,2 +1,2 @@
|
|||||||
# the path to the data directory
|
# the path to the data directory
|
||||||
data.directory=dependency-check-data
|
data.directory=data/3.0
|
||||||
|
|||||||
@@ -1,3 +0,0 @@
|
|||||||
# define custom tasks here
|
|
||||||
|
|
||||||
dependencycheck=org.owasp.dependencycheck.taskdefs.DependencyCheckTask
|
|
||||||
20
dependency-check-ant/src/site/markdown/config-purge.md
Normal file
20
dependency-check-ant/src/site/markdown/config-purge.md
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
Configuration
|
||||||
|
====================
|
||||||
|
The dependency-check-purge task deletes the local copy of the NVD. This task
|
||||||
|
should rarely be used, if ever. This is included as a convenience method in
|
||||||
|
the rare circumstance that the local H2 database becomes corrupt.
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<target name="dependency-check-purge" description="Dependency-Check purge">
|
||||||
|
<dependency-check-purge />
|
||||||
|
</target>
|
||||||
|
```
|
||||||
|
|
||||||
|
Configuration: dependency-check-purge Task
|
||||||
|
--------------------
|
||||||
|
The following properties can be set on the dependency-check-purge task.
|
||||||
|
|
||||||
|
Property | Description | Default Value
|
||||||
|
----------------------|------------------------------------------------------------------------|------------------
|
||||||
|
dataDirectory | Data directory that is used to store the local copy of the NVD | data
|
||||||
|
failOnError | Whether the build should fail if there is an error executing the purge | true
|
||||||
45
dependency-check-ant/src/site/markdown/config-update.md
Normal file
45
dependency-check-ant/src/site/markdown/config-update.md
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
Configuration
|
||||||
|
====================
|
||||||
|
The dependency-check-update task downloads and updates the local copy of the NVD.
|
||||||
|
There are several reasons that one may want to use this task; primarily, creating
|
||||||
|
an update that will be run only once a day or once every few days (but not greater
|
||||||
|
than 7 days) and then use the `autoUpdate="false"` setting on individual
|
||||||
|
dependency-check scans. See [Internet Access Required](https://jeremylong.github.io/DependencyCheck/data/index.html)
|
||||||
|
for more information on why this task would be used.
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<target name="dependency-check-update" description="Dependency-Check Update">
|
||||||
|
<dependency-check-update />
|
||||||
|
</target>
|
||||||
|
```
|
||||||
|
|
||||||
|
Configuration: dependency-check-update Task
|
||||||
|
--------------------
|
||||||
|
The following properties can be set on the dependency-check task.
|
||||||
|
|
||||||
|
Property | Description | Default Value
|
||||||
|
----------------------|------------------------------------|------------------
|
||||||
|
proxyServer | The Proxy Server. |
|
||||||
|
proxyPort | The Proxy Port. |
|
||||||
|
proxyUsername | Defines the proxy user name. |
|
||||||
|
proxyPassword | Defines the proxy password. |
|
||||||
|
connectionTimeout | The URL Connection Timeout. |
|
||||||
|
failOnError | Whether the build should fail if there is an error executing the update | true
|
||||||
|
|
||||||
|
Advanced Configuration
|
||||||
|
====================
|
||||||
|
The following properties can be configured in the plugin. However, they are less frequently changed. One exception
|
||||||
|
may be the cvedUrl properties, which can be used to host a mirror of the NVD within an enterprise environment.
|
||||||
|
|
||||||
|
Property | Description | Default Value
|
||||||
|
---------------------|-------------------------------------------------------------------------------------------------------|------------------
|
||||||
|
cveUrl12Modified | URL for the modified CVE 1.2. | https://nvd.nist.gov/download/nvdcve-Modified.xml.gz
|
||||||
|
cveUrl20Modified | URL for the modified CVE 2.0. | https://nvd.nist.gov/feeds/xml/cve/nvdcve-2.0-Modified.xml.gz
|
||||||
|
cveUrl12Base | Base URL for each year's CVE 1.2, the %d will be replaced with the year. | https://nvd.nist.gov/download/nvdcve-%d.xml.gz
|
||||||
|
cveUrl20Base | Base URL for each year's CVE 2.0, the %d will be replaced with the year. | https://nvd.nist.gov/feeds/xml/cve/nvdcve-2.0-%d.xml.gz
|
||||||
|
dataDirectory | Data directory that is used to store the local copy of the NVD. This should generally not be changed. | data
|
||||||
|
databaseDriverName | The name of the database driver. Example: org.h2.Driver. |
|
||||||
|
databaseDriverPath | The path to the database driver JAR file; only used if the driver is not in the class path. |
|
||||||
|
connectionString | The connection string used to connect to the database. |
|
||||||
|
databaseUser | The username used when connecting to the database. |
|
||||||
|
databasePassword | The password used when connecting to the database. |
|
||||||
@@ -1,5 +1,11 @@
|
|||||||
Configuration
|
Configuration
|
||||||
====================
|
====================
|
||||||
|
Once dependency-check-ant has been [installed](index.html) the defined tasks can be used.
|
||||||
|
|
||||||
|
* dependency-check - the primary task used to check the project dependencies. Configuration options are below.
|
||||||
|
* dependency-check-purge - deletes the local copy of the NVD; this should rarely be used (if ever). See the [purge configuration](config-purge.html) for more information.
|
||||||
|
* dependency-check-update - downloads and updates the local copy of the NVD. See the [update configuration](config-update.html) for more information.
|
||||||
|
|
||||||
To configure the dependency-check task you can add it to a target and include a
|
To configure the dependency-check task you can add it to a target and include a
|
||||||
file based [resource collection](http://ant.apache.org/manual/Types/resources.html#collection)
|
file based [resource collection](http://ant.apache.org/manual/Types/resources.html#collection)
|
||||||
such as a [FileSet](http://ant.apache.org/manual/Types/fileset.html), [DirSet](http://ant.apache.org/manual/Types/dirset.html),
|
such as a [FileSet](http://ant.apache.org/manual/Types/fileset.html), [DirSet](http://ant.apache.org/manual/Types/dirset.html),
|
||||||
@@ -8,7 +14,7 @@ the project's dependencies.
|
|||||||
|
|
||||||
```xml
|
```xml
|
||||||
<target name="dependency-check" description="Dependency-Check Analysis">
|
<target name="dependency-check" description="Dependency-Check Analysis">
|
||||||
<dependency-check applicationname="Hello World"
|
<dependency-check projectname="Hello World"
|
||||||
reportoutputdirectory="${basedir}"
|
reportoutputdirectory="${basedir}"
|
||||||
reportformat="ALL">
|
reportformat="ALL">
|
||||||
|
|
||||||
@@ -18,18 +24,76 @@ the project's dependencies.
|
|||||||
</dependency-check>
|
</dependency-check>
|
||||||
</target>
|
</target>
|
||||||
```
|
```
|
||||||
The following table lists the configurable properties:
|
|
||||||
|
|
||||||
Property | Description | Requirement
|
Configuration: dependency-check Task
|
||||||
----------------------|-------------|---------
|
--------------------
|
||||||
ApplicationName | The name of the application to use in the generated report. | Required
|
The following properties can be set on the dependency-check task.
|
||||||
ReportFormat | The format of the report to be generated. Allowed values are: HTML, XML, VULN, or ALL. The default value is HTML.| Optional
|
|
||||||
ReportOutputDirectory | The directory where dependency-check will store data used for analysis. Defaults to the current working directory. | Optional
|
|
||||||
FailBuildOn | If set and a CVE is found that is greater then the specified value the build will fail. The default value is 11 which means that the build will not fail. Valid values are 0-11. | Optional
|
|
||||||
AutoUpdate | If set to false the NVD CVE data is not automatically updated. Setting this to false could result in false negatives. However, this may be required in some environments. The default value is true. | Optional
|
|
||||||
DataDirectory | The directory where dependency-check will store data used for analysis. Defaults to a folder called, called 'dependency-check-data', that is in the same directory as the dependency-check-ant jar file was installed in. *It is not recommended to change this.* | Optional
|
|
||||||
ProxyUrl | Defines the proxy used to connect to the Internet. | Optional
|
|
||||||
ProxyPort | Defines the port for the proxy. | Optional
|
|
||||||
ConnectionTimeout | The connection timeout used when downloading data files from the Internet. | Optional
|
|
||||||
|
|
||||||
|
Property | Description | Default Value
|
||||||
|
----------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------------
|
||||||
|
autoUpdate | Sets whether auto-updating of the NVD CVE/CPE data is enabled. It is not recommended that this be turned to false. | true
|
||||||
|
cveValidForHours | Sets the number of hours to wait before checking for new updates from the NVD | 4
|
||||||
|
failBuildOnCVSS | Specifies if the build should be failed if a CVSS score above a specified level is identified. The default is 11 which means since the CVSS scores are 0-10, by default the build will never fail. | 11
|
||||||
|
failOnError | Whether the build should fail if there is an error executing the dependency-check analysis | true
|
||||||
|
projectName | The name of the project being scanned. | Dependency-Check
|
||||||
|
reportFormat | The report format to be generated (HTML, XML, VULN, ALL). This configuration option has no affect if using this within the Site plugin unless the externalReport is set to true. | HTML
|
||||||
|
reportOutputDirectory | The location to write the report(s). Note, this is not used if generating the report as part of a `mvn site` build | 'target'
|
||||||
|
suppressionFile | The file path to the XML suppression file \- used to suppress [false positives](../general/suppression.html) |
|
||||||
|
hintsFile | The file path to the XML hints file \- used to resolve [false negatives](../general/hints.html) |
|
||||||
|
proxyServer | The Proxy Server; see the [proxy configuration](../data/proxy.html) page for more information. |
|
||||||
|
proxyPort | The Proxy Port. |
|
||||||
|
proxyUsername | Defines the proxy user name. |
|
||||||
|
proxyPassword | Defines the proxy password. |
|
||||||
|
connectionTimeout | The URL Connection Timeout. |
|
||||||
|
enableExperimental | Enable the [experimental analyzers](../analyzers/index.html). If not enabled the experimental analyzers (see below) will not be loaded or used. | false
|
||||||
|
|
||||||
|
Analyzer Configuration
|
||||||
|
====================
|
||||||
|
The following properties are used to configure the various file type analyzers.
|
||||||
|
These properties can be used to turn off specific analyzers if it is not needed.
|
||||||
|
Note, that specific analyzers will automatically disable themselves if no file
|
||||||
|
types that they support are detected - so specifically disabling them may not
|
||||||
|
be needed.
|
||||||
|
|
||||||
|
Property | Description | Default Value
|
||||||
|
------------------------------|-----------------------------------------------------------------------------------|------------------
|
||||||
|
archiveAnalyzerEnabled | Sets whether the Archive Analyzer will be used. | true
|
||||||
|
zipExtensions | A comma-separated list of additional file extensions to be treated like a ZIP file, the contents will be extracted and analyzed. |
|
||||||
|
jarAnalyzer | Sets whether the Jar Analyzer will be used. | true
|
||||||
|
centralAnalyzerEnabled | Sets whether the Central Analyzer will be used. **Disabling this analyzer is not recommended as it could lead to false negatives (e.g. libraries that have vulnerabilities may not be reported correctly).** If this analyzer is being disabled there is a good chance you also want to disable the Nexus Analyzer (see below). | true
|
||||||
|
nexusAnalyzerEnabled | Sets whether Nexus Analyzer will be used. This analyzer is superceded by the Central Analyzer; however, you can configure this to run against a Nexus Pro installation. | true
|
||||||
|
nexusUrl | Defines the Nexus web service endpoint (example http://domain.enterprise/nexus/service/local/). If not set the Nexus Analyzer will be disabled. |
|
||||||
|
nexusUsesProxy | Whether or not the defined proxy should be used when connecting to Nexus. | true
|
||||||
|
pyDistributionAnalyzerEnabled | Sets whether the [experimental](../analyzers/index.html) Python Distribution Analyzer will be used. | true
|
||||||
|
pyPackageAnalyzerEnabled | Sets whether the [experimental](../analyzers/index.html) Python Package Analyzer will be used. | true
|
||||||
|
rubygemsAnalyzerEnabled | Sets whether the [experimental](../analyzers/index.html) Ruby Gemspec Analyzer will be used. | true
|
||||||
|
opensslAnalyzerEnabled | Sets whether the openssl Analyzer should be used. | true
|
||||||
|
cmakeAnalyzerEnabled | Sets whether the [experimental](../analyzers/index.html) CMake Analyzer should be used. | true
|
||||||
|
autoconfAnalyzerEnabled | Sets whether the [experimental](../analyzers/index.html) autoconf Analyzer should be used. | true
|
||||||
|
composerAnalyzerEnabled | Sets whether the [experimental](../analyzers/index.html) PHP Composer Lock File Analyzer should be used. | true
|
||||||
|
nodeAnalyzerEnabled | Sets whether the [experimental](../analyzers/index.html) Node.js Analyzer should be used. | true
|
||||||
|
nuspecAnalyzerEnabled | Sets whether the .NET Nuget Nuspec Analyzer will be used. | true
|
||||||
|
cocoapodsAnalyzerEnabled | Sets whether the [experimental](../analyzers/index.html) Cocoapods Analyzer should be used. | true
|
||||||
|
bundleAuditAnalyzerEnabled | Sets whether the [experimental](../analyzers/index.html) Bundle Audit Analyzer should be used. | true
|
||||||
|
bundleAuditPath | Sets the path to the bundle audit executable; only used if bundle audit analyzer is enabled and experimental analyzers are enabled. |
|
||||||
|
swiftPackageManagerAnalyzerEnabled | Sets whether the [experimental](../analyzers/index.html) Switft Package Analyzer should be used. | true
|
||||||
|
assemblyAnalyzerEnabled | Sets whether the .NET Assembly Analyzer should be used. | true
|
||||||
|
pathToMono | The path to Mono for .NET assembly analysis on non-windows systems. |
|
||||||
|
|
||||||
|
Advanced Configuration
|
||||||
|
====================
|
||||||
|
The following properties can be configured in the plugin. However, they are less frequently changed. One exception
|
||||||
|
may be the cvedUrl properties, which can be used to host a mirror of the NVD within an enterprise environment.
|
||||||
|
|
||||||
|
Property | Description | Default Value
|
||||||
|
---------------------|--------------------------------------------------------------------------|------------------
|
||||||
|
cveUrl12Modified | URL for the modified CVE 1.2. | http://nvd.nist.gov/download/nvdcve-modified.xml
|
||||||
|
cveUrl20Modified | URL for the modified CVE 2.0. | http://static.nvd.nist.gov/feeds/xml/cve/nvdcve-2.0-modified.xml
|
||||||
|
cveUrl12Base | Base URL for each year's CVE 1.2, the %d will be replaced with the year. | http://nvd.nist.gov/download/nvdcve-%d.xml
|
||||||
|
cveUrl20Base | Base URL for each year's CVE 2.0, the %d will be replaced with the year. | http://static.nvd.nist.gov/feeds/xml/cve/nvdcve-2.0-%d.xml
|
||||||
|
dataDirectory | Data directory that is used to store the local copy of the NVD. This should generally not be changed. | data
|
||||||
|
databaseDriverName | The name of the database driver. Example: org.h2.Driver. |
|
||||||
|
databaseDriverPath | The path to the database driver JAR file; only used if the driver is not in the class path. |
|
||||||
|
connectionString | The connection string used to connect to the database. |
|
||||||
|
databaseUser | The username used when connecting to the database. |
|
||||||
|
databasePassword | The password used when connecting to the database. |
|
||||||
|
|||||||
38
dependency-check-ant/src/site/markdown/index.md.vm
Normal file
38
dependency-check-ant/src/site/markdown/index.md.vm
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
About
|
||||||
|
====================
|
||||||
|
OWASP dependency-check-ant is an Ant Task that uses dependency-check-core to detect publicly
|
||||||
|
disclosed vulnerabilities associated with the project's dependencies. The task will
|
||||||
|
generate a report listing the dependency, any identified Common Platform Enumeration (CPE)
|
||||||
|
identifiers, and the associated Common Vulnerability and Exposure (CVE) entries.
|
||||||
|
|
||||||
|
Installation
|
||||||
|
====================
|
||||||
|
1. Download dependency-check-ant from [bintray here](http://dl.bintray.com/jeremy-long/owasp/dependency-check-ant-${project.version}-release.zip).
|
||||||
|
2. Unzip the archive
|
||||||
|
3. Add the taskdef to your build.xml:
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<!-- Set the value to the installation directory's path -->
|
||||||
|
<property name="dependency-check.home" value="C:/tools/dependency-check-ant"/>
|
||||||
|
<path id="dependency-check.path">
|
||||||
|
<pathelement location="${dependency-check.home}/dependency-check-ant.jar"/>
|
||||||
|
<fileset dir="${dependency-check.home}/lib">
|
||||||
|
<include name="*.jar"/>
|
||||||
|
</fileset>
|
||||||
|
</path>
|
||||||
|
<taskdef resource="dependency-check-taskdefs.properties">
|
||||||
|
<classpath refid="dependency-check.path" />
|
||||||
|
</taskdef>
|
||||||
|
```
|
||||||
|
4. Use the defined taskdefs:
|
||||||
|
* [dependency-check](configuration.html) - the primary task used to check the project dependencies.
|
||||||
|
* [dependency-check-purge](config-purge.html) - deletes the local copy of the NVD; this should rarely be used (if ever).
|
||||||
|
* [dependency-check-update](config-update.html) - downloads and updates the local copy of the NVD.
|
||||||
|
|
||||||
|
|
||||||
|
It is important to understand that the first time this task is executed it may
|
||||||
|
take 10 minutes or more as it downloads and processes the data from the National
|
||||||
|
Vulnerability Database (NVD) hosted by NIST: https://nvd.nist.gov
|
||||||
|
|
||||||
|
After the first batch download, as long as the task is executed at least once every
|
||||||
|
seven days the update will only take a few seconds.
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
Installation
|
|
||||||
====================
|
|
||||||
Download dependency-check-ant from [bintray here](http://dl.bintray.com/jeremy-long/owasp/dependency-check-ant-${project.version}.jar).
|
|
||||||
To install dependency-check-ant place the dependency-check-ant-${project.version}.jar into
|
|
||||||
the lib directory of your Ant instalation directory. Once installed you can add
|
|
||||||
the taskdef to you build.xml and add the task to a new or existing target.
|
|
||||||
|
|
||||||
It is important to understand that the first time this task is executed it may
|
|
||||||
take 20 minutes or more as it downloads and processes the data from the National
|
|
||||||
Vulnerability Database (NVD) hosted by NIST: https://nvd.nist.gov
|
|
||||||
|
|
||||||
After the first batch download, as long as the task is executed at least once every
|
|
||||||
seven days the update will only take a few seconds.
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
Usage
|
|
||||||
====================
|
|
||||||
First, add the dependency-check-ant taskdef to your build.xml:
|
|
||||||
|
|
||||||
```xml
|
|
||||||
<taskdef name="dependency-check" classname="org.owasp.dependencycheck.taskdefs.DependencyCheckTask"/>
|
|
||||||
```
|
|
||||||
|
|
||||||
Next, add the task to a target of your choosing:
|
|
||||||
|
|
||||||
```xml
|
|
||||||
<target name="dependency-check" description="Dependency-Check Analysis">
|
|
||||||
<dependency-check applicationname="Hello World"
|
|
||||||
autoupdate="true"
|
|
||||||
reportoutputdirectory="${basedir}"
|
|
||||||
reportformat="HTML">
|
|
||||||
|
|
||||||
<fileset dir="lib">
|
|
||||||
<include name="**/*.jar"/>
|
|
||||||
</fileset>
|
|
||||||
</dependency-check>
|
|
||||||
</target>
|
|
||||||
```
|
|
||||||
|
|
||||||
See the [configuration guide](configuration.html) for more information.
|
|
||||||
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 10 KiB |
@@ -2,35 +2,34 @@
|
|||||||
<!--
|
<!--
|
||||||
This file is part of dependency-check-ant.
|
This file is part of dependency-check-ant.
|
||||||
|
|
||||||
Dependency-check-ant is free software: you can redistribute it and/or modify it
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
under the terms of the GNU General Public License as published by the Free
|
you may not use this file except in compliance with the License.
|
||||||
Software Foundation, either version 3 of the License, or (at your option) any
|
You may obtain a copy of the License at
|
||||||
later version.
|
|
||||||
|
|
||||||
Dependency-check-ant is distributed in the hope that it will be useful, but
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
|
||||||
details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License along with
|
Unless required by applicable law or agreed to in writing, software
|
||||||
dependency-check-ant. If not, see http://www.gnu.org/licenses/.
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
|
||||||
Copyright (c) 2013 Jeremy Long. All Rights Reserved.
|
Copyright (c) 2013 Jeremy Long. All Rights Reserved.
|
||||||
-->
|
-->
|
||||||
<project name="dependency-check-ant">
|
<project name="dependency-check-ant">
|
||||||
<bannerLeft>
|
<bannerLeft>
|
||||||
<name>dependency-check-ant</name>
|
<name>OWASP dependency-check-ant</name>
|
||||||
|
<alt>OWASP dependency-check-ant</alt>
|
||||||
|
<src>./images/dc-ant.svg</src>
|
||||||
</bannerLeft>
|
</bannerLeft>
|
||||||
<body>
|
<body>
|
||||||
<breadcrumbs>
|
<breadcrumbs>
|
||||||
<item name="dependency-check" href="../index.html"/>
|
<item name="dependency-check" href="../index.html"/>
|
||||||
</breadcrumbs>
|
</breadcrumbs>
|
||||||
<menu name="Getting Started">
|
<menu name="Getting Started">
|
||||||
<item name="Installation" href="installation.html"/>
|
<item name="Installation" href="index.html"/>
|
||||||
<item name="Usage" href="usage.html"/>
|
|
||||||
<item name="Configuration" href="configuration.html"/>
|
<item name="Configuration" href="configuration.html"/>
|
||||||
</menu>
|
</menu>
|
||||||
<menu ref="Project Documentation" />
|
|
||||||
<menu ref="reports" />
|
<menu ref="reports" />
|
||||||
</body>
|
</body>
|
||||||
</project>
|
</project>
|
||||||
@@ -1,63 +1,61 @@
|
|||||||
/*
|
/*
|
||||||
* This file is part of dependency-check-ant.
|
* This file is part of dependency-check-ant.
|
||||||
*
|
*
|
||||||
* Dependency-check-ant is free software: you can redistribute it and/or modify it
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* under the terms of the GNU General Public License as published by the Free
|
* you may not use this file except in compliance with the License.
|
||||||
* Software Foundation, either version 3 of the License, or (at your option) any
|
* You may obtain a copy of the License at
|
||||||
* later version.
|
|
||||||
*
|
*
|
||||||
* Dependency-check-ant is distributed in the hope that it will be useful, but
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
|
||||||
* details.
|
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License along with
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* dependency-check-ant. If not, see http://www.gnu.org/licenses/.
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
*
|
*
|
||||||
* Copyright (c) 2013 Jeremy Long. All Rights Reserved.
|
* Copyright (c) 2013 Jeremy Long. All Rights Reserved.
|
||||||
*/
|
*/
|
||||||
package org.owasp.dependencycheck.taskdefs;
|
package org.owasp.dependencycheck.taskdefs;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import static junit.framework.TestCase.assertTrue;
|
|
||||||
|
import org.apache.tools.ant.BuildException;
|
||||||
|
import org.apache.tools.ant.BuildFileRule;
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
import org.junit.AfterClass;
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.BeforeClass;
|
import org.junit.Rule;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.apache.tools.ant.BuildFileTest;
|
import org.junit.rules.ExpectedException;
|
||||||
import org.owasp.dependencycheck.data.nvdcve.BaseDBTestCase;
|
import org.owasp.dependencycheck.BaseDBTestCase;
|
||||||
|
import org.owasp.dependencycheck.utils.Settings;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author Jeremy Long (jeremy.long@owasp.org)
|
* @author Jeremy Long
|
||||||
*/
|
*/
|
||||||
public class DependencyCheckTaskTest extends BuildFileTest {
|
public class DependencyCheckTaskTest {
|
||||||
|
|
||||||
public DependencyCheckTaskTest() {
|
@Rule
|
||||||
}
|
public BuildFileRule buildFileRule = new BuildFileRule();
|
||||||
|
|
||||||
@BeforeClass
|
@Rule
|
||||||
public static void setUpClass() {
|
public ExpectedException expectedException = ExpectedException.none();
|
||||||
}
|
|
||||||
|
|
||||||
@AfterClass
|
|
||||||
public static void tearDownClass() {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
@Override
|
|
||||||
public void setUp() throws Exception {
|
public void setUp() throws Exception {
|
||||||
|
Settings.initialize();
|
||||||
BaseDBTestCase.ensureDBExists();
|
BaseDBTestCase.ensureDBExists();
|
||||||
final String buildFile = this.getClass().getClassLoader().getResource("build.xml").getPath();
|
final String buildFile = this.getClass().getClassLoader().getResource("build.xml").getPath();
|
||||||
configureProject(buildFile);
|
buildFileRule.configureProject(buildFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
@After
|
@After
|
||||||
@Override
|
|
||||||
public void tearDown() {
|
public void tearDown() {
|
||||||
//no cleanup...
|
//no cleanup...
|
||||||
//executeTarget("cleanup");
|
//executeTarget("cleanup");
|
||||||
|
Settings.cleanup(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -65,16 +63,12 @@ public class DependencyCheckTaskTest extends BuildFileTest {
|
|||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testAddFileSet() throws Exception {
|
public void testAddFileSet() throws Exception {
|
||||||
File report = new File("target/DependencyCheck-Report.html");
|
File report = new File("target/dependency-check-report.html");
|
||||||
if (report.exists()) {
|
if (report.exists() && !report.delete()) {
|
||||||
if (!report.delete()) {
|
|
||||||
throw new Exception("Unable to delete 'target/DependencyCheck-Report.html' prior to test.");
|
throw new Exception("Unable to delete 'target/DependencyCheck-Report.html' prior to test.");
|
||||||
}
|
}
|
||||||
}
|
buildFileRule.executeTarget("test.fileset");
|
||||||
executeTarget("test.fileset");
|
|
||||||
|
|
||||||
assertTrue("DependencyCheck report was not generated", report.exists());
|
assertTrue("DependencyCheck report was not generated", report.exists());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -84,13 +78,13 @@ public class DependencyCheckTaskTest extends BuildFileTest {
|
|||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testAddFileList() throws Exception {
|
public void testAddFileList() throws Exception {
|
||||||
File report = new File("target/DependencyCheck-Report.xml");
|
File report = new File("target/dependency-check-report.xml");
|
||||||
if (report.exists()) {
|
if (report.exists()) {
|
||||||
if (!report.delete()) {
|
if (!report.delete()) {
|
||||||
throw new Exception("Unable to delete 'target/DependencyCheck-Report.xml' prior to test.");
|
throw new Exception("Unable to delete 'target/DependencyCheck-Report.xml' prior to test.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
executeTarget("test.filelist");
|
buildFileRule.executeTarget("test.filelist");
|
||||||
|
|
||||||
assertTrue("DependencyCheck report was not generated", report.exists());
|
assertTrue("DependencyCheck report was not generated", report.exists());
|
||||||
}
|
}
|
||||||
@@ -102,13 +96,13 @@ public class DependencyCheckTaskTest extends BuildFileTest {
|
|||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testAddDirSet() throws Exception {
|
public void testAddDirSet() throws Exception {
|
||||||
File report = new File("target/DependencyCheck-Vulnerability.html");
|
File report = new File("target/dependency-check-vulnerability.html");
|
||||||
if (report.exists()) {
|
if (report.exists()) {
|
||||||
if (!report.delete()) {
|
if (!report.delete()) {
|
||||||
throw new Exception("Unable to delete 'target/DependencyCheck-Vulnerability.html' prior to test.");
|
throw new Exception("Unable to delete 'target/DependencyCheck-Vulnerability.html' prior to test.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
executeTarget("test.dirset");
|
buildFileRule.executeTarget("test.dirset");
|
||||||
assertTrue("DependencyCheck report was not generated", report.exists());
|
assertTrue("DependencyCheck report was not generated", report.exists());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -117,7 +111,7 @@ public class DependencyCheckTaskTest extends BuildFileTest {
|
|||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testGetFailBuildOnCVSS() {
|
public void testGetFailBuildOnCVSS() {
|
||||||
expectBuildException("failCVSS", "asdfasdfscore");
|
expectedException.expect(BuildException.class);
|
||||||
System.out.println(this.getOutput());
|
buildFileRule.executeTarget("failCVSS");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project name="Dependency-Check Test Build" default="test.fileset" basedir=".">
|
<project name="Dependency-Check Test Build" default="test.fileset" basedir=".">
|
||||||
|
|
||||||
<taskdef name="dependency-check" classname="org.owasp.dependencycheck.taskdefs.DependencyCheckTask" />
|
<taskdef name="dependency-check" classname="org.owasp.dependencycheck.taskdefs.Check" />
|
||||||
|
|
||||||
<target name="test.fileset">
|
<target name="test.fileset">
|
||||||
<dependency-check
|
<dependency-check
|
||||||
@@ -61,11 +61,14 @@
|
|||||||
|
|
||||||
<target name="failCVSS">
|
<target name="failCVSS">
|
||||||
<dependency-check
|
<dependency-check
|
||||||
applicationName="test formatBAD"
|
applicationName="test failCVSS"
|
||||||
reportOutputDirectory="${project.build.directory}"
|
reportOutputDirectory="${project.build.directory}"
|
||||||
reportFormat="XML"
|
reportFormat="XML"
|
||||||
autoupdate="false"
|
autoupdate="false"
|
||||||
failBuildOnCVSS="8">
|
failBuildOnCVSS="3">
|
||||||
|
<fileset dir="${project.build.directory}/test-classes/jars">
|
||||||
|
<include name="axis-1.4.jar"/>
|
||||||
|
</fileset>
|
||||||
</dependency-check>
|
</dependency-check>
|
||||||
</target>
|
</target>
|
||||||
</project>
|
</project>
|
||||||
|
|||||||
@@ -1,674 +1,202 @@
|
|||||||
GNU GENERAL PUBLIC LICENSE
|
|
||||||
Version 3, 29 June 2007
|
|
||||||
|
|
||||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
Apache License
|
||||||
Everyone is permitted to copy and distribute verbatim copies
|
Version 2.0, January 2004
|
||||||
of this license document, but changing it is not allowed.
|
http://www.apache.org/licenses/
|
||||||
|
|
||||||
Preamble
|
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||||
|
|
||||||
The GNU General Public License is a free, copyleft license for
|
1. Definitions.
|
||||||
software and other kinds of works.
|
|
||||||
|
"License" shall mean the terms and conditions for use, reproduction,
|
||||||
The licenses for most software and other practical works are designed
|
and distribution as defined by Sections 1 through 9 of this document.
|
||||||
to take away your freedom to share and change the works. By contrast,
|
|
||||||
the GNU General Public License is intended to guarantee your freedom to
|
"Licensor" shall mean the copyright owner or entity authorized by
|
||||||
share and change all versions of a program--to make sure it remains free
|
the copyright owner that is granting the License.
|
||||||
software for all its users. We, the Free Software Foundation, use the
|
|
||||||
GNU General Public License for most of our software; it applies also to
|
"Legal Entity" shall mean the union of the acting entity and all
|
||||||
any other work released this way by its authors. You can apply it to
|
other entities that control, are controlled by, or are under common
|
||||||
your programs, too.
|
control with that entity. For the purposes of this definition,
|
||||||
|
"control" means (i) the power, direct or indirect, to cause the
|
||||||
When we speak of free software, we are referring to freedom, not
|
direction or management of such entity, whether by contract or
|
||||||
price. Our General Public Licenses are designed to make sure that you
|
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||||
have the freedom to distribute copies of free software (and charge for
|
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||||
them if you wish), that you receive source code or can get it if you
|
|
||||||
want it, that you can change the software or use pieces of it in new
|
"You" (or "Your") shall mean an individual or Legal Entity
|
||||||
free programs, and that you know you can do these things.
|
exercising permissions granted by this License.
|
||||||
|
|
||||||
To protect your rights, we need to prevent others from denying you
|
"Source" form shall mean the preferred form for making modifications,
|
||||||
these rights or asking you to surrender the rights. Therefore, you have
|
including but not limited to software source code, documentation
|
||||||
certain responsibilities if you distribute copies of the software, or if
|
source, and configuration files.
|
||||||
you modify it: responsibilities to respect the freedom of others.
|
|
||||||
|
"Object" form shall mean any form resulting from mechanical
|
||||||
For example, if you distribute copies of such a program, whether
|
transformation or translation of a Source form, including but
|
||||||
gratis or for a fee, you must pass on to the recipients the same
|
not limited to compiled object code, generated documentation,
|
||||||
freedoms that you received. You must make sure that they, too, receive
|
and conversions to other media types.
|
||||||
or can get the source code. And you must show them these terms so they
|
|
||||||
know their rights.
|
"Work" shall mean the work of authorship, whether in Source or
|
||||||
|
Object form, made available under the License, as indicated by a
|
||||||
Developers that use the GNU GPL protect your rights with two steps:
|
copyright notice that is included in or attached to the work
|
||||||
(1) assert copyright on the software, and (2) offer you this License
|
(an example is provided in the Appendix below).
|
||||||
giving you legal permission to copy, distribute and/or modify it.
|
|
||||||
|
"Derivative Works" shall mean any work, whether in Source or Object
|
||||||
For the developers' and authors' protection, the GPL clearly explains
|
form, that is based on (or derived from) the Work and for which the
|
||||||
that there is no warranty for this free software. For both users' and
|
editorial revisions, annotations, elaborations, or other modifications
|
||||||
authors' sake, the GPL requires that modified versions be marked as
|
represent, as a whole, an original work of authorship. For the purposes
|
||||||
changed, so that their problems will not be attributed erroneously to
|
of this License, Derivative Works shall not include works that remain
|
||||||
authors of previous versions.
|
separable from, or merely link (or bind by name) to the interfaces of,
|
||||||
|
the Work and Derivative Works thereof.
|
||||||
Some devices are designed to deny users access to install or run
|
|
||||||
modified versions of the software inside them, although the manufacturer
|
"Contribution" shall mean any work of authorship, including
|
||||||
can do so. This is fundamentally incompatible with the aim of
|
the original version of the Work and any modifications or additions
|
||||||
protecting users' freedom to change the software. The systematic
|
to that Work or Derivative Works thereof, that is intentionally
|
||||||
pattern of such abuse occurs in the area of products for individuals to
|
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||||
use, which is precisely where it is most unacceptable. Therefore, we
|
or by an individual or Legal Entity authorized to submit on behalf of
|
||||||
have designed this version of the GPL to prohibit the practice for those
|
the copyright owner. For the purposes of this definition, "submitted"
|
||||||
products. If such problems arise substantially in other domains, we
|
means any form of electronic, verbal, or written communication sent
|
||||||
stand ready to extend this provision to those domains in future versions
|
to the Licensor or its representatives, including but not limited to
|
||||||
of the GPL, as needed to protect the freedom of users.
|
communication on electronic mailing lists, source code control systems,
|
||||||
|
and issue tracking systems that are managed by, or on behalf of, the
|
||||||
Finally, every program is threatened constantly by software patents.
|
Licensor for the purpose of discussing and improving the Work, but
|
||||||
States should not allow patents to restrict development and use of
|
excluding communication that is conspicuously marked or otherwise
|
||||||
software on general-purpose computers, but in those that do, we wish to
|
designated in writing by the copyright owner as "Not a Contribution."
|
||||||
avoid the special danger that patents applied to a free program could
|
|
||||||
make it effectively proprietary. To prevent this, the GPL assures that
|
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||||
patents cannot be used to render the program non-free.
|
on behalf of whom a Contribution has been received by Licensor and
|
||||||
|
subsequently incorporated within the Work.
|
||||||
The precise terms and conditions for copying, distribution and
|
|
||||||
modification follow.
|
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
TERMS AND CONDITIONS
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
copyright license to reproduce, prepare Derivative Works of,
|
||||||
0. Definitions.
|
publicly display, publicly perform, sublicense, and distribute the
|
||||||
|
Work and such Derivative Works in Source or Object form.
|
||||||
"This License" refers to version 3 of the GNU General Public License.
|
|
||||||
|
3. Grant of Patent License. Subject to the terms and conditions of
|
||||||
"Copyright" also means copyright-like laws that apply to other kinds of
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
works, such as semiconductor masks.
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
(except as stated in this section) patent license to make, have made,
|
||||||
"The Program" refers to any copyrightable work licensed under this
|
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||||
License. Each licensee is addressed as "you". "Licensees" and
|
where such license applies only to those patent claims licensable
|
||||||
"recipients" may be individuals or organizations.
|
by such Contributor that are necessarily infringed by their
|
||||||
|
Contribution(s) alone or by combination of their Contribution(s)
|
||||||
To "modify" a work means to copy from or adapt all or part of the work
|
with the Work to which such Contribution(s) was submitted. If You
|
||||||
in a fashion requiring copyright permission, other than the making of an
|
institute patent litigation against any entity (including a
|
||||||
exact copy. The resulting work is called a "modified version" of the
|
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||||
earlier work or a work "based on" the earlier work.
|
or a Contribution incorporated within the Work constitutes direct
|
||||||
|
or contributory patent infringement, then any patent licenses
|
||||||
A "covered work" means either the unmodified Program or a work based
|
granted to You under this License for that Work shall terminate
|
||||||
on the Program.
|
as of the date such litigation is filed.
|
||||||
|
|
||||||
To "propagate" a work means to do anything with it that, without
|
4. Redistribution. You may reproduce and distribute copies of the
|
||||||
permission, would make you directly or secondarily liable for
|
Work or Derivative Works thereof in any medium, with or without
|
||||||
infringement under applicable copyright law, except executing it on a
|
modifications, and in Source or Object form, provided that You
|
||||||
computer or modifying a private copy. Propagation includes copying,
|
meet the following conditions:
|
||||||
distribution (with or without modification), making available to the
|
|
||||||
public, and in some countries other activities as well.
|
(a) You must give any other recipients of the Work or
|
||||||
|
Derivative Works a copy of this License; and
|
||||||
To "convey" a work means any kind of propagation that enables other
|
|
||||||
parties to make or receive copies. Mere interaction with a user through
|
(b) You must cause any modified files to carry prominent notices
|
||||||
a computer network, with no transfer of a copy, is not conveying.
|
stating that You changed the files; and
|
||||||
|
|
||||||
An interactive user interface displays "Appropriate Legal Notices"
|
(c) You must retain, in the Source form of any Derivative Works
|
||||||
to the extent that it includes a convenient and prominently visible
|
that You distribute, all copyright, patent, trademark, and
|
||||||
feature that (1) displays an appropriate copyright notice, and (2)
|
attribution notices from the Source form of the Work,
|
||||||
tells the user that there is no warranty for the work (except to the
|
excluding those notices that do not pertain to any part of
|
||||||
extent that warranties are provided), that licensees may convey the
|
the Derivative Works; and
|
||||||
work under this License, and how to view a copy of this License. If
|
|
||||||
the interface presents a list of user commands or options, such as a
|
(d) If the Work includes a "NOTICE" text file as part of its
|
||||||
menu, a prominent item in the list meets this criterion.
|
distribution, then any Derivative Works that You distribute must
|
||||||
|
include a readable copy of the attribution notices contained
|
||||||
1. Source Code.
|
within such NOTICE file, excluding those notices that do not
|
||||||
|
pertain to any part of the Derivative Works, in at least one
|
||||||
The "source code" for a work means the preferred form of the work
|
of the following places: within a NOTICE text file distributed
|
||||||
for making modifications to it. "Object code" means any non-source
|
as part of the Derivative Works; within the Source form or
|
||||||
form of a work.
|
documentation, if provided along with the Derivative Works; or,
|
||||||
|
within a display generated by the Derivative Works, if and
|
||||||
A "Standard Interface" means an interface that either is an official
|
wherever such third-party notices normally appear. The contents
|
||||||
standard defined by a recognized standards body, or, in the case of
|
of the NOTICE file are for informational purposes only and
|
||||||
interfaces specified for a particular programming language, one that
|
do not modify the License. You may add Your own attribution
|
||||||
is widely used among developers working in that language.
|
notices within Derivative Works that You distribute, alongside
|
||||||
|
or as an addendum to the NOTICE text from the Work, provided
|
||||||
The "System Libraries" of an executable work include anything, other
|
that such additional attribution notices cannot be construed
|
||||||
than the work as a whole, that (a) is included in the normal form of
|
as modifying the License.
|
||||||
packaging a Major Component, but which is not part of that Major
|
|
||||||
Component, and (b) serves only to enable use of the work with that
|
You may add Your own copyright statement to Your modifications and
|
||||||
Major Component, or to implement a Standard Interface for which an
|
may provide additional or different license terms and conditions
|
||||||
implementation is available to the public in source code form. A
|
for use, reproduction, or distribution of Your modifications, or
|
||||||
"Major Component", in this context, means a major essential component
|
for any such Derivative Works as a whole, provided Your use,
|
||||||
(kernel, window system, and so on) of the specific operating system
|
reproduction, and distribution of the Work otherwise complies with
|
||||||
(if any) on which the executable work runs, or a compiler used to
|
the conditions stated in this License.
|
||||||
produce the work, or an object code interpreter used to run it.
|
|
||||||
|
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||||
The "Corresponding Source" for a work in object code form means all
|
any Contribution intentionally submitted for inclusion in the Work
|
||||||
the source code needed to generate, install, and (for an executable
|
by You to the Licensor shall be under the terms and conditions of
|
||||||
work) run the object code and to modify the work, including scripts to
|
this License, without any additional terms or conditions.
|
||||||
control those activities. However, it does not include the work's
|
Notwithstanding the above, nothing herein shall supersede or modify
|
||||||
System Libraries, or general-purpose tools or generally available free
|
the terms of any separate license agreement you may have executed
|
||||||
programs which are used unmodified in performing those activities but
|
with Licensor regarding such Contributions.
|
||||||
which are not part of the work. For example, Corresponding Source
|
|
||||||
includes interface definition files associated with source files for
|
6. Trademarks. This License does not grant permission to use the trade
|
||||||
the work, and the source code for shared libraries and dynamically
|
names, trademarks, service marks, or product names of the Licensor,
|
||||||
linked subprograms that the work is specifically designed to require,
|
except as required for reasonable and customary use in describing the
|
||||||
such as by intimate data communication or control flow between those
|
origin of the Work and reproducing the content of the NOTICE file.
|
||||||
subprograms and other parts of the work.
|
|
||||||
|
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||||
The Corresponding Source need not include anything that users
|
agreed to in writing, Licensor provides the Work (and each
|
||||||
can regenerate automatically from other parts of the Corresponding
|
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||||
Source.
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||||
|
implied, including, without limitation, any warranties or conditions
|
||||||
The Corresponding Source for a work in source code form is that
|
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||||
same work.
|
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||||
|
appropriateness of using or redistributing the Work and assume any
|
||||||
2. Basic Permissions.
|
risks associated with Your exercise of permissions under this License.
|
||||||
|
|
||||||
All rights granted under this License are granted for the term of
|
8. Limitation of Liability. In no event and under no legal theory,
|
||||||
copyright on the Program, and are irrevocable provided the stated
|
whether in tort (including negligence), contract, or otherwise,
|
||||||
conditions are met. This License explicitly affirms your unlimited
|
unless required by applicable law (such as deliberate and grossly
|
||||||
permission to run the unmodified Program. The output from running a
|
negligent acts) or agreed to in writing, shall any Contributor be
|
||||||
covered work is covered by this License only if the output, given its
|
liable to You for damages, including any direct, indirect, special,
|
||||||
content, constitutes a covered work. This License acknowledges your
|
incidental, or consequential damages of any character arising as a
|
||||||
rights of fair use or other equivalent, as provided by copyright law.
|
result of this License or out of the use or inability to use the
|
||||||
|
Work (including but not limited to damages for loss of goodwill,
|
||||||
You may make, run and propagate covered works that you do not
|
work stoppage, computer failure or malfunction, or any and all
|
||||||
convey, without conditions so long as your license otherwise remains
|
other commercial damages or losses), even if such Contributor
|
||||||
in force. You may convey covered works to others for the sole purpose
|
has been advised of the possibility of such damages.
|
||||||
of having them make modifications exclusively for you, or provide you
|
|
||||||
with facilities for running those works, provided that you comply with
|
9. Accepting Warranty or Additional Liability. While redistributing
|
||||||
the terms of this License in conveying all material for which you do
|
the Work or Derivative Works thereof, You may choose to offer,
|
||||||
not control copyright. Those thus making or running the covered works
|
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||||
for you must do so exclusively on your behalf, under your direction
|
or other liability obligations and/or rights consistent with this
|
||||||
and control, on terms that prohibit them from making any copies of
|
License. However, in accepting such obligations, You may act only
|
||||||
your copyrighted material outside their relationship with you.
|
on Your own behalf and on Your sole responsibility, not on behalf
|
||||||
|
of any other Contributor, and only if You agree to indemnify,
|
||||||
Conveying under any other circumstances is permitted solely under
|
defend, and hold each Contributor harmless for any liability
|
||||||
the conditions stated below. Sublicensing is not allowed; section 10
|
incurred by, or claims asserted against, such Contributor by reason
|
||||||
makes it unnecessary.
|
of your accepting any such warranty or additional liability.
|
||||||
|
|
||||||
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
|
||||||
|
|
||||||
No covered work shall be deemed part of an effective technological
|
|
||||||
measure under any applicable law fulfilling obligations under article
|
|
||||||
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
|
||||||
similar laws prohibiting or restricting circumvention of such
|
|
||||||
measures.
|
|
||||||
|
|
||||||
When you convey a covered work, you waive any legal power to forbid
|
|
||||||
circumvention of technological measures to the extent such circumvention
|
|
||||||
is effected by exercising rights under this License with respect to
|
|
||||||
the covered work, and you disclaim any intention to limit operation or
|
|
||||||
modification of the work as a means of enforcing, against the work's
|
|
||||||
users, your or third parties' legal rights to forbid circumvention of
|
|
||||||
technological measures.
|
|
||||||
|
|
||||||
4. Conveying Verbatim Copies.
|
|
||||||
|
|
||||||
You may convey verbatim copies of the Program's source code as you
|
|
||||||
receive it, in any medium, provided that you conspicuously and
|
|
||||||
appropriately publish on each copy an appropriate copyright notice;
|
|
||||||
keep intact all notices stating that this License and any
|
|
||||||
non-permissive terms added in accord with section 7 apply to the code;
|
|
||||||
keep intact all notices of the absence of any warranty; and give all
|
|
||||||
recipients a copy of this License along with the Program.
|
|
||||||
|
|
||||||
You may charge any price or no price for each copy that you convey,
|
|
||||||
and you may offer support or warranty protection for a fee.
|
|
||||||
|
|
||||||
5. Conveying Modified Source Versions.
|
|
||||||
|
|
||||||
You may convey a work based on the Program, or the modifications to
|
|
||||||
produce it from the Program, in the form of source code under the
|
|
||||||
terms of section 4, provided that you also meet all of these conditions:
|
|
||||||
|
|
||||||
a) The work must carry prominent notices stating that you modified
|
|
||||||
it, and giving a relevant date.
|
|
||||||
|
|
||||||
b) The work must carry prominent notices stating that it is
|
|
||||||
released under this License and any conditions added under section
|
|
||||||
7. This requirement modifies the requirement in section 4 to
|
|
||||||
"keep intact all notices".
|
|
||||||
|
|
||||||
c) You must license the entire work, as a whole, under this
|
|
||||||
License to anyone who comes into possession of a copy. This
|
|
||||||
License will therefore apply, along with any applicable section 7
|
|
||||||
additional terms, to the whole of the work, and all its parts,
|
|
||||||
regardless of how they are packaged. This License gives no
|
|
||||||
permission to license the work in any other way, but it does not
|
|
||||||
invalidate such permission if you have separately received it.
|
|
||||||
|
|
||||||
d) If the work has interactive user interfaces, each must display
|
|
||||||
Appropriate Legal Notices; however, if the Program has interactive
|
|
||||||
interfaces that do not display Appropriate Legal Notices, your
|
|
||||||
work need not make them do so.
|
|
||||||
|
|
||||||
A compilation of a covered work with other separate and independent
|
|
||||||
works, which are not by their nature extensions of the covered work,
|
|
||||||
and which are not combined with it such as to form a larger program,
|
|
||||||
in or on a volume of a storage or distribution medium, is called an
|
|
||||||
"aggregate" if the compilation and its resulting copyright are not
|
|
||||||
used to limit the access or legal rights of the compilation's users
|
|
||||||
beyond what the individual works permit. Inclusion of a covered work
|
|
||||||
in an aggregate does not cause this License to apply to the other
|
|
||||||
parts of the aggregate.
|
|
||||||
|
|
||||||
6. Conveying Non-Source Forms.
|
|
||||||
|
|
||||||
You may convey a covered work in object code form under the terms
|
|
||||||
of sections 4 and 5, provided that you also convey the
|
|
||||||
machine-readable Corresponding Source under the terms of this License,
|
|
||||||
in one of these ways:
|
|
||||||
|
|
||||||
a) Convey the object code in, or embodied in, a physical product
|
|
||||||
(including a physical distribution medium), accompanied by the
|
|
||||||
Corresponding Source fixed on a durable physical medium
|
|
||||||
customarily used for software interchange.
|
|
||||||
|
|
||||||
b) Convey the object code in, or embodied in, a physical product
|
|
||||||
(including a physical distribution medium), accompanied by a
|
|
||||||
written offer, valid for at least three years and valid for as
|
|
||||||
long as you offer spare parts or customer support for that product
|
|
||||||
model, to give anyone who possesses the object code either (1) a
|
|
||||||
copy of the Corresponding Source for all the software in the
|
|
||||||
product that is covered by this License, on a durable physical
|
|
||||||
medium customarily used for software interchange, for a price no
|
|
||||||
more than your reasonable cost of physically performing this
|
|
||||||
conveying of source, or (2) access to copy the
|
|
||||||
Corresponding Source from a network server at no charge.
|
|
||||||
|
|
||||||
c) Convey individual copies of the object code with a copy of the
|
|
||||||
written offer to provide the Corresponding Source. This
|
|
||||||
alternative is allowed only occasionally and noncommercially, and
|
|
||||||
only if you received the object code with such an offer, in accord
|
|
||||||
with subsection 6b.
|
|
||||||
|
|
||||||
d) Convey the object code by offering access from a designated
|
|
||||||
place (gratis or for a charge), and offer equivalent access to the
|
|
||||||
Corresponding Source in the same way through the same place at no
|
|
||||||
further charge. You need not require recipients to copy the
|
|
||||||
Corresponding Source along with the object code. If the place to
|
|
||||||
copy the object code is a network server, the Corresponding Source
|
|
||||||
may be on a different server (operated by you or a third party)
|
|
||||||
that supports equivalent copying facilities, provided you maintain
|
|
||||||
clear directions next to the object code saying where to find the
|
|
||||||
Corresponding Source. Regardless of what server hosts the
|
|
||||||
Corresponding Source, you remain obligated to ensure that it is
|
|
||||||
available for as long as needed to satisfy these requirements.
|
|
||||||
|
|
||||||
e) Convey the object code using peer-to-peer transmission, provided
|
|
||||||
you inform other peers where the object code and Corresponding
|
|
||||||
Source of the work are being offered to the general public at no
|
|
||||||
charge under subsection 6d.
|
|
||||||
|
|
||||||
A separable portion of the object code, whose source code is excluded
|
|
||||||
from the Corresponding Source as a System Library, need not be
|
|
||||||
included in conveying the object code work.
|
|
||||||
|
|
||||||
A "User Product" is either (1) a "consumer product", which means any
|
|
||||||
tangible personal property which is normally used for personal, family,
|
|
||||||
or household purposes, or (2) anything designed or sold for incorporation
|
|
||||||
into a dwelling. In determining whether a product is a consumer product,
|
|
||||||
doubtful cases shall be resolved in favor of coverage. For a particular
|
|
||||||
product received by a particular user, "normally used" refers to a
|
|
||||||
typical or common use of that class of product, regardless of the status
|
|
||||||
of the particular user or of the way in which the particular user
|
|
||||||
actually uses, or expects or is expected to use, the product. A product
|
|
||||||
is a consumer product regardless of whether the product has substantial
|
|
||||||
commercial, industrial or non-consumer uses, unless such uses represent
|
|
||||||
the only significant mode of use of the product.
|
|
||||||
|
|
||||||
"Installation Information" for a User Product means any methods,
|
|
||||||
procedures, authorization keys, or other information required to install
|
|
||||||
and execute modified versions of a covered work in that User Product from
|
|
||||||
a modified version of its Corresponding Source. The information must
|
|
||||||
suffice to ensure that the continued functioning of the modified object
|
|
||||||
code is in no case prevented or interfered with solely because
|
|
||||||
modification has been made.
|
|
||||||
|
|
||||||
If you convey an object code work under this section in, or with, or
|
|
||||||
specifically for use in, a User Product, and the conveying occurs as
|
|
||||||
part of a transaction in which the right of possession and use of the
|
|
||||||
User Product is transferred to the recipient in perpetuity or for a
|
|
||||||
fixed term (regardless of how the transaction is characterized), the
|
|
||||||
Corresponding Source conveyed under this section must be accompanied
|
|
||||||
by the Installation Information. But this requirement does not apply
|
|
||||||
if neither you nor any third party retains the ability to install
|
|
||||||
modified object code on the User Product (for example, the work has
|
|
||||||
been installed in ROM).
|
|
||||||
|
|
||||||
The requirement to provide Installation Information does not include a
|
|
||||||
requirement to continue to provide support service, warranty, or updates
|
|
||||||
for a work that has been modified or installed by the recipient, or for
|
|
||||||
the User Product in which it has been modified or installed. Access to a
|
|
||||||
network may be denied when the modification itself materially and
|
|
||||||
adversely affects the operation of the network or violates the rules and
|
|
||||||
protocols for communication across the network.
|
|
||||||
|
|
||||||
Corresponding Source conveyed, and Installation Information provided,
|
|
||||||
in accord with this section must be in a format that is publicly
|
|
||||||
documented (and with an implementation available to the public in
|
|
||||||
source code form), and must require no special password or key for
|
|
||||||
unpacking, reading or copying.
|
|
||||||
|
|
||||||
7. Additional Terms.
|
|
||||||
|
|
||||||
"Additional permissions" are terms that supplement the terms of this
|
|
||||||
License by making exceptions from one or more of its conditions.
|
|
||||||
Additional permissions that are applicable to the entire Program shall
|
|
||||||
be treated as though they were included in this License, to the extent
|
|
||||||
that they are valid under applicable law. If additional permissions
|
|
||||||
apply only to part of the Program, that part may be used separately
|
|
||||||
under those permissions, but the entire Program remains governed by
|
|
||||||
this License without regard to the additional permissions.
|
|
||||||
|
|
||||||
When you convey a copy of a covered work, you may at your option
|
|
||||||
remove any additional permissions from that copy, or from any part of
|
|
||||||
it. (Additional permissions may be written to require their own
|
|
||||||
removal in certain cases when you modify the work.) You may place
|
|
||||||
additional permissions on material, added by you to a covered work,
|
|
||||||
for which you have or can give appropriate copyright permission.
|
|
||||||
|
|
||||||
Notwithstanding any other provision of this License, for material you
|
|
||||||
add to a covered work, you may (if authorized by the copyright holders of
|
|
||||||
that material) supplement the terms of this License with terms:
|
|
||||||
|
|
||||||
a) Disclaiming warranty or limiting liability differently from the
|
|
||||||
terms of sections 15 and 16 of this License; or
|
|
||||||
|
|
||||||
b) Requiring preservation of specified reasonable legal notices or
|
|
||||||
author attributions in that material or in the Appropriate Legal
|
|
||||||
Notices displayed by works containing it; or
|
|
||||||
|
|
||||||
c) Prohibiting misrepresentation of the origin of that material, or
|
|
||||||
requiring that modified versions of such material be marked in
|
|
||||||
reasonable ways as different from the original version; or
|
|
||||||
|
|
||||||
d) Limiting the use for publicity purposes of names of licensors or
|
|
||||||
authors of the material; or
|
|
||||||
|
|
||||||
e) Declining to grant rights under trademark law for use of some
|
|
||||||
trade names, trademarks, or service marks; or
|
|
||||||
|
|
||||||
f) Requiring indemnification of licensors and authors of that
|
|
||||||
material by anyone who conveys the material (or modified versions of
|
|
||||||
it) with contractual assumptions of liability to the recipient, for
|
|
||||||
any liability that these contractual assumptions directly impose on
|
|
||||||
those licensors and authors.
|
|
||||||
|
|
||||||
All other non-permissive additional terms are considered "further
|
|
||||||
restrictions" within the meaning of section 10. If the Program as you
|
|
||||||
received it, or any part of it, contains a notice stating that it is
|
|
||||||
governed by this License along with a term that is a further
|
|
||||||
restriction, you may remove that term. If a license document contains
|
|
||||||
a further restriction but permits relicensing or conveying under this
|
|
||||||
License, you may add to a covered work material governed by the terms
|
|
||||||
of that license document, provided that the further restriction does
|
|
||||||
not survive such relicensing or conveying.
|
|
||||||
|
|
||||||
If you add terms to a covered work in accord with this section, you
|
|
||||||
must place, in the relevant source files, a statement of the
|
|
||||||
additional terms that apply to those files, or a notice indicating
|
|
||||||
where to find the applicable terms.
|
|
||||||
|
|
||||||
Additional terms, permissive or non-permissive, may be stated in the
|
|
||||||
form of a separately written license, or stated as exceptions;
|
|
||||||
the above requirements apply either way.
|
|
||||||
|
|
||||||
8. Termination.
|
|
||||||
|
|
||||||
You may not propagate or modify a covered work except as expressly
|
|
||||||
provided under this License. Any attempt otherwise to propagate or
|
|
||||||
modify it is void, and will automatically terminate your rights under
|
|
||||||
this License (including any patent licenses granted under the third
|
|
||||||
paragraph of section 11).
|
|
||||||
|
|
||||||
However, if you cease all violation of this License, then your
|
|
||||||
license from a particular copyright holder is reinstated (a)
|
|
||||||
provisionally, unless and until the copyright holder explicitly and
|
|
||||||
finally terminates your license, and (b) permanently, if the copyright
|
|
||||||
holder fails to notify you of the violation by some reasonable means
|
|
||||||
prior to 60 days after the cessation.
|
|
||||||
|
|
||||||
Moreover, your license from a particular copyright holder is
|
|
||||||
reinstated permanently if the copyright holder notifies you of the
|
|
||||||
violation by some reasonable means, this is the first time you have
|
|
||||||
received notice of violation of this License (for any work) from that
|
|
||||||
copyright holder, and you cure the violation prior to 30 days after
|
|
||||||
your receipt of the notice.
|
|
||||||
|
|
||||||
Termination of your rights under this section does not terminate the
|
|
||||||
licenses of parties who have received copies or rights from you under
|
|
||||||
this License. If your rights have been terminated and not permanently
|
|
||||||
reinstated, you do not qualify to receive new licenses for the same
|
|
||||||
material under section 10.
|
|
||||||
|
|
||||||
9. Acceptance Not Required for Having Copies.
|
|
||||||
|
|
||||||
You are not required to accept this License in order to receive or
|
|
||||||
run a copy of the Program. Ancillary propagation of a covered work
|
|
||||||
occurring solely as a consequence of using peer-to-peer transmission
|
|
||||||
to receive a copy likewise does not require acceptance. However,
|
|
||||||
nothing other than this License grants you permission to propagate or
|
|
||||||
modify any covered work. These actions infringe copyright if you do
|
|
||||||
not accept this License. Therefore, by modifying or propagating a
|
|
||||||
covered work, you indicate your acceptance of this License to do so.
|
|
||||||
|
|
||||||
10. Automatic Licensing of Downstream Recipients.
|
|
||||||
|
|
||||||
Each time you convey a covered work, the recipient automatically
|
|
||||||
receives a license from the original licensors, to run, modify and
|
|
||||||
propagate that work, subject to this License. You are not responsible
|
|
||||||
for enforcing compliance by third parties with this License.
|
|
||||||
|
|
||||||
An "entity transaction" is a transaction transferring control of an
|
|
||||||
organization, or substantially all assets of one, or subdividing an
|
|
||||||
organization, or merging organizations. If propagation of a covered
|
|
||||||
work results from an entity transaction, each party to that
|
|
||||||
transaction who receives a copy of the work also receives whatever
|
|
||||||
licenses to the work the party's predecessor in interest had or could
|
|
||||||
give under the previous paragraph, plus a right to possession of the
|
|
||||||
Corresponding Source of the work from the predecessor in interest, if
|
|
||||||
the predecessor has it or can get it with reasonable efforts.
|
|
||||||
|
|
||||||
You may not impose any further restrictions on the exercise of the
|
|
||||||
rights granted or affirmed under this License. For example, you may
|
|
||||||
not impose a license fee, royalty, or other charge for exercise of
|
|
||||||
rights granted under this License, and you may not initiate litigation
|
|
||||||
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
|
||||||
any patent claim is infringed by making, using, selling, offering for
|
|
||||||
sale, or importing the Program or any portion of it.
|
|
||||||
|
|
||||||
11. Patents.
|
|
||||||
|
|
||||||
A "contributor" is a copyright holder who authorizes use under this
|
|
||||||
License of the Program or a work on which the Program is based. The
|
|
||||||
work thus licensed is called the contributor's "contributor version".
|
|
||||||
|
|
||||||
A contributor's "essential patent claims" are all patent claims
|
|
||||||
owned or controlled by the contributor, whether already acquired or
|
|
||||||
hereafter acquired, that would be infringed by some manner, permitted
|
|
||||||
by this License, of making, using, or selling its contributor version,
|
|
||||||
but do not include claims that would be infringed only as a
|
|
||||||
consequence of further modification of the contributor version. For
|
|
||||||
purposes of this definition, "control" includes the right to grant
|
|
||||||
patent sublicenses in a manner consistent with the requirements of
|
|
||||||
this License.
|
|
||||||
|
|
||||||
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
|
||||||
patent license under the contributor's essential patent claims, to
|
|
||||||
make, use, sell, offer for sale, import and otherwise run, modify and
|
|
||||||
propagate the contents of its contributor version.
|
|
||||||
|
|
||||||
In the following three paragraphs, a "patent license" is any express
|
|
||||||
agreement or commitment, however denominated, not to enforce a patent
|
|
||||||
(such as an express permission to practice a patent or covenant not to
|
|
||||||
sue for patent infringement). To "grant" such a patent license to a
|
|
||||||
party means to make such an agreement or commitment not to enforce a
|
|
||||||
patent against the party.
|
|
||||||
|
|
||||||
If you convey a covered work, knowingly relying on a patent license,
|
|
||||||
and the Corresponding Source of the work is not available for anyone
|
|
||||||
to copy, free of charge and under the terms of this License, through a
|
|
||||||
publicly available network server or other readily accessible means,
|
|
||||||
then you must either (1) cause the Corresponding Source to be so
|
|
||||||
available, or (2) arrange to deprive yourself of the benefit of the
|
|
||||||
patent license for this particular work, or (3) arrange, in a manner
|
|
||||||
consistent with the requirements of this License, to extend the patent
|
|
||||||
license to downstream recipients. "Knowingly relying" means you have
|
|
||||||
actual knowledge that, but for the patent license, your conveying the
|
|
||||||
covered work in a country, or your recipient's use of the covered work
|
|
||||||
in a country, would infringe one or more identifiable patents in that
|
|
||||||
country that you have reason to believe are valid.
|
|
||||||
|
|
||||||
If, pursuant to or in connection with a single transaction or
|
|
||||||
arrangement, you convey, or propagate by procuring conveyance of, a
|
|
||||||
covered work, and grant a patent license to some of the parties
|
|
||||||
receiving the covered work authorizing them to use, propagate, modify
|
|
||||||
or convey a specific copy of the covered work, then the patent license
|
|
||||||
you grant is automatically extended to all recipients of the covered
|
|
||||||
work and works based on it.
|
|
||||||
|
|
||||||
A patent license is "discriminatory" if it does not include within
|
|
||||||
the scope of its coverage, prohibits the exercise of, or is
|
|
||||||
conditioned on the non-exercise of one or more of the rights that are
|
|
||||||
specifically granted under this License. You may not convey a covered
|
|
||||||
work if you are a party to an arrangement with a third party that is
|
|
||||||
in the business of distributing software, under which you make payment
|
|
||||||
to the third party based on the extent of your activity of conveying
|
|
||||||
the work, and under which the third party grants, to any of the
|
|
||||||
parties who would receive the covered work from you, a discriminatory
|
|
||||||
patent license (a) in connection with copies of the covered work
|
|
||||||
conveyed by you (or copies made from those copies), or (b) primarily
|
|
||||||
for and in connection with specific products or compilations that
|
|
||||||
contain the covered work, unless you entered into that arrangement,
|
|
||||||
or that patent license was granted, prior to 28 March 2007.
|
|
||||||
|
|
||||||
Nothing in this License shall be construed as excluding or limiting
|
|
||||||
any implied license or other defenses to infringement that may
|
|
||||||
otherwise be available to you under applicable patent law.
|
|
||||||
|
|
||||||
12. No Surrender of Others' Freedom.
|
|
||||||
|
|
||||||
If conditions are imposed on you (whether by court order, agreement or
|
|
||||||
otherwise) that contradict the conditions of this License, they do not
|
|
||||||
excuse you from the conditions of this License. If you cannot convey a
|
|
||||||
covered work so as to satisfy simultaneously your obligations under this
|
|
||||||
License and any other pertinent obligations, then as a consequence you may
|
|
||||||
not convey it at all. For example, if you agree to terms that obligate you
|
|
||||||
to collect a royalty for further conveying from those to whom you convey
|
|
||||||
the Program, the only way you could satisfy both those terms and this
|
|
||||||
License would be to refrain entirely from conveying the Program.
|
|
||||||
|
|
||||||
13. Use with the GNU Affero General Public License.
|
|
||||||
|
|
||||||
Notwithstanding any other provision of this License, you have
|
|
||||||
permission to link or combine any covered work with a work licensed
|
|
||||||
under version 3 of the GNU Affero General Public License into a single
|
|
||||||
combined work, and to convey the resulting work. The terms of this
|
|
||||||
License will continue to apply to the part which is the covered work,
|
|
||||||
but the special requirements of the GNU Affero General Public License,
|
|
||||||
section 13, concerning interaction through a network will apply to the
|
|
||||||
combination as such.
|
|
||||||
|
|
||||||
14. Revised Versions of this License.
|
|
||||||
|
|
||||||
The Free Software Foundation may publish revised and/or new versions of
|
|
||||||
the GNU General Public License from time to time. Such new versions will
|
|
||||||
be similar in spirit to the present version, but may differ in detail to
|
|
||||||
address new problems or concerns.
|
|
||||||
|
|
||||||
Each version is given a distinguishing version number. If the
|
|
||||||
Program specifies that a certain numbered version of the GNU General
|
|
||||||
Public License "or any later version" applies to it, you have the
|
|
||||||
option of following the terms and conditions either of that numbered
|
|
||||||
version or of any later version published by the Free Software
|
|
||||||
Foundation. If the Program does not specify a version number of the
|
|
||||||
GNU General Public License, you may choose any version ever published
|
|
||||||
by the Free Software Foundation.
|
|
||||||
|
|
||||||
If the Program specifies that a proxy can decide which future
|
|
||||||
versions of the GNU General Public License can be used, that proxy's
|
|
||||||
public statement of acceptance of a version permanently authorizes you
|
|
||||||
to choose that version for the Program.
|
|
||||||
|
|
||||||
Later license versions may give you additional or different
|
|
||||||
permissions. However, no additional obligations are imposed on any
|
|
||||||
author or copyright holder as a result of your choosing to follow a
|
|
||||||
later version.
|
|
||||||
|
|
||||||
15. Disclaimer of Warranty.
|
|
||||||
|
|
||||||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
|
||||||
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
|
||||||
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
|
||||||
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
|
||||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
|
||||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
|
||||||
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
|
||||||
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
|
||||||
|
|
||||||
16. Limitation of Liability.
|
|
||||||
|
|
||||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
|
||||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
|
||||||
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
|
||||||
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
|
||||||
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
|
||||||
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
|
||||||
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
|
||||||
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
|
||||||
SUCH DAMAGES.
|
|
||||||
|
|
||||||
17. Interpretation of Sections 15 and 16.
|
|
||||||
|
|
||||||
If the disclaimer of warranty and limitation of liability provided
|
|
||||||
above cannot be given local legal effect according to their terms,
|
|
||||||
reviewing courts shall apply local law that most closely approximates
|
|
||||||
an absolute waiver of all civil liability in connection with the
|
|
||||||
Program, unless a warranty or assumption of liability accompanies a
|
|
||||||
copy of the Program in return for a fee.
|
|
||||||
|
|
||||||
END OF TERMS AND CONDITIONS
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
How to Apply These Terms to Your New Programs
|
APPENDIX: How to apply the Apache License to your work.
|
||||||
|
|
||||||
If you develop a new program, and you want it to be of the greatest
|
To apply the Apache License to your work, attach the following
|
||||||
possible use to the public, the best way to achieve this is to make it
|
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||||
free software which everyone can redistribute and change under these terms.
|
replaced with your own identifying information. (Don't include
|
||||||
|
the brackets!) The text should be enclosed in the appropriate
|
||||||
|
comment syntax for the file format. We also recommend that a
|
||||||
|
file or class name and description of purpose be included on the
|
||||||
|
same "printed page" as the copyright notice for easier
|
||||||
|
identification within third-party archives.
|
||||||
|
|
||||||
To do so, attach the following notices to the program. It is safest
|
Copyright [yyyy] [name of copyright owner]
|
||||||
to attach them to the start of each source file to most effectively
|
|
||||||
state the exclusion of warranty; and each file should have at least
|
|
||||||
the "copyright" line and a pointer to where the full notice is found.
|
|
||||||
|
|
||||||
<one line to give the program's name and a brief idea of what it does.>
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
Copyright (C) <year> <name of author>
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
Unless required by applicable law or agreed to in writing, software
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
GNU General Public License for more details.
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
Also add information on how to contact you by electronic and paper mail.
|
|
||||||
|
|
||||||
If the program does terminal interaction, make it output a short
|
|
||||||
notice like this when it starts in an interactive mode:
|
|
||||||
|
|
||||||
<program> Copyright (C) <year> <name of author>
|
|
||||||
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
|
||||||
This is free software, and you are welcome to redistribute it
|
|
||||||
under certain conditions; type `show c' for details.
|
|
||||||
|
|
||||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
|
||||||
parts of the General Public License. Of course, your program's commands
|
|
||||||
might be different; for a GUI interface, you would use an "about box".
|
|
||||||
|
|
||||||
You should also get your employer (if you work as a programmer) or school,
|
|
||||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
|
||||||
For more information on this, and how to apply and follow the GNU GPL, see
|
|
||||||
<http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
The GNU General Public License does not permit incorporating your program
|
|
||||||
into proprietary programs. If your program is a subroutine library, you
|
|
||||||
may consider it more useful to permit linking proprietary applications with
|
|
||||||
the library. If this is what you want to do, use the GNU Lesser General
|
|
||||||
Public License instead of this License. But first, please read
|
|
||||||
<http://www.gnu.org/philosophy/why-not-lgpl.html>.
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ performed are a "best effort" and as such, there could be false positives as wel
|
|||||||
vulnerabilities in 3rd party components is a well-known problem and is currently documented in the 2013 OWASP
|
vulnerabilities in 3rd party components is a well-known problem and is currently documented in the 2013 OWASP
|
||||||
Top 10 as [A9 - Using Components with Known Vulnerabilities](https://www.owasp.org/index.php/Top_10_2013-A9-Using_Components_with_Known_Vulnerabilities).
|
Top 10 as [A9 - Using Components with Known Vulnerabilities](https://www.owasp.org/index.php/Top_10_2013-A9-Using_Components_with_Known_Vulnerabilities).
|
||||||
|
|
||||||
Documentation and links to production binary releases can be found on the [github pages](http://jeremylong.github.io/DependencyCheck/dependency-check-cli/installation.html).
|
Documentation and links to production binary releases can be found on the [github pages](http://jeremylong.github.io/DependencyCheck/dependency-check-cli/index.html).
|
||||||
|
|
||||||
Mailing List
|
Mailing List
|
||||||
------------
|
------------
|
||||||
@@ -17,8 +17,8 @@ Post: [dependency-check@googlegroups.com](mailto:dependency-check@googlegroups.c
|
|||||||
Copyright & License
|
Copyright & License
|
||||||
------------
|
------------
|
||||||
|
|
||||||
Dependency-Check is Copyright (c) 2012-2013 Jeremy Long. All Rights Reserved.
|
Dependency-Check is Copyright (c) 2012-2014 Jeremy Long. All Rights Reserved.
|
||||||
|
|
||||||
Permission to modify and redistribute is granted under the terms of the GPLv3 license. See the [LICENSE.txt](https://github.com/jeremylong/DependencyCheck/dependency-check-cli/blob/master/LICENSE.txt) file for the full license.
|
Permission to modify and redistribute is granted under the terms of the Apache 2.0 license. See the [LICENSE.txt](https://raw.githubusercontent.com/jeremylong/DependencyCheck/master/LICENSE.txt) file for the full license.
|
||||||
|
|
||||||
Dependency-Check Command Line makes use of other open source libraries. Please see the [NOTICE.txt](https://github.com/jeremylong/DependencyCheck/dependency-check-cli/blob/master/NOTICES.txt) file for more information.
|
Dependency-Check Command Line makes use of other open source libraries. Please see the [NOTICE.txt](https://raw.githubusercontent.com/jeremylong/DependencyCheck/master/dependency-check-cli/NOTICE.txt) file for more information.
|
||||||
|
|||||||
@@ -1,223 +0,0 @@
|
|||||||
<?xml version="1.0"?>
|
|
||||||
<!DOCTYPE module PUBLIC
|
|
||||||
"-//Puppy Crawl//DTD Check Configuration 1.3//EN"
|
|
||||||
"http://www.puppycrawl.com/dtds/configuration_1_3.dtd">
|
|
||||||
|
|
||||||
<module name="Checker">
|
|
||||||
<!--
|
|
||||||
If you set the basedir property below, then all reported file
|
|
||||||
names will be relative to the specified directory. See
|
|
||||||
http://checkstyle.sourceforge.net/5.x/config.html#Checker
|
|
||||||
|
|
||||||
<property name="basedir" value="${basedir}"/>
|
|
||||||
-->
|
|
||||||
|
|
||||||
<property name="severity" value="error"/>
|
|
||||||
|
|
||||||
<module name="SuppressionFilter">
|
|
||||||
<property name="file" value="${checkstyle.suppressions.file}"/>
|
|
||||||
</module>
|
|
||||||
|
|
||||||
<module name="JavadocPackage">
|
|
||||||
<property name="allowLegacy" value="false"/>
|
|
||||||
</module>
|
|
||||||
|
|
||||||
<module name="Translation">
|
|
||||||
<property name="severity" value="warning"/>
|
|
||||||
</module>
|
|
||||||
|
|
||||||
<module name="FileTabCharacter">
|
|
||||||
<property name="eachLine" value="false"/>
|
|
||||||
</module>
|
|
||||||
|
|
||||||
<module name="FileLength">
|
|
||||||
<property name="fileExtensions" value="java"/>
|
|
||||||
</module>
|
|
||||||
|
|
||||||
<module name="NewlineAtEndOfFile">
|
|
||||||
<property name="fileExtensions" value="java"/>
|
|
||||||
<property name="lineSeparator" value="lf"/>
|
|
||||||
</module>
|
|
||||||
|
|
||||||
<module name="RegexpHeader">
|
|
||||||
<property name="headerFile" value="${checkstyle.header.file}"/>
|
|
||||||
<property name="fileExtensions" value="java"/>
|
|
||||||
<property name="id" value="header"/>
|
|
||||||
</module>
|
|
||||||
|
|
||||||
<module name="RegexpSingleline">
|
|
||||||
<property name="format" value="\s+$"/>
|
|
||||||
<property name="minimum" value="0"/>
|
|
||||||
<property name="maximum" value="0"/>
|
|
||||||
</module>
|
|
||||||
|
|
||||||
<module name="TreeWalker">
|
|
||||||
<property name="tabWidth" value="4"/>
|
|
||||||
|
|
||||||
<module name="AvoidStarImport"/>
|
|
||||||
<module name="ConstantName"/>
|
|
||||||
<module name="EmptyBlock"/>
|
|
||||||
<module name="EmptyForIteratorPad"/>
|
|
||||||
<module name="EqualsHashCode"/>
|
|
||||||
<module name="OneStatementPerLine"/>
|
|
||||||
|
|
||||||
<!-- module name="IllegalCatch"/ -->
|
|
||||||
<!--module name="ImportControl">
|
|
||||||
<property name="file" value="${checkstyle.importcontrol.file}"/>
|
|
||||||
</module-->
|
|
||||||
<module name="IllegalImport"/>
|
|
||||||
<module name="IllegalInstantiation"/>
|
|
||||||
<module name="IllegalThrows"/>
|
|
||||||
<module name="InnerAssignment"/>
|
|
||||||
<module name="JavadocType">
|
|
||||||
<property name="authorFormat" value="\S"/>
|
|
||||||
</module>
|
|
||||||
<module name="JavadocMethod">
|
|
||||||
<property name="allowUndeclaredRTE" value="true"/>
|
|
||||||
<property name="allowThrowsTagsForSubclasses" value="true"/>
|
|
||||||
<property name="allowMissingPropertyJavadoc" value="true"/>
|
|
||||||
</module>
|
|
||||||
<module name="JavadocVariable"/>
|
|
||||||
<module name="JavadocStyle">
|
|
||||||
<property name="scope" value="public"/>
|
|
||||||
</module>
|
|
||||||
|
|
||||||
<module name="LeftCurly">
|
|
||||||
<property name="option" value="eol"/>
|
|
||||||
<property name="tokens" value="CLASS_DEF"/>
|
|
||||||
<property name="tokens" value="CTOR_DEF"/>
|
|
||||||
<property name="tokens" value="INTERFACE_DEF"/>
|
|
||||||
<property name="tokens" value="METHOD_DEF"/>
|
|
||||||
<property name="tokens" value="LITERAL_CATCH"/>
|
|
||||||
<property name="tokens" value="LITERAL_DO"/>
|
|
||||||
<property name="tokens" value="LITERAL_ELSE"/>
|
|
||||||
<property name="tokens" value="LITERAL_FINALLY"/>
|
|
||||||
<property name="tokens" value="LITERAL_FOR"/>
|
|
||||||
<property name="tokens" value="LITERAL_IF"/>
|
|
||||||
<property name="tokens" value="LITERAL_SWITCH"/>
|
|
||||||
<property name="tokens" value="LITERAL_SYNCHRONIZED"/>
|
|
||||||
<property name="tokens" value="LITERAL_TRY"/>
|
|
||||||
<property name="tokens" value="LITERAL_WHILE"/>
|
|
||||||
</module>
|
|
||||||
|
|
||||||
<module name="OuterTypeNumber"/>
|
|
||||||
<module name="LineLength">
|
|
||||||
<property name="ignorePattern" value="^ *\* *[^ ]+$"/>
|
|
||||||
<property name="max" value="150"/>
|
|
||||||
</module>
|
|
||||||
|
|
||||||
<module name="MethodCount">
|
|
||||||
<property name="maxTotal" value="40"/>
|
|
||||||
</module>
|
|
||||||
|
|
||||||
<module name="LocalFinalVariableName"/>
|
|
||||||
<module name="LocalVariableName"/>
|
|
||||||
<module name="MemberName">
|
|
||||||
<property name="format" value="^[a-z][a-zA-Z0-9]*$"/>
|
|
||||||
</module>
|
|
||||||
<module name="MethodLength">
|
|
||||||
<property name="max" value="160"/>
|
|
||||||
<property name="countEmpty" value="false"/>
|
|
||||||
</module>
|
|
||||||
<module name="MethodName"/>
|
|
||||||
<module name="MethodParamPad"/>
|
|
||||||
<module name="ModifierOrder"/>
|
|
||||||
<module name="NeedBraces"/>
|
|
||||||
<module name="NoWhitespaceAfter">
|
|
||||||
<property name="tokens" value="ARRAY_INIT"/>
|
|
||||||
<property name="tokens" value="BNOT"/>
|
|
||||||
<property name="tokens" value="DEC"/>
|
|
||||||
<property name="tokens" value="DOT"/>
|
|
||||||
<property name="tokens" value="INC"/>
|
|
||||||
<property name="tokens" value="LNOT"/>
|
|
||||||
<property name="tokens" value="UNARY_MINUS"/>
|
|
||||||
<property name="tokens" value="UNARY_PLUS"/>
|
|
||||||
</module>
|
|
||||||
|
|
||||||
<module name="NoWhitespaceBefore"/>
|
|
||||||
<module name="NoWhitespaceBefore">
|
|
||||||
<property name="tokens" value="DOT"/>
|
|
||||||
<property name="allowLineBreaks" value="true"/>
|
|
||||||
</module>
|
|
||||||
|
|
||||||
<module name="OperatorWrap"/>
|
|
||||||
<module name="OperatorWrap">
|
|
||||||
<property name="tokens" value="ASSIGN"/>
|
|
||||||
<property name="tokens" value="DIV_ASSIGN"/>
|
|
||||||
<property name="tokens" value="PLUS_ASSIGN"/>
|
|
||||||
<property name="tokens" value="MINUS_ASSIGN"/>
|
|
||||||
<property name="tokens" value="STAR_ASSIGN"/>
|
|
||||||
<property name="tokens" value="MOD_ASSIGN"/>
|
|
||||||
<property name="tokens" value="SR_ASSIGN"/>
|
|
||||||
<property name="tokens" value="BSR_ASSIGN"/>
|
|
||||||
<property name="tokens" value="SL_ASSIGN"/>
|
|
||||||
<property name="tokens" value="BXOR_ASSIGN"/>
|
|
||||||
<property name="tokens" value="BOR_ASSIGN"/>
|
|
||||||
<property name="tokens" value="BAND_ASSIGN"/>
|
|
||||||
<property name="option" value="eol"/>
|
|
||||||
</module>
|
|
||||||
<module name="PackageName"/>
|
|
||||||
<module name="ParameterName">
|
|
||||||
<property name="format" value="^[a-z][a-zA-Z0-9]*$"/>
|
|
||||||
</module>
|
|
||||||
<module name="ParameterNumber">
|
|
||||||
<property name="id" value="paramNum"/>
|
|
||||||
</module>
|
|
||||||
<module name="ParenPad"/>
|
|
||||||
<module name="TypecastParenPad"/>
|
|
||||||
<module name="RedundantImport"/>
|
|
||||||
<module name="RedundantModifier"/>
|
|
||||||
<module name="RightCurly">
|
|
||||||
<property name="option" value="same"/>
|
|
||||||
</module>
|
|
||||||
<module name="SimplifyBooleanExpression"/>
|
|
||||||
<module name="SimplifyBooleanReturn"/>
|
|
||||||
<module name="StaticVariableName">
|
|
||||||
<property name="format" value="^[a-z][a-zA-Z0-9]*$"/>
|
|
||||||
</module>
|
|
||||||
<module name="TypeName"/>
|
|
||||||
<module name="UnusedImports"/>
|
|
||||||
<module name="UpperEll"/>
|
|
||||||
<module name="VisibilityModifier"/>
|
|
||||||
<module name="WhitespaceAfter"/>
|
|
||||||
<module name="WhitespaceAround"/>
|
|
||||||
<module name="GenericWhitespace"/>
|
|
||||||
<module name="FinalClass"/>
|
|
||||||
<module name="MissingSwitchDefault"/>
|
|
||||||
<!--module name="MagicNumber"/-->
|
|
||||||
<!--module name="Indentation">
|
|
||||||
<property name="basicOffset" value="4"/>
|
|
||||||
<property name="braceAdjustment" value="0"/>
|
|
||||||
<property name="caseIndent" value="0"/>
|
|
||||||
</module-->
|
|
||||||
<module name="ArrayTrailingComma"/>
|
|
||||||
<module name="FinalLocalVariable"/>
|
|
||||||
<module name="EqualsAvoidNull"/>
|
|
||||||
<module name="ParameterAssignment"/>
|
|
||||||
|
|
||||||
<!-- Generates quite a few errors -->
|
|
||||||
<module name="CyclomaticComplexity">
|
|
||||||
<property name="severity" value="ignore"/>
|
|
||||||
</module>
|
|
||||||
|
|
||||||
<module name="NestedForDepth">
|
|
||||||
<property name="max" value="2"/>
|
|
||||||
</module>
|
|
||||||
<module name="NestedIfDepth">
|
|
||||||
<property name="max" value="4"/>
|
|
||||||
</module>
|
|
||||||
<module name="NestedTryDepth">
|
|
||||||
<property name="max" value="2"/>
|
|
||||||
</module>
|
|
||||||
<!--module name="ExplicitInitialization"/-->
|
|
||||||
<module name="AnnotationUseStyle"/>
|
|
||||||
<module name="MissingDeprecated"/>
|
|
||||||
<module name="MissingOverride">
|
|
||||||
<property name="javaFiveCompatibility" value="true"/>
|
|
||||||
</module>
|
|
||||||
<module name="PackageAnnotation"/>
|
|
||||||
<module name="SuppressWarnings"/>
|
|
||||||
<module name="OuterTypeFilename"/>
|
|
||||||
<module name="HideUtilityClassConstructor"/>
|
|
||||||
</module>
|
|
||||||
</module>
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
^/\*\s*$
|
|
||||||
^ \* This file is part of dependency-check-cli\.\s*$
|
|
||||||
^ \*\s*$
|
|
||||||
^ \* Dependency-check-cli is free software\: you can redistribute it and/or modify it\s*$
|
|
||||||
^ \* under the terms of the GNU General Public License as published by the Free\s*$
|
|
||||||
^ \* Software Foundation, either version 3 of the License, or \(at your option\) any\s*$
|
|
||||||
^ \* later version\.
|
|
||||||
^ \*\s*$
|
|
||||||
^ \* Dependency-check-cli is distributed in the hope that it will be useful, but\s*$
|
|
||||||
^ \* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\s*$
|
|
||||||
^ \* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more\s*$
|
|
||||||
^ \* details\.\s*$
|
|
||||||
^ \*\s*$
|
|
||||||
^ \* You should have received a copy of the GNU General Public License along with\s*$
|
|
||||||
^ \* dependency-check-cli\. If not, see http://www.gnu.org/licenses/\.\s*$
|
|
||||||
^ \*\s*$
|
|
||||||
^ \* Copyright \(c\) 201[23] (Jeremy Long|Steve Springett)\. All Rights Reserved\.\s*$
|
|
||||||
^ \*/\s*$
|
|
||||||
^package
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
<?xml version="1.0"?>
|
|
||||||
|
|
||||||
<!DOCTYPE suppressions PUBLIC
|
|
||||||
"-//Puppy Crawl//DTD Suppressions 1.0//EN"
|
|
||||||
"http://www.puppycrawl.com/dtds/suppressions_1_0.dtd">
|
|
||||||
|
|
||||||
<suppressions>
|
|
||||||
<suppress checks=".*" files=".*[\\/]package-info\.java" />
|
|
||||||
</suppressions>
|
|
||||||
@@ -1,35 +1,33 @@
|
|||||||
<!--
|
<!--
|
||||||
This file is part of Dependency-Check.
|
This file is part of Dependency-Check.
|
||||||
|
|
||||||
Dependency-Check is free software: you can redistribute it and/or modify
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
it under the terms of the GNU General Public License as published by
|
you may not use this file except in compliance with the License.
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
You may obtain a copy of the License at
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
Dependency-Check is distributed in the hope that it will be useful,
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
Unless required by applicable law or agreed to in writing, software
|
||||||
along with Dependency-Check. If not, see <http://www.gnu.org/licenses />.
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
|
||||||
Copyright (c) 2012 - Jeremy Long. All Rights Reserved.
|
Copyright (c) 2012 - Jeremy Long. All Rights Reserved.
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>org.owasp</groupId>
|
<groupId>org.owasp</groupId>
|
||||||
<artifactId>dependency-check-parent</artifactId>
|
<artifactId>dependency-check-parent</artifactId>
|
||||||
<version>1.0.3</version>
|
<version>1.4.6-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>dependency-check-cli</artifactId>
|
<artifactId>dependency-check-cli</artifactId>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
<name>Dependency-Check Command Line</name>
|
<name>Dependency-Check Command Line</name>
|
||||||
<description>Dependency-Check-Maven is a Maven Plugin that attempts to detect publicly disclosed vulnerabilities contained within project dependencies. It does this by determining if there is a Common Platform Enumeration (CPE) identifier for a given dependency. If found, it will generate a report linking to the associated CVE entries.</description>
|
<description>dependency-check-cli is an command line tool that uses dependency-check-core to detect publicly disclosed vulnerabilities associated with the scanned project dependencies. The tool will generate a report listing the dependency, any identified Common Platform Enumeration (CPE) identifiers, and the associated Common Vulnerability and Exposure (CVE) entries.</description>
|
||||||
<!-- begin copy from http://minds.coremedia.com/2012/09/11/problem-solved-deploy-multi-module-maven-project-site-as-github-pages/ -->
|
<!-- begin copy from http://minds.coremedia.com/2012/09/11/problem-solved-deploy-multi-module-maven-project-site-as-github-pages/ -->
|
||||||
<distributionManagement>
|
<distributionManagement>
|
||||||
<site>
|
<site>
|
||||||
@@ -46,6 +44,7 @@ Copyright (c) 2012 - Jeremy Long. All Rights Reserved.
|
|||||||
<directory>src/main/resources</directory>
|
<directory>src/main/resources</directory>
|
||||||
<includes>
|
<includes>
|
||||||
<include>**/*.properties</include>
|
<include>**/*.properties</include>
|
||||||
|
<include>logback.xml</include>
|
||||||
</includes>
|
</includes>
|
||||||
<filtering>true</filtering>
|
<filtering>true</filtering>
|
||||||
</resource>
|
</resource>
|
||||||
@@ -62,24 +61,21 @@ Copyright (c) 2012 - Jeremy Long. All Rights Reserved.
|
|||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-jar-plugin</artifactId>
|
<artifactId>maven-jar-plugin</artifactId>
|
||||||
<version>2.4</version>
|
|
||||||
<configuration>
|
<configuration>
|
||||||
<archive>
|
<archive>
|
||||||
<manifest>
|
<manifest>
|
||||||
<mainClass>org.owasp.dependencycheck.App</mainClass>
|
<mainClass>org.owasp.dependencycheck.App</mainClass>
|
||||||
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
|
|
||||||
</manifest>
|
</manifest>
|
||||||
</archive>
|
</archive>
|
||||||
<excludes>
|
|
||||||
<exclude>**/checkstyle*</exclude>
|
|
||||||
</excludes>
|
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.codehaus.mojo</groupId>
|
<groupId>org.codehaus.mojo</groupId>
|
||||||
<artifactId>cobertura-maven-plugin</artifactId>
|
<artifactId>cobertura-maven-plugin</artifactId>
|
||||||
<version>2.5.2</version>
|
|
||||||
<configuration>
|
<configuration>
|
||||||
|
<!--instrumentation>
|
||||||
|
<ignoreTrivial>true</ignoreTrivial>
|
||||||
|
</instrumentation-->
|
||||||
<check>
|
<check>
|
||||||
<branchRate>85</branchRate>
|
<branchRate>85</branchRate>
|
||||||
<lineRate>85</lineRate>
|
<lineRate>85</lineRate>
|
||||||
@@ -113,14 +109,9 @@ Copyright (c) 2012 - Jeremy Long. All Rights Reserved.
|
|||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-surefire-plugin</artifactId>
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
<version>2.14</version>
|
|
||||||
<configuration>
|
<configuration>
|
||||||
|
<argLine>-Dfile.encoding=UTF-8</argLine>
|
||||||
<systemProperties>
|
<systemProperties>
|
||||||
<property>
|
|
||||||
<name>net.sourceforge.cobertura.datafile</name>
|
|
||||||
<value>${project.build.directory}/cobertura/cobertura.ser</value>
|
|
||||||
<workingDirectory>target</workingDirectory>
|
|
||||||
</property>
|
|
||||||
<property>
|
<property>
|
||||||
<name>cpe</name>
|
<name>cpe</name>
|
||||||
<value>data/cpe</value>
|
<value>data/cpe</value>
|
||||||
@@ -134,157 +125,14 @@ Copyright (c) 2012 - Jeremy Long. All Rights Reserved.
|
|||||||
</systemProperties>
|
</systemProperties>
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-compiler-plugin</artifactId>
|
|
||||||
<version>2.3.2</version>
|
|
||||||
<configuration>
|
|
||||||
<showDeprecation>false</showDeprecation>
|
|
||||||
</configuration>
|
|
||||||
</plugin>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-site-plugin</artifactId>
|
|
||||||
<version>3.3</version>
|
|
||||||
<dependencies>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.apache.maven.doxia</groupId>
|
|
||||||
<artifactId>doxia-module-markdown</artifactId>
|
|
||||||
<version>1.4</version>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
|
||||||
<configuration>
|
|
||||||
<skipDeploy>true</skipDeploy>
|
|
||||||
<reportPlugins>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-project-info-reports-plugin</artifactId>
|
|
||||||
<version>2.6</version>
|
|
||||||
<reportSets>
|
|
||||||
<reportSet>
|
|
||||||
<reports>
|
|
||||||
<report>index</report>
|
|
||||||
<report>summary</report>
|
|
||||||
<report>license</report>
|
|
||||||
<report>help</report>
|
|
||||||
</reports>
|
|
||||||
</reportSet>
|
|
||||||
</reportSets>
|
|
||||||
</plugin>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-javadoc-plugin</artifactId>
|
|
||||||
<version>2.9</version>
|
|
||||||
<reportSets>
|
|
||||||
<reportSet>
|
|
||||||
<id>default</id>
|
|
||||||
<reports>
|
|
||||||
<report>javadoc</report>
|
|
||||||
</reports>
|
|
||||||
</reportSet>
|
|
||||||
</reportSets>
|
|
||||||
</plugin>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.codehaus.mojo</groupId>
|
|
||||||
<artifactId>versions-maven-plugin</artifactId>
|
|
||||||
<version>2.0</version>
|
|
||||||
<reportSets>
|
|
||||||
<reportSet>
|
|
||||||
<reports>
|
|
||||||
<report>dependency-updates-report</report>
|
|
||||||
<report>plugin-updates-report</report>
|
|
||||||
</reports>
|
|
||||||
</reportSet>
|
|
||||||
</reportSets>
|
|
||||||
</plugin>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-jxr-plugin</artifactId>
|
|
||||||
<version>2.3</version>
|
|
||||||
</plugin>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.codehaus.mojo</groupId>
|
|
||||||
<artifactId>cobertura-maven-plugin</artifactId>
|
|
||||||
<version>2.5.2</version>
|
|
||||||
</plugin>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-surefire-report-plugin</artifactId>
|
|
||||||
<version>2.14</version>
|
|
||||||
<reportSets>
|
|
||||||
<reportSet>
|
|
||||||
<reports>
|
|
||||||
<report>report-only</report>
|
|
||||||
</reports>
|
|
||||||
</reportSet>
|
|
||||||
</reportSets>
|
|
||||||
</plugin>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.codehaus.mojo</groupId>
|
|
||||||
<artifactId>taglist-maven-plugin</artifactId>
|
|
||||||
<version>2.4</version>
|
|
||||||
<configuration>
|
|
||||||
<tagListOptions>
|
|
||||||
<tagClasses>
|
|
||||||
<tagClass>
|
|
||||||
<displayName>Todo Work</displayName>
|
|
||||||
<tags>
|
|
||||||
<tag>
|
|
||||||
<matchString>todo</matchString>
|
|
||||||
<matchType>ignoreCase</matchType>
|
|
||||||
</tag>
|
|
||||||
<tag>
|
|
||||||
<matchString>FIXME</matchString>
|
|
||||||
<matchType>exact</matchType>
|
|
||||||
</tag>
|
|
||||||
</tags>
|
|
||||||
</tagClass>
|
|
||||||
</tagClasses>
|
|
||||||
</tagListOptions>
|
|
||||||
</configuration>
|
|
||||||
</plugin>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-checkstyle-plugin</artifactId>
|
|
||||||
<version>2.10</version>
|
|
||||||
<configuration>
|
|
||||||
<enableRulesSummary>false</enableRulesSummary>
|
|
||||||
<configLocation>${basedir}/config/checkstyle-checks.xml</configLocation>
|
|
||||||
<headerLocation>${basedir}/config/checkstyle-header.txt</headerLocation>
|
|
||||||
<suppressionsLocation>${basedir}/config/checkstyle-suppressions.xml</suppressionsLocation>
|
|
||||||
<suppressionsFileExpression>checkstyle.suppressions.file</suppressionsFileExpression>
|
|
||||||
</configuration>
|
|
||||||
</plugin>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-pmd-plugin</artifactId>
|
|
||||||
<version>3.0.1</version>
|
|
||||||
<configuration>
|
|
||||||
<targetJdk>1.6</targetJdk>
|
|
||||||
<linkXref>true</linkXref>
|
|
||||||
<sourceEncoding>utf-8</sourceEncoding>
|
|
||||||
<excludes>
|
|
||||||
<exclude>**/generated/*.java</exclude>
|
|
||||||
</excludes>
|
|
||||||
</configuration>
|
|
||||||
</plugin>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.codehaus.mojo</groupId>
|
|
||||||
<artifactId>findbugs-maven-plugin</artifactId>
|
|
||||||
<version>2.5.2</version>
|
|
||||||
</plugin>
|
|
||||||
</reportPlugins>
|
|
||||||
</configuration>
|
|
||||||
</plugin>
|
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.codehaus.mojo</groupId>
|
<groupId>org.codehaus.mojo</groupId>
|
||||||
<artifactId>appassembler-maven-plugin</artifactId>
|
<artifactId>appassembler-maven-plugin</artifactId>
|
||||||
<version>1.4</version>
|
|
||||||
<configuration>
|
<configuration>
|
||||||
<programs>
|
<programs>
|
||||||
<program>
|
<program>
|
||||||
<mainClass>org.owasp.dependencycheck.App</mainClass>
|
<mainClass>org.owasp.dependencycheck.App</mainClass>
|
||||||
<name>dependency-check</name>
|
<id>dependency-check</id>
|
||||||
</program>
|
</program>
|
||||||
</programs>
|
</programs>
|
||||||
<assembleDirectory>${project.build.directory}/release</assembleDirectory>
|
<assembleDirectory>${project.build.directory}/release</assembleDirectory>
|
||||||
@@ -292,6 +140,8 @@ Copyright (c) 2012 - Jeremy Long. All Rights Reserved.
|
|||||||
<binFileExtensions>
|
<binFileExtensions>
|
||||||
<unix>.sh</unix>
|
<unix>.sh</unix>
|
||||||
</binFileExtensions>
|
</binFileExtensions>
|
||||||
|
<configurationDirectory>plugins/*</configurationDirectory>
|
||||||
|
<includeConfigurationDirectoryInClasspath>true</includeConfigurationDirectoryInClasspath>
|
||||||
</configuration>
|
</configuration>
|
||||||
<executions>
|
<executions>
|
||||||
<execution>
|
<execution>
|
||||||
@@ -325,16 +175,78 @@ Copyright (c) 2012 - Jeremy Long. All Rights Reserved.
|
|||||||
</plugin>
|
</plugin>
|
||||||
</plugins>
|
</plugins>
|
||||||
</build>
|
</build>
|
||||||
|
<reporting>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-checkstyle-plugin</artifactId>
|
||||||
|
<version>${reporting.checkstyle-plugin.version}</version>
|
||||||
|
<configuration>
|
||||||
|
<enableRulesSummary>false</enableRulesSummary>
|
||||||
|
<enableFilesSummary>false</enableFilesSummary>
|
||||||
|
<configLocation>${basedir}/../src/main/config/checkstyle-checks.xml</configLocation>
|
||||||
|
<headerLocation>${basedir}/../src/main/config/checkstyle-header.txt</headerLocation>
|
||||||
|
<suppressionsLocation>${basedir}/../src/main/config/checkstyle-suppressions.xml</suppressionsLocation>
|
||||||
|
<suppressionsFileExpression>checkstyle.suppressions.file</suppressionsFileExpression>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-pmd-plugin</artifactId>
|
||||||
|
<version>${reporting.pmd-plugin.version}</version>
|
||||||
|
<configuration>
|
||||||
|
<targetJdk>1.6</targetJdk>
|
||||||
|
<linkXRef>true</linkXRef>
|
||||||
|
<sourceEncoding>utf-8</sourceEncoding>
|
||||||
|
<excludes>
|
||||||
|
<exclude>**/generated/*.java</exclude>
|
||||||
|
</excludes>
|
||||||
|
<rulesets>
|
||||||
|
<ruleset>../src/main/config/dcrules.xml</ruleset>
|
||||||
|
<ruleset>/rulesets/java/basic.xml</ruleset>
|
||||||
|
<ruleset>/rulesets/java/imports.xml</ruleset>
|
||||||
|
<ruleset>/rulesets/java/unusedcode.xml</ruleset>
|
||||||
|
</rulesets>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</reporting>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>commons-cli</groupId>
|
<groupId>commons-cli</groupId>
|
||||||
<artifactId>commons-cli</artifactId>
|
<artifactId>commons-cli</artifactId>
|
||||||
<version>1.2</version>
|
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.owasp</groupId>
|
<groupId>org.owasp</groupId>
|
||||||
<artifactId>dependency-check-core</artifactId>
|
<artifactId>dependency-check-core</artifactId>
|
||||||
<version>${project.parent.version}</version>
|
<version>${project.parent.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.owasp</groupId>
|
||||||
|
<artifactId>dependency-check-utils</artifactId>
|
||||||
|
<version>${project.parent.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.slf4j</groupId>
|
||||||
|
<artifactId>slf4j-api</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>ch.qos.logback</groupId>
|
||||||
|
<artifactId>logback-core</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>ch.qos.logback</groupId>
|
||||||
|
<artifactId>logback-classic</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.ant</groupId>
|
||||||
|
<artifactId>ant</artifactId>
|
||||||
|
<exclusions>
|
||||||
|
<exclusion>
|
||||||
|
<groupId>org.apache.ant</groupId>
|
||||||
|
<artifactId>ant-launcher</artifactId>
|
||||||
|
</exclusion>
|
||||||
|
</exclusions>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</project>
|
</project>
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
|
|
||||||
Copyright (c) 2012-2013 Jeremy Long. All rights reserved.
|
Copyright (c) 2012-2013 Jeremy Long. All rights reserved.
|
||||||
|
|
||||||
Licensed under the GPL License, Version 3; you may not use this work
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
except in compliance with the License. You may obtain a copy of the
|
you may not use this file except in compliance with the License.
|
||||||
License in the LICENSE.txt file, or at:
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
http://www.gnu.org/licenses/gpl-3.0.txt
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
Unless required by applicable law or agreed to in writing, software
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
|||||||
@@ -2,11 +2,8 @@
|
|||||||
<assembly
|
<assembly
|
||||||
xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"
|
xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
xsi:schemaLocation="
|
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2
|
||||||
http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2
|
http://maven.apache.org/xsd/assembly-1.1.2.xsd">
|
||||||
http://maven.apache.org/xsd/assembly-1.1.2.xsd
|
|
||||||
"
|
|
||||||
>
|
|
||||||
<id>release</id>
|
<id>release</id>
|
||||||
<formats>
|
<formats>
|
||||||
<format>zip</format>
|
<format>zip</format>
|
||||||
@@ -14,25 +11,48 @@
|
|||||||
<includeBaseDirectory>false</includeBaseDirectory>
|
<includeBaseDirectory>false</includeBaseDirectory>
|
||||||
<fileSets>
|
<fileSets>
|
||||||
<fileSet>
|
<fileSet>
|
||||||
<outputDirectory>/</outputDirectory>
|
<outputDirectory>dependency-check/bin</outputDirectory>
|
||||||
<directory>${project.build.directory}/release</directory>
|
<directory>${project.build.directory}/release/bin</directory>
|
||||||
|
<includes>
|
||||||
|
<include>*.sh</include>
|
||||||
|
</includes>
|
||||||
|
<fileMode>0755</fileMode>
|
||||||
</fileSet>
|
</fileSet>
|
||||||
<fileSet>
|
<fileSet>
|
||||||
|
<outputDirectory>dependency-check/bin</outputDirectory>
|
||||||
|
<directory>${project.build.directory}/release/bin</directory>
|
||||||
|
<includes>
|
||||||
|
<include>*.bat</include>
|
||||||
|
</includes>
|
||||||
|
</fileSet>
|
||||||
|
<fileSet>
|
||||||
|
<outputDirectory>dependency-check/repo</outputDirectory>
|
||||||
|
<directory>${project.build.directory}/release/repo</directory>
|
||||||
|
</fileSet>
|
||||||
|
<fileSet>
|
||||||
|
<directory>.</directory>
|
||||||
|
<outputDirectory>dependency-check/plugins</outputDirectory>
|
||||||
|
<excludes>
|
||||||
|
<exclude>*/**</exclude>
|
||||||
|
</excludes>
|
||||||
|
</fileSet>
|
||||||
|
<fileSet>
|
||||||
|
<outputDirectory>dependency-check</outputDirectory>
|
||||||
<includes>
|
<includes>
|
||||||
<include>LICENSE*</include>
|
<include>LICENSE*</include>
|
||||||
<include>NOTICE*</include>
|
<include>NOTICE*</include>
|
||||||
</includes>
|
</includes>
|
||||||
</fileSet>
|
</fileSet>
|
||||||
<fileSet>
|
<fileSet>
|
||||||
<outputDirectory>licenses</outputDirectory>
|
<outputDirectory>dependency-check/licenses</outputDirectory>
|
||||||
<directory>${basedir}/src/main/resources/META-INF/licenses</directory>
|
<directory>${basedir}/src/main/resources/META-INF/licenses</directory>
|
||||||
</fileSet>
|
</fileSet>
|
||||||
<fileSet>
|
<fileSet>
|
||||||
<outputDirectory>licenses</outputDirectory>
|
<outputDirectory>dependency-check/licenses</outputDirectory>
|
||||||
<directory>${basedir}/../dependency-check-core/src/main/resources/META-INF/licenses</directory>
|
<directory>${basedir}/../dependency-check-core/src/main/resources/META-INF/licenses</directory>
|
||||||
</fileSet>
|
</fileSet>
|
||||||
<fileSet>
|
<fileSet>
|
||||||
<outputDirectory>/</outputDirectory>
|
<outputDirectory>dependency-check</outputDirectory>
|
||||||
<directory>${basedir}</directory>
|
<directory>${basedir}</directory>
|
||||||
<includes>
|
<includes>
|
||||||
<include>README.md</include>
|
<include>README.md</include>
|
||||||
@@ -40,21 +60,4 @@
|
|||||||
</includes>
|
</includes>
|
||||||
</fileSet>
|
</fileSet>
|
||||||
</fileSets>
|
</fileSets>
|
||||||
<!--
|
|
||||||
<fileSets>
|
|
||||||
<fileSet>
|
|
||||||
<outputDirectory>/</outputDirectory>
|
|
||||||
<directory>${project.build.directory}</directory>
|
|
||||||
<includes>
|
|
||||||
<include>dependency-check*.jar</include>
|
|
||||||
</includes>
|
|
||||||
</fileSet>
|
|
||||||
</fileSets>
|
|
||||||
<dependencySets>
|
|
||||||
<dependencySet>
|
|
||||||
<outputDirectory>/lib</outputDirectory>
|
|
||||||
<scope>runtime</scope>
|
|
||||||
</dependencySet>
|
|
||||||
</dependencySets>
|
|
||||||
-->
|
|
||||||
</assembly>
|
</assembly>
|
||||||
@@ -1,65 +1,61 @@
|
|||||||
/*
|
/*
|
||||||
* This file is part of dependency-check-cli.
|
* This file is part of dependency-check-cli.
|
||||||
*
|
*
|
||||||
* Dependency-check-cli is free software: you can redistribute it and/or modify it
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* under the terms of the GNU General Public License as published by the Free
|
* you may not use this file except in compliance with the License.
|
||||||
* Software Foundation, either version 3 of the License, or (at your option) any
|
* You may obtain a copy of the License at
|
||||||
* later version.
|
|
||||||
*
|
*
|
||||||
* Dependency-check-cli is distributed in the hope that it will be useful, but
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
|
||||||
* details.
|
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License along with
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* dependency-check-cli. If not, see http://www.gnu.org/licenses/.
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
*
|
*
|
||||||
* Copyright (c) 2012 Jeremy Long. All Rights Reserved.
|
* Copyright (c) 2012 Jeremy Long. All Rights Reserved.
|
||||||
*/
|
*/
|
||||||
package org.owasp.dependencycheck;
|
package org.owasp.dependencycheck;
|
||||||
|
|
||||||
|
import ch.qos.logback.classic.LoggerContext;
|
||||||
|
import ch.qos.logback.classic.encoder.PatternLayoutEncoder;
|
||||||
|
import ch.qos.logback.classic.spi.ILoggingEvent;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.logging.Level;
|
import java.util.Set;
|
||||||
import java.util.logging.LogManager;
|
|
||||||
import java.util.logging.Logger;
|
|
||||||
import org.apache.commons.cli.ParseException;
|
import org.apache.commons.cli.ParseException;
|
||||||
import org.owasp.dependencycheck.reporting.ReportGenerator;
|
import org.owasp.dependencycheck.data.nvdcve.CveDB;
|
||||||
|
import org.owasp.dependencycheck.data.nvdcve.DatabaseException;
|
||||||
|
import org.owasp.dependencycheck.data.nvdcve.DatabaseProperties;
|
||||||
import org.owasp.dependencycheck.dependency.Dependency;
|
import org.owasp.dependencycheck.dependency.Dependency;
|
||||||
import org.owasp.dependencycheck.cli.CliParser;
|
import org.apache.tools.ant.DirectoryScanner;
|
||||||
|
import org.owasp.dependencycheck.dependency.Vulnerability;
|
||||||
|
import org.owasp.dependencycheck.reporting.ReportGenerator;
|
||||||
import org.owasp.dependencycheck.utils.Settings;
|
import org.owasp.dependencycheck.utils.Settings;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import ch.qos.logback.core.FileAppender;
|
||||||
|
import org.owasp.dependencycheck.data.update.exception.UpdateException;
|
||||||
|
import org.owasp.dependencycheck.exception.ExceptionCollection;
|
||||||
|
import org.owasp.dependencycheck.exception.ReportException;
|
||||||
|
import org.owasp.dependencycheck.utils.InvalidSettingException;
|
||||||
|
import org.slf4j.impl.StaticLoggerBinder;
|
||||||
|
|
||||||
/*
|
|
||||||
* This file is part of App.
|
|
||||||
*
|
|
||||||
* App is free software: you can redistribute it and/or modify it under the
|
|
||||||
* terms of the GNU General Public License as published by the Free Software
|
|
||||||
* Foundation, either version 3 of the License, or (at your option) any later
|
|
||||||
* version.
|
|
||||||
*
|
|
||||||
* App is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
||||||
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
|
||||||
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License along with
|
|
||||||
* App. If not, see http://www.gnu.org/licenses/.
|
|
||||||
*
|
|
||||||
* Copyright (c) 2012 Jeremy Long. All Rights Reserved.
|
|
||||||
*/
|
|
||||||
/**
|
/**
|
||||||
* The command line interface for the DependencyCheck application.
|
* The command line interface for the DependencyCheck application.
|
||||||
*
|
*
|
||||||
* @author Jeremy Long (jeremy.long@owasp.org)
|
* @author Jeremy Long
|
||||||
*/
|
*/
|
||||||
public class App {
|
public class App {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The location of the log properties configuration file.
|
* The logger.
|
||||||
*/
|
*/
|
||||||
private static final String LOG_PROPERTIES_FILE = "log.properties";
|
private static final Logger LOGGER = LoggerFactory.getLogger(App.class);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The main method for the application.
|
* The main method for the application.
|
||||||
@@ -67,63 +63,134 @@ public class App {
|
|||||||
* @param args the command line arguments
|
* @param args the command line arguments
|
||||||
*/
|
*/
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
prepareLogger();
|
int exitCode = 0;
|
||||||
|
try {
|
||||||
|
Settings.initialize();
|
||||||
final App app = new App();
|
final App app = new App();
|
||||||
app.run(args);
|
exitCode = app.run(args);
|
||||||
}
|
LOGGER.debug("Exit code: " + exitCode);
|
||||||
|
|
||||||
/**
|
|
||||||
* Configures the logger for use by the application.
|
|
||||||
*/
|
|
||||||
private static void prepareLogger() {
|
|
||||||
InputStream in = null;
|
|
||||||
try {
|
|
||||||
in = App.class.getClassLoader().getResourceAsStream(LOG_PROPERTIES_FILE);
|
|
||||||
LogManager.getLogManager().reset();
|
|
||||||
LogManager.getLogManager().readConfiguration(in);
|
|
||||||
} catch (IOException ex) {
|
|
||||||
Logger.getLogger(App.class.getName()).log(Level.FINE, "IO Error preparing the logger", ex);
|
|
||||||
} catch (SecurityException ex) {
|
|
||||||
Logger.getLogger(App.class.getName()).log(Level.FINE, "Error preparing the logger", ex);
|
|
||||||
} finally {
|
} finally {
|
||||||
if (in != null) {
|
Settings.cleanup(true);
|
||||||
try {
|
|
||||||
in.close();
|
|
||||||
} catch (Exception ex) {
|
|
||||||
Logger.getLogger(App.class.getName()).log(Level.FINEST, "Error closing resource stream", ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
System.exit(exitCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Main CLI entry-point into the application.
|
* Main CLI entry-point into the application.
|
||||||
*
|
*
|
||||||
* @param args the command line arguments
|
* @param args the command line arguments
|
||||||
|
* @return the exit code to return
|
||||||
*/
|
*/
|
||||||
public void run(String[] args) {
|
public int run(String[] args) {
|
||||||
|
int exitCode = 0;
|
||||||
final CliParser cli = new CliParser();
|
final CliParser cli = new CliParser();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
cli.parse(args);
|
cli.parse(args);
|
||||||
} catch (FileNotFoundException ex) {
|
} catch (FileNotFoundException ex) {
|
||||||
System.err.println(ex.getMessage());
|
System.err.println(ex.getMessage());
|
||||||
cli.printHelp();
|
cli.printHelp();
|
||||||
return;
|
return -1;
|
||||||
} catch (ParseException ex) {
|
} catch (ParseException ex) {
|
||||||
System.err.println(ex.getMessage());
|
System.err.println(ex.getMessage());
|
||||||
cli.printHelp();
|
cli.printHelp();
|
||||||
return;
|
return -2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cli.isGetVersion()) {
|
if (cli.getVerboseLog() != null) {
|
||||||
|
prepareLogger(cli.getVerboseLog());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cli.isPurge()) {
|
||||||
|
if (cli.getConnectionString() != null) {
|
||||||
|
LOGGER.error("Unable to purge the database when using a non-default connection string");
|
||||||
|
exitCode = -3;
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
populateSettings(cli);
|
||||||
|
} catch (InvalidSettingException ex) {
|
||||||
|
LOGGER.error(ex.getMessage());
|
||||||
|
LOGGER.debug("Error loading properties file", ex);
|
||||||
|
exitCode = -4;
|
||||||
|
}
|
||||||
|
File db;
|
||||||
|
try {
|
||||||
|
db = new File(Settings.getDataDirectory(), "dc.h2.db");
|
||||||
|
if (db.exists()) {
|
||||||
|
if (db.delete()) {
|
||||||
|
LOGGER.info("Database file purged; local copy of the NVD has been removed");
|
||||||
|
} else {
|
||||||
|
LOGGER.error("Unable to delete '{}'; please delete the file manually", db.getAbsolutePath());
|
||||||
|
exitCode = -5;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
LOGGER.error("Unable to purge database; the database file does not exists: {}", db.getAbsolutePath());
|
||||||
|
exitCode = -6;
|
||||||
|
}
|
||||||
|
} catch (IOException ex) {
|
||||||
|
LOGGER.error("Unable to delete the database");
|
||||||
|
exitCode = -7;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (cli.isGetVersion()) {
|
||||||
cli.printVersionInfo();
|
cli.printVersionInfo();
|
||||||
|
} else if (cli.isUpdateOnly()) {
|
||||||
|
try {
|
||||||
|
populateSettings(cli);
|
||||||
|
} catch (InvalidSettingException ex) {
|
||||||
|
LOGGER.error(ex.getMessage());
|
||||||
|
LOGGER.debug("Error loading properties file", ex);
|
||||||
|
exitCode = -4;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
runUpdateOnly();
|
||||||
|
} catch (UpdateException ex) {
|
||||||
|
LOGGER.error(ex.getMessage());
|
||||||
|
exitCode = -8;
|
||||||
|
} catch (DatabaseException ex) {
|
||||||
|
LOGGER.error(ex.getMessage());
|
||||||
|
exitCode = -9;
|
||||||
|
}
|
||||||
} else if (cli.isRunScan()) {
|
} else if (cli.isRunScan()) {
|
||||||
updateSettings(cli.isAutoUpdate(), cli.getConnectionTimeout(), cli.getProxyUrl(), cli.getProxyPort(), cli.getDataDirectory());
|
try {
|
||||||
runScan(cli.getReportDirectory(), cli.getReportFormat(), cli.getApplicationName(), cli.getScanFiles());
|
populateSettings(cli);
|
||||||
|
} catch (InvalidSettingException ex) {
|
||||||
|
LOGGER.error(ex.getMessage());
|
||||||
|
LOGGER.debug("Error loading properties file", ex);
|
||||||
|
exitCode = -4;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
final String[] scanFiles = cli.getScanFiles();
|
||||||
|
if (scanFiles != null) {
|
||||||
|
exitCode = runScan(cli.getReportDirectory(), cli.getReportFormat(), cli.getProjectName(), scanFiles,
|
||||||
|
cli.getExcludeList(), cli.getSymLinkDepth(), cli.getFailOnCVSS());
|
||||||
|
} else {
|
||||||
|
LOGGER.error("No scan files configured");
|
||||||
|
}
|
||||||
|
} catch (InvalidScanPathException ex) {
|
||||||
|
LOGGER.error("An invalid scan path was detected; unable to scan '//*' paths");
|
||||||
|
exitCode = -10;
|
||||||
|
} catch (DatabaseException ex) {
|
||||||
|
LOGGER.error(ex.getMessage());
|
||||||
|
exitCode = -11;
|
||||||
|
} catch (ReportException ex) {
|
||||||
|
LOGGER.error(ex.getMessage());
|
||||||
|
exitCode = -12;
|
||||||
|
} catch (ExceptionCollection ex) {
|
||||||
|
if (ex.isFatal()) {
|
||||||
|
exitCode = -13;
|
||||||
|
LOGGER.error("One or more fatal errors occurred");
|
||||||
|
} else {
|
||||||
|
exitCode = -14;
|
||||||
|
}
|
||||||
|
for (Throwable e : ex.getExceptions()) {
|
||||||
|
LOGGER.error(e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
cli.printHelp();
|
cli.printHelp();
|
||||||
}
|
}
|
||||||
|
return exitCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -135,41 +202,196 @@ public class App {
|
|||||||
* @param outputFormat the output format of the report
|
* @param outputFormat the output format of the report
|
||||||
* @param applicationName the application name for the report
|
* @param applicationName the application name for the report
|
||||||
* @param files the files/directories to scan
|
* @param files the files/directories to scan
|
||||||
|
* @param excludes the patterns for files/directories to exclude
|
||||||
|
* @param symLinkDepth the depth that symbolic links will be followed
|
||||||
|
* @param cvssFailScore the score to fail on if a vulnerability is found
|
||||||
|
* @return the exit code if there was an error
|
||||||
|
*
|
||||||
|
* @throws InvalidScanPathException thrown if the path to scan starts with
|
||||||
|
* "//"
|
||||||
|
* @throws ReportException thrown when the report cannot be generated
|
||||||
|
* @throws DatabaseException thrown when there is an error connecting to the
|
||||||
|
* database
|
||||||
|
* @throws ExceptionCollection thrown when an exception occurs during
|
||||||
|
* analysis; there may be multiple exceptions contained within the
|
||||||
|
* collection.
|
||||||
*/
|
*/
|
||||||
private void runScan(String reportDirectory, String outputFormat, String applicationName, String[] files) {
|
private int runScan(String reportDirectory, String outputFormat, String applicationName, String[] files,
|
||||||
final Engine scanner = new Engine();
|
String[] excludes, int symLinkDepth, int cvssFailScore) throws InvalidScanPathException, DatabaseException,
|
||||||
|
ExceptionCollection, ReportException {
|
||||||
|
Engine engine = null;
|
||||||
|
int retCode = 0;
|
||||||
|
try {
|
||||||
|
engine = new Engine();
|
||||||
|
final List<String> antStylePaths = new ArrayList<>();
|
||||||
for (String file : files) {
|
for (String file : files) {
|
||||||
scanner.scan(file);
|
final String antPath = ensureCanonicalPath(file);
|
||||||
|
antStylePaths.add(antPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
scanner.analyzeDependencies();
|
final Set<File> paths = new HashSet<>();
|
||||||
final List<Dependency> dependencies = scanner.getDependencies();
|
for (String file : antStylePaths) {
|
||||||
|
LOGGER.debug("Scanning {}", file);
|
||||||
|
final DirectoryScanner scanner = new DirectoryScanner();
|
||||||
|
String include = file.replace('\\', '/');
|
||||||
|
File baseDir;
|
||||||
|
|
||||||
|
if (include.startsWith("//")) {
|
||||||
|
throw new InvalidScanPathException("Unable to scan paths specified by //");
|
||||||
|
} else {
|
||||||
|
final int pos = getLastFileSeparator(include);
|
||||||
|
final String tmpBase = include.substring(0, pos);
|
||||||
|
final String tmpInclude = include.substring(pos + 1);
|
||||||
|
if (tmpInclude.indexOf('*') >= 0 || tmpInclude.indexOf('?') >= 0
|
||||||
|
|| (new File(include)).isFile()) {
|
||||||
|
baseDir = new File(tmpBase);
|
||||||
|
include = tmpInclude;
|
||||||
|
} else {
|
||||||
|
baseDir = new File(tmpBase, tmpInclude);
|
||||||
|
include = "**/*";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
scanner.setBasedir(baseDir);
|
||||||
|
final String[] includes = {include};
|
||||||
|
scanner.setIncludes(includes);
|
||||||
|
scanner.setMaxLevelsOfSymlinks(symLinkDepth);
|
||||||
|
if (symLinkDepth <= 0) {
|
||||||
|
scanner.setFollowSymlinks(false);
|
||||||
|
}
|
||||||
|
if (excludes != null && excludes.length > 0) {
|
||||||
|
scanner.addExcludes(excludes);
|
||||||
|
}
|
||||||
|
scanner.scan();
|
||||||
|
if (scanner.getIncludedFilesCount() > 0) {
|
||||||
|
for (String s : scanner.getIncludedFiles()) {
|
||||||
|
final File f = new File(baseDir, s);
|
||||||
|
LOGGER.debug("Found file {}", f.toString());
|
||||||
|
paths.add(f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
engine.scan(paths);
|
||||||
|
|
||||||
|
ExceptionCollection exCol = null;
|
||||||
|
try {
|
||||||
|
engine.analyzeDependencies();
|
||||||
|
} catch (ExceptionCollection ex) {
|
||||||
|
if (ex.isFatal()) {
|
||||||
|
throw ex;
|
||||||
|
}
|
||||||
|
exCol = ex;
|
||||||
|
}
|
||||||
|
final List<Dependency> dependencies = engine.getDependencies();
|
||||||
|
DatabaseProperties prop = null;
|
||||||
|
try (CveDB cve = CveDB.getInstance()) {
|
||||||
|
prop = cve.getDatabaseProperties();
|
||||||
|
} catch (DatabaseException ex) {
|
||||||
|
//TODO shouldn't this be a fatal exception
|
||||||
|
LOGGER.debug("Unable to retrieve DB Properties", ex);
|
||||||
|
}
|
||||||
|
final ReportGenerator report = new ReportGenerator(applicationName, dependencies, engine.getAnalyzers(), prop);
|
||||||
|
|
||||||
final ReportGenerator report = new ReportGenerator(applicationName, dependencies, scanner.getAnalyzers());
|
|
||||||
try {
|
try {
|
||||||
report.generateReports(reportDirectory, outputFormat);
|
report.generateReports(reportDirectory, outputFormat);
|
||||||
} catch (IOException ex) {
|
} catch (ReportException ex) {
|
||||||
Logger.getLogger(App.class.getName()).log(Level.SEVERE, "There was an IO error while attempting to generate the report.");
|
if (exCol != null) {
|
||||||
Logger.getLogger(App.class.getName()).log(Level.INFO, null, ex);
|
exCol.addException(ex);
|
||||||
} catch (Exception ex) {
|
throw exCol;
|
||||||
Logger.getLogger(App.class.getName()).log(Level.SEVERE, "There was an error while attempting to generate the report.");
|
} else {
|
||||||
Logger.getLogger(App.class.getName()).log(Level.INFO, null, ex);
|
throw ex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (exCol != null && exCol.getExceptions().size() > 0) {
|
||||||
|
throw exCol;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Set the exit code based on whether we found a high enough vulnerability
|
||||||
|
for (Dependency dep : dependencies) {
|
||||||
|
if (!dep.getVulnerabilities().isEmpty()) {
|
||||||
|
for (Vulnerability vuln : dep.getVulnerabilities()) {
|
||||||
|
LOGGER.debug("VULNERABILITY FOUND " + dep.getDisplayFileName());
|
||||||
|
if (vuln.getCvssScore() > cvssFailScore) {
|
||||||
|
retCode = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return retCode;
|
||||||
|
} finally {
|
||||||
|
if (engine != null) {
|
||||||
|
engine.cleanup();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Only executes the update phase of dependency-check.
|
||||||
|
*
|
||||||
|
* @throws UpdateException thrown if there is an error updating
|
||||||
|
* @throws DatabaseException thrown if a fatal error occurred and a
|
||||||
|
* connection to the database could not be established
|
||||||
|
*/
|
||||||
|
private void runUpdateOnly() throws UpdateException, DatabaseException {
|
||||||
|
Engine engine = null;
|
||||||
|
try {
|
||||||
|
engine = new Engine();
|
||||||
|
engine.doUpdates();
|
||||||
|
} finally {
|
||||||
|
if (engine != null) {
|
||||||
|
engine.cleanup();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates the global Settings.
|
* Updates the global Settings.
|
||||||
*
|
*
|
||||||
* @param autoUpdate whether or not to update cached web data sources
|
* @param cli a reference to the CLI Parser that contains the command line
|
||||||
* @param connectionTimeout the timeout to use when downloading resources
|
* arguments used to set the corresponding settings in the core engine.
|
||||||
* (null or blank will use default)
|
*
|
||||||
* @param proxyUrl the proxy url (null or blank means no proxy will be used)
|
* @throws InvalidSettingException thrown when a user defined properties
|
||||||
* @param proxyPort the proxy port (null or blank means no port will be
|
* file is unable to be loaded.
|
||||||
* used)
|
|
||||||
* @param dataDirectory the directory to store/retrieve persistent data from
|
|
||||||
*/
|
*/
|
||||||
private void updateSettings(boolean autoUpdate, String connectionTimeout, String proxyUrl, String proxyPort, String dataDirectory) {
|
private void populateSettings(CliParser cli) throws InvalidSettingException {
|
||||||
|
final boolean autoUpdate = cli.isAutoUpdate();
|
||||||
|
final String connectionTimeout = cli.getConnectionTimeout();
|
||||||
|
final String proxyServer = cli.getProxyServer();
|
||||||
|
final String proxyPort = cli.getProxyPort();
|
||||||
|
final String proxyUser = cli.getProxyUsername();
|
||||||
|
final String proxyPass = cli.getProxyPassword();
|
||||||
|
final String dataDirectory = cli.getDataDirectory();
|
||||||
|
final File propertiesFile = cli.getPropertiesFile();
|
||||||
|
final String suppressionFile = cli.getSuppressionFile();
|
||||||
|
final String hintsFile = cli.getHintsFile();
|
||||||
|
final String nexusUrl = cli.getNexusUrl();
|
||||||
|
final String databaseDriverName = cli.getDatabaseDriverName();
|
||||||
|
final String databaseDriverPath = cli.getDatabaseDriverPath();
|
||||||
|
final String connectionString = cli.getConnectionString();
|
||||||
|
final String databaseUser = cli.getDatabaseUser();
|
||||||
|
final String databasePassword = cli.getDatabasePassword();
|
||||||
|
final String additionalZipExtensions = cli.getAdditionalZipExtensions();
|
||||||
|
final String pathToMono = cli.getPathToMono();
|
||||||
|
final String cveMod12 = cli.getModifiedCve12Url();
|
||||||
|
final String cveMod20 = cli.getModifiedCve20Url();
|
||||||
|
final String cveBase12 = cli.getBaseCve12Url();
|
||||||
|
final String cveBase20 = cli.getBaseCve20Url();
|
||||||
|
final Integer cveValidForHours = cli.getCveValidForHours();
|
||||||
|
final boolean experimentalEnabled = cli.isExperimentalEnabled();
|
||||||
|
|
||||||
|
if (propertiesFile != null) {
|
||||||
|
try {
|
||||||
|
Settings.mergeProperties(propertiesFile);
|
||||||
|
} catch (FileNotFoundException ex) {
|
||||||
|
throw new InvalidSettingException("Unable to find properties file '" + propertiesFile.getPath() + "'", ex);
|
||||||
|
} catch (IOException ex) {
|
||||||
|
throw new InvalidSettingException("Error reading properties file '" + propertiesFile.getPath() + "'", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// We have to wait until we've merged the properties before attempting to set whether we use
|
||||||
|
// the proxy for Nexus since it could be disabled in the properties, but not explicitly stated
|
||||||
|
// on the command line
|
||||||
|
final boolean nexusUsesProxy = cli.isNexusUsesProxy();
|
||||||
if (dataDirectory != null) {
|
if (dataDirectory != null) {
|
||||||
Settings.setString(Settings.KEYS.DATA_DIRECTORY, dataDirectory);
|
Settings.setString(Settings.KEYS.DATA_DIRECTORY, dataDirectory);
|
||||||
} else if (System.getProperty("basedir") != null) {
|
} else if (System.getProperty("basedir") != null) {
|
||||||
@@ -182,17 +404,140 @@ public class App {
|
|||||||
final File dataDir = new File(base, sub);
|
final File dataDir = new File(base, sub);
|
||||||
Settings.setString(Settings.KEYS.DATA_DIRECTORY, dataDir.getAbsolutePath());
|
Settings.setString(Settings.KEYS.DATA_DIRECTORY, dataDir.getAbsolutePath());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, autoUpdate);
|
Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, autoUpdate);
|
||||||
if (proxyUrl != null && !proxyUrl.isEmpty()) {
|
Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_SERVER, proxyServer);
|
||||||
Settings.setString(Settings.KEYS.PROXY_URL, proxyUrl);
|
Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_PORT, proxyPort);
|
||||||
|
Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_USERNAME, proxyUser);
|
||||||
|
Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_PASSWORD, proxyPass);
|
||||||
|
Settings.setStringIfNotEmpty(Settings.KEYS.CONNECTION_TIMEOUT, connectionTimeout);
|
||||||
|
Settings.setStringIfNotEmpty(Settings.KEYS.SUPPRESSION_FILE, suppressionFile);
|
||||||
|
Settings.setStringIfNotEmpty(Settings.KEYS.HINTS_FILE, hintsFile);
|
||||||
|
Settings.setIntIfNotNull(Settings.KEYS.CVE_CHECK_VALID_FOR_HOURS, cveValidForHours);
|
||||||
|
|
||||||
|
//File Type Analyzer Settings
|
||||||
|
Settings.setBoolean(Settings.KEYS.ANALYZER_EXPERIMENTAL_ENABLED, experimentalEnabled);
|
||||||
|
Settings.setBoolean(Settings.KEYS.ANALYZER_JAR_ENABLED, !cli.isJarDisabled());
|
||||||
|
Settings.setBoolean(Settings.KEYS.ANALYZER_ARCHIVE_ENABLED, !cli.isArchiveDisabled());
|
||||||
|
Settings.setBoolean(Settings.KEYS.ANALYZER_PYTHON_DISTRIBUTION_ENABLED, !cli.isPythonDistributionDisabled());
|
||||||
|
Settings.setBoolean(Settings.KEYS.ANALYZER_PYTHON_PACKAGE_ENABLED, !cli.isPythonPackageDisabled());
|
||||||
|
Settings.setBoolean(Settings.KEYS.ANALYZER_AUTOCONF_ENABLED, !cli.isAutoconfDisabled());
|
||||||
|
Settings.setBoolean(Settings.KEYS.ANALYZER_CMAKE_ENABLED, !cli.isCmakeDisabled());
|
||||||
|
Settings.setBoolean(Settings.KEYS.ANALYZER_NUSPEC_ENABLED, !cli.isNuspecDisabled());
|
||||||
|
Settings.setBoolean(Settings.KEYS.ANALYZER_ASSEMBLY_ENABLED, !cli.isAssemblyDisabled());
|
||||||
|
Settings.setBoolean(Settings.KEYS.ANALYZER_BUNDLE_AUDIT_ENABLED, !cli.isBundleAuditDisabled());
|
||||||
|
Settings.setBoolean(Settings.KEYS.ANALYZER_OPENSSL_ENABLED, !cli.isOpenSSLDisabled());
|
||||||
|
Settings.setBoolean(Settings.KEYS.ANALYZER_COMPOSER_LOCK_ENABLED, !cli.isComposerDisabled());
|
||||||
|
Settings.setBoolean(Settings.KEYS.ANALYZER_NODE_PACKAGE_ENABLED, !cli.isNodeJsDisabled());
|
||||||
|
Settings.setBoolean(Settings.KEYS.ANALYZER_SWIFT_PACKAGE_MANAGER_ENABLED, !cli.isSwiftPackageAnalyzerDisabled());
|
||||||
|
Settings.setBoolean(Settings.KEYS.ANALYZER_COCOAPODS_ENABLED, !cli.isCocoapodsAnalyzerDisabled());
|
||||||
|
Settings.setBoolean(Settings.KEYS.ANALYZER_RUBY_GEMSPEC_ENABLED, !cli.isRubyGemspecDisabled());
|
||||||
|
Settings.setBoolean(Settings.KEYS.ANALYZER_CENTRAL_ENABLED, !cli.isCentralDisabled());
|
||||||
|
Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED, !cli.isNexusDisabled());
|
||||||
|
|
||||||
|
Settings.setStringIfNotEmpty(Settings.KEYS.ANALYZER_BUNDLE_AUDIT_PATH, cli.getPathToBundleAudit());
|
||||||
|
Settings.setStringIfNotEmpty(Settings.KEYS.ANALYZER_NEXUS_URL, nexusUrl);
|
||||||
|
Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_USES_PROXY, nexusUsesProxy);
|
||||||
|
Settings.setStringIfNotEmpty(Settings.KEYS.DB_DRIVER_NAME, databaseDriverName);
|
||||||
|
Settings.setStringIfNotEmpty(Settings.KEYS.DB_DRIVER_PATH, databaseDriverPath);
|
||||||
|
Settings.setStringIfNotEmpty(Settings.KEYS.DB_CONNECTION_STRING, connectionString);
|
||||||
|
Settings.setStringIfNotEmpty(Settings.KEYS.DB_USER, databaseUser);
|
||||||
|
Settings.setStringIfNotEmpty(Settings.KEYS.DB_PASSWORD, databasePassword);
|
||||||
|
Settings.setStringIfNotEmpty(Settings.KEYS.ADDITIONAL_ZIP_EXTENSIONS, additionalZipExtensions);
|
||||||
|
Settings.setStringIfNotEmpty(Settings.KEYS.ANALYZER_ASSEMBLY_MONO_PATH, pathToMono);
|
||||||
|
if (cveBase12 != null && !cveBase12.isEmpty()) {
|
||||||
|
Settings.setString(Settings.KEYS.CVE_SCHEMA_1_2, cveBase12);
|
||||||
|
Settings.setString(Settings.KEYS.CVE_SCHEMA_2_0, cveBase20);
|
||||||
|
Settings.setString(Settings.KEYS.CVE_MODIFIED_12_URL, cveMod12);
|
||||||
|
Settings.setString(Settings.KEYS.CVE_MODIFIED_20_URL, cveMod20);
|
||||||
}
|
}
|
||||||
if (proxyPort != null && !proxyPort.isEmpty()) {
|
|
||||||
Settings.setString(Settings.KEYS.PROXY_PORT, proxyPort);
|
|
||||||
}
|
}
|
||||||
if (connectionTimeout != null && !connectionTimeout.isEmpty()) {
|
|
||||||
Settings.setString(Settings.KEYS.CONNECTION_TIMEOUT, connectionTimeout);
|
/**
|
||||||
|
* Creates a file appender and adds it to logback.
|
||||||
|
*
|
||||||
|
* @param verboseLog the path to the verbose log file
|
||||||
|
*/
|
||||||
|
private void prepareLogger(String verboseLog) {
|
||||||
|
final StaticLoggerBinder loggerBinder = StaticLoggerBinder.getSingleton();
|
||||||
|
final LoggerContext context = (LoggerContext) loggerBinder.getLoggerFactory();
|
||||||
|
|
||||||
|
final PatternLayoutEncoder encoder = new PatternLayoutEncoder();
|
||||||
|
encoder.setPattern("%d %C:%L%n%-5level - %msg%n");
|
||||||
|
encoder.setContext(context);
|
||||||
|
encoder.start();
|
||||||
|
final FileAppender<ILoggingEvent> fa = new FileAppender<>();
|
||||||
|
fa.setAppend(true);
|
||||||
|
fa.setEncoder(encoder);
|
||||||
|
fa.setContext(context);
|
||||||
|
fa.setFile(verboseLog);
|
||||||
|
final File f = new File(verboseLog);
|
||||||
|
String name = f.getName();
|
||||||
|
final int i = name.lastIndexOf('.');
|
||||||
|
if (i > 1) {
|
||||||
|
name = name.substring(0, i);
|
||||||
|
}
|
||||||
|
fa.setName(name);
|
||||||
|
fa.start();
|
||||||
|
final ch.qos.logback.classic.Logger rootLogger = context.getLogger(ch.qos.logback.classic.Logger.ROOT_LOGGER_NAME);
|
||||||
|
rootLogger.addAppender(fa);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Takes a path and resolves it to be a canonical & absolute path. The
|
||||||
|
* caveats are that this method will take an Ant style file selector path
|
||||||
|
* (../someDir/**\/*.jar) and convert it to an absolute/canonical path (at
|
||||||
|
* least to the left of the first * or ?).
|
||||||
|
*
|
||||||
|
* @param path the path to canonicalize
|
||||||
|
* @return the canonical path
|
||||||
|
*/
|
||||||
|
protected String ensureCanonicalPath(String path) {
|
||||||
|
String basePath;
|
||||||
|
String wildCards = null;
|
||||||
|
final String file = path.replace('\\', '/');
|
||||||
|
if (file.contains("*") || file.contains("?")) {
|
||||||
|
|
||||||
|
int pos = getLastFileSeparator(file);
|
||||||
|
if (pos < 0) {
|
||||||
|
return file;
|
||||||
|
}
|
||||||
|
pos += 1;
|
||||||
|
basePath = file.substring(0, pos);
|
||||||
|
wildCards = file.substring(pos);
|
||||||
|
} else {
|
||||||
|
basePath = file;
|
||||||
|
}
|
||||||
|
|
||||||
|
File f = new File(basePath);
|
||||||
|
try {
|
||||||
|
f = f.getCanonicalFile();
|
||||||
|
if (wildCards != null) {
|
||||||
|
f = new File(f, wildCards);
|
||||||
|
}
|
||||||
|
} catch (IOException ex) {
|
||||||
|
LOGGER.warn("Invalid path '{}' was provided.", path);
|
||||||
|
LOGGER.debug("Invalid path provided", ex);
|
||||||
|
}
|
||||||
|
return f.getAbsolutePath().replace('\\', '/');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the position of the last file separator.
|
||||||
|
*
|
||||||
|
* @param file a file path
|
||||||
|
* @return the position of the last file separator
|
||||||
|
*/
|
||||||
|
private int getLastFileSeparator(String file) {
|
||||||
|
if (file.contains("*") || file.contains("?")) {
|
||||||
|
int p1 = file.indexOf('*');
|
||||||
|
int p2 = file.indexOf('?');
|
||||||
|
p1 = p1 > 0 ? p1 : file.length();
|
||||||
|
p2 = p2 > 0 ? p2 : file.length();
|
||||||
|
int pos = p1 < p2 ? p1 : p2;
|
||||||
|
pos = file.lastIndexOf('/', pos);
|
||||||
|
return pos;
|
||||||
|
} else {
|
||||||
|
return file.lastIndexOf('/');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,66 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of dependency-check-cli.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
* Copyright (c) 2014 Jeremy Long. All Rights Reserved.
|
||||||
|
*/
|
||||||
|
package org.owasp.dependencycheck;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Thrown if an invalid path is encountered.
|
||||||
|
*
|
||||||
|
* @author Jeremy Long
|
||||||
|
*/
|
||||||
|
public class InvalidScanPathException extends Exception {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The serial version UID for serialization.
|
||||||
|
*/
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new InvalidScanPathException.
|
||||||
|
*/
|
||||||
|
public InvalidScanPathException() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new InvalidScanPathException.
|
||||||
|
*
|
||||||
|
* @param msg a message for the exception
|
||||||
|
*/
|
||||||
|
public InvalidScanPathException(String msg) {
|
||||||
|
super(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new InvalidScanPathException.
|
||||||
|
*
|
||||||
|
* @param ex the cause of the exception
|
||||||
|
*/
|
||||||
|
public InvalidScanPathException(Throwable ex) {
|
||||||
|
super(ex);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new InvalidScanPathException.
|
||||||
|
*
|
||||||
|
* @param msg a message for the exception
|
||||||
|
* @param ex the cause of the exception
|
||||||
|
*/
|
||||||
|
public InvalidScanPathException(String msg, Throwable ex) {
|
||||||
|
super(msg, ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,473 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of dependency-check-cli.
|
|
||||||
*
|
|
||||||
* Dependency-check-cli is free software: you can redistribute it and/or modify it
|
|
||||||
* under the terms of the GNU General Public License as published by the Free
|
|
||||||
* Software Foundation, either version 3 of the License, or (at your option) any
|
|
||||||
* later version.
|
|
||||||
*
|
|
||||||
* Dependency-check-cli is distributed in the hope that it will be useful, but
|
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
|
||||||
* details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License along with
|
|
||||||
* dependency-check-cli. If not, see http://www.gnu.org/licenses/.
|
|
||||||
*
|
|
||||||
* Copyright (c) 2012 Jeremy Long. All Rights Reserved.
|
|
||||||
*/
|
|
||||||
package org.owasp.dependencycheck.cli;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileNotFoundException;
|
|
||||||
import org.apache.commons.cli.CommandLine;
|
|
||||||
import org.apache.commons.cli.CommandLineParser;
|
|
||||||
import org.apache.commons.cli.HelpFormatter;
|
|
||||||
import org.apache.commons.cli.Option;
|
|
||||||
import org.apache.commons.cli.OptionBuilder;
|
|
||||||
import org.apache.commons.cli.OptionGroup;
|
|
||||||
import org.apache.commons.cli.Options;
|
|
||||||
import org.apache.commons.cli.ParseException;
|
|
||||||
import org.apache.commons.cli.PosixParser;
|
|
||||||
import org.owasp.dependencycheck.reporting.ReportGenerator.Format;
|
|
||||||
import org.owasp.dependencycheck.utils.Settings;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A utility to parse command line arguments for the DependencyCheck.
|
|
||||||
*
|
|
||||||
* @author Jeremy Long (jeremy.long@owasp.org)
|
|
||||||
*/
|
|
||||||
public final class CliParser {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The command line.
|
|
||||||
*/
|
|
||||||
private CommandLine line;
|
|
||||||
/**
|
|
||||||
* The options for the command line parser.
|
|
||||||
*/
|
|
||||||
private final Options options = createCommandLineOptions();
|
|
||||||
/**
|
|
||||||
* Indicates whether the arguments are valid.
|
|
||||||
*/
|
|
||||||
private boolean isValid = true;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parses the arguments passed in and captures the results for later use.
|
|
||||||
*
|
|
||||||
* @param args the command line arguments
|
|
||||||
* @throws FileNotFoundException is thrown when a 'file' argument does not
|
|
||||||
* point to a file that exists.
|
|
||||||
* @throws ParseException is thrown when a Parse Exception occurs.
|
|
||||||
*/
|
|
||||||
public void parse(String[] args) throws FileNotFoundException, ParseException {
|
|
||||||
line = parseArgs(args);
|
|
||||||
|
|
||||||
if (line != null) {
|
|
||||||
validateArgs();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parses the command line arguments.
|
|
||||||
*
|
|
||||||
* @param args the command line arguments
|
|
||||||
* @return the results of parsing the command line arguments
|
|
||||||
* @throws ParseException if the arguments are invalid
|
|
||||||
*/
|
|
||||||
private CommandLine parseArgs(String[] args) throws ParseException {
|
|
||||||
final CommandLineParser parser = new PosixParser();
|
|
||||||
return parser.parse(options, args);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Validates that the command line arguments are valid.
|
|
||||||
*
|
|
||||||
* @throws FileNotFoundException if there is a file specified by either the
|
|
||||||
* SCAN or CPE command line arguments that does not exist.
|
|
||||||
* @throws ParseException is thrown if there is an exception parsing the
|
|
||||||
* command line.
|
|
||||||
*/
|
|
||||||
private void validateArgs() throws FileNotFoundException, ParseException {
|
|
||||||
if (isRunScan()) {
|
|
||||||
validatePathExists(getScanFiles(), "scan");
|
|
||||||
validatePathExists(getReportDirectory(), "out");
|
|
||||||
if (!line.hasOption(ArgumentName.APP_NAME)) {
|
|
||||||
throw new ParseException("Missing 'app' argument; the scan cannot be run without the an application name.");
|
|
||||||
}
|
|
||||||
if (line.hasOption(ArgumentName.OUTPUT_FORMAT)) {
|
|
||||||
final String format = line.getOptionValue(ArgumentName.OUTPUT_FORMAT);
|
|
||||||
try {
|
|
||||||
Format.valueOf(format);
|
|
||||||
} catch (IllegalArgumentException ex) {
|
|
||||||
final String msg = String.format("An invalid 'format' of '%s' was specified. Supported output formats are XML, HTML, VULN, or ALL", format);
|
|
||||||
throw new ParseException(msg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Validates whether or not the path(s) points at a file that exists; if the
|
|
||||||
* path(s) does not point to an existing file a FileNotFoundException is
|
|
||||||
* thrown.
|
|
||||||
*
|
|
||||||
* @param paths the paths to validate if they exists
|
|
||||||
* @param optType the option being validated (e.g. scan, out, etc.)
|
|
||||||
* @throws FileNotFoundException is thrown if one of the paths being
|
|
||||||
* validated does not exist.
|
|
||||||
*/
|
|
||||||
private void validatePathExists(String[] paths, String optType) throws FileNotFoundException {
|
|
||||||
for (String path : paths) {
|
|
||||||
validatePathExists(path, optType);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Validates whether or not the path points at a file that exists; if the
|
|
||||||
* path does not point to an existing file a FileNotFoundException is
|
|
||||||
* thrown.
|
|
||||||
*
|
|
||||||
* @param path the paths to validate if they exists
|
|
||||||
* @param optType the option being validated (e.g. scan, out, etc.)
|
|
||||||
* @throws FileNotFoundException is thrown if the path being validated does
|
|
||||||
* not exist.
|
|
||||||
*/
|
|
||||||
private void validatePathExists(String path, String optType) throws FileNotFoundException {
|
|
||||||
final File f = new File(path);
|
|
||||||
if (!f.exists()) {
|
|
||||||
isValid = false;
|
|
||||||
final String msg = String.format("Invalid '%s' argument: '%s'", optType, path);
|
|
||||||
throw new FileNotFoundException(msg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Generates an Options collection that is used to parse the command line
|
|
||||||
* and to display the help message.
|
|
||||||
*
|
|
||||||
* @return the command line options used for parsing the command line
|
|
||||||
*/
|
|
||||||
@SuppressWarnings("static-access")
|
|
||||||
private Options createCommandLineOptions() {
|
|
||||||
final Option help = new Option(ArgumentName.HELP_SHORT, ArgumentName.HELP, false,
|
|
||||||
"Print this message.");
|
|
||||||
|
|
||||||
final Option version = new Option(ArgumentName.VERSION_SHORT, ArgumentName.VERSION,
|
|
||||||
false, "Print the version information.");
|
|
||||||
|
|
||||||
final Option noUpdate = new Option(ArgumentName.DISABLE_AUTO_UPDATE_SHORT, ArgumentName.DISABLE_AUTO_UPDATE,
|
|
||||||
false, "Disables the automatic updating of the CPE data.");
|
|
||||||
|
|
||||||
final Option appName = OptionBuilder.withArgName("name").hasArg().withLongOpt(ArgumentName.APP_NAME)
|
|
||||||
.withDescription("The name of the application being scanned. This is a required argument.")
|
|
||||||
.create(ArgumentName.APP_NAME_SHORT);
|
|
||||||
|
|
||||||
final Option connectionTimeout = OptionBuilder.withArgName("timeout").hasArg().withLongOpt(ArgumentName.CONNECTION_TIMEOUT)
|
|
||||||
.withDescription("The connection timeout (in milliseconds) to use when downloading resources.")
|
|
||||||
.create(ArgumentName.CONNECTION_TIMEOUT_SHORT);
|
|
||||||
|
|
||||||
final Option proxyUrl = OptionBuilder.withArgName("url").hasArg().withLongOpt(ArgumentName.PROXY_URL)
|
|
||||||
.withDescription("The proxy url to use when downloading resources.")
|
|
||||||
.create(ArgumentName.PROXY_URL_SHORT);
|
|
||||||
|
|
||||||
final Option proxyPort = OptionBuilder.withArgName("port").hasArg().withLongOpt(ArgumentName.PROXY_PORT)
|
|
||||||
.withDescription("The proxy port to use when downloading resources.")
|
|
||||||
.create(ArgumentName.PROXY_PORT_SHORT);
|
|
||||||
|
|
||||||
final Option path = OptionBuilder.withArgName("path").hasArg().withLongOpt(ArgumentName.SCAN)
|
|
||||||
.withDescription("The path to scan - this option can be specified multiple times.")
|
|
||||||
.create(ArgumentName.SCAN_SHORT);
|
|
||||||
|
|
||||||
final Option props = OptionBuilder.withArgName("file").hasArg().withLongOpt(ArgumentName.PROP)
|
|
||||||
.withDescription("A property file to load.")
|
|
||||||
.create(ArgumentName.PROP_SHORT);
|
|
||||||
|
|
||||||
final Option data = OptionBuilder.withArgName("path").hasArg().withLongOpt(ArgumentName.DATA_DIRECTORY)
|
|
||||||
.withDescription("The location of the data directory used to store persistent data. This option should generally not be set.")
|
|
||||||
.create(ArgumentName.DATA_DIRECTORY_SHORT);
|
|
||||||
|
|
||||||
final Option out = OptionBuilder.withArgName("folder").hasArg().withLongOpt(ArgumentName.OUT)
|
|
||||||
.withDescription("The folder to write reports to. This defaults to the current directory.")
|
|
||||||
.create(ArgumentName.OUT_SHORT);
|
|
||||||
|
|
||||||
final Option outputFormat = OptionBuilder.withArgName("format").hasArg().withLongOpt(ArgumentName.OUTPUT_FORMAT)
|
|
||||||
.withDescription("The output format to write to (XML, HTML, VULN, ALL). The default is HTML.")
|
|
||||||
.create(ArgumentName.OUTPUT_FORMAT_SHORT);
|
|
||||||
|
|
||||||
final OptionGroup og = new OptionGroup();
|
|
||||||
og.addOption(path);
|
|
||||||
|
|
||||||
final Options opts = new Options();
|
|
||||||
opts.addOptionGroup(og);
|
|
||||||
opts.addOption(out);
|
|
||||||
opts.addOption(outputFormat);
|
|
||||||
opts.addOption(appName);
|
|
||||||
opts.addOption(version);
|
|
||||||
opts.addOption(help);
|
|
||||||
opts.addOption(noUpdate);
|
|
||||||
opts.addOption(props);
|
|
||||||
opts.addOption(data);
|
|
||||||
opts.addOption(proxyPort);
|
|
||||||
opts.addOption(proxyUrl);
|
|
||||||
opts.addOption(connectionTimeout);
|
|
||||||
|
|
||||||
return opts;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determines if the 'version' command line argument was passed in.
|
|
||||||
*
|
|
||||||
* @return whether or not the 'version' command line argument was passed in
|
|
||||||
*/
|
|
||||||
public boolean isGetVersion() {
|
|
||||||
return (line != null) && line.hasOption(ArgumentName.VERSION);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determines if the 'help' command line argument was passed in.
|
|
||||||
*
|
|
||||||
* @return whether or not the 'help' command line argument was passed in
|
|
||||||
*/
|
|
||||||
public boolean isGetHelp() {
|
|
||||||
return (line != null) && line.hasOption(ArgumentName.HELP);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determines if the 'scan' command line argument was passed in.
|
|
||||||
*
|
|
||||||
* @return whether or not the 'scan' command line argument was passed in
|
|
||||||
*/
|
|
||||||
public boolean isRunScan() {
|
|
||||||
return (line != null) && isValid && line.hasOption(ArgumentName.SCAN);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Displays the command line help message to the standard output.
|
|
||||||
*/
|
|
||||||
public void printHelp() {
|
|
||||||
final HelpFormatter formatter = new HelpFormatter();
|
|
||||||
final String nl = System.getProperty("line.separator");
|
|
||||||
|
|
||||||
formatter.printHelp(Settings.getString("application.name", "DependencyCheck"),
|
|
||||||
nl + Settings.getString("application.name", "DependencyCheck")
|
|
||||||
+ " can be used to identify if there are any known CVE vulnerabilities in libraries utilized by an application. "
|
|
||||||
+ Settings.getString("application.name", "DependencyCheck")
|
|
||||||
+ " will automatically update required data from the Internet, such as the CVE and CPE data files from nvd.nist.gov." + nl + nl,
|
|
||||||
options,
|
|
||||||
"",
|
|
||||||
true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieves the file command line parameter(s) specified for the 'scan'
|
|
||||||
* argument.
|
|
||||||
*
|
|
||||||
* @return the file paths specified on the command line for scan
|
|
||||||
*/
|
|
||||||
public String[] getScanFiles() {
|
|
||||||
return line.getOptionValues(ArgumentName.SCAN);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the directory to write the reports to specified on the command
|
|
||||||
* line.
|
|
||||||
*
|
|
||||||
* @return the path to the reports directory.
|
|
||||||
*/
|
|
||||||
public String getReportDirectory() {
|
|
||||||
return line.getOptionValue(ArgumentName.OUT, ".");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the output format specified on the command line. Defaults to HTML
|
|
||||||
* if no format was specified.
|
|
||||||
*
|
|
||||||
* @return the output format name.
|
|
||||||
*/
|
|
||||||
public String getReportFormat() {
|
|
||||||
return line.getOptionValue(ArgumentName.OUTPUT_FORMAT, "HTML");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the application name specified on the command line.
|
|
||||||
*
|
|
||||||
* @return the application name.
|
|
||||||
*/
|
|
||||||
public String getApplicationName() {
|
|
||||||
return line.getOptionValue(ArgumentName.APP_NAME);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the connection timeout.
|
|
||||||
*
|
|
||||||
* @return the connection timeout
|
|
||||||
*/
|
|
||||||
public String getConnectionTimeout() {
|
|
||||||
return line.getOptionValue(ArgumentName.CONNECTION_TIMEOUT);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the proxy url.
|
|
||||||
*
|
|
||||||
* @return the proxy url
|
|
||||||
*/
|
|
||||||
public String getProxyUrl() {
|
|
||||||
return line.getOptionValue(ArgumentName.PROXY_URL);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the proxy port.
|
|
||||||
*
|
|
||||||
* @return the proxy port
|
|
||||||
*/
|
|
||||||
public String getProxyPort() {
|
|
||||||
return line.getOptionValue(ArgumentName.PROXY_PORT);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the value of dataDirectory.
|
|
||||||
*
|
|
||||||
* @return the value of dataDirectory
|
|
||||||
*/
|
|
||||||
public String getDataDirectory() {
|
|
||||||
return line.getOptionValue(ArgumentName.DATA_DIRECTORY);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>Prints the manifest information to standard output.</p>
|
|
||||||
* <ul><li>Implementation-Title: ${pom.name}</li>
|
|
||||||
* <li>Implementation-Version: ${pom.version}</li></ul>
|
|
||||||
*/
|
|
||||||
public void printVersionInfo() {
|
|
||||||
final String version = String.format("%s version %s",
|
|
||||||
Settings.getString("application.name", "DependencyCheck"),
|
|
||||||
Settings.getString("application.version", "Unknown"));
|
|
||||||
System.out.println(version);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if the auto update feature has been disabled. If it has been
|
|
||||||
* disabled via the command line this will return false.
|
|
||||||
*
|
|
||||||
* @return if auto-update is allowed.
|
|
||||||
*/
|
|
||||||
public boolean isAutoUpdate() {
|
|
||||||
return (line == null) || !line.hasOption(ArgumentName.DISABLE_AUTO_UPDATE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A collection of static final strings that represent the possible command
|
|
||||||
* line arguments.
|
|
||||||
*/
|
|
||||||
public static class ArgumentName {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The long CLI argument name specifying the directory/file to scan.
|
|
||||||
*/
|
|
||||||
public static final String SCAN = "scan";
|
|
||||||
/**
|
|
||||||
* The short CLI argument name specifying the directory/file to scan.
|
|
||||||
*/
|
|
||||||
public static final String SCAN_SHORT = "s";
|
|
||||||
/**
|
|
||||||
* The long CLI argument name specifying that the CPE/CVE/etc. data
|
|
||||||
* should not be automatically updated.
|
|
||||||
*/
|
|
||||||
public static final String DISABLE_AUTO_UPDATE = "noupdate";
|
|
||||||
/**
|
|
||||||
* The short CLI argument name specifying that the CPE/CVE/etc. data
|
|
||||||
* should not be automatically updated.
|
|
||||||
*/
|
|
||||||
public static final String DISABLE_AUTO_UPDATE_SHORT = "n";
|
|
||||||
/**
|
|
||||||
* The long CLI argument name specifying the directory to write the
|
|
||||||
* reports to.
|
|
||||||
*/
|
|
||||||
public static final String OUT = "out";
|
|
||||||
/**
|
|
||||||
* The short CLI argument name specifying the directory to write the
|
|
||||||
* reports to.
|
|
||||||
*/
|
|
||||||
public static final String OUT_SHORT = "o";
|
|
||||||
/**
|
|
||||||
* The long CLI argument name specifying the output format to write the
|
|
||||||
* reports to.
|
|
||||||
*/
|
|
||||||
public static final String OUTPUT_FORMAT = "format";
|
|
||||||
/**
|
|
||||||
* The short CLI argument name specifying the output format to write the
|
|
||||||
* reports to.
|
|
||||||
*/
|
|
||||||
public static final String OUTPUT_FORMAT_SHORT = "f";
|
|
||||||
/**
|
|
||||||
* The long CLI argument name specifying the name of the application to
|
|
||||||
* be scanned.
|
|
||||||
*/
|
|
||||||
public static final String APP_NAME = "app";
|
|
||||||
/**
|
|
||||||
* The short CLI argument name specifying the name of the application to
|
|
||||||
* be scanned.
|
|
||||||
*/
|
|
||||||
public static final String APP_NAME_SHORT = "a";
|
|
||||||
/**
|
|
||||||
* The long CLI argument name asking for help.
|
|
||||||
*/
|
|
||||||
public static final String HELP = "help";
|
|
||||||
/**
|
|
||||||
* The short CLI argument name asking for help.
|
|
||||||
*/
|
|
||||||
public static final String HELP_SHORT = "h";
|
|
||||||
/**
|
|
||||||
* The long CLI argument name asking for the version.
|
|
||||||
*/
|
|
||||||
public static final String VERSION_SHORT = "v";
|
|
||||||
/**
|
|
||||||
* The short CLI argument name asking for the version.
|
|
||||||
*/
|
|
||||||
public static final String VERSION = "version";
|
|
||||||
/**
|
|
||||||
* The short CLI argument name indicating the proxy port.
|
|
||||||
*/
|
|
||||||
public static final String PROXY_PORT_SHORT = "p";
|
|
||||||
/**
|
|
||||||
* The CLI argument name indicating the proxy port.
|
|
||||||
*/
|
|
||||||
public static final String PROXY_PORT = "proxyport";
|
|
||||||
/**
|
|
||||||
* The short CLI argument name indicating the proxy url.
|
|
||||||
*/
|
|
||||||
public static final String PROXY_URL_SHORT = "u";
|
|
||||||
/**
|
|
||||||
* The CLI argument name indicating the proxy url.
|
|
||||||
*/
|
|
||||||
public static final String PROXY_URL = "proxyurl";
|
|
||||||
/**
|
|
||||||
* The short CLI argument name indicating the proxy url.
|
|
||||||
*/
|
|
||||||
public static final String CONNECTION_TIMEOUT_SHORT = "c";
|
|
||||||
/**
|
|
||||||
* The CLI argument name indicating the proxy url.
|
|
||||||
*/
|
|
||||||
public static final String CONNECTION_TIMEOUT = "connectiontimeout";
|
|
||||||
/**
|
|
||||||
* The short CLI argument name for setting the location of an additional
|
|
||||||
* properties file.
|
|
||||||
*/
|
|
||||||
public static final String PROP_SHORT = "p";
|
|
||||||
/**
|
|
||||||
* The CLI argument name for setting the location of an additional
|
|
||||||
* properties file.
|
|
||||||
*/
|
|
||||||
public static final String PROP = "propertyfile";
|
|
||||||
/**
|
|
||||||
* The CLI argument name for setting the location of the data directory.
|
|
||||||
*/
|
|
||||||
public static final String DATA_DIRECTORY = "data";
|
|
||||||
/**
|
|
||||||
* The short CLI argument name for setting the location of the data
|
|
||||||
* directory.
|
|
||||||
*/
|
|
||||||
public static final String DATA_DIRECTORY_SHORT = "d";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
/**
|
|
||||||
* <html>
|
|
||||||
* <head>
|
|
||||||
* <title>org.owasp.dependencycheck.cli</title>
|
|
||||||
* </head>
|
|
||||||
* <body>
|
|
||||||
* Includes utility classes such as the CLI Parser,
|
|
||||||
* </body>
|
|
||||||
* </html>
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.owasp.dependencycheck.cli;
|
|
||||||
@@ -1,12 +1,4 @@
|
|||||||
/**
|
/**
|
||||||
* <html>
|
|
||||||
* <head>
|
|
||||||
* <title>org.owasp.dependencycheck</title>
|
|
||||||
* </head>
|
|
||||||
* <body>
|
|
||||||
* Includes the main entry point for the DependencyChecker.
|
* Includes the main entry point for the DependencyChecker.
|
||||||
* </body>
|
|
||||||
* </html>
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.owasp.dependencycheck;
|
package org.owasp.dependencycheck;
|
||||||
|
|||||||
@@ -1,24 +0,0 @@
|
|||||||
handlers=java.util.logging.ConsoleHandler
|
|
||||||
#, java.util.logging.FileHandler
|
|
||||||
|
|
||||||
# logging levels
|
|
||||||
# FINEST, FINER, FINE, CONFIG, INFO, WARNING and SEVERE.
|
|
||||||
|
|
||||||
# Configure the ConsoleHandler.
|
|
||||||
java.util.logging.ConsoleHandler.level=INFO
|
|
||||||
|
|
||||||
org.owasp.dependencycheck.data.nvdcve.xml
|
|
||||||
|
|
||||||
# Configure the FileHandler.
|
|
||||||
java.util.logging.FileHandler.formatter=java.util.logging.SimpleFormatter
|
|
||||||
java.util.logging.FileHandler.level=FINE
|
|
||||||
|
|
||||||
# The following special tokens can be used in the pattern property
|
|
||||||
# which specifies the location and name of the log file.
|
|
||||||
# / - standard path separator
|
|
||||||
# %t - system temporary directory
|
|
||||||
# %h - value of the user.home system property
|
|
||||||
# %g - generation number for rotating logs
|
|
||||||
# %u - unique number to avoid conflicts
|
|
||||||
# FileHandler writes to %h/demo0.log by default.
|
|
||||||
java.util.logging.FileHandler.pattern=./logs/DependencyCheck.log
|
|
||||||
16
dependency-check-cli/src/main/resources/logback.xml
Normal file
16
dependency-check-cli/src/main/resources/logback.xml
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
<configuration>
|
||||||
|
<contextName>dependency-check</contextName>
|
||||||
|
<!-- Logging configuration -->
|
||||||
|
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
|
||||||
|
<Target>System.out</Target>
|
||||||
|
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
|
||||||
|
<level>INFO</level>
|
||||||
|
</filter>
|
||||||
|
<encoder>
|
||||||
|
<pattern>[%level] %msg%n</pattern>
|
||||||
|
</encoder>
|
||||||
|
</appender>
|
||||||
|
<root level="DEBUG">
|
||||||
|
<appender-ref ref="console"/>
|
||||||
|
</root>
|
||||||
|
</configuration>
|
||||||
67
dependency-check-cli/src/site/markdown/arguments.md
Normal file
67
dependency-check-cli/src/site/markdown/arguments.md
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
Command Line Arguments
|
||||||
|
======================
|
||||||
|
|
||||||
|
The following table lists the command line arguments:
|
||||||
|
|
||||||
|
Short | Argument Name | Parameter | Description | Requirement
|
||||||
|
-------|-----------------------|-----------------|-------------|------------
|
||||||
|
| \-\-project | \<name\> | The name of the project being scanned. | Required
|
||||||
|
\-s | \-\-scan | \<path\> | The path to scan \- this option can be specified multiple times. It is also possible to specify Ant style paths (e.g. directory/**/*.jar). | Required
|
||||||
|
| \-\-exclude | \<pattern\> | The path patterns to exclude from the scan \- this option can be specified multiple times. This accepts Ant style path patterns (e.g. **/exclude/**). | Optional
|
||||||
|
| \-\-symLink | \<depth\> | The depth that symbolic links will be followed; the default is 0 meaning symbolic links will not be followed. | Optional
|
||||||
|
\-o | \-\-out | \<path\> | The folder to write reports to. This defaults to the current directory. If the format is not set to ALL one could specify a specific file name. | Optional
|
||||||
|
\-f | \-\-format | \<format\> | The output format to write to (XML, HTML, VULN, ALL). The default is HTML. | Required
|
||||||
|
| \-\-failOnCvss | \<score\> | If the score set between 0 and 10 the exit code from dependency-check will indicate if a vulnerability with a CVSS score equal to or higher was identified. | Optional
|
||||||
|
\-l | \-\-log | \<file\> | The file path to write verbose logging information. | Optional
|
||||||
|
\-n | \-\-noupdate | | Disables the automatic updating of the CPE data. | Optional
|
||||||
|
| \-\-suppression | \<file\> | The file path to the suppression XML file; used to suppress [false positives](../general/suppression.html). | Optional
|
||||||
|
\-h | \-\-help | | Print the help message. | Optional
|
||||||
|
| \-\-advancedHelp | | Print the advanced help message. | Optional
|
||||||
|
\-v | \-\-version | | Print the version information. | Optional
|
||||||
|
| \-\-cveValidForHours | \<hours\> | The number of hours to wait before checking for new updates from the NVD. The default is 4 hours. | Optional
|
||||||
|
| \-\-experimental | | Enable the [experimental analyzers](../analyzers/index.html). If not set the analyzers marked as experimental below will not be loaded or used. | Optional
|
||||||
|
|
||||||
|
Advanced Options
|
||||||
|
================
|
||||||
|
Short | Argument Name | Parameter | Description | Default Value
|
||||||
|
-------|-----------------------|-----------------|----------------------------------------------------------------------------------|-------------------
|
||||||
|
| \-\-cveUrl12Modified | \<url\> | URL for the modified CVE 1.2 | https://nvd.nist.gov/download/nvdcve-Modified.xml.gz
|
||||||
|
| \-\-cveUrl20Modified | \<url\> | URL for the modified CVE 2.0 | https://nvd.nist.gov/feeds/xml/cve/nvdcve-2.0-Modified.xml.gz
|
||||||
|
| \-\-cveUrl12Base | \<url\> | Base URL for each year's CVE 1.2, the %d will be replaced with the year | https://nvd.nist.gov/download/nvdcve-%d.xml.gz
|
||||||
|
| \-\-cveUrl20Base | \<url\> | Base URL for each year's CVE 2.0, the %d will be replaced with the year | https://nvd.nist.gov/feeds/xml/cve/nvdcve-2.0-%d.xml.gz
|
||||||
|
\-P | \-\-propertyfile | \<file\> | Specifies a file that contains properties to use instead of applicaion defaults. |
|
||||||
|
| \-\-updateonly | | If set only the update phase of dependency-check will be executed; no scan will be executed and no report will be generated. |
|
||||||
|
| \-\-disablePyDist | | Sets whether the [experimental](../analyzers/index.html) Python Distribution Analyzer will be used. | false
|
||||||
|
| \-\-disablePyPkg | | Sets whether the [experimental](../analyzers/index.html) Python Package Analyzer will be used. | false
|
||||||
|
| \-\-disableNodeJS | | Sets whether the [experimental](../analyzers/index.html) Node.js Package Analyzer will be used. | false
|
||||||
|
| \-\-disableRubygems | | Sets whether the [experimental](../analyzers/index.html) Ruby Gemspec Analyzer will be used. | false
|
||||||
|
| \-\-disableBundleAudit | | Sets whether the [experimental](../analyzers/index.html) Ruby Bundler Audit Analyzer will be used. | false
|
||||||
|
| \-\-disableCocoapodsAnalyzer | | Sets whether the [experimental](../analyzers/index.html) Cocoapods Analyzer will be used. | false
|
||||||
|
| \-\-disableSwiftPackageManagerAnalyzer | | Sets whether the [experimental](../analyzers/index.html) Swift Package Manager Analyzer will be used. | false
|
||||||
|
| \-\-disableAutoconf | | Sets whether the [experimental](../analyzers/index.html) Autoconf Analyzer will be used. | false
|
||||||
|
| \-\-disableOpenSSL | | Sets whether the OpenSSL Analyzer will be used. | false
|
||||||
|
| \-\-disableCmake | | Sets whether the [experimental](../analyzers/index.html) Cmake Analyzer will be disabled. | false
|
||||||
|
| \-\-disableArchive | | Sets whether the Archive Analyzer will be disabled. | false
|
||||||
|
| \-\-zipExtensions | \<strings\> | A comma-separated list of additional file extensions to be treated like a ZIP file, the contents will be extracted and analyzed. |
|
||||||
|
| \-\-disableJar | | Sets whether the Jar Analyzer will be disabled. | false
|
||||||
|
| \-\-disableComposer | | Sets whether the [experimental](../analyzers/index.html) PHP Composer Lock File Analyzer will be disabled. | false
|
||||||
|
| \-\-disableCentral | | Sets whether the Central Analyzer will be used. **Disabling this analyzer is not recommended as it could lead to false negatives (e.g. libraries that have vulnerabilities may not be reported correctly).** If this analyzer is being disabled there is a good chance you also want to disable the Nexus Analyzer. | false
|
||||||
|
| \-\-disableNexus | | Sets whether the Nexus Analyzer will be used. Note, this has been superceded by the Central Analyzer. However, you can configure the Nexus URL to utilize an internally hosted Nexus Pro server. | false
|
||||||
|
| \-\-nexus | \<url\> | The url to the Nexus Server's web service end point (example: http://domain.enterprise/nexus/service/local/). If not set the Nexus Analyzer will be disabled. |
|
||||||
|
| \-\-nexusUsesProxy | \<true\|false\> | Whether or not the defined proxy should be used when connecting to Nexus. | true
|
||||||
|
| \-\-disableNuspec | | Sets whether or not the .NET Nuget Nuspec Analyzer will be used. | false
|
||||||
|
| \-\-disableAssembly | | Sets whether or not the .NET Assembly Analyzer should be used. | false
|
||||||
|
| \-\-mono | \<path\> | The path to Mono for .NET Assembly analysis on non-windows systems. |
|
||||||
|
| \-\-bundleAudit | | The path to the bundle-audit executable. |
|
||||||
|
| \-\-proxyserver | \<server\> | The proxy server to use when downloading resources; see the [proxy configuration](../data/proxy.html) page for more information. |
|
||||||
|
| \-\-proxyport | \<port\> | The proxy port to use when downloading resources. |
|
||||||
|
| \-\-connectiontimeout | \<timeout\> | The connection timeout (in milliseconds) to use when downloading resources. |
|
||||||
|
| \-\-proxypass | \<pass\> | The proxy password to use when downloading resources. |
|
||||||
|
| \-\-proxyuser | \<user\> | The proxy username to use when downloading resources. |
|
||||||
|
| \-\-connectionString | \<connStr\> | The connection string to the database. |
|
||||||
|
| \-\-dbDriverName | \<driver\> | The database driver name. |
|
||||||
|
| \-\-dbDriverPath | \<path\> | The path to the database driver; note, this does not need to be set unless the JAR is outside of the class path. |
|
||||||
|
| \-\-dbPassword | \<password\> | The password for connecting to the database. |
|
||||||
|
| \-\-dbUser | \<user\> | The username used to connect to the database. |
|
||||||
|
\-d | \-\-data | \<path\> | The location of the data directory used to store persistent data. This option should generally not be set. |
|
||||||
|
| \-\-purge | | Delete the local copy of the NVD. This is used to force a refresh of the data. |
|
||||||
36
dependency-check-cli/src/site/markdown/index.md.vm
Normal file
36
dependency-check-cli/src/site/markdown/index.md.vm
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
About
|
||||||
|
====================
|
||||||
|
OWASP dependency-check-cli is an command line tool that uses dependency-check-core to detect
|
||||||
|
publicly disclosed vulnerabilities associated with the scanned project dependencies. The tool
|
||||||
|
will generate a report listing the dependency, any identified Common Platform Enumeration (CPE)
|
||||||
|
identifiers, and the associated Common Vulnerability and Exposure (CVE) entries.
|
||||||
|
|
||||||
|
Installation & Usage
|
||||||
|
====================
|
||||||
|
Download the dependency-check command line tool [here](http://dl.bintray.com/jeremy-long/owasp/dependency-check-${project.version}-release.zip).
|
||||||
|
Extract the zip file to a location on your computer and put the 'bin' directory into the
|
||||||
|
path environment variable.
|
||||||
|
|
||||||
|
#set( $H = '#' )
|
||||||
|
|
||||||
|
$H$H$H Homebrew
|
||||||
|
$ brew install dependency-check
|
||||||
|
|
||||||
|
This puts an executable `dependency-check` script in the `/bin` directory of
|
||||||
|
your homebrew installation.
|
||||||
|
|
||||||
|
To scan a folder on the system you can run:
|
||||||
|
|
||||||
|
$H$H$H Windows
|
||||||
|
dependency-check.bat --project "My App Name" --scan "c:\java\application\lib"
|
||||||
|
|
||||||
|
$H$H$H *nix
|
||||||
|
dependency-check.sh --project "My App Name" --scan "/java/application/lib"
|
||||||
|
|
||||||
|
To view the command line arguments, see the <a href="arguments.html">arguments page</a>, or you can run:
|
||||||
|
|
||||||
|
$H$H$H Windows
|
||||||
|
dependency-check.bat --help
|
||||||
|
|
||||||
|
$H$H$H *nix
|
||||||
|
dependency-check.sh --help
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
Installation & Usage
|
|
||||||
--------------------
|
|
||||||
Downlod the dependency-check command line tool [here](http://dl.bintray.com/jeremy-long/owasp/dependency-check-${project.version}-release.zip).
|
|
||||||
Extract the zip file to a location on your computer and put the 'bin' directory into the
|
|
||||||
path environment variable. On \*nix systems you will likely need to make the shell
|
|
||||||
script executable:
|
|
||||||
|
|
||||||
$ chmod +777 dependency-check.sh
|
|
||||||
|
|
||||||
To scan a folder on the system you can run:
|
|
||||||
|
|
||||||
### Windows
|
|
||||||
dependency-check.bat --app "My App Name" --scan "c:\java\application\lib"
|
|
||||||
|
|
||||||
### \*nix
|
|
||||||
dependency-check.sh --app "My App Name" --scan "/java/application/lib"
|
|
||||||
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 10 KiB |
@@ -2,33 +2,34 @@
|
|||||||
<!--
|
<!--
|
||||||
This file is part of dependency-check-cli.
|
This file is part of dependency-check-cli.
|
||||||
|
|
||||||
Dependency-check-cli is free software: you can redistribute it and/or modify it
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
under the terms of the GNU General Public License as published by the Free
|
you may not use this file except in compliance with the License.
|
||||||
Software Foundation, either version 3 of the License, or (at your option) any
|
You may obtain a copy of the License at
|
||||||
later version.
|
|
||||||
|
|
||||||
Dependency-check-cli is distributed in the hope that it will be useful, but
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
|
||||||
details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License along with
|
Unless required by applicable law or agreed to in writing, software
|
||||||
dependency-check-cli. If not, see http://www.gnu.org/licenses/.
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
|
||||||
Copyright (c) 2013 Jeremy Long. All Rights Reserved.
|
Copyright (c) 2013 Jeremy Long. All Rights Reserved.
|
||||||
-->
|
-->
|
||||||
<project name="dependency-check-cli">
|
<project name="dependency-check-cli">
|
||||||
<bannerLeft>
|
<bannerLeft>
|
||||||
<name>dependency-check-cli</name>
|
<name>OWASP dependency-check-cli</name>
|
||||||
|
<alt>OWASP dependency-check-cli</alt>
|
||||||
|
<src>./images/dc-cli.svg</src>
|
||||||
</bannerLeft>
|
</bannerLeft>
|
||||||
<body>
|
<body>
|
||||||
<breadcrumbs>
|
<breadcrumbs>
|
||||||
<item name="dependency-check" href="../index.html"/>
|
<item name="dependency-check" href="../index.html"/>
|
||||||
</breadcrumbs>
|
</breadcrumbs>
|
||||||
<menu name="Getting Started">
|
<menu name="Getting Started">
|
||||||
<item name="Installation" href="installation.html"/>
|
<item name="Installation" href="index.html"/>
|
||||||
|
<item name="Configuration" href="arguments.html"/>
|
||||||
</menu>
|
</menu>
|
||||||
<menu ref="Project Documentation" />
|
|
||||||
<menu ref="reports" />
|
<menu ref="reports" />
|
||||||
</body>
|
</body>
|
||||||
</project>
|
</project>
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of dependency-check-core.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
* Copyright (c) 2015 The OWASP Foundatio. All Rights Reserved.
|
||||||
|
*/
|
||||||
|
package org.owasp.dependencycheck;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author jeremy
|
||||||
|
*/
|
||||||
|
public class AppTest {
|
||||||
|
/**
|
||||||
|
* Test of ensureCanonicalPath method, of class App.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testEnsureCanonicalPath() {
|
||||||
|
String file = "../*.jar";
|
||||||
|
App instance = new App();
|
||||||
|
String result = instance.ensureCanonicalPath(file);
|
||||||
|
assertFalse(result.contains(".."));
|
||||||
|
assertTrue(result.endsWith("*.jar"));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test of ensureCanonicalPath method, of class App.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testEnsureCanonicalPath2() {
|
||||||
|
String file = "../some/skip/../path/file.txt";
|
||||||
|
App instance = new App();
|
||||||
|
String expResult = "/some/path/file.txt";
|
||||||
|
String result = instance.ensureCanonicalPath(file);
|
||||||
|
assertTrue("result=" + result, result.endsWith(expResult));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,57 +1,48 @@
|
|||||||
/*
|
/*
|
||||||
* This file is part of Dependency-Check.
|
* This file is part of Dependency-Check.
|
||||||
*
|
*
|
||||||
* Dependency-Check is free software: you can redistribute it and/or modify it
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* under the terms of the GNU General Public License as published by the Free
|
* you may not use this file except in compliance with the License.
|
||||||
* Software Foundation, either version 3 of the License, or (at your option) any
|
* You may obtain a copy of the License at
|
||||||
* later version.
|
|
||||||
*
|
*
|
||||||
* Dependency-Check is distributed in the hope that it will be useful, but
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
|
||||||
* details.
|
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License along with
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* Dependency-Check. If not, see http://www.gnu.org/licenses/.
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
*
|
*
|
||||||
* Copyright (c) 2012 Jeremy Long. All Rights Reserved.
|
* Copyright (c) 2012 Jeremy Long. All Rights Reserved.
|
||||||
*/
|
*/
|
||||||
package org.owasp.dependencycheck.cli;
|
package org.owasp.dependencycheck;
|
||||||
|
|
||||||
import org.owasp.dependencycheck.cli.CliParser;
|
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.PrintStream;
|
import java.io.PrintStream;
|
||||||
import org.apache.commons.cli.ParseException;
|
import org.apache.commons.cli.ParseException;
|
||||||
import org.junit.After;
|
|
||||||
import org.junit.AfterClass;
|
import org.junit.AfterClass;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Before;
|
|
||||||
import org.junit.BeforeClass;
|
import org.junit.BeforeClass;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
import org.owasp.dependencycheck.utils.Settings;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author Jeremy Long (jeremy.long@owasp.org)
|
* @author Jeremy Long
|
||||||
*/
|
*/
|
||||||
public class CliParserTest {
|
public class CliParserTest {
|
||||||
|
|
||||||
@BeforeClass
|
@BeforeClass
|
||||||
public static void setUpClass() throws Exception {
|
public static void setUpClass() throws Exception {
|
||||||
|
Settings.initialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
@AfterClass
|
@AfterClass
|
||||||
public static void tearDownClass() throws Exception {
|
public static void tearDownClass() throws Exception {
|
||||||
}
|
Settings.cleanup(true);
|
||||||
|
|
||||||
@Before
|
|
||||||
public void setUp() throws Exception {
|
|
||||||
}
|
|
||||||
|
|
||||||
@After
|
|
||||||
public void tearDown() throws Exception {
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -113,6 +104,63 @@ public class CliParserTest {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test of parse method with failOnCVSS without an argument
|
||||||
|
*
|
||||||
|
* @throws Exception thrown when an exception occurs.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testParse_failOnCVSSNoArg() throws Exception {
|
||||||
|
|
||||||
|
String[] args = {"--failOnCVSS"};
|
||||||
|
|
||||||
|
CliParser instance = new CliParser();
|
||||||
|
try {
|
||||||
|
instance.parse(args);
|
||||||
|
} catch (ParseException ex) {
|
||||||
|
Assert.assertTrue(ex.getMessage().contains("Missing argument"));
|
||||||
|
}
|
||||||
|
Assert.assertFalse(instance.isGetVersion());
|
||||||
|
Assert.assertFalse(instance.isGetHelp());
|
||||||
|
Assert.assertFalse(instance.isRunScan());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test of parse method with failOnCVSS invalid argument. It should default to 11
|
||||||
|
*
|
||||||
|
* @throws Exception thrown when an exception occurs.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testParse_failOnCVSSInvalidArgument() throws Exception {
|
||||||
|
|
||||||
|
String[] args = {"--failOnCVSS","bad"};
|
||||||
|
|
||||||
|
CliParser instance = new CliParser();
|
||||||
|
instance.parse(args);
|
||||||
|
Assert.assertEquals("Default should be 11", 11, instance.getFailOnCVSS());
|
||||||
|
Assert.assertFalse(instance.isGetVersion());
|
||||||
|
Assert.assertFalse(instance.isGetHelp());
|
||||||
|
Assert.assertFalse(instance.isRunScan());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test of parse method with failOnCVSS invalid argument. It should default to 11
|
||||||
|
*
|
||||||
|
* @throws Exception thrown when an exception occurs.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testParse_failOnCVSSValidArgument() throws Exception {
|
||||||
|
|
||||||
|
String[] args = {"--failOnCVSS","6"};
|
||||||
|
|
||||||
|
CliParser instance = new CliParser();
|
||||||
|
instance.parse(args);
|
||||||
|
Assert.assertEquals(6, instance.getFailOnCVSS());
|
||||||
|
Assert.assertFalse(instance.isGetVersion());
|
||||||
|
Assert.assertFalse(instance.isGetHelp());
|
||||||
|
Assert.assertFalse(instance.isRunScan());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test of parse method with jar and cpe args, of class CliParser.
|
* Test of parse method with jar and cpe args, of class CliParser.
|
||||||
*
|
*
|
||||||
@@ -194,7 +242,7 @@ public class CliParserTest {
|
|||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testParse_scan_withFileExists() throws Exception {
|
public void testParse_scan_withFileExists() throws Exception {
|
||||||
File path = new File(this.getClass().getClassLoader().getResource("checkSumTest.file").getPath());
|
File path = new File(this.getClass().getClassLoader().getResource("checkSumTest.file").toURI().getPath());
|
||||||
String[] args = {"-scan", path.getCanonicalPath(), "-out", "./", "-app", "test"};
|
String[] args = {"-scan", path.getCanonicalPath(), "-out", "./", "-app", "test"};
|
||||||
|
|
||||||
CliParser instance = new CliParser();
|
CliParser instance = new CliParser();
|
||||||
202
dependency-check-core/LICENSE.txt
Normal file
202
dependency-check-core/LICENSE.txt
Normal file
@@ -0,0 +1,202 @@
|
|||||||
|
|
||||||
|
Apache License
|
||||||
|
Version 2.0, January 2004
|
||||||
|
http://www.apache.org/licenses/
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||||
|
|
||||||
|
1. Definitions.
|
||||||
|
|
||||||
|
"License" shall mean the terms and conditions for use, reproduction,
|
||||||
|
and distribution as defined by Sections 1 through 9 of this document.
|
||||||
|
|
||||||
|
"Licensor" shall mean the copyright owner or entity authorized by
|
||||||
|
the copyright owner that is granting the License.
|
||||||
|
|
||||||
|
"Legal Entity" shall mean the union of the acting entity and all
|
||||||
|
other entities that control, are controlled by, or are under common
|
||||||
|
control with that entity. For the purposes of this definition,
|
||||||
|
"control" means (i) the power, direct or indirect, to cause the
|
||||||
|
direction or management of such entity, whether by contract or
|
||||||
|
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||||
|
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||||
|
|
||||||
|
"You" (or "Your") shall mean an individual or Legal Entity
|
||||||
|
exercising permissions granted by this License.
|
||||||
|
|
||||||
|
"Source" form shall mean the preferred form for making modifications,
|
||||||
|
including but not limited to software source code, documentation
|
||||||
|
source, and configuration files.
|
||||||
|
|
||||||
|
"Object" form shall mean any form resulting from mechanical
|
||||||
|
transformation or translation of a Source form, including but
|
||||||
|
not limited to compiled object code, generated documentation,
|
||||||
|
and conversions to other media types.
|
||||||
|
|
||||||
|
"Work" shall mean the work of authorship, whether in Source or
|
||||||
|
Object form, made available under the License, as indicated by a
|
||||||
|
copyright notice that is included in or attached to the work
|
||||||
|
(an example is provided in the Appendix below).
|
||||||
|
|
||||||
|
"Derivative Works" shall mean any work, whether in Source or Object
|
||||||
|
form, that is based on (or derived from) the Work and for which the
|
||||||
|
editorial revisions, annotations, elaborations, or other modifications
|
||||||
|
represent, as a whole, an original work of authorship. For the purposes
|
||||||
|
of this License, Derivative Works shall not include works that remain
|
||||||
|
separable from, or merely link (or bind by name) to the interfaces of,
|
||||||
|
the Work and Derivative Works thereof.
|
||||||
|
|
||||||
|
"Contribution" shall mean any work of authorship, including
|
||||||
|
the original version of the Work and any modifications or additions
|
||||||
|
to that Work or Derivative Works thereof, that is intentionally
|
||||||
|
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||||
|
or by an individual or Legal Entity authorized to submit on behalf of
|
||||||
|
the copyright owner. For the purposes of this definition, "submitted"
|
||||||
|
means any form of electronic, verbal, or written communication sent
|
||||||
|
to the Licensor or its representatives, including but not limited to
|
||||||
|
communication on electronic mailing lists, source code control systems,
|
||||||
|
and issue tracking systems that are managed by, or on behalf of, the
|
||||||
|
Licensor for the purpose of discussing and improving the Work, but
|
||||||
|
excluding communication that is conspicuously marked or otherwise
|
||||||
|
designated in writing by the copyright owner as "Not a Contribution."
|
||||||
|
|
||||||
|
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||||
|
on behalf of whom a Contribution has been received by Licensor and
|
||||||
|
subsequently incorporated within the Work.
|
||||||
|
|
||||||
|
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
copyright license to reproduce, prepare Derivative Works of,
|
||||||
|
publicly display, publicly perform, sublicense, and distribute the
|
||||||
|
Work and such Derivative Works in Source or Object form.
|
||||||
|
|
||||||
|
3. Grant of Patent License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
(except as stated in this section) patent license to make, have made,
|
||||||
|
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||||
|
where such license applies only to those patent claims licensable
|
||||||
|
by such Contributor that are necessarily infringed by their
|
||||||
|
Contribution(s) alone or by combination of their Contribution(s)
|
||||||
|
with the Work to which such Contribution(s) was submitted. If You
|
||||||
|
institute patent litigation against any entity (including a
|
||||||
|
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||||
|
or a Contribution incorporated within the Work constitutes direct
|
||||||
|
or contributory patent infringement, then any patent licenses
|
||||||
|
granted to You under this License for that Work shall terminate
|
||||||
|
as of the date such litigation is filed.
|
||||||
|
|
||||||
|
4. Redistribution. You may reproduce and distribute copies of the
|
||||||
|
Work or Derivative Works thereof in any medium, with or without
|
||||||
|
modifications, and in Source or Object form, provided that You
|
||||||
|
meet the following conditions:
|
||||||
|
|
||||||
|
(a) You must give any other recipients of the Work or
|
||||||
|
Derivative Works a copy of this License; and
|
||||||
|
|
||||||
|
(b) You must cause any modified files to carry prominent notices
|
||||||
|
stating that You changed the files; and
|
||||||
|
|
||||||
|
(c) You must retain, in the Source form of any Derivative Works
|
||||||
|
that You distribute, all copyright, patent, trademark, and
|
||||||
|
attribution notices from the Source form of the Work,
|
||||||
|
excluding those notices that do not pertain to any part of
|
||||||
|
the Derivative Works; and
|
||||||
|
|
||||||
|
(d) If the Work includes a "NOTICE" text file as part of its
|
||||||
|
distribution, then any Derivative Works that You distribute must
|
||||||
|
include a readable copy of the attribution notices contained
|
||||||
|
within such NOTICE file, excluding those notices that do not
|
||||||
|
pertain to any part of the Derivative Works, in at least one
|
||||||
|
of the following places: within a NOTICE text file distributed
|
||||||
|
as part of the Derivative Works; within the Source form or
|
||||||
|
documentation, if provided along with the Derivative Works; or,
|
||||||
|
within a display generated by the Derivative Works, if and
|
||||||
|
wherever such third-party notices normally appear. The contents
|
||||||
|
of the NOTICE file are for informational purposes only and
|
||||||
|
do not modify the License. You may add Your own attribution
|
||||||
|
notices within Derivative Works that You distribute, alongside
|
||||||
|
or as an addendum to the NOTICE text from the Work, provided
|
||||||
|
that such additional attribution notices cannot be construed
|
||||||
|
as modifying the License.
|
||||||
|
|
||||||
|
You may add Your own copyright statement to Your modifications and
|
||||||
|
may provide additional or different license terms and conditions
|
||||||
|
for use, reproduction, or distribution of Your modifications, or
|
||||||
|
for any such Derivative Works as a whole, provided Your use,
|
||||||
|
reproduction, and distribution of the Work otherwise complies with
|
||||||
|
the conditions stated in this License.
|
||||||
|
|
||||||
|
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||||
|
any Contribution intentionally submitted for inclusion in the Work
|
||||||
|
by You to the Licensor shall be under the terms and conditions of
|
||||||
|
this License, without any additional terms or conditions.
|
||||||
|
Notwithstanding the above, nothing herein shall supersede or modify
|
||||||
|
the terms of any separate license agreement you may have executed
|
||||||
|
with Licensor regarding such Contributions.
|
||||||
|
|
||||||
|
6. Trademarks. This License does not grant permission to use the trade
|
||||||
|
names, trademarks, service marks, or product names of the Licensor,
|
||||||
|
except as required for reasonable and customary use in describing the
|
||||||
|
origin of the Work and reproducing the content of the NOTICE file.
|
||||||
|
|
||||||
|
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||||
|
agreed to in writing, Licensor provides the Work (and each
|
||||||
|
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||||
|
implied, including, without limitation, any warranties or conditions
|
||||||
|
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||||
|
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||||
|
appropriateness of using or redistributing the Work and assume any
|
||||||
|
risks associated with Your exercise of permissions under this License.
|
||||||
|
|
||||||
|
8. Limitation of Liability. In no event and under no legal theory,
|
||||||
|
whether in tort (including negligence), contract, or otherwise,
|
||||||
|
unless required by applicable law (such as deliberate and grossly
|
||||||
|
negligent acts) or agreed to in writing, shall any Contributor be
|
||||||
|
liable to You for damages, including any direct, indirect, special,
|
||||||
|
incidental, or consequential damages of any character arising as a
|
||||||
|
result of this License or out of the use or inability to use the
|
||||||
|
Work (including but not limited to damages for loss of goodwill,
|
||||||
|
work stoppage, computer failure or malfunction, or any and all
|
||||||
|
other commercial damages or losses), even if such Contributor
|
||||||
|
has been advised of the possibility of such damages.
|
||||||
|
|
||||||
|
9. Accepting Warranty or Additional Liability. While redistributing
|
||||||
|
the Work or Derivative Works thereof, You may choose to offer,
|
||||||
|
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||||
|
or other liability obligations and/or rights consistent with this
|
||||||
|
License. However, in accepting such obligations, You may act only
|
||||||
|
on Your own behalf and on Your sole responsibility, not on behalf
|
||||||
|
of any other Contributor, and only if You agree to indemnify,
|
||||||
|
defend, and hold each Contributor harmless for any liability
|
||||||
|
incurred by, or claims asserted against, such Contributor by reason
|
||||||
|
of your accepting any such warranty or additional liability.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
APPENDIX: How to apply the Apache License to your work.
|
||||||
|
|
||||||
|
To apply the Apache License to your work, attach the following
|
||||||
|
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||||
|
replaced with your own identifying information. (Don't include
|
||||||
|
the brackets!) The text should be enclosed in the appropriate
|
||||||
|
comment syntax for the file format. We also recommend that a
|
||||||
|
file or class name and description of purpose be included on the
|
||||||
|
same "printed page" as the copyright notice for easier
|
||||||
|
identification within third-party archives.
|
||||||
|
|
||||||
|
Copyright [yyyy] [name of copyright owner]
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
18
dependency-check-core/NOTICE.txt
Normal file
18
dependency-check-core/NOTICE.txt
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
dependency-check
|
||||||
|
|
||||||
|
Copyright (c) 2012-2013 Jeremy Long. All Rights Reserved.
|
||||||
|
|
||||||
|
The licenses for the software listed below can be found in the META-INF/licenses/[dependency name].
|
||||||
|
|
||||||
|
This product includes software developed by The Apache Software Foundation (http://www.apache.org/).
|
||||||
|
|
||||||
|
This product includes software developed by Jquery.com (http://jquery.com/).
|
||||||
|
|
||||||
|
This product includes software developed by Jonathan Hedley (jsoup.org)
|
||||||
|
|
||||||
|
This software contains unmodified binary redistributions for H2 database engine (http://www.h2database.com/), which is dual licensed and available under a modified version of the MPL 1.1 (Mozilla Public License) or under the (unmodified) EPL 1.0 (Eclipse Public License).
|
||||||
|
An original copy of the license agreement can be found at: http://www.h2database.com/html/license.html
|
||||||
|
|
||||||
|
This product includes data from the Common Weakness Enumeration (CWE): http://cwe.mitre.org/
|
||||||
|
|
||||||
|
This product downloads and utilizes data from the National Vulnerability Database hosted by NIST: http://nvd.nist.gov/download.cfm
|
||||||
28
dependency-check-core/README.md
Normal file
28
dependency-check-core/README.md
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
Dependency-Check-Core
|
||||||
|
================
|
||||||
|
|
||||||
|
Dependency-Check-Core is the main engine used by all of the other modules to do the analysis and reporting.
|
||||||
|
|
||||||
|
Mailing List
|
||||||
|
------------
|
||||||
|
|
||||||
|
Subscribe: [dependency-check+subscribe@googlegroups.com] [subscribe]
|
||||||
|
|
||||||
|
Post: [dependency-check@googlegroups.com] [post]
|
||||||
|
|
||||||
|
Archive: [google group](https://groups.google.com/forum/#!forum/dependency-check)
|
||||||
|
|
||||||
|
Copyright & License
|
||||||
|
------------
|
||||||
|
|
||||||
|
Dependency-Check is Copyright (c) 2012-2014 Jeremy Long. All Rights Reserved.
|
||||||
|
|
||||||
|
Permission to modify and redistribute is granted under the terms of the Apache 2.0 license. See the [LICENSE.txt](https://raw.githubusercontent.com/jeremylong/DependencyCheck/master/LICENSE.txt) file for the full license.
|
||||||
|
|
||||||
|
Dependency-Check makes use of several other open source libraries. Please see the [NOTICE.txt] [notices] file for more information.
|
||||||
|
|
||||||
|
|
||||||
|
[wiki]: https://github.com/jeremylong/DependencyCheck/wiki
|
||||||
|
[subscribe]: mailto:dependency-check+subscribe@googlegroups.com
|
||||||
|
[post]: mailto:dependency-check@googlegroups.com
|
||||||
|
[notices]: https://raw.githubusercontent.com/jeremylong/DependencyCheck/master/NOTICE.txt
|
||||||
@@ -1,223 +0,0 @@
|
|||||||
<?xml version="1.0"?>
|
|
||||||
<!DOCTYPE module PUBLIC
|
|
||||||
"-//Puppy Crawl//DTD Check Configuration 1.3//EN"
|
|
||||||
"http://www.puppycrawl.com/dtds/configuration_1_3.dtd">
|
|
||||||
|
|
||||||
<module name="Checker">
|
|
||||||
<!--
|
|
||||||
If you set the basedir property below, then all reported file
|
|
||||||
names will be relative to the specified directory. See
|
|
||||||
http://checkstyle.sourceforge.net/5.x/config.html#Checker
|
|
||||||
|
|
||||||
<property name="basedir" value="${basedir}"/>
|
|
||||||
-->
|
|
||||||
|
|
||||||
<property name="severity" value="error"/>
|
|
||||||
|
|
||||||
<module name="SuppressionFilter">
|
|
||||||
<property name="file" value="${checkstyle.suppressions.file}"/>
|
|
||||||
</module>
|
|
||||||
|
|
||||||
<module name="JavadocPackage">
|
|
||||||
<property name="allowLegacy" value="false"/>
|
|
||||||
</module>
|
|
||||||
|
|
||||||
<module name="Translation">
|
|
||||||
<property name="severity" value="warning"/>
|
|
||||||
</module>
|
|
||||||
|
|
||||||
<module name="FileTabCharacter">
|
|
||||||
<property name="eachLine" value="false"/>
|
|
||||||
</module>
|
|
||||||
|
|
||||||
<module name="FileLength">
|
|
||||||
<property name="fileExtensions" value="java"/>
|
|
||||||
</module>
|
|
||||||
|
|
||||||
<module name="NewlineAtEndOfFile">
|
|
||||||
<property name="fileExtensions" value="java"/>
|
|
||||||
<property name="lineSeparator" value="lf"/>
|
|
||||||
</module>
|
|
||||||
|
|
||||||
<module name="RegexpHeader">
|
|
||||||
<property name="headerFile" value="${checkstyle.header.file}"/>
|
|
||||||
<property name="fileExtensions" value="java"/>
|
|
||||||
<property name="id" value="header"/>
|
|
||||||
</module>
|
|
||||||
|
|
||||||
<module name="RegexpSingleline">
|
|
||||||
<property name="format" value="\s+$"/>
|
|
||||||
<property name="minimum" value="0"/>
|
|
||||||
<property name="maximum" value="0"/>
|
|
||||||
</module>
|
|
||||||
|
|
||||||
<module name="TreeWalker">
|
|
||||||
<property name="tabWidth" value="4"/>
|
|
||||||
|
|
||||||
<module name="AvoidStarImport"/>
|
|
||||||
<module name="ConstantName"/>
|
|
||||||
<module name="EmptyBlock"/>
|
|
||||||
<module name="EmptyForIteratorPad"/>
|
|
||||||
<module name="EqualsHashCode"/>
|
|
||||||
<module name="OneStatementPerLine"/>
|
|
||||||
|
|
||||||
<!-- module name="IllegalCatch"/ -->
|
|
||||||
<!--module name="ImportControl">
|
|
||||||
<property name="file" value="${checkstyle.importcontrol.file}"/>
|
|
||||||
</module-->
|
|
||||||
<module name="IllegalImport"/>
|
|
||||||
<module name="IllegalInstantiation"/>
|
|
||||||
<module name="IllegalThrows"/>
|
|
||||||
<module name="InnerAssignment"/>
|
|
||||||
<module name="JavadocType">
|
|
||||||
<property name="authorFormat" value="\S"/>
|
|
||||||
</module>
|
|
||||||
<module name="JavadocMethod">
|
|
||||||
<property name="allowUndeclaredRTE" value="true"/>
|
|
||||||
<property name="allowThrowsTagsForSubclasses" value="true"/>
|
|
||||||
<property name="allowMissingPropertyJavadoc" value="true"/>
|
|
||||||
</module>
|
|
||||||
<module name="JavadocVariable"/>
|
|
||||||
<module name="JavadocStyle">
|
|
||||||
<property name="scope" value="public"/>
|
|
||||||
</module>
|
|
||||||
|
|
||||||
<module name="LeftCurly">
|
|
||||||
<property name="option" value="eol"/>
|
|
||||||
<property name="tokens" value="CLASS_DEF"/>
|
|
||||||
<property name="tokens" value="CTOR_DEF"/>
|
|
||||||
<property name="tokens" value="INTERFACE_DEF"/>
|
|
||||||
<property name="tokens" value="METHOD_DEF"/>
|
|
||||||
<property name="tokens" value="LITERAL_CATCH"/>
|
|
||||||
<property name="tokens" value="LITERAL_DO"/>
|
|
||||||
<property name="tokens" value="LITERAL_ELSE"/>
|
|
||||||
<property name="tokens" value="LITERAL_FINALLY"/>
|
|
||||||
<property name="tokens" value="LITERAL_FOR"/>
|
|
||||||
<property name="tokens" value="LITERAL_IF"/>
|
|
||||||
<property name="tokens" value="LITERAL_SWITCH"/>
|
|
||||||
<property name="tokens" value="LITERAL_SYNCHRONIZED"/>
|
|
||||||
<property name="tokens" value="LITERAL_TRY"/>
|
|
||||||
<property name="tokens" value="LITERAL_WHILE"/>
|
|
||||||
</module>
|
|
||||||
|
|
||||||
<module name="OuterTypeNumber"/>
|
|
||||||
<module name="LineLength">
|
|
||||||
<property name="ignorePattern" value="^ *\* *[^ ]+$"/>
|
|
||||||
<property name="max" value="150"/>
|
|
||||||
</module>
|
|
||||||
|
|
||||||
<module name="MethodCount">
|
|
||||||
<property name="maxTotal" value="40"/>
|
|
||||||
</module>
|
|
||||||
|
|
||||||
<module name="LocalFinalVariableName"/>
|
|
||||||
<module name="LocalVariableName"/>
|
|
||||||
<module name="MemberName">
|
|
||||||
<property name="format" value="^[a-z][a-zA-Z0-9]*$"/>
|
|
||||||
</module>
|
|
||||||
<module name="MethodLength">
|
|
||||||
<property name="max" value="160"/>
|
|
||||||
<property name="countEmpty" value="false"/>
|
|
||||||
</module>
|
|
||||||
<module name="MethodName"/>
|
|
||||||
<module name="MethodParamPad"/>
|
|
||||||
<module name="ModifierOrder"/>
|
|
||||||
<module name="NeedBraces"/>
|
|
||||||
<module name="NoWhitespaceAfter">
|
|
||||||
<property name="tokens" value="ARRAY_INIT"/>
|
|
||||||
<property name="tokens" value="BNOT"/>
|
|
||||||
<property name="tokens" value="DEC"/>
|
|
||||||
<property name="tokens" value="DOT"/>
|
|
||||||
<property name="tokens" value="INC"/>
|
|
||||||
<property name="tokens" value="LNOT"/>
|
|
||||||
<property name="tokens" value="UNARY_MINUS"/>
|
|
||||||
<property name="tokens" value="UNARY_PLUS"/>
|
|
||||||
</module>
|
|
||||||
|
|
||||||
<module name="NoWhitespaceBefore"/>
|
|
||||||
<module name="NoWhitespaceBefore">
|
|
||||||
<property name="tokens" value="DOT"/>
|
|
||||||
<property name="allowLineBreaks" value="true"/>
|
|
||||||
</module>
|
|
||||||
|
|
||||||
<module name="OperatorWrap"/>
|
|
||||||
<module name="OperatorWrap">
|
|
||||||
<property name="tokens" value="ASSIGN"/>
|
|
||||||
<property name="tokens" value="DIV_ASSIGN"/>
|
|
||||||
<property name="tokens" value="PLUS_ASSIGN"/>
|
|
||||||
<property name="tokens" value="MINUS_ASSIGN"/>
|
|
||||||
<property name="tokens" value="STAR_ASSIGN"/>
|
|
||||||
<property name="tokens" value="MOD_ASSIGN"/>
|
|
||||||
<property name="tokens" value="SR_ASSIGN"/>
|
|
||||||
<property name="tokens" value="BSR_ASSIGN"/>
|
|
||||||
<property name="tokens" value="SL_ASSIGN"/>
|
|
||||||
<property name="tokens" value="BXOR_ASSIGN"/>
|
|
||||||
<property name="tokens" value="BOR_ASSIGN"/>
|
|
||||||
<property name="tokens" value="BAND_ASSIGN"/>
|
|
||||||
<property name="option" value="eol"/>
|
|
||||||
</module>
|
|
||||||
<module name="PackageName"/>
|
|
||||||
<module name="ParameterName">
|
|
||||||
<property name="format" value="^[a-z][a-zA-Z0-9]*$"/>
|
|
||||||
</module>
|
|
||||||
<module name="ParameterNumber">
|
|
||||||
<property name="id" value="paramNum"/>
|
|
||||||
</module>
|
|
||||||
<module name="ParenPad"/>
|
|
||||||
<module name="TypecastParenPad"/>
|
|
||||||
<module name="RedundantImport"/>
|
|
||||||
<module name="RedundantModifier"/>
|
|
||||||
<module name="RightCurly">
|
|
||||||
<property name="option" value="same"/>
|
|
||||||
</module>
|
|
||||||
<module name="SimplifyBooleanExpression"/>
|
|
||||||
<module name="SimplifyBooleanReturn"/>
|
|
||||||
<module name="StaticVariableName">
|
|
||||||
<property name="format" value="^[a-z][a-zA-Z0-9]*$"/>
|
|
||||||
</module>
|
|
||||||
<module name="TypeName"/>
|
|
||||||
<module name="UnusedImports"/>
|
|
||||||
<module name="UpperEll"/>
|
|
||||||
<module name="VisibilityModifier"/>
|
|
||||||
<module name="WhitespaceAfter"/>
|
|
||||||
<module name="WhitespaceAround"/>
|
|
||||||
<module name="GenericWhitespace"/>
|
|
||||||
<module name="FinalClass"/>
|
|
||||||
<module name="MissingSwitchDefault"/>
|
|
||||||
<!--module name="MagicNumber"/-->
|
|
||||||
<!--module name="Indentation">
|
|
||||||
<property name="basicOffset" value="4"/>
|
|
||||||
<property name="braceAdjustment" value="0"/>
|
|
||||||
<property name="caseIndent" value="0"/>
|
|
||||||
</module-->
|
|
||||||
<module name="ArrayTrailingComma"/>
|
|
||||||
<module name="FinalLocalVariable"/>
|
|
||||||
<module name="EqualsAvoidNull"/>
|
|
||||||
<module name="ParameterAssignment"/>
|
|
||||||
|
|
||||||
<!-- Generates quite a few errors -->
|
|
||||||
<module name="CyclomaticComplexity">
|
|
||||||
<property name="severity" value="ignore"/>
|
|
||||||
</module>
|
|
||||||
|
|
||||||
<module name="NestedForDepth">
|
|
||||||
<property name="max" value="2"/>
|
|
||||||
</module>
|
|
||||||
<module name="NestedIfDepth">
|
|
||||||
<property name="max" value="4"/>
|
|
||||||
</module>
|
|
||||||
<module name="NestedTryDepth">
|
|
||||||
<property name="max" value="2"/>
|
|
||||||
</module>
|
|
||||||
<!--module name="ExplicitInitialization"/-->
|
|
||||||
<module name="AnnotationUseStyle"/>
|
|
||||||
<module name="MissingDeprecated"/>
|
|
||||||
<module name="MissingOverride">
|
|
||||||
<property name="javaFiveCompatibility" value="true"/>
|
|
||||||
</module>
|
|
||||||
<module name="PackageAnnotation"/>
|
|
||||||
<module name="SuppressWarnings"/>
|
|
||||||
<module name="OuterTypeFilename"/>
|
|
||||||
<module name="HideUtilityClassConstructor"/>
|
|
||||||
</module>
|
|
||||||
</module>
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
^/\*\s*$
|
|
||||||
^ \* This file is part of dependency-check-core\.\s*$
|
|
||||||
^ \*\s*$
|
|
||||||
^ \* Dependency-check-core is free software\: you can redistribute it and/or modify it\s*$
|
|
||||||
^ \* under the terms of the GNU General Public License as published by the Free\s*$
|
|
||||||
^ \* Software Foundation, either version 3 of the License, or \(at your option\) any\s*$
|
|
||||||
^ \* later version\.
|
|
||||||
^ \*\s*$
|
|
||||||
^ \* Dependency-check-core is distributed in the hope that it will be useful, but\s*$
|
|
||||||
^ \* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\s*$
|
|
||||||
^ \* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more\s*$
|
|
||||||
^ \* details\.\s*$
|
|
||||||
^ \*\s*$
|
|
||||||
^ \* You should have received a copy of the GNU General Public License along with\s*$
|
|
||||||
^ \* dependency-check-core\. If not, see http://www.gnu.org/licenses/\.\s*$
|
|
||||||
^ \*\s*$
|
|
||||||
^ \* Copyright \(c\) 201[23] (Jeremy Long|Steve Springett)\. All Rights Reserved\.\s*$
|
|
||||||
^ \*/\s*$
|
|
||||||
^package
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
<?xml version="1.0"?>
|
|
||||||
|
|
||||||
<!DOCTYPE suppressions PUBLIC
|
|
||||||
"-//Puppy Crawl//DTD Suppressions 1.0//EN"
|
|
||||||
"http://www.puppycrawl.com/dtds/suppressions_1_0.dtd">
|
|
||||||
|
|
||||||
<suppressions>
|
|
||||||
<suppress checks=".*" files=".*[\\/]package-info\.java" />
|
|
||||||
<suppress checks=".*" files=".*org[\\/]owasp[\\/]dependencycheck[\\/]utils[\\/]Filter.java" />
|
|
||||||
<suppress checks=".*" files=".*org[\\/]owasp[\\/]dependencycheck[\\/]utils[\\/]Checksum.java" />
|
|
||||||
<suppress checks=".*" files=".*[\\/]generated[\\/].*.java" />
|
|
||||||
</suppressions>
|
|
||||||
@@ -1,34 +1,33 @@
|
|||||||
<!--
|
<!--
|
||||||
Copyright (c) 2012 - Jeremy Long
|
This file is part of dependency-check-core.
|
||||||
|
|
||||||
This file is part of Dependency-Check.
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
Dependency-Check is free software: you can redistribute it and/or modify
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
Dependency-Check is distributed in the hope that it will be useful,
|
Unless required by applicable law or agreed to in writing, software
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
GNU General Public License for more details.
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
Copyright (c) 2012 Jeremy Long. All Rights Reserved.
|
||||||
along with Dependency-Check. If not, see <http://www.gnu.org/licenses />.
|
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>org.owasp</groupId>
|
<groupId>org.owasp</groupId>
|
||||||
<artifactId>dependency-check-parent</artifactId>
|
<artifactId>dependency-check-parent</artifactId>
|
||||||
<version>1.0.3</version>
|
<version>1.4.6-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>dependency-check-core</artifactId>
|
<artifactId>dependency-check-core</artifactId>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
<name>Dependency-Check Core</name>
|
<name>Dependency-Check Core</name>
|
||||||
|
<description>dependency-check-core is the engine and reporting tool used to identify and report if there are any known, publicly disclosed vulnerabilities in the scanned project's dependencies. The engine extracts meta-data from the dependencies and uses this to do fuzzy key-word matching against the Common Platfrom Enumeration (CPE), if any CPE identifiers are found the associated Common Vulnerability and Exposure (CVE) entries are added to the generated report.</description>
|
||||||
<!-- begin copy from http://minds.coremedia.com/2012/09/11/problem-solved-deploy-multi-module-maven-project-site-as-github-pages/ -->
|
<!-- begin copy from http://minds.coremedia.com/2012/09/11/problem-solved-deploy-multi-module-maven-project-site-as-github-pages/ -->
|
||||||
<distributionManagement>
|
<distributionManagement>
|
||||||
<site>
|
<site>
|
||||||
@@ -71,6 +70,13 @@ along with Dependency-Check. If not, see <http://www.gnu.org/licenses />.
|
|||||||
</resource>
|
</resource>
|
||||||
</resources>
|
</resources>
|
||||||
<testResources>
|
<testResources>
|
||||||
|
<testResource>
|
||||||
|
<directory>src/test/resources</directory>
|
||||||
|
<includes>
|
||||||
|
<include>**/*.properties</include>
|
||||||
|
</includes>
|
||||||
|
<filtering>true</filtering>
|
||||||
|
</testResource>
|
||||||
<testResource>
|
<testResource>
|
||||||
<directory>${basedir}/../src/test/resources</directory>
|
<directory>${basedir}/../src/test/resources</directory>
|
||||||
<filtering>false</filtering>
|
<filtering>false</filtering>
|
||||||
@@ -84,7 +90,6 @@ along with Dependency-Check. If not, see <http://www.gnu.org/licenses />.
|
|||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-dependency-plugin</artifactId>
|
<artifactId>maven-dependency-plugin</artifactId>
|
||||||
<version>2.8</version>
|
|
||||||
<executions>
|
<executions>
|
||||||
<execution>
|
<execution>
|
||||||
<phase>generate-resources</phase>
|
<phase>generate-resources</phase>
|
||||||
@@ -93,7 +98,7 @@ along with Dependency-Check. If not, see <http://www.gnu.org/licenses />.
|
|||||||
</goals>
|
</goals>
|
||||||
<configuration>
|
<configuration>
|
||||||
<outputDirectory>${project.build.directory}/test-classes</outputDirectory>
|
<outputDirectory>${project.build.directory}/test-classes</outputDirectory>
|
||||||
<includeScope>provided</includeScope>
|
<includeScope>test</includeScope>
|
||||||
</configuration>
|
</configuration>
|
||||||
</execution>
|
</execution>
|
||||||
</executions>
|
</executions>
|
||||||
@@ -101,40 +106,27 @@ along with Dependency-Check. If not, see <http://www.gnu.org/licenses />.
|
|||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-jar-plugin</artifactId>
|
<artifactId>maven-jar-plugin</artifactId>
|
||||||
<version>2.4</version>
|
|
||||||
<executions>
|
<executions>
|
||||||
<execution>
|
|
||||||
<id>jar</id>
|
|
||||||
<phase>package</phase>
|
|
||||||
<goals>
|
|
||||||
<goal>jar</goal>
|
|
||||||
</goals>
|
|
||||||
</execution>
|
|
||||||
<execution>
|
<execution>
|
||||||
<id>test-jar</id>
|
<id>test-jar</id>
|
||||||
<phase>package</phase>
|
<phase>package</phase>
|
||||||
<goals>
|
<goals>
|
||||||
<goal>test-jar</goal>
|
<goal>test-jar</goal>
|
||||||
</goals>
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<includes>
|
||||||
|
<include>**/*.class</include>
|
||||||
|
</includes>
|
||||||
|
</configuration>
|
||||||
</execution>
|
</execution>
|
||||||
</executions>
|
</executions>
|
||||||
<configuration>
|
|
||||||
<archive>
|
|
||||||
<manifest>
|
|
||||||
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
|
|
||||||
</manifest>
|
|
||||||
</archive>
|
|
||||||
<excludes>
|
|
||||||
<exclude>**/checkstyle*</exclude>
|
|
||||||
</excludes>
|
|
||||||
</configuration>
|
|
||||||
</plugin>
|
</plugin>
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.codehaus.mojo</groupId>
|
<groupId>org.codehaus.mojo</groupId>
|
||||||
<artifactId>cobertura-maven-plugin</artifactId>
|
<artifactId>cobertura-maven-plugin</artifactId>
|
||||||
<version>2.5.2</version>
|
|
||||||
<configuration>
|
<configuration>
|
||||||
<instrumentation>
|
<instrumentation>
|
||||||
|
<!--ignoreTrivial>true</ignoreTrivial-->
|
||||||
<ignores>
|
<ignores>
|
||||||
<ignore>.*\$KEYS\.class</ignore>
|
<ignore>.*\$KEYS\.class</ignore>
|
||||||
<ignore>.*\$Element\.class</ignore>
|
<ignore>.*\$Element\.class</ignore>
|
||||||
@@ -182,14 +174,9 @@ along with Dependency-Check. If not, see <http://www.gnu.org/licenses />.
|
|||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-surefire-plugin</artifactId>
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
<version>2.14</version>
|
|
||||||
<configuration>
|
<configuration>
|
||||||
|
<argLine>-Dfile.encoding=UTF-8</argLine>
|
||||||
<systemProperties>
|
<systemProperties>
|
||||||
<property>
|
|
||||||
<name>net.sourceforge.cobertura.datafile</name>
|
|
||||||
<value>${project.build.directory}/cobertura/cobertura.ser</value>
|
|
||||||
<workingDirectory>target</workingDirectory>
|
|
||||||
</property>
|
|
||||||
<property>
|
<property>
|
||||||
<name>data.directory</name>
|
<name>data.directory</name>
|
||||||
<value>${project.build.directory}/data</value>
|
<value>${project.build.directory}/data</value>
|
||||||
@@ -201,22 +188,326 @@ along with Dependency-Check. If not, see <http://www.gnu.org/licenses />.
|
|||||||
</systemProperties>
|
</systemProperties>
|
||||||
<excludes>
|
<excludes>
|
||||||
<exclude>**/*IntegrationTest.java</exclude>
|
<exclude>**/*IntegrationTest.java</exclude>
|
||||||
|
<exclude>**/*MySQLTest.java</exclude>
|
||||||
</excludes>
|
</excludes>
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-failsafe-plugin</artifactId>
|
<artifactId>maven-failsafe-plugin</artifactId>
|
||||||
<version>2.14</version>
|
|
||||||
<configuration>
|
<configuration>
|
||||||
<systemProperties>
|
<systemProperties>
|
||||||
<property>
|
<property>
|
||||||
<name>data.directory</name>
|
<name>data.directory</name>
|
||||||
<value>${project.build.directory}/data</value>
|
<value>${project.build.directory}/data</value>
|
||||||
</property>
|
</property>
|
||||||
|
<property>
|
||||||
|
<name>temp.directory</name>
|
||||||
|
<value>${project.build.directory}/temp</value>
|
||||||
|
</property>
|
||||||
|
</systemProperties>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
<reporting>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-surefire-report-plugin</artifactId>
|
||||||
|
<reportSets>
|
||||||
|
<reportSet>
|
||||||
|
<id>integration-tests</id>
|
||||||
|
<reports>
|
||||||
|
<report>report-only</report>
|
||||||
|
<report>failsafe-report-only</report>
|
||||||
|
</reports>
|
||||||
|
</reportSet>
|
||||||
|
</reportSets>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-checkstyle-plugin</artifactId>
|
||||||
|
<version>${reporting.checkstyle-plugin.version}</version>
|
||||||
|
<configuration>
|
||||||
|
<enableRulesSummary>false</enableRulesSummary>
|
||||||
|
<enableFilesSummary>false</enableFilesSummary>
|
||||||
|
<configLocation>${basedir}/../src/main/config/checkstyle-checks.xml</configLocation>
|
||||||
|
<headerLocation>${basedir}/../src/main/config/checkstyle-header.txt</headerLocation>
|
||||||
|
<suppressionsLocation>${basedir}/../src/main/config/checkstyle-suppressions.xml</suppressionsLocation>
|
||||||
|
<suppressionsFileExpression>checkstyle.suppressions.file</suppressionsFileExpression>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-pmd-plugin</artifactId>
|
||||||
|
<version>${reporting.pmd-plugin.version}</version>
|
||||||
|
<configuration>
|
||||||
|
<targetJdk>1.6</targetJdk>
|
||||||
|
<linkXRef>true</linkXRef>
|
||||||
|
<sourceEncoding>utf-8</sourceEncoding>
|
||||||
|
<excludes>
|
||||||
|
<exclude>**/generated/*.java</exclude>
|
||||||
|
</excludes>
|
||||||
|
<rulesets>
|
||||||
|
<ruleset>../src/main/config/dcrules.xml</ruleset>
|
||||||
|
<ruleset>/rulesets/java/basic.xml</ruleset>
|
||||||
|
<ruleset>/rulesets/java/imports.xml</ruleset>
|
||||||
|
<ruleset>/rulesets/java/unusedcode.xml</ruleset>
|
||||||
|
</rulesets>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</reporting>
|
||||||
|
<dependencies>
|
||||||
|
<!-- Note, to stay compatible with Jenkins installations only JARs compiled to 1.6 can be used -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>joda-time</groupId>
|
||||||
|
<artifactId>joda-time</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.google.code.findbugs</groupId>
|
||||||
|
<artifactId>annotations</artifactId>
|
||||||
|
<optional>true</optional>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.slf4j</groupId>
|
||||||
|
<artifactId>slf4j-api</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<!-- Set this to test so that each project that uses this has to have its own implementation of SLF4J -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>ch.qos.logback</groupId>
|
||||||
|
<artifactId>logback-classic</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.owasp</groupId>
|
||||||
|
<artifactId>dependency-check-utils</artifactId>
|
||||||
|
<version>${project.parent.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.lucene</groupId>
|
||||||
|
<artifactId>lucene-test-framework</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.jmockit</groupId>
|
||||||
|
<artifactId>jmockit</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.commons</groupId>
|
||||||
|
<artifactId>commons-compress</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>commons-io</groupId>
|
||||||
|
<artifactId>commons-io</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.commons</groupId>
|
||||||
|
<artifactId>commons-lang3</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.lucene</groupId>
|
||||||
|
<artifactId>lucene-core</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.lucene</groupId>
|
||||||
|
<artifactId>lucene-analyzers-common</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.lucene</groupId>
|
||||||
|
<artifactId>lucene-queryparser</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.velocity</groupId>
|
||||||
|
<artifactId>velocity</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.h2database</groupId>
|
||||||
|
<artifactId>h2</artifactId>
|
||||||
|
<scope>runtime</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.glassfish</groupId>
|
||||||
|
<artifactId>javax.json</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.jsoup</groupId>
|
||||||
|
<artifactId>jsoup</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.sun.mail</groupId>
|
||||||
|
<artifactId>mailapi</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<!-- The following dependencies are only used during testing -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.maven.scm</groupId>
|
||||||
|
<artifactId>maven-scm-provider-cvsexe</artifactId>
|
||||||
|
<version>1.8.1</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
<optional>true</optional>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework</groupId>
|
||||||
|
<artifactId>spring-webmvc</artifactId>
|
||||||
|
<version>2.5.5</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
<optional>true</optional>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.security</groupId>
|
||||||
|
<artifactId>spring-security-web</artifactId>
|
||||||
|
<version>3.0.0.RELEASE</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
<optional>true</optional>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.hazelcast</groupId>
|
||||||
|
<artifactId>hazelcast</artifactId>
|
||||||
|
<version>2.5</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
<optional>true</optional>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>net.sf.ehcache</groupId>
|
||||||
|
<artifactId>ehcache-core</artifactId>
|
||||||
|
<version>2.2.0</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
<optional>true</optional>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.struts</groupId>
|
||||||
|
<artifactId>struts2-core</artifactId>
|
||||||
|
<version>2.1.2</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
<optional>true</optional>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.mortbay.jetty</groupId>
|
||||||
|
<artifactId>jetty</artifactId>
|
||||||
|
<version>6.1.0</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
<optional>true</optional>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.axis2</groupId>
|
||||||
|
<artifactId>axis2-spring</artifactId>
|
||||||
|
<version>1.4.1</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
<optional>true</optional>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.axis2</groupId>
|
||||||
|
<artifactId>axis2-adb</artifactId>
|
||||||
|
<version>1.4.1</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
<optional>true</optional>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.geronimo.daytrader</groupId>
|
||||||
|
<artifactId>daytrader-ear</artifactId>
|
||||||
|
<version>2.1.7</version>
|
||||||
|
<type>ear</type>
|
||||||
|
<scope>test</scope>
|
||||||
|
<optional>true</optional>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.glassfish.main.admingui</groupId>
|
||||||
|
<artifactId>war</artifactId>
|
||||||
|
<version>4.0</version>
|
||||||
|
<type>war</type>
|
||||||
|
<scope>test</scope>
|
||||||
|
<optional>true</optional>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.dojotoolkit</groupId>
|
||||||
|
<artifactId>dojo-war</artifactId>
|
||||||
|
<version>1.3.0</version>
|
||||||
|
<type>war</type>
|
||||||
|
<scope>test</scope>
|
||||||
|
<optional>true</optional>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.openjpa</groupId>
|
||||||
|
<artifactId>openjpa</artifactId>
|
||||||
|
<version>2.0.1</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
<optional>true</optional>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.google.inject</groupId>
|
||||||
|
<artifactId>guice</artifactId>
|
||||||
|
<version>3.0</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
<optional>true</optional>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.retry</groupId>
|
||||||
|
<artifactId>spring-retry</artifactId>
|
||||||
|
<version>1.1.0.RELEASE</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
<optional>true</optional>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>uk.ltd.getahead</groupId>
|
||||||
|
<artifactId>dwr</artifactId>
|
||||||
|
<version>1.1.1</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
<optional>true</optional>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>xalan</groupId>
|
||||||
|
<artifactId>xalan</artifactId>
|
||||||
|
<version>2.7.0</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
<optional>true</optional>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.thoughtworks.xstream</groupId>
|
||||||
|
<artifactId>xstream</artifactId>
|
||||||
|
<version>1.4.8</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
<optional>true</optional>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
<profiles>
|
||||||
|
<profile>
|
||||||
|
<id>MySQL-IntegrationTest</id>
|
||||||
|
<activation>
|
||||||
|
<property>
|
||||||
|
<name>mysql</name>
|
||||||
|
</property>
|
||||||
|
</activation>
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<skip>true</skip>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-failsafe-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<systemProperties>
|
||||||
|
<property>
|
||||||
|
<name>data.driver_path</name>
|
||||||
|
<value>${driver_path}</value>
|
||||||
|
</property>
|
||||||
|
<property>
|
||||||
|
<name>data.driver_name</name>
|
||||||
|
<value>${driver_name}</value>
|
||||||
|
</property>
|
||||||
|
<property>
|
||||||
|
<name>data.connection_string</name>
|
||||||
|
<value>${connection_string}</value>
|
||||||
|
</property>
|
||||||
</systemProperties>
|
</systemProperties>
|
||||||
<includes>
|
<includes>
|
||||||
<include>**/*IntegrationTest.java</include>
|
<include>**/*MySQLTest.java</include>
|
||||||
</includes>
|
</includes>
|
||||||
</configuration>
|
</configuration>
|
||||||
<executions>
|
<executions>
|
||||||
@@ -228,345 +519,216 @@ along with Dependency-Check. If not, see <http://www.gnu.org/licenses />.
|
|||||||
</execution>
|
</execution>
|
||||||
</executions>
|
</executions>
|
||||||
</plugin>
|
</plugin>
|
||||||
<plugin>
|
</plugins>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
</build>
|
||||||
<artifactId>maven-site-plugin</artifactId>
|
</profile>
|
||||||
<version>3.3</version>
|
<profile>
|
||||||
|
<id>Postgresql-IntegrationTest</id>
|
||||||
|
<activation>
|
||||||
|
<property>
|
||||||
|
<name>postgresql</name>
|
||||||
|
</property>
|
||||||
|
</activation>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.maven.doxia</groupId>
|
<groupId>org.postgresql</groupId>
|
||||||
<artifactId>doxia-module-markdown</artifactId>
|
<artifactId>postgresql</artifactId>
|
||||||
<version>1.4</version>
|
<version>9.4-1204-jdbc42</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
<configuration>
|
<configuration>
|
||||||
<skipDeploy>true</skipDeploy>
|
<skip>true</skip>
|
||||||
<reportPlugins>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-project-info-reports-plugin</artifactId>
|
|
||||||
<version>2.6</version>
|
|
||||||
<reportSets>
|
|
||||||
<reportSet>
|
|
||||||
<reports>
|
|
||||||
<report>index</report>
|
|
||||||
<report>summary</report>
|
|
||||||
<report>license</report>
|
|
||||||
<report>help</report>
|
|
||||||
</reports>
|
|
||||||
</reportSet>
|
|
||||||
</reportSets>
|
|
||||||
</plugin>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-javadoc-plugin</artifactId>
|
|
||||||
<version>2.9</version>
|
|
||||||
<reportSets>
|
|
||||||
<reportSet>
|
|
||||||
<id>default</id>
|
|
||||||
<reports>
|
|
||||||
<report>javadoc</report>
|
|
||||||
</reports>
|
|
||||||
</reportSet>
|
|
||||||
</reportSets>
|
|
||||||
</plugin>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.codehaus.mojo</groupId>
|
|
||||||
<artifactId>versions-maven-plugin</artifactId>
|
|
||||||
<version>2.0</version>
|
|
||||||
<reportSets>
|
|
||||||
<reportSet>
|
|
||||||
<reports>
|
|
||||||
<report>dependency-updates-report</report>
|
|
||||||
<report>plugin-updates-report</report>
|
|
||||||
</reports>
|
|
||||||
</reportSet>
|
|
||||||
</reportSets>
|
|
||||||
</plugin>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-jxr-plugin</artifactId>
|
|
||||||
<version>2.3</version>
|
|
||||||
</plugin>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.codehaus.mojo</groupId>
|
|
||||||
<artifactId>cobertura-maven-plugin</artifactId>
|
|
||||||
<version>2.5.2</version>
|
|
||||||
</plugin>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-surefire-report-plugin</artifactId>
|
|
||||||
<version>2.14</version>
|
|
||||||
<reportSets>
|
|
||||||
<reportSet>
|
|
||||||
<reports>
|
|
||||||
<report>report-only</report>
|
|
||||||
</reports>
|
|
||||||
</reportSet>
|
|
||||||
<reportSet>
|
|
||||||
<id>integration-tests</id>
|
|
||||||
<reports>
|
|
||||||
<report>report-only</report>
|
|
||||||
<report>failsafe-report-only</report>
|
|
||||||
</reports>
|
|
||||||
</reportSet>
|
|
||||||
</reportSets>
|
|
||||||
</plugin>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.codehaus.mojo</groupId>
|
|
||||||
<artifactId>taglist-maven-plugin</artifactId>
|
|
||||||
<version>2.4</version>
|
|
||||||
<configuration>
|
|
||||||
<tagListOptions>
|
|
||||||
<tagClasses>
|
|
||||||
<tagClass>
|
|
||||||
<displayName>Todo Work</displayName>
|
|
||||||
<tags>
|
|
||||||
<tag>
|
|
||||||
<matchString>todo</matchString>
|
|
||||||
<matchType>ignoreCase</matchType>
|
|
||||||
</tag>
|
|
||||||
<tag>
|
|
||||||
<matchString>FIXME</matchString>
|
|
||||||
<matchType>exact</matchType>
|
|
||||||
</tag>
|
|
||||||
</tags>
|
|
||||||
</tagClass>
|
|
||||||
</tagClasses>
|
|
||||||
</tagListOptions>
|
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-checkstyle-plugin</artifactId>
|
<artifactId>maven-failsafe-plugin</artifactId>
|
||||||
<version>2.10</version>
|
|
||||||
<configuration>
|
<configuration>
|
||||||
<enableRulesSummary>false</enableRulesSummary>
|
<systemProperties>
|
||||||
<configLocation>${basedir}/config/checkstyle-checks.xml</configLocation>
|
<property>
|
||||||
<headerLocation>${basedir}/config/checkstyle-header.txt</headerLocation>
|
<name>data.driver_path</name>
|
||||||
<suppressionsLocation>${basedir}/config/checkstyle-suppressions.xml</suppressionsLocation>
|
<value>${driver_path}</value>
|
||||||
<suppressionsFileExpression>checkstyle.suppressions.file</suppressionsFileExpression>
|
</property>
|
||||||
</configuration>
|
<property>
|
||||||
</plugin>
|
<name>data.driver_name</name>
|
||||||
<plugin>
|
<value>${driver_name}</value>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
</property>
|
||||||
<artifactId>maven-pmd-plugin</artifactId>
|
<property>
|
||||||
<version>3.0.1</version>
|
<name>data.connection_string</name>
|
||||||
<configuration>
|
<value>${connection_string}</value>
|
||||||
<targetJdk>1.6</targetJdk>
|
</property>
|
||||||
<linkXref>true</linkXref>
|
</systemProperties>
|
||||||
<sourceEncoding>utf-8</sourceEncoding>
|
<includes>
|
||||||
<excludes>
|
<include>**/*MySQLTest.java</include>
|
||||||
<exclude>**/generated/*.java</exclude>
|
</includes>
|
||||||
</excludes>
|
|
||||||
</configuration>
|
|
||||||
</plugin>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.codehaus.mojo</groupId>
|
|
||||||
<artifactId>findbugs-maven-plugin</artifactId>
|
|
||||||
<version>2.5.2</version>
|
|
||||||
</plugin>
|
|
||||||
</reportPlugins>
|
|
||||||
</configuration>
|
|
||||||
</plugin>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-compiler-plugin</artifactId>
|
|
||||||
<version>2.3.2</version>
|
|
||||||
<configuration>
|
|
||||||
<showDeprecation>false</showDeprecation>
|
|
||||||
</configuration>
|
</configuration>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<goals>
|
||||||
|
<goal>integration-test</goal>
|
||||||
|
<goal>verify</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
</plugin>
|
</plugin>
|
||||||
</plugins>
|
</plugins>
|
||||||
</build>
|
</build>
|
||||||
|
</profile>
|
||||||
|
<!--
|
||||||
|
The following profile adds additional dependencies that are only
|
||||||
|
used during testing.
|
||||||
|
|
||||||
|
TODO move the following FP tests to a seperate invoker test in the
|
||||||
|
maven plugin project. Add checks against the XML to validate that
|
||||||
|
these do not report FP.
|
||||||
|
-->
|
||||||
|
<!--profile>
|
||||||
|
<id>False Positive Tests</id>
|
||||||
|
<activation>
|
||||||
|
<property>
|
||||||
|
<name>releaseTesting</name>
|
||||||
|
</property>
|
||||||
|
</activation>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.lucene</groupId>
|
<groupId>org.apache.xmlgraphics</groupId>
|
||||||
<artifactId>lucene-test-framework</artifactId>
|
<artifactId>batik-util</artifactId>
|
||||||
<version>4.3.1</version>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.google.code.findbugs</groupId>
|
|
||||||
<artifactId>annotations</artifactId>
|
|
||||||
<version>2.0.1</version>
|
|
||||||
<optional>true</optional>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>commons-cli</groupId>
|
|
||||||
<artifactId>commons-cli</artifactId>
|
|
||||||
<version>1.2</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>commons-io</groupId>
|
|
||||||
<artifactId>commons-io</artifactId>
|
|
||||||
<version>2.4</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>commons-lang</groupId>
|
|
||||||
<artifactId>commons-lang</artifactId>
|
|
||||||
<version>2.5</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.apache.lucene</groupId>
|
|
||||||
<artifactId>lucene-core</artifactId>
|
|
||||||
<version>4.3.1</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.apache.lucene</groupId>
|
|
||||||
<artifactId>lucene-analyzers-common</artifactId>
|
|
||||||
<version>4.3.1</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.apache.lucene</groupId>
|
|
||||||
<artifactId>lucene-queryparser</artifactId>
|
|
||||||
<version>4.3.1</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.apache.velocity</groupId>
|
|
||||||
<artifactId>velocity</artifactId>
|
|
||||||
<version>1.7</version>
|
<version>1.7</version>
|
||||||
</dependency>
|
<scope>test</scope>
|
||||||
<dependency>
|
|
||||||
<groupId>org.apache.velocity</groupId>
|
|
||||||
<artifactId>velocity-tools</artifactId>
|
|
||||||
<version>2.0</version>
|
|
||||||
<!-- very limited use of the velocity-tools, not all of the dependencies are needed-->
|
|
||||||
<exclusions>
|
|
||||||
<exclusion>
|
|
||||||
<groupId>commons-chain</groupId>
|
|
||||||
<artifactId>commons-chain</artifactId>
|
|
||||||
</exclusion>
|
|
||||||
<exclusion>
|
|
||||||
<groupId>javax.servlet</groupId>
|
|
||||||
<artifactId>servlet-api</artifactId>
|
|
||||||
</exclusion>
|
|
||||||
<exclusion>
|
|
||||||
<groupId>commons-validator</groupId>
|
|
||||||
<artifactId>commons-validator</artifactId>
|
|
||||||
</exclusion>
|
|
||||||
<exclusion>
|
|
||||||
<groupId>dom4j</groupId>
|
|
||||||
<artifactId>dom4j</artifactId>
|
|
||||||
</exclusion>
|
|
||||||
<exclusion>
|
|
||||||
<groupId>sslext</groupId>
|
|
||||||
<artifactId>sslext</artifactId>
|
|
||||||
</exclusion>
|
|
||||||
<exclusion>
|
|
||||||
<groupId>org.apache.struts</groupId>
|
|
||||||
<artifactId>struts-core</artifactId>
|
|
||||||
</exclusion>
|
|
||||||
<exclusion>
|
|
||||||
<groupId>antlr</groupId>
|
|
||||||
<artifactId>antlr</artifactId>
|
|
||||||
</exclusion>
|
|
||||||
<exclusion>
|
|
||||||
<groupId>org.apache.struts</groupId>
|
|
||||||
<artifactId>struts-taglib</artifactId>
|
|
||||||
</exclusion>
|
|
||||||
<exclusion>
|
|
||||||
<groupId>org.apache.struts</groupId>
|
|
||||||
<artifactId>struts-tiles</artifactId>
|
|
||||||
</exclusion>
|
|
||||||
</exclusions>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.h2database</groupId>
|
|
||||||
<artifactId>h2</artifactId>
|
|
||||||
<version>1.3.172</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.jsoup</groupId>
|
|
||||||
<artifactId>jsoup</artifactId>
|
|
||||||
<version>1.7.2</version>
|
|
||||||
<type>jar</type>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.apache.commons</groupId>
|
|
||||||
<artifactId>commons-compress</artifactId>
|
|
||||||
<version>1.5</version>
|
|
||||||
</dependency>
|
|
||||||
<!-- The following dependencies are only used during testing -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.apache.maven.scm</groupId>
|
|
||||||
<artifactId>maven-scm-provider-cvsexe</artifactId>
|
|
||||||
<version>1.8.1</version>
|
|
||||||
<scope>provided</scope>
|
|
||||||
<optional>true</optional>
|
<optional>true</optional>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework</groupId>
|
<groupId>org.apache.ws.security</groupId>
|
||||||
<artifactId>spring-webmvc</artifactId>
|
<artifactId>wss4j</artifactId>
|
||||||
<version>2.5.5</version>
|
<version>1.5.7</version>
|
||||||
<scope>provided</scope>
|
<scope>test</scope>
|
||||||
<optional>true</optional>
|
<optional>true</optional>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.hazelcast</groupId>
|
<groupId>com.ganyo</groupId>
|
||||||
<artifactId>hazelcast</artifactId>
|
<artifactId>gcm-server</artifactId>
|
||||||
<version>2.5</version>
|
<version>1.0.2</version>
|
||||||
<scope>provided</scope>
|
<scope>test</scope>
|
||||||
<optional>true</optional>
|
<optional>true</optional>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>net.sf.ehcache</groupId>
|
<groupId>org.python</groupId>
|
||||||
<artifactId>ehcache-core</artifactId>
|
<artifactId>jython-standalone</artifactId>
|
||||||
<version>2.2.0</version>
|
<version>2.7-b1</version>
|
||||||
<scope>provided</scope>
|
<scope>test</scope>
|
||||||
<optional>true</optional>
|
<optional>true</optional>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.struts</groupId>
|
<groupId>org.jruby</groupId>
|
||||||
<artifactId>struts2-core</artifactId>
|
<artifactId>jruby-complete</artifactId>
|
||||||
<version>2.1.2</version>
|
<version>1.7.4</version>
|
||||||
<scope>provided</scope>
|
<scope>test</scope>
|
||||||
<optional>true</optional>
|
<optional>true</optional>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.mortbay.jetty</groupId>
|
<groupId>org.jruby</groupId>
|
||||||
<artifactId>jetty</artifactId>
|
<artifactId>jruby</artifactId>
|
||||||
<version>6.1.0</version>
|
<version>1.6.3</version>
|
||||||
<scope>provided</scope>
|
<scope>test</scope>
|
||||||
<optional>true</optional>
|
<optional>true</optional>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.axis2</groupId>
|
<groupId>org.glassfish.jersey.core</groupId>
|
||||||
<artifactId>axis2-spring</artifactId>
|
<artifactId>jersey-client</artifactId>
|
||||||
|
<version>2.12</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
<optional>true</optional>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.sun.jersey</groupId>
|
||||||
|
<artifactId>jersey-client</artifactId>
|
||||||
|
<version>1.11.1</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
<optional>true</optional>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.sun.faces</groupId>
|
||||||
|
<artifactId>jsf-impl</artifactId>
|
||||||
|
<version>2.2.8-02</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
<optional>true</optional>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.google.inject</groupId>
|
||||||
|
<artifactId>guice</artifactId>
|
||||||
|
<version>3.0</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
<optional>true</optional>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.opensaml</groupId>
|
||||||
|
<artifactId>xmltooling</artifactId>
|
||||||
<version>1.4.1</version>
|
<version>1.4.1</version>
|
||||||
<scope>provided</scope>
|
<scope>test</scope>
|
||||||
<optional>true</optional>
|
<optional>true</optional>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.axis2</groupId>
|
<groupId>com.google.code.gson</groupId>
|
||||||
<artifactId>axis2-adb</artifactId>
|
<artifactId>gson</artifactId>
|
||||||
<version>1.4.1</version>
|
<version>2.3.1</version>
|
||||||
<scope>provided</scope>
|
<scope>test</scope>
|
||||||
<optional>true</optional>
|
<optional>true</optional>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.geronimo.daytrader</groupId>
|
<groupId>com.google.gerrit</groupId>
|
||||||
<artifactId>daytrader-ear</artifactId>
|
<artifactId>gerrit-extension-api</artifactId>
|
||||||
<version>2.1.7</version>
|
<version>2.11</version>
|
||||||
<type>ear</type>
|
<scope>test</scope>
|
||||||
<scope>provided</scope>
|
|
||||||
<optional>true</optional>
|
<optional>true</optional>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.glassfish.main.admingui</groupId>
|
<groupId>com.google.apis</groupId>
|
||||||
<artifactId>war</artifactId>
|
<artifactId>google-api-services-sqladmin</artifactId>
|
||||||
<version>4.0</version>
|
<version>v1beta4-rev5-1.20.0</version>
|
||||||
<type>war</type>
|
<scope>test</scope>
|
||||||
<scope>provided</scope>
|
|
||||||
<optional>true</optional>
|
<optional>true</optional>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.dojotoolkit</groupId>
|
<groupId>com.google.gwt.google-apis</groupId>
|
||||||
<artifactId>dojo-war</artifactId>
|
<artifactId>gwt-gears</artifactId>
|
||||||
<version>1.3.0</version>
|
<version>1.2.1</version>
|
||||||
<type>war</type>
|
<scope>test</scope>
|
||||||
<scope>provided</scope>
|
<optional>true</optional>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.mozilla</groupId>
|
||||||
|
<artifactId>rhino</artifactId>
|
||||||
|
<version>1.7.6</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
<optional>true</optional>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.microsoft.windowsazure</groupId>
|
||||||
|
<artifactId>microsoft-azure-api-media</artifactId>
|
||||||
|
<version>0.5.0</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
<optional>true</optional>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.microsoft.windowsazure</groupId>
|
||||||
|
<artifactId>microsoft-azure-api-management-sql</artifactId>
|
||||||
|
<version>0.5.0</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
<optional>true</optional>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.microsoft.bingads</groupId>
|
||||||
|
<artifactId>microsoft.bingads</artifactId>
|
||||||
|
<version>9.3.4</version>
|
||||||
|
<scope>test</scope>
|
||||||
<optional>true</optional>
|
<optional>true</optional>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
</profile-->
|
||||||
|
</profiles>
|
||||||
</project>
|
</project>
|
||||||
|
|||||||
@@ -0,0 +1,129 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of dependency-check-core.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
* Copyright (c) 2016 Stefan Neuhaus. All Rights Reserved.
|
||||||
|
*/
|
||||||
|
package org.owasp.dependencycheck;
|
||||||
|
|
||||||
|
import org.owasp.dependencycheck.analyzer.Analyzer;
|
||||||
|
import org.owasp.dependencycheck.analyzer.FileTypeAnalyzer;
|
||||||
|
import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
|
||||||
|
import org.owasp.dependencycheck.dependency.Dependency;
|
||||||
|
import org.owasp.dependencycheck.utils.Settings;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.Callable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Task to support parallelism of dependency-check analysis. Analyses a single
|
||||||
|
* {@link Dependency} by a specific {@link Analyzer}.
|
||||||
|
*
|
||||||
|
* @author Stefan Neuhaus
|
||||||
|
*/
|
||||||
|
public class AnalysisTask implements Callable<Void> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instance of the logger.
|
||||||
|
*/
|
||||||
|
private static final Logger LOGGER = LoggerFactory.getLogger(AnalysisTask.class);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A reference to the analyzer.
|
||||||
|
*/
|
||||||
|
private final Analyzer analyzer;
|
||||||
|
/**
|
||||||
|
* The dependency to analyze.
|
||||||
|
*/
|
||||||
|
private final Dependency dependency;
|
||||||
|
/**
|
||||||
|
* A reference to the dependency-check engine.
|
||||||
|
*/
|
||||||
|
private final Engine engine;
|
||||||
|
/**
|
||||||
|
* The list of exceptions that may occur during analysis.
|
||||||
|
*/
|
||||||
|
private final List<Throwable> exceptions;
|
||||||
|
/**
|
||||||
|
* A reference to the global settings object.
|
||||||
|
*/
|
||||||
|
private final Settings settings;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new analysis task.
|
||||||
|
*
|
||||||
|
* @param analyzer a reference of the analyzer to execute
|
||||||
|
* @param dependency the dependency to analyze
|
||||||
|
* @param engine the dependency-check engine
|
||||||
|
* @param exceptions exceptions that occur during analysis will be added to
|
||||||
|
* this collection of exceptions
|
||||||
|
* @param settings a reference to the global settings object; this is
|
||||||
|
* necessary so that when the thread is started the dependencies have a
|
||||||
|
* correct reference to the global settings.
|
||||||
|
*/
|
||||||
|
AnalysisTask(Analyzer analyzer, Dependency dependency, Engine engine, List<Throwable> exceptions, Settings settings) {
|
||||||
|
this.analyzer = analyzer;
|
||||||
|
this.dependency = dependency;
|
||||||
|
this.engine = engine;
|
||||||
|
this.exceptions = exceptions;
|
||||||
|
this.settings = settings;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Executes the analysis task.
|
||||||
|
*
|
||||||
|
* @return null
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Void call() {
|
||||||
|
try {
|
||||||
|
Settings.setInstance(settings);
|
||||||
|
|
||||||
|
if (shouldAnalyze()) {
|
||||||
|
LOGGER.debug("Begin Analysis of '{}' ({})", dependency.getActualFilePath(), analyzer.getName());
|
||||||
|
try {
|
||||||
|
analyzer.analyze(dependency, engine);
|
||||||
|
} catch (AnalysisException ex) {
|
||||||
|
LOGGER.warn("An error occurred while analyzing '{}' ({}).", dependency.getActualFilePath(), analyzer.getName());
|
||||||
|
LOGGER.debug("", ex);
|
||||||
|
exceptions.add(ex);
|
||||||
|
} catch (Throwable ex) {
|
||||||
|
LOGGER.warn("An unexpected error occurred during analysis of '{}' ({}): {}",
|
||||||
|
dependency.getActualFilePath(), analyzer.getName(), ex.getMessage());
|
||||||
|
LOGGER.debug("", ex);
|
||||||
|
exceptions.add(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
Settings.cleanup(false);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines if the analyzer can analyze the given dependency.
|
||||||
|
*
|
||||||
|
* @return whether or not the analyzer can analyze the dependency
|
||||||
|
*/
|
||||||
|
protected boolean shouldAnalyze() {
|
||||||
|
if (analyzer instanceof FileTypeAnalyzer) {
|
||||||
|
final FileTypeAnalyzer fileTypeAnalyzer = (FileTypeAnalyzer) analyzer;
|
||||||
|
return fileTypeAnalyzer.accept(dependency.getActualFile());
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,43 +1,59 @@
|
|||||||
/*
|
/*
|
||||||
* This file is part of dependency-check-core.
|
* This file is part of dependency-check-core.
|
||||||
*
|
*
|
||||||
* Dependency-check-core is free software: you can redistribute it and/or modify it
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* under the terms of the GNU General Public License as published by the Free
|
* you may not use this file except in compliance with the License.
|
||||||
* Software Foundation, either version 3 of the License, or (at your option) any
|
* You may obtain a copy of the License at
|
||||||
* later version.
|
|
||||||
*
|
*
|
||||||
* Dependency-check-core is distributed in the hope that it will be useful, but
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
|
||||||
* details.
|
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License along with
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* dependency-check-core. If not, see http://www.gnu.org/licenses/.
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
*
|
*
|
||||||
* Copyright (c) 2012 Jeremy Long. All Rights Reserved.
|
* Copyright (c) 2012 Jeremy Long. All Rights Reserved.
|
||||||
*/
|
*/
|
||||||
package org.owasp.dependencycheck;
|
package org.owasp.dependencycheck;
|
||||||
|
|
||||||
import java.util.EnumMap;
|
|
||||||
import java.io.File;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.logging.Level;
|
|
||||||
import java.util.logging.Logger;
|
|
||||||
import org.owasp.dependencycheck.analyzer.AnalysisException;
|
|
||||||
import org.owasp.dependencycheck.analyzer.AnalysisPhase;
|
import org.owasp.dependencycheck.analyzer.AnalysisPhase;
|
||||||
import org.owasp.dependencycheck.analyzer.Analyzer;
|
import org.owasp.dependencycheck.analyzer.Analyzer;
|
||||||
import org.owasp.dependencycheck.analyzer.AnalyzerService;
|
import org.owasp.dependencycheck.analyzer.AnalyzerService;
|
||||||
import org.owasp.dependencycheck.data.CachedWebDataSource;
|
import org.owasp.dependencycheck.analyzer.FileTypeAnalyzer;
|
||||||
import org.owasp.dependencycheck.data.UpdateException;
|
import org.owasp.dependencycheck.data.nvdcve.ConnectionFactory;
|
||||||
import org.owasp.dependencycheck.data.UpdateService;
|
import org.owasp.dependencycheck.data.nvdcve.CveDB;
|
||||||
|
import org.owasp.dependencycheck.data.nvdcve.DatabaseException;
|
||||||
|
import org.owasp.dependencycheck.data.update.CachedWebDataSource;
|
||||||
|
import org.owasp.dependencycheck.data.update.UpdateService;
|
||||||
|
import org.owasp.dependencycheck.data.update.exception.UpdateException;
|
||||||
import org.owasp.dependencycheck.dependency.Dependency;
|
import org.owasp.dependencycheck.dependency.Dependency;
|
||||||
import org.owasp.dependencycheck.utils.FileUtils;
|
import org.owasp.dependencycheck.exception.ExceptionCollection;
|
||||||
|
import org.owasp.dependencycheck.exception.InitializationException;
|
||||||
|
import org.owasp.dependencycheck.exception.NoDataException;
|
||||||
import org.owasp.dependencycheck.utils.InvalidSettingException;
|
import org.owasp.dependencycheck.utils.InvalidSettingException;
|
||||||
import org.owasp.dependencycheck.utils.Settings;
|
import org.owasp.dependencycheck.utils.Settings;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileFilter;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.EnumMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.CancellationException;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
import java.util.concurrent.Future;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Scans files, directories, etc. for Dependencies. Analyzers are loaded and
|
* Scans files, directories, etc. for Dependencies. Analyzers are loaded and
|
||||||
@@ -45,74 +61,101 @@ import org.owasp.dependencycheck.utils.Settings;
|
|||||||
* Analyzer is associated with the file type then the file is turned into a
|
* Analyzer is associated with the file type then the file is turned into a
|
||||||
* dependency.
|
* dependency.
|
||||||
*
|
*
|
||||||
* @author Jeremy Long (jeremy.long@owasp.org)
|
* @author Jeremy Long
|
||||||
*/
|
*/
|
||||||
public class Engine {
|
public class Engine implements FileFilter {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The list of dependencies.
|
* The list of dependencies.
|
||||||
*/
|
*/
|
||||||
private final List<Dependency> dependencies = new ArrayList<Dependency>();
|
private final List<Dependency> dependencies = Collections.synchronizedList(new ArrayList<Dependency>());
|
||||||
/**
|
/**
|
||||||
* A Map of analyzers grouped by Analysis phase.
|
* A Map of analyzers grouped by Analysis phase.
|
||||||
*/
|
*/
|
||||||
private final EnumMap<AnalysisPhase, List<Analyzer>> analyzers =
|
private final Map<AnalysisPhase, List<Analyzer>> analyzers = new EnumMap<>(AnalysisPhase.class);
|
||||||
new EnumMap<AnalysisPhase, List<Analyzer>>(AnalysisPhase.class);
|
|
||||||
/**
|
/**
|
||||||
* A set of extensions supported by the analyzers.
|
* A Map of analyzers grouped by Analysis phase.
|
||||||
*/
|
*/
|
||||||
private final Set<String> extensions = new HashSet<String>();
|
private final Set<FileTypeAnalyzer> fileTypeAnalyzers = new HashSet<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The ClassLoader to use when dynamically loading Analyzer and Update
|
||||||
|
* services.
|
||||||
|
*/
|
||||||
|
private ClassLoader serviceClassLoader = Thread.currentThread().getContextClassLoader();
|
||||||
|
/**
|
||||||
|
* A reference to the database.
|
||||||
|
*/
|
||||||
|
private CveDB database = null;
|
||||||
|
/**
|
||||||
|
* The Logger for use throughout the class.
|
||||||
|
*/
|
||||||
|
private static final Logger LOGGER = LoggerFactory.getLogger(Engine.class);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new Engine.
|
* Creates a new Engine.
|
||||||
|
*
|
||||||
|
* @throws DatabaseException thrown if there is an error connecting to the
|
||||||
|
* database
|
||||||
*/
|
*/
|
||||||
public Engine() {
|
public Engine() throws DatabaseException {
|
||||||
boolean autoUpdate = true;
|
initializeEngine();
|
||||||
try {
|
|
||||||
autoUpdate = Settings.getBoolean(Settings.KEYS.AUTO_UPDATE);
|
|
||||||
} catch (InvalidSettingException ex) {
|
|
||||||
Logger.getLogger(Engine.class.getName()).log(Level.FINE, "Invalid setting for auto-update; using true.");
|
|
||||||
}
|
|
||||||
if (autoUpdate) {
|
|
||||||
doUpdates();
|
|
||||||
}
|
|
||||||
loadAnalyzers();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new Engine.
|
* Creates a new Engine.
|
||||||
*
|
*
|
||||||
* @param autoUpdate indicates whether or not data should be updated from
|
* @param serviceClassLoader a reference the class loader being used
|
||||||
* the Internet
|
* @throws DatabaseException thrown if there is an error connecting to the
|
||||||
* @deprecated This function should no longer be used; the autoupdate flag
|
* database
|
||||||
* should be set using:
|
|
||||||
* <code>Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, value);</code>
|
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
public Engine(ClassLoader serviceClassLoader) throws DatabaseException {
|
||||||
public Engine(boolean autoUpdate) {
|
this.serviceClassLoader = serviceClassLoader;
|
||||||
if (autoUpdate) {
|
initializeEngine();
|
||||||
doUpdates();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new Engine using the specified classloader to dynamically load
|
||||||
|
* Analyzer and Update services.
|
||||||
|
*
|
||||||
|
* @throws DatabaseException thrown if there is an error connecting to the
|
||||||
|
* database
|
||||||
|
*/
|
||||||
|
protected final void initializeEngine() throws DatabaseException {
|
||||||
|
ConnectionFactory.initialize();
|
||||||
loadAnalyzers();
|
loadAnalyzers();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Properly cleans up resources allocated during analysis.
|
||||||
|
*/
|
||||||
|
public void cleanup() {
|
||||||
|
if (database != null) {
|
||||||
|
database.close();
|
||||||
|
database = null;
|
||||||
|
}
|
||||||
|
ConnectionFactory.cleanup();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loads the analyzers specified in the configuration file (or system
|
* Loads the analyzers specified in the configuration file (or system
|
||||||
* properties).
|
* properties).
|
||||||
*/
|
*/
|
||||||
private void loadAnalyzers() {
|
private void loadAnalyzers() {
|
||||||
|
if (!analyzers.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
for (AnalysisPhase phase : AnalysisPhase.values()) {
|
for (AnalysisPhase phase : AnalysisPhase.values()) {
|
||||||
analyzers.put(phase, new ArrayList<Analyzer>());
|
analyzers.put(phase, new ArrayList<Analyzer>());
|
||||||
}
|
}
|
||||||
|
|
||||||
final AnalyzerService service = AnalyzerService.getInstance();
|
final AnalyzerService service = new AnalyzerService(serviceClassLoader);
|
||||||
final Iterator<Analyzer> iterator = service.getAnalyzers();
|
final List<Analyzer> iterator = service.getAnalyzers();
|
||||||
while (iterator.hasNext()) {
|
for (Analyzer a : iterator) {
|
||||||
final Analyzer a = iterator.next();
|
|
||||||
analyzers.get(a.getAnalysisPhase()).add(a);
|
analyzers.get(a.getAnalysisPhase()).add(a);
|
||||||
if (a.getSupportedExtensions() != null) {
|
if (a instanceof FileTypeAnalyzer) {
|
||||||
extensions.addAll(a.getSupportedExtensions());
|
this.fileTypeAnalyzers.add((FileTypeAnalyzer) a);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -128,28 +171,65 @@ public class Engine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the dependencies identified.
|
* Get the dependencies identified. The returned list is a reference to the
|
||||||
|
* engine's synchronized list. <b>You must synchronize on the returned
|
||||||
|
* list</b> when you modify and iterate over it from multiple threads. E.g.
|
||||||
|
* this holds for analyzers supporting parallel processing during their
|
||||||
|
* analysis phase.
|
||||||
*
|
*
|
||||||
* @return the dependencies identified
|
* @return the dependencies identified
|
||||||
|
* @see Collections#synchronizedList(List)
|
||||||
|
* @see Analyzer#supportsParallelProcessing()
|
||||||
*/
|
*/
|
||||||
public List<Dependency> getDependencies() {
|
public synchronized List<Dependency> getDependencies() {
|
||||||
return dependencies;
|
return dependencies;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the dependencies.
|
||||||
|
*
|
||||||
|
* @param dependencies the dependencies
|
||||||
|
*/
|
||||||
|
public void setDependencies(List<Dependency> dependencies) {
|
||||||
|
synchronized (this.dependencies) {
|
||||||
|
this.dependencies.clear();
|
||||||
|
this.dependencies.addAll(dependencies);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Scans an array of files or directories. If a directory is specified, it
|
* Scans an array of files or directories. If a directory is specified, it
|
||||||
* will be scanned recursively. Any dependencies identified are added to the
|
* will be scanned recursively. Any dependencies identified are added to the
|
||||||
* dependency collection.
|
* dependency collection.
|
||||||
*
|
*
|
||||||
|
* @param paths an array of paths to files or directories to be analyzed
|
||||||
|
* @return the list of dependencies scanned
|
||||||
* @since v0.3.2.5
|
* @since v0.3.2.5
|
||||||
*
|
|
||||||
* @param paths an array of paths to files or directories to be analyzed.
|
|
||||||
*/
|
*/
|
||||||
public void scan(String[] paths) {
|
public List<Dependency> scan(String[] paths) {
|
||||||
for (String path : paths) {
|
return scan(paths, null);
|
||||||
final File file = new File(path);
|
|
||||||
scan(file);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Scans an array of files or directories. If a directory is specified, it
|
||||||
|
* will be scanned recursively. Any dependencies identified are added to the
|
||||||
|
* dependency collection.
|
||||||
|
*
|
||||||
|
* @param paths an array of paths to files or directories to be analyzed
|
||||||
|
* @param projectReference the name of the project or scope in which the
|
||||||
|
* dependency was identified
|
||||||
|
* @return the list of dependencies scanned
|
||||||
|
* @since v1.4.4
|
||||||
|
*/
|
||||||
|
public List<Dependency> scan(String[] paths, String projectReference) {
|
||||||
|
final List<Dependency> deps = new ArrayList<>();
|
||||||
|
for (String path : paths) {
|
||||||
|
final List<Dependency> d = scan(path, projectReference);
|
||||||
|
if (d != null) {
|
||||||
|
deps.addAll(d);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return deps;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -157,11 +237,27 @@ public class Engine {
|
|||||||
* scanned recursively. Any dependencies identified are added to the
|
* scanned recursively. Any dependencies identified are added to the
|
||||||
* dependency collection.
|
* dependency collection.
|
||||||
*
|
*
|
||||||
* @param path the path to a file or directory to be analyzed.
|
* @param path the path to a file or directory to be analyzed
|
||||||
|
* @return the list of dependencies scanned
|
||||||
*/
|
*/
|
||||||
public void scan(String path) {
|
public List<Dependency> scan(String path) {
|
||||||
|
return scan(path, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Scans a given file or directory. If a directory is specified, it will be
|
||||||
|
* scanned recursively. Any dependencies identified are added to the
|
||||||
|
* dependency collection.
|
||||||
|
*
|
||||||
|
* @param path the path to a file or directory to be analyzed
|
||||||
|
* @param projectReference the name of the project or scope in which the
|
||||||
|
* dependency was identified
|
||||||
|
* @return the list of dependencies scanned
|
||||||
|
* @since v1.4.4
|
||||||
|
*/
|
||||||
|
public List<Dependency> scan(String path, String projectReference) {
|
||||||
final File file = new File(path);
|
final File file = new File(path);
|
||||||
scan(file);
|
return scan(file, projectReference);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -169,44 +265,69 @@ public class Engine {
|
|||||||
* will be scanned recursively. Any dependencies identified are added to the
|
* will be scanned recursively. Any dependencies identified are added to the
|
||||||
* dependency collection.
|
* dependency collection.
|
||||||
*
|
*
|
||||||
* @since v0.3.2.5
|
|
||||||
*
|
|
||||||
* @param files an array of paths to files or directories to be analyzed.
|
* @param files an array of paths to files or directories to be analyzed.
|
||||||
|
* @return the list of dependencies
|
||||||
|
* @since v0.3.2.5
|
||||||
*/
|
*/
|
||||||
public void scan(File[] files) {
|
public List<Dependency> scan(File[] files) {
|
||||||
for (File file : files) {
|
return scan(files, null);
|
||||||
scan(file);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Scans a list of files or directories. If a directory is specified, it
|
* Scans an array of files or directories. If a directory is specified, it
|
||||||
* will be scanned recursively. Any dependencies identified are added to the
|
* will be scanned recursively. Any dependencies identified are added to the
|
||||||
* dependency collection.
|
* dependency collection.
|
||||||
*
|
*
|
||||||
* @since v0.3.2.5
|
* @param files an array of paths to files or directories to be analyzed.
|
||||||
*
|
* @param projectReference the name of the project or scope in which the
|
||||||
* @param files a set of paths to files or directories to be analyzed.
|
* dependency was identified
|
||||||
|
* @return the list of dependencies
|
||||||
|
* @since v1.4.4
|
||||||
*/
|
*/
|
||||||
public void scan(Set<File> files) {
|
public List<Dependency> scan(File[] files, String projectReference) {
|
||||||
|
final List<Dependency> deps = new ArrayList<>();
|
||||||
for (File file : files) {
|
for (File file : files) {
|
||||||
scan(file);
|
final List<Dependency> d = scan(file, projectReference);
|
||||||
|
if (d != null) {
|
||||||
|
deps.addAll(d);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return deps;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Scans a list of files or directories. If a directory is specified, it
|
* Scans a collection of files or directories. If a directory is specified,
|
||||||
* will be scanned recursively. Any dependencies identified are added to the
|
* it will be scanned recursively. Any dependencies identified are added to
|
||||||
* dependency collection.
|
* the dependency collection.
|
||||||
*
|
*
|
||||||
|
* @param files a set of paths to files or directories to be analyzed
|
||||||
|
* @return the list of dependencies scanned
|
||||||
* @since v0.3.2.5
|
* @since v0.3.2.5
|
||||||
*
|
|
||||||
* @param files a set of paths to files or directories to be analyzed.
|
|
||||||
*/
|
*/
|
||||||
public void scan(List<File> files) {
|
public List<Dependency> scan(Collection<File> files) {
|
||||||
for (File file : files) {
|
return scan(files, null);
|
||||||
scan(file);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Scans a collection of files or directories. If a directory is specified,
|
||||||
|
* it will be scanned recursively. Any dependencies identified are added to
|
||||||
|
* the dependency collection.
|
||||||
|
*
|
||||||
|
* @param files a set of paths to files or directories to be analyzed
|
||||||
|
* @param projectReference the name of the project or scope in which the
|
||||||
|
* dependency was identified
|
||||||
|
* @return the list of dependencies scanned
|
||||||
|
* @since v1.4.4
|
||||||
|
*/
|
||||||
|
public List<Dependency> scan(Collection<File> files, String projectReference) {
|
||||||
|
final List<Dependency> deps = new ArrayList<>();
|
||||||
|
for (File file : files) {
|
||||||
|
final List<Dependency> d = scan(file, projectReference);
|
||||||
|
if (d != null) {
|
||||||
|
deps.addAll(d);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return deps;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -214,142 +335,383 @@ public class Engine {
|
|||||||
* scanned recursively. Any dependencies identified are added to the
|
* scanned recursively. Any dependencies identified are added to the
|
||||||
* dependency collection.
|
* dependency collection.
|
||||||
*
|
*
|
||||||
|
* @param file the path to a file or directory to be analyzed
|
||||||
|
* @return the list of dependencies scanned
|
||||||
* @since v0.3.2.4
|
* @since v0.3.2.4
|
||||||
*
|
|
||||||
* @param file the path to a file or directory to be analyzed.
|
|
||||||
*/
|
*/
|
||||||
public void scan(File file) {
|
public List<Dependency> scan(File file) {
|
||||||
|
return scan(file, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Scans a given file or directory. If a directory is specified, it will be
|
||||||
|
* scanned recursively. Any dependencies identified are added to the
|
||||||
|
* dependency collection.
|
||||||
|
*
|
||||||
|
* @param file the path to a file or directory to be analyzed
|
||||||
|
* @param projectReference the name of the project or scope in which the
|
||||||
|
* dependency was identified
|
||||||
|
* @return the list of dependencies scanned
|
||||||
|
* @since v1.4.4
|
||||||
|
*/
|
||||||
|
public List<Dependency> scan(File file, String projectReference) {
|
||||||
if (file.exists()) {
|
if (file.exists()) {
|
||||||
if (file.isDirectory()) {
|
if (file.isDirectory()) {
|
||||||
scanDirectory(file);
|
return scanDirectory(file, projectReference);
|
||||||
} else {
|
} else {
|
||||||
scanFile(file);
|
final Dependency d = scanFile(file, projectReference);
|
||||||
|
if (d != null) {
|
||||||
|
final List<Dependency> deps = new ArrayList<>();
|
||||||
|
deps.add(d);
|
||||||
|
return deps;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Recursively scans files and directories. Any dependencies identified are
|
* Recursively scans files and directories. Any dependencies identified are
|
||||||
* added to the dependency collection.
|
* added to the dependency collection.
|
||||||
*
|
*
|
||||||
* @param dir the directory to scan.
|
* @param dir the directory to scan
|
||||||
|
* @return the list of Dependency objects scanned
|
||||||
*/
|
*/
|
||||||
protected void scanDirectory(File dir) {
|
protected List<Dependency> scanDirectory(File dir) {
|
||||||
|
return scanDirectory(dir, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Recursively scans files and directories. Any dependencies identified are
|
||||||
|
* added to the dependency collection.
|
||||||
|
*
|
||||||
|
* @param dir the directory to scan
|
||||||
|
* @param projectReference the name of the project or scope in which the
|
||||||
|
* dependency was identified
|
||||||
|
* @return the list of Dependency objects scanned
|
||||||
|
* @since v1.4.4
|
||||||
|
*/
|
||||||
|
protected List<Dependency> scanDirectory(File dir, String projectReference) {
|
||||||
final File[] files = dir.listFiles();
|
final File[] files = dir.listFiles();
|
||||||
|
final List<Dependency> deps = new ArrayList<>();
|
||||||
if (files != null) {
|
if (files != null) {
|
||||||
for (File f : files) {
|
for (File f : files) {
|
||||||
if (f.isDirectory()) {
|
if (f.isDirectory()) {
|
||||||
scanDirectory(f);
|
final List<Dependency> d = scanDirectory(f, projectReference);
|
||||||
|
if (d != null) {
|
||||||
|
deps.addAll(d);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
scanFile(f);
|
final Dependency d = scanFile(f, projectReference);
|
||||||
|
deps.add(d);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return deps;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Scans a specified file. If a dependency is identified it is added to the
|
* Scans a specified file. If a dependency is identified it is added to the
|
||||||
* dependency collection.
|
* dependency collection.
|
||||||
*
|
*
|
||||||
* @param file The file to scan.
|
* @param file The file to scan
|
||||||
|
* @return the scanned dependency
|
||||||
*/
|
*/
|
||||||
protected void scanFile(File file) {
|
protected Dependency scanFile(File file) {
|
||||||
if (!file.isFile()) {
|
return scanFile(file, null);
|
||||||
final String msg = String.format("Path passed to scanFile(File) is not a file: %s. Skipping the file.", file.toString());
|
|
||||||
Logger.getLogger(Engine.class.getName()).log(Level.FINE, msg);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
final String fileName = file.getName();
|
|
||||||
final String extension = FileUtils.getFileExtension(fileName);
|
|
||||||
if (extension != null) {
|
|
||||||
if (extensions.contains(extension)) {
|
|
||||||
final Dependency dependency = new Dependency(file);
|
|
||||||
dependencies.add(dependency);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
final String msg = String.format("No file extension found on file '%s'. The file was not analyzed.",
|
|
||||||
file.toString());
|
|
||||||
Logger.getLogger(Engine.class.getName()).log(Level.FINEST, msg);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Runs the analyzers against all of the dependencies.
|
* Scans a specified file. If a dependency is identified it is added to the
|
||||||
|
* dependency collection.
|
||||||
|
*
|
||||||
|
* @param file The file to scan
|
||||||
|
* @param projectReference the name of the project or scope in which the
|
||||||
|
* dependency was identified
|
||||||
|
* @return the scanned dependency
|
||||||
|
* @since v1.4.4
|
||||||
*/
|
*/
|
||||||
public void analyzeDependencies() {
|
protected Dependency scanFile(File file, String projectReference) {
|
||||||
//phase one initialize
|
Dependency dependency = null;
|
||||||
for (AnalysisPhase phase : AnalysisPhase.values()) {
|
if (file.isFile()) {
|
||||||
final List<Analyzer> analyzerList = analyzers.get(phase);
|
if (accept(file)) {
|
||||||
for (Analyzer a : analyzerList) {
|
dependency = new Dependency(file);
|
||||||
|
if (projectReference != null) {
|
||||||
|
dependency.addProjectReference(projectReference);
|
||||||
|
}
|
||||||
|
final String sha1 = dependency.getSha1sum();
|
||||||
|
boolean found = false;
|
||||||
|
synchronized (dependencies) {
|
||||||
|
if (sha1 != null) {
|
||||||
|
for (Dependency existing : dependencies) {
|
||||||
|
if (sha1.equals(existing.getSha1sum())) {
|
||||||
|
found = true;
|
||||||
|
if (projectReference != null) {
|
||||||
|
existing.addProjectReference(projectReference);
|
||||||
|
}
|
||||||
|
if (existing.getActualFilePath() != null && dependency.getActualFilePath() != null
|
||||||
|
&& !existing.getActualFilePath().equals(dependency.getActualFilePath())) {
|
||||||
|
existing.addRelatedDependency(dependency);
|
||||||
|
} else {
|
||||||
|
dependency = existing;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!found) {
|
||||||
|
dependencies.add(dependency);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
LOGGER.debug("Path passed to scanFile(File) is not a file: {}. Skipping the file.", file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return dependency;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Runs the analyzers against all of the dependencies. Since the mutable
|
||||||
|
* dependencies list is exposed via {@link #getDependencies()}, this method
|
||||||
|
* iterates over a copy of the dependencies list. Thus, the potential for
|
||||||
|
* {@link java.util.ConcurrentModificationException}s is avoided, and
|
||||||
|
* analyzers may safely add or remove entries from the dependencies list.
|
||||||
|
* <p>
|
||||||
|
* Every effort is made to complete analysis on the dependencies. In some
|
||||||
|
* cases an exception will occur with part of the analysis being performed
|
||||||
|
* which may not affect the entire analysis. If an exception occurs it will
|
||||||
|
* be included in the thrown exception collection.
|
||||||
|
*
|
||||||
|
* @throws ExceptionCollection a collections of any exceptions that occurred
|
||||||
|
* during analysis
|
||||||
|
*/
|
||||||
|
public void analyzeDependencies() throws ExceptionCollection {
|
||||||
|
final List<Throwable> exceptions = Collections.synchronizedList(new ArrayList<Throwable>());
|
||||||
|
|
||||||
|
initializeAndUpdateDatabase(exceptions);
|
||||||
|
|
||||||
|
//need to ensure that data exists
|
||||||
try {
|
try {
|
||||||
a.initialize();
|
ensureDataExists();
|
||||||
} catch (Exception ex) {
|
} catch (NoDataException ex) {
|
||||||
final String msg = String.format("\"Exception occurred initializing \"%s\".\"", a.getName());
|
throwFatalExceptionCollection("Unable to continue dependency-check analysis.", ex, exceptions);
|
||||||
Logger.getLogger(Engine.class.getName()).log(Level.SEVERE, msg);
|
|
||||||
Logger.getLogger(Engine.class.getName()).log(Level.INFO, msg, ex);
|
|
||||||
try {
|
|
||||||
a.close();
|
|
||||||
} catch (Exception ex1) {
|
|
||||||
Logger.getLogger(Engine.class.getName()).log(Level.FINEST, null, ex1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LOGGER.debug("\n----------------------------------------------------\nBEGIN ANALYSIS\n----------------------------------------------------");
|
||||||
|
LOGGER.info("Analysis Started");
|
||||||
|
final long analysisStart = System.currentTimeMillis();
|
||||||
|
|
||||||
// analysis phases
|
// analysis phases
|
||||||
for (AnalysisPhase phase : AnalysisPhase.values()) {
|
for (AnalysisPhase phase : AnalysisPhase.values()) {
|
||||||
final List<Analyzer> analyzerList = analyzers.get(phase);
|
final List<Analyzer> analyzerList = analyzers.get(phase);
|
||||||
|
|
||||||
for (Analyzer a : analyzerList) {
|
for (final Analyzer analyzer : analyzerList) {
|
||||||
/* need to create a copy of the collection because some of the
|
final long analyzerStart = System.currentTimeMillis();
|
||||||
* analyzers may modify it. This prevents ConcurrentModificationExceptions.
|
|
||||||
* This is okay for adds/deletes because it happens per analyzer.
|
|
||||||
*/
|
|
||||||
final Set<Dependency> dependencySet = new HashSet<Dependency>();
|
|
||||||
dependencySet.addAll(dependencies);
|
|
||||||
for (Dependency d : dependencySet) {
|
|
||||||
if (a.supportsExtension(d.getFileExtension())) {
|
|
||||||
try {
|
try {
|
||||||
a.analyze(d, this);
|
initializeAnalyzer(analyzer);
|
||||||
} catch (AnalysisException ex) {
|
} catch (InitializationException ex) {
|
||||||
d.addAnalysisException(ex);
|
exceptions.add(ex);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (analyzer.isEnabled()) {
|
||||||
|
executeAnalysisTasks(analyzer, exceptions);
|
||||||
|
|
||||||
|
final long analyzerDurationMillis = System.currentTimeMillis() - analyzerStart;
|
||||||
|
final long analyzerDurationSeconds = TimeUnit.MILLISECONDS.toSeconds(analyzerDurationMillis);
|
||||||
|
LOGGER.info("Finished {} ({} seconds)", analyzer.getName(), analyzerDurationSeconds);
|
||||||
|
} else {
|
||||||
|
LOGGER.debug("Skipping {} (not enabled)", analyzer.getName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for (AnalysisPhase phase : AnalysisPhase.values()) {
|
||||||
|
final List<Analyzer> analyzerList = analyzers.get(phase);
|
||||||
|
|
||||||
|
for (Analyzer a : analyzerList) {
|
||||||
|
closeAnalyzer(a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LOGGER.debug("\n----------------------------------------------------\nEND ANALYSIS\n----------------------------------------------------");
|
||||||
|
final long analysisDurationSeconds = TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis() - analysisStart);
|
||||||
|
LOGGER.info("Analysis Complete ({} seconds)", analysisDurationSeconds);
|
||||||
|
if (exceptions.size() > 0) {
|
||||||
|
throw new ExceptionCollection("One or more exceptions occurred during dependency-check analysis", exceptions);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Performs any necessary updates and initializes the database.
|
||||||
|
*
|
||||||
|
* @param exceptions a collection to store non-fatal exceptions
|
||||||
|
* @throws ExceptionCollection thrown if fatal exceptions occur
|
||||||
|
*/
|
||||||
|
private void initializeAndUpdateDatabase(final List<Throwable> exceptions) throws ExceptionCollection {
|
||||||
|
boolean autoUpdate = true;
|
||||||
|
try {
|
||||||
|
autoUpdate = Settings.getBoolean(Settings.KEYS.AUTO_UPDATE);
|
||||||
|
} catch (InvalidSettingException ex) {
|
||||||
|
LOGGER.debug("Invalid setting for auto-update; using true.");
|
||||||
|
exceptions.add(ex);
|
||||||
|
}
|
||||||
|
if (autoUpdate) {
|
||||||
|
try {
|
||||||
|
database = CveDB.getInstance();
|
||||||
|
doUpdates();
|
||||||
|
} catch (UpdateException ex) {
|
||||||
|
exceptions.add(ex);
|
||||||
|
LOGGER.warn("Unable to update Cached Web DataSource, using local "
|
||||||
|
+ "data instead. Results may not include recent vulnerabilities.");
|
||||||
|
LOGGER.debug("Update Error", ex);
|
||||||
|
} catch (DatabaseException ex) {
|
||||||
|
throw new ExceptionCollection("Unable to connect to the database", ex);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
if (ConnectionFactory.isH2Connection() && !ConnectionFactory.h2DataFileExists()) {
|
||||||
|
throw new ExceptionCollection(new NoDataException("Autoupdate is disabled and the database does not exist"), true);
|
||||||
|
} else {
|
||||||
|
database = CveDB.getInstance();
|
||||||
|
}
|
||||||
|
} catch (IOException ex) {
|
||||||
|
throw new ExceptionCollection(new DatabaseException("Autoupdate is disabled and unable to connect to the database"), true);
|
||||||
|
} catch (DatabaseException ex) {
|
||||||
|
throwFatalExceptionCollection("Unable to connect to the dependency-check database.", ex, exceptions);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//close/cleanup
|
/**
|
||||||
for (AnalysisPhase phase : AnalysisPhase.values()) {
|
* Executes executes the analyzer using multiple threads.
|
||||||
final List<Analyzer> analyzerList = analyzers.get(phase);
|
*
|
||||||
for (Analyzer a : analyzerList) {
|
* @param exceptions a collection of exceptions that occurred during
|
||||||
|
* analysis
|
||||||
|
* @param analyzer the analyzer to execute
|
||||||
|
* @throws ExceptionCollection thrown if exceptions occurred during analysis
|
||||||
|
*/
|
||||||
|
protected void executeAnalysisTasks(Analyzer analyzer, List<Throwable> exceptions) throws ExceptionCollection {
|
||||||
|
LOGGER.debug("Starting {}", analyzer.getName());
|
||||||
|
final List<AnalysisTask> analysisTasks = getAnalysisTasks(analyzer, exceptions);
|
||||||
|
final ExecutorService executorService = getExecutorService(analyzer);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
a.close();
|
final List<Future<Void>> results = executorService.invokeAll(analysisTasks, 10, TimeUnit.MINUTES);
|
||||||
} catch (Exception ex) {
|
|
||||||
Logger.getLogger(Engine.class.getName()).log(Level.FINEST, null, ex);
|
// ensure there was no exception during execution
|
||||||
|
for (Future<Void> result : results) {
|
||||||
|
try {
|
||||||
|
result.get();
|
||||||
|
} catch (ExecutionException e) {
|
||||||
|
throwFatalExceptionCollection("Analysis task failed with a fatal exception.", e, exceptions);
|
||||||
|
} catch (CancellationException e) {
|
||||||
|
throwFatalExceptionCollection("Analysis task timed out.", e, exceptions);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
throwFatalExceptionCollection("Analysis has been interrupted.", e, exceptions);
|
||||||
|
} finally {
|
||||||
|
executorService.shutdown();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the analysis tasks for the dependencies.
|
||||||
|
*
|
||||||
|
* @param analyzer the analyzer to create tasks for
|
||||||
|
* @param exceptions the collection of exceptions to collect
|
||||||
|
* @return a collection of analysis tasks
|
||||||
|
*/
|
||||||
|
protected List<AnalysisTask> getAnalysisTasks(Analyzer analyzer, List<Throwable> exceptions) {
|
||||||
|
final List<AnalysisTask> result = new ArrayList<>();
|
||||||
|
synchronized (dependencies) {
|
||||||
|
for (final Dependency dependency : dependencies) {
|
||||||
|
final AnalysisTask task = new AnalysisTask(analyzer, dependency, this, exceptions, Settings.getInstance());
|
||||||
|
result.add(task);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the executor service for a given analyzer.
|
||||||
|
*
|
||||||
|
* @param analyzer the analyzer to obtain an executor
|
||||||
|
* @return the executor service
|
||||||
|
*/
|
||||||
|
protected ExecutorService getExecutorService(Analyzer analyzer) {
|
||||||
|
if (analyzer.supportsParallelProcessing()) {
|
||||||
|
final int maximumNumberOfThreads = Runtime.getRuntime().availableProcessors();
|
||||||
|
LOGGER.debug("Parallel processing with up to {} threads: {}.", maximumNumberOfThreads, analyzer.getName());
|
||||||
|
return Executors.newFixedThreadPool(maximumNumberOfThreads);
|
||||||
|
} else {
|
||||||
|
LOGGER.debug("Parallel processing is not supported: {}.", analyzer.getName());
|
||||||
|
return Executors.newSingleThreadExecutor();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes the given analyzer.
|
||||||
|
*
|
||||||
|
* @param analyzer the analyzer to initialize
|
||||||
|
* @throws InitializationException thrown when there is a problem
|
||||||
|
* initializing the analyzer
|
||||||
|
*/
|
||||||
|
protected void initializeAnalyzer(Analyzer analyzer) throws InitializationException {
|
||||||
|
try {
|
||||||
|
LOGGER.debug("Initializing {}", analyzer.getName());
|
||||||
|
analyzer.initialize();
|
||||||
|
} catch (InitializationException ex) {
|
||||||
|
LOGGER.error("Exception occurred initializing {}.", analyzer.getName());
|
||||||
|
LOGGER.debug("", ex);
|
||||||
|
try {
|
||||||
|
analyzer.close();
|
||||||
|
} catch (Throwable ex1) {
|
||||||
|
LOGGER.trace("", ex1);
|
||||||
|
}
|
||||||
|
throw ex;
|
||||||
|
} catch (Throwable ex) {
|
||||||
|
LOGGER.error("Unexpected exception occurred initializing {}.", analyzer.getName());
|
||||||
|
LOGGER.debug("", ex);
|
||||||
|
try {
|
||||||
|
analyzer.close();
|
||||||
|
} catch (Throwable ex1) {
|
||||||
|
LOGGER.trace("", ex1);
|
||||||
|
}
|
||||||
|
throw new InitializationException("Unexpected Exception", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Closes the given analyzer.
|
||||||
|
*
|
||||||
|
* @param analyzer the analyzer to close
|
||||||
|
*/
|
||||||
|
protected void closeAnalyzer(Analyzer analyzer) {
|
||||||
|
LOGGER.debug("Closing Analyzer '{}'", analyzer.getName());
|
||||||
|
try {
|
||||||
|
analyzer.close();
|
||||||
|
} catch (Throwable ex) {
|
||||||
|
LOGGER.trace("", ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cycles through the cached web data sources and calls update on all of
|
* Cycles through the cached web data sources and calls update on all of
|
||||||
* them.
|
* them.
|
||||||
|
*
|
||||||
|
* @throws UpdateException thrown if the operation fails
|
||||||
*/
|
*/
|
||||||
private void doUpdates() {
|
public void doUpdates() throws UpdateException {
|
||||||
final UpdateService service = UpdateService.getInstance();
|
LOGGER.info("Checking for updates");
|
||||||
|
final long updateStart = System.currentTimeMillis();
|
||||||
|
final UpdateService service = new UpdateService(serviceClassLoader);
|
||||||
final Iterator<CachedWebDataSource> iterator = service.getDataSources();
|
final Iterator<CachedWebDataSource> iterator = service.getDataSources();
|
||||||
while (iterator.hasNext()) {
|
while (iterator.hasNext()) {
|
||||||
final CachedWebDataSource source = iterator.next();
|
final CachedWebDataSource source = iterator.next();
|
||||||
try {
|
|
||||||
source.update();
|
source.update();
|
||||||
} catch (UpdateException ex) {
|
|
||||||
Logger.getLogger(Engine.class.getName()).log(Level.WARNING,
|
|
||||||
"Unable to update Cached Web DataSource, using local data instead. Results may not include recent vulnerabilities.");
|
|
||||||
Logger.getLogger(Engine.class.getName()).log(Level.FINE,
|
|
||||||
String.format("Unable to update details for %s", source.getClass().getName()), ex);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
LOGGER.info("Check for updates complete ({} ms)", System.currentTimeMillis() - updateStart);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -359,7 +721,7 @@ public class Engine {
|
|||||||
* @return a list of Analyzers
|
* @return a list of Analyzers
|
||||||
*/
|
*/
|
||||||
public List<Analyzer> getAnalyzers() {
|
public List<Analyzer> getAnalyzers() {
|
||||||
final List<Analyzer> ret = new ArrayList<Analyzer>();
|
final List<Analyzer> ret = new ArrayList<>();
|
||||||
for (AnalysisPhase phase : AnalysisPhase.values()) {
|
for (AnalysisPhase phase : AnalysisPhase.values()) {
|
||||||
final List<Analyzer> analyzerList = analyzers.get(phase);
|
final List<Analyzer> analyzerList = analyzers.get(phase);
|
||||||
ret.addAll(analyzerList);
|
ret.addAll(analyzerList);
|
||||||
@@ -370,22 +732,68 @@ public class Engine {
|
|||||||
/**
|
/**
|
||||||
* Checks all analyzers to see if an extension is supported.
|
* Checks all analyzers to see if an extension is supported.
|
||||||
*
|
*
|
||||||
* @param ext a file extension
|
* @param file a file extension
|
||||||
* @return true or false depending on whether or not the file extension is
|
* @return true or false depending on whether or not the file extension is
|
||||||
* supported
|
* supported
|
||||||
*/
|
*/
|
||||||
public boolean supportsExtension(String ext) {
|
@Override
|
||||||
if (ext == null) {
|
public boolean accept(File file) {
|
||||||
|
if (file == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
for (AnalysisPhase phase : AnalysisPhase.values()) {
|
boolean scan = false;
|
||||||
final List<Analyzer> analyzerList = analyzers.get(phase);
|
for (FileTypeAnalyzer a : this.fileTypeAnalyzers) {
|
||||||
for (Analyzer a : analyzerList) {
|
/* note, we can't break early on this loop as the analyzers need to know if
|
||||||
if (a.getSupportedExtensions() != null && a.supportsExtension(ext)) {
|
they have files to work on prior to initialization */
|
||||||
return true;
|
scan |= a.accept(file);
|
||||||
|
}
|
||||||
|
return scan;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the set of file type analyzers.
|
||||||
|
*
|
||||||
|
* @return the set of file type analyzers
|
||||||
|
*/
|
||||||
|
public Set<FileTypeAnalyzer> getFileTypeAnalyzers() {
|
||||||
|
return this.fileTypeAnalyzers;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a file type analyzer. This has been added solely to assist in unit
|
||||||
|
* testing the Engine.
|
||||||
|
*
|
||||||
|
* @param fta the file type analyzer to add
|
||||||
|
*/
|
||||||
|
protected void addFileTypeAnalyzer(FileTypeAnalyzer fta) {
|
||||||
|
this.fileTypeAnalyzers.add(fta);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks the CPE Index to ensure documents exists. If none exist a
|
||||||
|
* NoDataException is thrown.
|
||||||
|
*
|
||||||
|
* @throws NoDataException thrown if no data exists in the CPE Index
|
||||||
|
*/
|
||||||
|
private void ensureDataExists() throws NoDataException {
|
||||||
|
if (database == null || !database.dataExists()) {
|
||||||
|
throw new NoDataException("No documents exist");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return false;
|
/**
|
||||||
|
* Constructs and throws a fatal exception collection.
|
||||||
|
*
|
||||||
|
* @param message the exception message
|
||||||
|
* @param throwable the cause
|
||||||
|
* @param exceptions a collection of exception to include
|
||||||
|
* @throws ExceptionCollection a collection of exceptions that occurred
|
||||||
|
* during analysis
|
||||||
|
*/
|
||||||
|
private void throwFatalExceptionCollection(String message, Throwable throwable, List<Throwable> exceptions) throws ExceptionCollection {
|
||||||
|
LOGGER.error("{}\n\n{}", throwable.getMessage(), message);
|
||||||
|
LOGGER.debug("", throwable);
|
||||||
|
exceptions.add(throwable);
|
||||||
|
throw new ExceptionCollection(message, exceptions, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,6 @@
|
|||||||
|
/**
|
||||||
|
* The agent package holds an agent API that can be used by other applications that have information about dependencies; but would
|
||||||
|
* rather implement something in their code directly rather then spawn a process to run the entire dependency-check engine. This
|
||||||
|
* basically provides programmatic access to running a scan.
|
||||||
|
*/
|
||||||
|
package org.owasp.dependencycheck.agent;
|
||||||
@@ -1,59 +1,141 @@
|
|||||||
/*
|
/*
|
||||||
* This file is part of dependency-check-core.
|
* This file is part of dependency-check-core.
|
||||||
*
|
*
|
||||||
* Dependency-check-core is free software: you can redistribute it and/or modify it
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* under the terms of the GNU General Public License as published by the Free
|
* you may not use this file except in compliance with the License.
|
||||||
* Software Foundation, either version 3 of the License, or (at your option) any
|
* You may obtain a copy of the License at
|
||||||
* later version.
|
|
||||||
*
|
*
|
||||||
* Dependency-check-core is distributed in the hope that it will be useful, but
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
|
||||||
* details.
|
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License along with
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* dependency-check-core. If not, see http://www.gnu.org/licenses/.
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
*
|
*
|
||||||
* Copyright (c) 2012 Jeremy Long. All Rights Reserved.
|
* Copyright (c) 2012 Jeremy Long. All Rights Reserved.
|
||||||
*/
|
*/
|
||||||
package org.owasp.dependencycheck.analyzer;
|
package org.owasp.dependencycheck.analyzer;
|
||||||
|
|
||||||
import java.util.Collections;
|
import org.owasp.dependencycheck.Engine;
|
||||||
import java.util.HashSet;
|
import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
|
||||||
import java.util.Set;
|
import org.owasp.dependencycheck.dependency.Dependency;
|
||||||
|
import org.owasp.dependencycheck.exception.InitializationException;
|
||||||
|
import org.owasp.dependencycheck.utils.InvalidSettingException;
|
||||||
|
import org.owasp.dependencycheck.utils.Settings;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Base class for analyzers to avoid code duplication of initialize and close as
|
||||||
|
* most analyzers do not need these methods.
|
||||||
*
|
*
|
||||||
* @author Jeremy Long (jeremy.long@owasp.org)
|
* @author Jeremy Long
|
||||||
*/
|
*/
|
||||||
public abstract class AbstractAnalyzer implements Analyzer {
|
public abstract class AbstractAnalyzer implements Analyzer {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Utility method to help in the creation of the extensions set. This
|
* The logger.
|
||||||
* constructs a new Set that can be used in a final static
|
|
||||||
* declaration.<br/><br/>
|
|
||||||
*
|
|
||||||
* This implementation was copied from
|
|
||||||
* http://stackoverflow.com/questions/2041778/initialize-java-hashset-values-by-construction
|
|
||||||
*
|
|
||||||
* @param strings a list of strings to add to the set.
|
|
||||||
* @return a Set of strings.
|
|
||||||
*/
|
*/
|
||||||
protected static Set<String> newHashSet(String... strings) {
|
private static final Logger LOGGER = LoggerFactory.getLogger(AbstractAnalyzer.class);
|
||||||
final Set<String> set = new HashSet<String>();
|
/**
|
||||||
|
* A flag indicating whether or not the analyzer is enabled.
|
||||||
|
*/
|
||||||
|
private volatile boolean enabled = true;
|
||||||
|
|
||||||
Collections.addAll(set, strings);
|
/**
|
||||||
return set;
|
* Get the value of enabled.
|
||||||
|
*
|
||||||
|
* @return the value of enabled
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean isEnabled() {
|
||||||
|
return enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the value of enabled.
|
||||||
|
*
|
||||||
|
* @param enabled new value of enabled
|
||||||
|
*/
|
||||||
|
public void setEnabled(boolean enabled) {
|
||||||
|
this.enabled = enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* Returns the setting key to determine if the analyzer is enabled.</p>
|
||||||
|
*
|
||||||
|
* @return the key for the analyzer's enabled property
|
||||||
|
*/
|
||||||
|
protected abstract String getAnalyzerEnabledSettingKey();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Analyzes a given dependency. If the dependency is an archive, such as a
|
||||||
|
* WAR or EAR, the contents are extracted, scanned, and added to the list of
|
||||||
|
* dependencies within the engine.
|
||||||
|
*
|
||||||
|
* @param dependency the dependency to analyze
|
||||||
|
* @param engine the engine scanning
|
||||||
|
* @throws AnalysisException thrown if there is an analysis exception
|
||||||
|
*/
|
||||||
|
protected abstract void analyzeDependency(Dependency dependency, Engine engine) throws AnalysisException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes a given Analyzer. This will be skipped if the analyzer is
|
||||||
|
* disabled.
|
||||||
|
*
|
||||||
|
* @throws InitializationException thrown if there is an exception
|
||||||
|
*/
|
||||||
|
protected void initializeAnalyzer() throws InitializationException {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Closes a given Analyzer. This will be skipped if the analyzer is
|
||||||
|
* disabled.
|
||||||
|
*
|
||||||
|
* @throws Exception thrown if there is an exception
|
||||||
|
*/
|
||||||
|
protected void closeAnalyzer() throws Exception {
|
||||||
|
// Intentionally empty, analyzer will override this if they must close a resource.
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Analyzes a given dependency. If the dependency is an archive, such as a
|
||||||
|
* WAR or EAR, the contents are extracted, scanned, and added to the list of
|
||||||
|
* dependencies within the engine.
|
||||||
|
*
|
||||||
|
* @param dependency the dependency to analyze
|
||||||
|
* @param engine the engine scanning
|
||||||
|
* @throws AnalysisException thrown if there is an analysis exception
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public final void analyze(Dependency dependency, Engine engine) throws AnalysisException {
|
||||||
|
if (this.isEnabled()) {
|
||||||
|
analyzeDependency(dependency, engine);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The initialize method does nothing for this Analyzer.
|
* The initialize method does nothing for this Analyzer.
|
||||||
*
|
*
|
||||||
* @throws Exception thrown if there is an exception
|
* @throws InitializationException thrown if there is an exception
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void initialize() throws Exception {
|
public final void initialize() throws InitializationException {
|
||||||
//do nothing
|
final String key = getAnalyzerEnabledSettingKey();
|
||||||
|
try {
|
||||||
|
this.setEnabled(Settings.getBoolean(key, true));
|
||||||
|
} catch (InvalidSettingException ex) {
|
||||||
|
LOGGER.warn("Invalid setting for property '{}'", key);
|
||||||
|
LOGGER.debug("", ex);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isEnabled()) {
|
||||||
|
initializeAnalyzer();
|
||||||
|
} else {
|
||||||
|
LOGGER.debug("{} has been disabled", getName());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -62,7 +144,19 @@ public abstract class AbstractAnalyzer implements Analyzer {
|
|||||||
* @throws Exception thrown if there is an exception
|
* @throws Exception thrown if there is an exception
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void close() throws Exception {
|
public final void close() throws Exception {
|
||||||
//do nothing
|
if (isEnabled()) {
|
||||||
|
closeAnalyzer();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The default is to support parallel processing.
|
||||||
|
*
|
||||||
|
* @return true
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean supportsParallelProcessing() {
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,148 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of dependency-check-core.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
* Copyright (c) 2014 Jeremy Long. All Rights Reserved.
|
||||||
|
*/
|
||||||
|
package org.owasp.dependencycheck.analyzer;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileFilter;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
import org.owasp.dependencycheck.exception.InitializationException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The base FileTypeAnalyzer that all analyzers that have specific file types
|
||||||
|
* they analyze should extend.
|
||||||
|
*
|
||||||
|
* @author Jeremy Long
|
||||||
|
*/
|
||||||
|
public abstract class AbstractFileTypeAnalyzer extends AbstractAnalyzer implements FileTypeAnalyzer {
|
||||||
|
|
||||||
|
//<editor-fold defaultstate="collapsed" desc="Field definitions, getters, and setters ">
|
||||||
|
/**
|
||||||
|
* The logger.
|
||||||
|
*/
|
||||||
|
private static final Logger LOGGER = LoggerFactory.getLogger(AbstractFileTypeAnalyzer.class);
|
||||||
|
/**
|
||||||
|
* Whether the file type analyzer detected any files it needs to analyze.
|
||||||
|
*/
|
||||||
|
private boolean filesMatched = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the value of filesMatched. A flag indicating whether the scan
|
||||||
|
* included any file types this analyzer supports.
|
||||||
|
*
|
||||||
|
* @return the value of filesMatched
|
||||||
|
*/
|
||||||
|
protected boolean isFilesMatched() {
|
||||||
|
return filesMatched;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the value of filesMatched. A flag indicating whether the scan
|
||||||
|
* included any file types this analyzer supports.
|
||||||
|
*
|
||||||
|
* @param filesMatched new value of filesMatched
|
||||||
|
*/
|
||||||
|
protected void setFilesMatched(boolean filesMatched) {
|
||||||
|
this.filesMatched = filesMatched;
|
||||||
|
}
|
||||||
|
|
||||||
|
//</editor-fold>
|
||||||
|
//<editor-fold defaultstate="collapsed" desc="Final implementations for the Analyzer interface">
|
||||||
|
/**
|
||||||
|
* Initializes the analyzer.
|
||||||
|
*
|
||||||
|
* @throws InitializationException thrown if there is an exception during
|
||||||
|
* initialization
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected final void initializeAnalyzer() throws InitializationException {
|
||||||
|
if (filesMatched) {
|
||||||
|
initializeFileTypeAnalyzer();
|
||||||
|
} else {
|
||||||
|
this.setEnabled(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//</editor-fold>
|
||||||
|
//<editor-fold defaultstate="collapsed" desc="Abstract methods children must implement">
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* Returns the {@link java.io.FileFilter} used to determine which files are
|
||||||
|
* to be analyzed. An example would be an analyzer that inspected Java jar
|
||||||
|
* files. Implementors may use
|
||||||
|
* {@link org.owasp.dependencycheck.utils.FileFilterBuilder}.</p>
|
||||||
|
* <p>
|
||||||
|
* If the analyzer returns null it will not cause additional files to be
|
||||||
|
* analyzed, but will be executed against every file loaded.</p>
|
||||||
|
*
|
||||||
|
* @return the file filter used to determine which files are to be analyzed
|
||||||
|
*/
|
||||||
|
protected abstract FileFilter getFileFilter();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes the file type analyzer.
|
||||||
|
*
|
||||||
|
* @throws InitializationException thrown if there is an exception during
|
||||||
|
* initialization
|
||||||
|
*/
|
||||||
|
protected abstract void initializeFileTypeAnalyzer() throws InitializationException;
|
||||||
|
|
||||||
|
//</editor-fold>
|
||||||
|
/**
|
||||||
|
* Determines if the file can be analyzed by the analyzer.
|
||||||
|
*
|
||||||
|
* @param pathname the path to the file
|
||||||
|
* @return true if the file can be analyzed by the given analyzer; otherwise
|
||||||
|
* false
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean accept(File pathname) {
|
||||||
|
final FileFilter filter = getFileFilter();
|
||||||
|
boolean accepted = false;
|
||||||
|
if (null == filter) {
|
||||||
|
LOGGER.error("The '{}' analyzer is misconfigured and does not have a file filter; it will be disabled", getName());
|
||||||
|
} else if (this.isEnabled()) {
|
||||||
|
accepted = filter.accept(pathname);
|
||||||
|
if (accepted) {
|
||||||
|
filesMatched = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return accepted;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* Utility method to help in the creation of the extensions set. This
|
||||||
|
* constructs a new Set that can be used in a final static declaration.</p>
|
||||||
|
* <p>
|
||||||
|
* This implementation was copied from
|
||||||
|
* http://stackoverflow.com/questions/2041778/initialize-java-hashset-values-by-construction</p>
|
||||||
|
*
|
||||||
|
* @param strings a list of strings to add to the set.
|
||||||
|
* @return a Set of strings.
|
||||||
|
*/
|
||||||
|
protected static Set<String> newHashSet(String... strings) {
|
||||||
|
final Set<String> set = new HashSet<>(strings.length);
|
||||||
|
Collections.addAll(set, strings);
|
||||||
|
return set;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,191 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of dependency-check-core.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
* Copyright (c) 2013 Jeremy Long. All Rights Reserved.
|
||||||
|
*/
|
||||||
|
package org.owasp.dependencycheck.analyzer;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.net.MalformedURLException;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
import org.owasp.dependencycheck.exception.InitializationException;
|
||||||
|
import org.owasp.dependencycheck.xml.suppression.SuppressionParseException;
|
||||||
|
import org.owasp.dependencycheck.xml.suppression.SuppressionParser;
|
||||||
|
import org.owasp.dependencycheck.xml.suppression.SuppressionRule;
|
||||||
|
import org.owasp.dependencycheck.utils.DownloadFailedException;
|
||||||
|
import org.owasp.dependencycheck.utils.Downloader;
|
||||||
|
import org.owasp.dependencycheck.utils.FileUtils;
|
||||||
|
import org.owasp.dependencycheck.utils.Settings;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.xml.sax.SAXException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Abstract base suppression analyzer that contains methods for parsing the
|
||||||
|
* suppression xml file.
|
||||||
|
*
|
||||||
|
* @author Jeremy Long
|
||||||
|
*/
|
||||||
|
public abstract class AbstractSuppressionAnalyzer extends AbstractAnalyzer {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Logger for use throughout the class
|
||||||
|
*/
|
||||||
|
private static final Logger LOGGER = LoggerFactory.getLogger(AbstractSuppressionAnalyzer.class);
|
||||||
|
|
||||||
|
//<editor-fold defaultstate="collapsed" desc="All standard implementation details of Analyzer">
|
||||||
|
/**
|
||||||
|
* Returns a list of file EXTENSIONS supported by this analyzer.
|
||||||
|
*
|
||||||
|
* @return a list of file EXTENSIONS supported by this analyzer.
|
||||||
|
*/
|
||||||
|
public Set<String> getSupportedExtensions() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
//</editor-fold>
|
||||||
|
/**
|
||||||
|
* The initialize method loads the suppression XML file.
|
||||||
|
*
|
||||||
|
* @throws InitializationException thrown if there is an exception
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void initializeAnalyzer() throws InitializationException {
|
||||||
|
try {
|
||||||
|
loadSuppressionData();
|
||||||
|
} catch (SuppressionParseException ex) {
|
||||||
|
throw new InitializationException("Error initializing the suppression analyzer", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The list of suppression rules
|
||||||
|
*/
|
||||||
|
private List<SuppressionRule> rules;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the value of rules.
|
||||||
|
*
|
||||||
|
* @return the value of rules
|
||||||
|
*/
|
||||||
|
public List<SuppressionRule> getRules() {
|
||||||
|
return rules;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the value of rules.
|
||||||
|
*
|
||||||
|
* @param rules new value of rules
|
||||||
|
*/
|
||||||
|
public void setRules(List<SuppressionRule> rules) {
|
||||||
|
this.rules = rules;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads the suppression rules file.
|
||||||
|
*
|
||||||
|
* @throws SuppressionParseException thrown if the XML cannot be parsed.
|
||||||
|
*/
|
||||||
|
private void loadSuppressionData() throws SuppressionParseException {
|
||||||
|
final SuppressionParser parser = new SuppressionParser();
|
||||||
|
File file = null;
|
||||||
|
try {
|
||||||
|
final InputStream in = this.getClass().getClassLoader().getResourceAsStream("dependencycheck-base-suppression.xml");
|
||||||
|
rules = parser.parseSuppressionRules(in);
|
||||||
|
} catch (SAXException ex) {
|
||||||
|
throw new SuppressionParseException("Unable to parse the base suppression data file", ex);
|
||||||
|
}
|
||||||
|
final String suppressionFilePath = Settings.getString(Settings.KEYS.SUPPRESSION_FILE);
|
||||||
|
if (suppressionFilePath == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
boolean deleteTempFile = false;
|
||||||
|
try {
|
||||||
|
final Pattern uriRx = Pattern.compile("^(https?|file)\\:.*", Pattern.CASE_INSENSITIVE);
|
||||||
|
if (uriRx.matcher(suppressionFilePath).matches()) {
|
||||||
|
deleteTempFile = true;
|
||||||
|
file = FileUtils.getTempFile("suppression", "xml");
|
||||||
|
final URL url = new URL(suppressionFilePath);
|
||||||
|
try {
|
||||||
|
Downloader.fetchFile(url, file, false);
|
||||||
|
} catch (DownloadFailedException ex) {
|
||||||
|
Downloader.fetchFile(url, file, true);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
file = new File(suppressionFilePath);
|
||||||
|
|
||||||
|
if (!file.exists()) {
|
||||||
|
try (InputStream suppressionsFromClasspath = this.getClass().getClassLoader().getResourceAsStream(suppressionFilePath)) {
|
||||||
|
if (suppressionsFromClasspath != null) {
|
||||||
|
deleteTempFile = true;
|
||||||
|
file = FileUtils.getTempFile("suppression", "xml");
|
||||||
|
try {
|
||||||
|
org.apache.commons.io.FileUtils.copyInputStreamToFile(suppressionsFromClasspath, file);
|
||||||
|
} catch (IOException ex) {
|
||||||
|
throwSuppressionParseException("Unable to locate suppressions file in classpath", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (file != null) {
|
||||||
|
if (!file.exists()) {
|
||||||
|
final String msg = String.format("Suppression file '%s' does not exists", file.getPath());
|
||||||
|
LOGGER.warn(msg);
|
||||||
|
throw new SuppressionParseException(msg);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
rules.addAll(parser.parseSuppressionRules(file));
|
||||||
|
LOGGER.debug("{} suppression rules were loaded.", rules.size());
|
||||||
|
} catch (SuppressionParseException ex) {
|
||||||
|
LOGGER.warn("Unable to parse suppression xml file '{}'", file.getPath());
|
||||||
|
LOGGER.warn(ex.getMessage());
|
||||||
|
throw ex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (DownloadFailedException ex) {
|
||||||
|
throwSuppressionParseException("Unable to fetch the configured suppression file", ex);
|
||||||
|
} catch (MalformedURLException ex) {
|
||||||
|
throwSuppressionParseException("Configured suppression file has an invalid URL", ex);
|
||||||
|
} catch (SuppressionParseException ex) {
|
||||||
|
throw ex;
|
||||||
|
} catch (IOException ex) {
|
||||||
|
throwSuppressionParseException("Unable to create temp file for suppressions", ex);
|
||||||
|
} finally {
|
||||||
|
if (deleteTempFile && file != null) {
|
||||||
|
FileUtils.delete(file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Utility method to throw parse exceptions.
|
||||||
|
*
|
||||||
|
* @param message the exception message
|
||||||
|
* @param exception the cause of the exception
|
||||||
|
* @throws SuppressionParseException throws the generated
|
||||||
|
* SuppressionParseException
|
||||||
|
*/
|
||||||
|
private void throwSuppressionParseException(String message, Exception exception) throws SuppressionParseException {
|
||||||
|
LOGGER.warn(message);
|
||||||
|
LOGGER.debug("", exception);
|
||||||
|
throw new SuppressionParseException(message, exception);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,18 +1,17 @@
|
|||||||
/*
|
/*
|
||||||
* This file is part of dependency-check-core.
|
* This file is part of dependency-check-core.
|
||||||
*
|
*
|
||||||
* Dependency-check-core is free software: you can redistribute it and/or modify it
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* under the terms of the GNU General Public License as published by the Free
|
* you may not use this file except in compliance with the License.
|
||||||
* Software Foundation, either version 3 of the License, or (at your option) any
|
* You may obtain a copy of the License at
|
||||||
* later version.
|
|
||||||
*
|
*
|
||||||
* Dependency-check-core is distributed in the hope that it will be useful, but
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
|
||||||
* details.
|
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License along with
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* dependency-check-core. If not, see http://www.gnu.org/licenses/.
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
*
|
*
|
||||||
* Copyright (c) 2012 Jeremy Long. All Rights Reserved.
|
* Copyright (c) 2012 Jeremy Long. All Rights Reserved.
|
||||||
*/
|
*/
|
||||||
@@ -21,7 +20,7 @@ package org.owasp.dependencycheck.analyzer;
|
|||||||
/**
|
/**
|
||||||
* An enumeration defining the phases of analysis.
|
* An enumeration defining the phases of analysis.
|
||||||
*
|
*
|
||||||
* @author Jeremy Long (jeremy.long@owasp.org)
|
* @author Jeremy Long
|
||||||
*/
|
*/
|
||||||
public enum AnalysisPhase {
|
public enum AnalysisPhase {
|
||||||
|
|
||||||
@@ -29,10 +28,18 @@ public enum AnalysisPhase {
|
|||||||
* Initialization phase.
|
* Initialization phase.
|
||||||
*/
|
*/
|
||||||
INITIAL,
|
INITIAL,
|
||||||
|
/**
|
||||||
|
* Pre information collection phase.
|
||||||
|
*/
|
||||||
|
PRE_INFORMATION_COLLECTION,
|
||||||
/**
|
/**
|
||||||
* Information collection phase.
|
* Information collection phase.
|
||||||
*/
|
*/
|
||||||
INFORMATION_COLLECTION,
|
INFORMATION_COLLECTION,
|
||||||
|
/**
|
||||||
|
* Post information collection phase.
|
||||||
|
*/
|
||||||
|
POST_INFORMATION_COLLECTION,
|
||||||
/**
|
/**
|
||||||
* Pre identifier analysis phase.
|
* Pre identifier analysis phase.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1,33 +1,33 @@
|
|||||||
/*
|
/*
|
||||||
* This file is part of dependency-check-core.
|
* This file is part of dependency-check-core.
|
||||||
*
|
*
|
||||||
* Dependency-check-core is free software: you can redistribute it and/or modify it
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* under the terms of the GNU General Public License as published by the Free
|
* you may not use this file except in compliance with the License.
|
||||||
* Software Foundation, either version 3 of the License, or (at your option) any
|
* You may obtain a copy of the License at
|
||||||
* later version.
|
|
||||||
*
|
*
|
||||||
* Dependency-check-core is distributed in the hope that it will be useful, but
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
|
||||||
* details.
|
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License along with
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* dependency-check-core. If not, see http://www.gnu.org/licenses/.
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
*
|
*
|
||||||
* Copyright (c) 2012 Jeremy Long. All Rights Reserved.
|
* Copyright (c) 2012 Jeremy Long. All Rights Reserved.
|
||||||
*/
|
*/
|
||||||
package org.owasp.dependencycheck.analyzer;
|
package org.owasp.dependencycheck.analyzer;
|
||||||
|
|
||||||
import java.util.Set;
|
|
||||||
import org.owasp.dependencycheck.Engine;
|
import org.owasp.dependencycheck.Engine;
|
||||||
|
import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
|
||||||
import org.owasp.dependencycheck.dependency.Dependency;
|
import org.owasp.dependencycheck.dependency.Dependency;
|
||||||
|
import org.owasp.dependencycheck.exception.InitializationException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An interface that defines an Analyzer that is used to identify Dependencies.
|
* An interface that defines an Analyzer that is used to identify Dependencies.
|
||||||
* An analyzer will collect information about the dependency in the form of
|
* An analyzer will collect information about the dependency in the form of
|
||||||
* Evidence.
|
* Evidence.
|
||||||
*
|
*
|
||||||
* @author Jeremy Long (jeremy.long@owasp.org)
|
* @author Jeremy Long
|
||||||
*/
|
*/
|
||||||
public interface Analyzer {
|
public interface Analyzer {
|
||||||
|
|
||||||
@@ -45,21 +45,6 @@ public interface Analyzer {
|
|||||||
*/
|
*/
|
||||||
void analyze(Dependency dependency, Engine engine) throws AnalysisException;
|
void analyze(Dependency dependency, Engine engine) throws AnalysisException;
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>Returns a list of supported file extensions. An example would be an
|
|
||||||
* analyzer that inspected java jar files. The getSupportedExtensions
|
|
||||||
* function would return a set with a single element "jar".</p>
|
|
||||||
*
|
|
||||||
* <p><b>Note:</b> when implementing this the extensions returned MUST be
|
|
||||||
* lowercase.</p>
|
|
||||||
*
|
|
||||||
* @return The file extensions supported by this analyzer.
|
|
||||||
*
|
|
||||||
* <p>If the analyzer returns null it will not cause additional files to be
|
|
||||||
* analyzed but will be executed against every file loaded</p>
|
|
||||||
*/
|
|
||||||
Set<String> getSupportedExtensions();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the name of the analyzer.
|
* Returns the name of the analyzer.
|
||||||
*
|
*
|
||||||
@@ -67,15 +52,6 @@ public interface Analyzer {
|
|||||||
*/
|
*/
|
||||||
String getName();
|
String getName();
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns whether or not this analyzer can process the given extension.
|
|
||||||
*
|
|
||||||
* @param extension the file extension to test for support.
|
|
||||||
* @return whether or not the specified file extension is supported by this
|
|
||||||
* analyzer.
|
|
||||||
*/
|
|
||||||
boolean supportsExtension(String extension);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the phase that the analyzer is intended to run in.
|
* Returns the phase that the analyzer is intended to run in.
|
||||||
*
|
*
|
||||||
@@ -87,10 +63,10 @@ public interface Analyzer {
|
|||||||
* The initialize method is called (once) prior to the analyze method being
|
* The initialize method is called (once) prior to the analyze method being
|
||||||
* called on all of the dependencies.
|
* called on all of the dependencies.
|
||||||
*
|
*
|
||||||
* @throws Exception is thrown if an exception occurs initializing the
|
* @throws InitializationException is thrown if an exception occurs
|
||||||
* analyzer.
|
* initializing the analyzer.
|
||||||
*/
|
*/
|
||||||
void initialize() throws Exception;
|
void initialize() throws InitializationException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The close method is called after all of the dependencies have been
|
* The close method is called after all of the dependencies have been
|
||||||
@@ -99,4 +75,18 @@ public interface Analyzer {
|
|||||||
* @throws Exception is thrown if an exception occurs closing the analyzer.
|
* @throws Exception is thrown if an exception occurs closing the analyzer.
|
||||||
*/
|
*/
|
||||||
void close() throws Exception;
|
void close() throws Exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether multiple instances of the same type of analyzer can run in parallel.
|
||||||
|
* Note that running analyzers of different types in parallel is not supported at all.
|
||||||
|
*
|
||||||
|
* @return {@code true} if the analyzer supports parallel processing, {@code false} else
|
||||||
|
*/
|
||||||
|
boolean supportsParallelProcessing();
|
||||||
|
/**
|
||||||
|
* Get the value of enabled.
|
||||||
|
*
|
||||||
|
* @return the value of enabled
|
||||||
|
*/
|
||||||
|
boolean isEnabled();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,66 +1,78 @@
|
|||||||
/*
|
/*
|
||||||
* This file is part of dependency-check-core.
|
* This file is part of dependency-check-core.
|
||||||
*
|
*
|
||||||
* Dependency-check-core is free software: you can redistribute it and/or modify it
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* under the terms of the GNU General Public License as published by the Free
|
* you may not use this file except in compliance with the License.
|
||||||
* Software Foundation, either version 3 of the License, or (at your option) any
|
* You may obtain a copy of the License at
|
||||||
* later version.
|
|
||||||
*
|
*
|
||||||
* Dependency-check-core is distributed in the hope that it will be useful, but
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
|
||||||
* details.
|
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License along with
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* dependency-check-core. If not, see http://www.gnu.org/licenses/.
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
*
|
*
|
||||||
* Copyright (c) 2012 Jeremy Long. All Rights Reserved.
|
* Copyright (c) 2012 Jeremy Long. All Rights Reserved.
|
||||||
*/
|
*/
|
||||||
package org.owasp.dependencycheck.analyzer;
|
package org.owasp.dependencycheck.analyzer;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
import java.util.ServiceLoader;
|
import java.util.ServiceLoader;
|
||||||
|
import org.owasp.dependencycheck.utils.InvalidSettingException;
|
||||||
|
import org.owasp.dependencycheck.utils.Settings;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* The Analyzer Service Loader. This class loads all services that implement
|
||||||
|
* org.owasp.dependencycheck.analyzer.Analyzer.
|
||||||
*
|
*
|
||||||
* @author Jeremy Long (jeremy.long@owasp.org)
|
* @author Jeremy Long
|
||||||
*/
|
*/
|
||||||
public final class AnalyzerService {
|
public class AnalyzerService {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The analyzer service singleton.
|
* The Logger for use throughout the class.
|
||||||
*/
|
*/
|
||||||
private static AnalyzerService service;
|
private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(AnalyzerService.class);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The service loader for analyzers.
|
* The service loader for analyzers.
|
||||||
*/
|
*/
|
||||||
private final ServiceLoader<Analyzer> loader;
|
private final ServiceLoader<Analyzer> service;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new instance of AnalyzerService.
|
* Creates a new instance of AnalyzerService.
|
||||||
|
*
|
||||||
|
* @param classLoader the ClassLoader to use when dynamically loading Analyzer and Update services
|
||||||
*/
|
*/
|
||||||
private AnalyzerService() {
|
public AnalyzerService(ClassLoader classLoader) {
|
||||||
loader = ServiceLoader.load(Analyzer.class);
|
service = ServiceLoader.load(Analyzer.class, classLoader);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve the singleton instance of AnalyzerService.
|
* Returns a list of all instances of the Analyzer interface.
|
||||||
*
|
*
|
||||||
* @return a singleton AnalyzerService.
|
* @return a list of Analyzers.
|
||||||
*/
|
*/
|
||||||
public static synchronized AnalyzerService getInstance() {
|
public List<Analyzer> getAnalyzers() {
|
||||||
if (service == null) {
|
final List<Analyzer> analyzers = new ArrayList<>();
|
||||||
service = new AnalyzerService();
|
final Iterator<Analyzer> iterator = service.iterator();
|
||||||
|
boolean experimentalEnabled = false;
|
||||||
|
try {
|
||||||
|
experimentalEnabled = Settings.getBoolean(Settings.KEYS.ANALYZER_EXPERIMENTAL_ENABLED, false);
|
||||||
|
} catch (InvalidSettingException ex) {
|
||||||
|
LOGGER.error("invalid experimental setting", ex);
|
||||||
}
|
}
|
||||||
return service;
|
while (iterator.hasNext()) {
|
||||||
|
final Analyzer a = iterator.next();
|
||||||
|
if (!experimentalEnabled && a.getClass().isAnnotationPresent(Experimental.class)) {
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
LOGGER.debug("Loaded Analyzer {}", a.getName());
|
||||||
/**
|
analyzers.add(a);
|
||||||
* Returns an Iterator for all instances of the Analyzer interface.
|
}
|
||||||
*
|
return analyzers;
|
||||||
* @return an iterator of Analyzers.
|
|
||||||
*/
|
|
||||||
public Iterator<Analyzer> getAnalyzers() {
|
|
||||||
return loader.iterator();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,69 +1,72 @@
|
|||||||
/*
|
/*
|
||||||
* This file is part of dependency-check-core.
|
* This file is part of dependency-check-core.
|
||||||
*
|
*
|
||||||
* Dependency-check-core is free software: you can redistribute it and/or modify it
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* under the terms of the GNU General Public License as published by the Free
|
* you may not use this file except in compliance with the License.
|
||||||
* Software Foundation, either version 3 of the License, or (at your option) any
|
* You may obtain a copy of the License at
|
||||||
* later version.
|
|
||||||
*
|
*
|
||||||
* Dependency-check-core is distributed in the hope that it will be useful, but
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
|
||||||
* details.
|
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License along with
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* dependency-check-core. If not, see http://www.gnu.org/licenses/.
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
*
|
*
|
||||||
* Copyright (c) 2013 Jeremy Long. All Rights Reserved.
|
* Copyright (c) 2013 Jeremy Long. All Rights Reserved.
|
||||||
*/
|
*/
|
||||||
package org.owasp.dependencycheck.analyzer;
|
package org.owasp.dependencycheck.analyzer;
|
||||||
|
|
||||||
import java.io.BufferedInputStream;
|
import java.io.BufferedInputStream;
|
||||||
import java.io.BufferedOutputStream;
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.FileFilter;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashSet;
|
import java.util.Enumeration;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.logging.Level;
|
|
||||||
import java.util.logging.Logger;
|
import org.apache.commons.compress.archivers.ArchiveEntry;
|
||||||
//import java.util.zip.ZipEntry;
|
import org.apache.commons.compress.archivers.ArchiveInputStream;
|
||||||
//import java.util.zip.ZipException;
|
import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
|
||||||
//import java.util.zip.ZipInputStream;
|
|
||||||
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
|
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
|
||||||
import org.apache.commons.compress.archivers.zip.ZipArchiveInputStream;
|
import org.apache.commons.compress.archivers.zip.ZipArchiveInputStream;
|
||||||
import org.h2.store.fs.FileUtils;
|
import org.apache.commons.compress.archivers.zip.ZipFile;
|
||||||
|
import org.apache.commons.compress.compressors.CompressorInputStream;
|
||||||
|
import org.apache.commons.compress.compressors.bzip2.BZip2CompressorInputStream;
|
||||||
|
import org.apache.commons.compress.compressors.bzip2.BZip2Utils;
|
||||||
|
import org.apache.commons.compress.compressors.gzip.GzipCompressorInputStream;
|
||||||
|
import org.apache.commons.compress.compressors.gzip.GzipUtils;
|
||||||
|
import org.apache.commons.compress.utils.IOUtils;
|
||||||
|
|
||||||
import org.owasp.dependencycheck.Engine;
|
import org.owasp.dependencycheck.Engine;
|
||||||
|
import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
|
||||||
|
import org.owasp.dependencycheck.analyzer.exception.ArchiveExtractionException;
|
||||||
import org.owasp.dependencycheck.dependency.Dependency;
|
import org.owasp.dependencycheck.dependency.Dependency;
|
||||||
|
import org.owasp.dependencycheck.exception.InitializationException;
|
||||||
|
import org.owasp.dependencycheck.utils.FileFilterBuilder;
|
||||||
|
import org.owasp.dependencycheck.utils.FileUtils;
|
||||||
import org.owasp.dependencycheck.utils.Settings;
|
import org.owasp.dependencycheck.utils.Settings;
|
||||||
|
|
||||||
/**
|
import org.slf4j.Logger;
|
||||||
* <p>An analyzer that works on archive files:
|
import org.slf4j.LoggerFactory;
|
||||||
* <ul>
|
|
||||||
* <li><b>ZIP</b> - if it is determined to be a JAR, WAR or EAR a copy is made
|
|
||||||
* and the copy is given the correct extension so that it will be correctly
|
|
||||||
* analyzed.</li>
|
|
||||||
* <li><b>WAR</b> - the WAR contents are extracted and added as dependencies to
|
|
||||||
* the scan. The displayed path is relative to the WAR.</li>
|
|
||||||
* <li><b>EAR</b> - the WAR contents are extracted and added as dependencies to
|
|
||||||
* the scan. Any WAR files are also processed so that the contained JAR files
|
|
||||||
* are added to the list of dependencies. The displayed path is relative to the
|
|
||||||
* EAR.</li>
|
|
||||||
* </ul></p>
|
|
||||||
*
|
|
||||||
* @author Jeremy Long (jeremy.long@owasp.org)
|
|
||||||
*/
|
|
||||||
public class ArchiveAnalyzer extends AbstractAnalyzer implements Analyzer {
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The buffer size to use when extracting files from the archive.
|
* <p>
|
||||||
|
* An analyzer that extracts files from archives and ensures any supported files
|
||||||
|
* contained within the archive are added to the dependency list.</p>
|
||||||
|
*
|
||||||
|
* @author Jeremy Long
|
||||||
*/
|
*/
|
||||||
private static final int BUFFER_SIZE = 4096;
|
public class ArchiveAnalyzer extends AbstractFileTypeAnalyzer {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The logger.
|
||||||
|
*/
|
||||||
|
private static final Logger LOGGER = LoggerFactory.getLogger(ArchiveAnalyzer.class);
|
||||||
/**
|
/**
|
||||||
* The count of directories created during analysis. This is used for
|
* The count of directories created during analysis. This is used for
|
||||||
* creating temporary directories.
|
* creating temporary directories.
|
||||||
@@ -82,7 +85,8 @@ public class ArchiveAnalyzer extends AbstractAnalyzer implements Analyzer {
|
|||||||
* Tracks the current scan/extraction depth for nested archives.
|
* Tracks the current scan/extraction depth for nested archives.
|
||||||
*/
|
*/
|
||||||
private int scanDepth = 0;
|
private int scanDepth = 0;
|
||||||
//<editor-fold defaultstate="collapsed" desc="All standard implmentation details of Analyzer">
|
|
||||||
|
//<editor-fold defaultstate="collapsed" desc="All standard implementation details of Analyzer">
|
||||||
/**
|
/**
|
||||||
* The name of the analyzer.
|
* The name of the analyzer.
|
||||||
*/
|
*/
|
||||||
@@ -92,17 +96,45 @@ public class ArchiveAnalyzer extends AbstractAnalyzer implements Analyzer {
|
|||||||
*/
|
*/
|
||||||
private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INITIAL;
|
private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INITIAL;
|
||||||
/**
|
/**
|
||||||
* The set of file extensions supported by this analyzer.
|
* The set of things we can handle with Zip methods
|
||||||
*/
|
*/
|
||||||
private static final Set<String> EXTENSIONS = newHashSet("zip", "ear", "war");
|
private static final Set<String> KNOWN_ZIP_EXT = newHashSet("zip", "ear", "war", "jar", "sar", "apk", "nupkg");
|
||||||
|
/**
|
||||||
|
* The set of file extensions supported by this analyzer. Note for
|
||||||
|
* developers, any additions to this list will need to be explicitly handled
|
||||||
|
* in {@link #extractFiles(File, File, Engine)}.
|
||||||
|
*/
|
||||||
|
private static final Set<String> EXTENSIONS = newHashSet("tar", "gz", "tgz", "bz2", "tbz2");
|
||||||
|
|
||||||
|
static {
|
||||||
|
final String additionalZipExt = Settings.getString(Settings.KEYS.ADDITIONAL_ZIP_EXTENSIONS);
|
||||||
|
if (additionalZipExt != null) {
|
||||||
|
final String[] ext = additionalZipExt.split("\\s*,\\s*");
|
||||||
|
Collections.addAll(KNOWN_ZIP_EXT, ext);
|
||||||
|
}
|
||||||
|
EXTENSIONS.addAll(KNOWN_ZIP_EXT);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a list of file EXTENSIONS supported by this analyzer.
|
* Detects files with extensions to remove from the engine's collection of
|
||||||
*
|
* dependencies.
|
||||||
* @return a list of file EXTENSIONS supported by this analyzer.
|
|
||||||
*/
|
*/
|
||||||
public Set<String> getSupportedExtensions() {
|
private static final FileFilter REMOVE_FROM_ANALYSIS = FileFilterBuilder.newInstance()
|
||||||
return EXTENSIONS;
|
.addExtensions("zip", "tar", "gz", "tgz", "bz2", "tbz2").build();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The file filter used to filter supported files.
|
||||||
|
*/
|
||||||
|
private static final FileFilter FILTER = FileFilterBuilder.newInstance().addExtensions(EXTENSIONS).build();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Detects files with .zip extension.
|
||||||
|
*/
|
||||||
|
private static final FileFilter ZIP_FILTER = FileFilterBuilder.newInstance().addExtensions("zip").build();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected FileFilter getFileFilter() {
|
||||||
|
return FILTER;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -110,64 +142,94 @@ public class ArchiveAnalyzer extends AbstractAnalyzer implements Analyzer {
|
|||||||
*
|
*
|
||||||
* @return the name of the analyzer.
|
* @return the name of the analyzer.
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return ANALYZER_NAME;
|
return ANALYZER_NAME;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns whether or not this analyzer can process the given extension.
|
|
||||||
*
|
|
||||||
* @param extension the file extension to test for support.
|
|
||||||
* @return whether or not the specified file extension is supported by this
|
|
||||||
* analyzer.
|
|
||||||
*/
|
|
||||||
public boolean supportsExtension(String extension) {
|
|
||||||
return EXTENSIONS.contains(extension);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the phase that the analyzer is intended to run in.
|
* Returns the phase that the analyzer is intended to run in.
|
||||||
*
|
*
|
||||||
* @return the phase that the analyzer is intended to run in.
|
* @return the phase that the analyzer is intended to run in.
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public AnalysisPhase getAnalysisPhase() {
|
public AnalysisPhase getAnalysisPhase() {
|
||||||
return ANALYSIS_PHASE;
|
return ANALYSIS_PHASE;
|
||||||
}
|
}
|
||||||
//</editor-fold>
|
//</editor-fold>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The initialize method does nothing for this Analyzer.
|
* Returns the key used in the properties file to reference the analyzer's
|
||||||
|
* enabled property.
|
||||||
*
|
*
|
||||||
* @throws Exception is thrown if there is an exception deleting or creating
|
* @return the analyzer's enabled property setting key
|
||||||
* temporary files
|
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void initialize() throws Exception {
|
protected String getAnalyzerEnabledSettingKey() {
|
||||||
final File baseDir = Settings.getTempDirectory();
|
return Settings.KEYS.ANALYZER_ARCHIVE_ENABLED;
|
||||||
if (!baseDir.exists()) {
|
|
||||||
baseDir.mkdirs();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The initialize method does nothing for this Analyzer.
|
||||||
|
*
|
||||||
|
* @throws InitializationException is thrown if there is an exception
|
||||||
|
* deleting or creating temporary files
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void initializeFileTypeAnalyzer() throws InitializationException {
|
||||||
|
try {
|
||||||
|
final File baseDir = Settings.getTempDirectory();
|
||||||
tempFileLocation = File.createTempFile("check", "tmp", baseDir);
|
tempFileLocation = File.createTempFile("check", "tmp", baseDir);
|
||||||
if (!tempFileLocation.delete()) {
|
if (!tempFileLocation.delete()) {
|
||||||
throw new AnalysisException("Unable to delete temporary file '" + tempFileLocation.getAbsolutePath() + "'.");
|
setEnabled(false);
|
||||||
|
final String msg = String.format("Unable to delete temporary file '%s'.", tempFileLocation.getAbsolutePath());
|
||||||
|
throw new InitializationException(msg);
|
||||||
}
|
}
|
||||||
if (!tempFileLocation.mkdirs()) {
|
if (!tempFileLocation.mkdirs()) {
|
||||||
throw new AnalysisException("Unable to create directory '" + tempFileLocation.getAbsolutePath() + "'.");
|
setEnabled(false);
|
||||||
|
final String msg = String.format("Unable to create directory '%s'.", tempFileLocation.getAbsolutePath());
|
||||||
|
throw new InitializationException(msg);
|
||||||
|
}
|
||||||
|
} catch (IOException ex) {
|
||||||
|
setEnabled(false);
|
||||||
|
throw new InitializationException("Unable to create a temporary file", ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The close method does nothing for this Analyzer.
|
* The close method deletes any temporary files and directories created
|
||||||
|
* during analysis.
|
||||||
*
|
*
|
||||||
* @throws Exception thrown if there is an exception deleting temporary
|
* @throws Exception thrown if there is an exception deleting temporary
|
||||||
* files
|
* files
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void close() throws Exception {
|
public void closeAnalyzer() throws Exception {
|
||||||
if (tempFileLocation != null && tempFileLocation.exists()) {
|
if (tempFileLocation != null && tempFileLocation.exists()) {
|
||||||
FileUtils.deleteRecursive(tempFileLocation.getAbsolutePath(), true);
|
LOGGER.debug("Attempting to delete temporary files");
|
||||||
|
final boolean success = FileUtils.delete(tempFileLocation);
|
||||||
|
if (!success && tempFileLocation.exists()) {
|
||||||
|
final String[] l = tempFileLocation.list();
|
||||||
|
if (l != null && l.length > 0) {
|
||||||
|
LOGGER.warn("Failed to delete some temporary files, see the log for more details");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Does not support parallel processing as it both modifies and iterates
|
||||||
|
* over the engine's list of dependencies.
|
||||||
|
*
|
||||||
|
* @return <code>true</code> if the analyzer supports parallel processing;
|
||||||
|
* otherwise <code>false</code>
|
||||||
|
* @see #analyzeDependency(Dependency, Engine)
|
||||||
|
* @see #findMoreDependencies(Engine, File)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean supportsParallelProcessing() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Analyzes a given dependency. If the dependency is an archive, such as a
|
* Analyzes a given dependency. If the dependency is an archive, such as a
|
||||||
@@ -179,46 +241,115 @@ public class ArchiveAnalyzer extends AbstractAnalyzer implements Analyzer {
|
|||||||
* @throws AnalysisException thrown if there is an analysis exception
|
* @throws AnalysisException thrown if there is an analysis exception
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void analyze(Dependency dependency, Engine engine) throws AnalysisException {
|
public void analyzeDependency(Dependency dependency, Engine engine) throws AnalysisException {
|
||||||
final File f = new File(dependency.getActualFilePath());
|
final File f = new File(dependency.getActualFilePath());
|
||||||
final File tmpDir = getNextTempDirectory();
|
final File tmpDir = getNextTempDirectory();
|
||||||
extractFiles(f, tmpDir, engine);
|
extractFiles(f, tmpDir, engine);
|
||||||
|
|
||||||
//make a copy
|
//make a copy
|
||||||
final List<Dependency> dependencies = new ArrayList<Dependency>(engine.getDependencies());
|
final List<Dependency> dependencySet = findMoreDependencies(engine, tmpDir);
|
||||||
engine.scan(tmpDir);
|
|
||||||
final List<Dependency> newDependencies = engine.getDependencies();
|
|
||||||
if (dependencies.size() != newDependencies.size()) {
|
|
||||||
//get the new dependencies
|
|
||||||
final Set<Dependency> dependencySet = new HashSet<Dependency>();
|
|
||||||
dependencySet.addAll(newDependencies);
|
|
||||||
dependencySet.removeAll(dependencies);
|
|
||||||
|
|
||||||
|
if (dependencySet != null && !dependencySet.isEmpty()) {
|
||||||
for (Dependency d : dependencySet) {
|
for (Dependency d : dependencySet) {
|
||||||
|
if (d.getFilePath().startsWith(tmpDir.getAbsolutePath())) {
|
||||||
//fix the dependency's display name and path
|
//fix the dependency's display name and path
|
||||||
final String displayPath = String.format("%s%s",
|
final String displayPath = String.format("%s%s",
|
||||||
dependency.getFilePath(),
|
dependency.getFilePath(),
|
||||||
d.getActualFilePath().substring(tmpDir.getAbsolutePath().length()));
|
d.getActualFilePath().substring(tmpDir.getAbsolutePath().length()));
|
||||||
final String displayName = String.format("%s%s%s",
|
final String displayName = String.format("%s: %s",
|
||||||
dependency.getFileName(),
|
dependency.getFileName(),
|
||||||
File.separator,
|
|
||||||
d.getFileName());
|
d.getFileName());
|
||||||
d.setFilePath(displayPath);
|
d.setFilePath(displayPath);
|
||||||
d.setFileName(displayName);
|
d.setFileName(displayName);
|
||||||
|
d.setProjectReferences(dependency.getProjectReferences());
|
||||||
|
|
||||||
//TODO - can we get more evidence from the parent? EAR contains module name, etc.
|
//TODO - can we get more evidence from the parent? EAR contains module name, etc.
|
||||||
|
|
||||||
//analyze the dependency (i.e. extract files) if it is a supported type.
|
//analyze the dependency (i.e. extract files) if it is a supported type.
|
||||||
if (this.supportsExtension(d.getFileExtension()) && scanDepth < MAX_SCAN_DEPTH) {
|
if (this.accept(d.getActualFile()) && scanDepth < MAX_SCAN_DEPTH) {
|
||||||
scanDepth += 1;
|
scanDepth += 1;
|
||||||
analyze(d, engine);
|
analyze(d, engine);
|
||||||
scanDepth -= 1;
|
scanDepth -= 1;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
for (Dependency sub : dependencySet) {
|
||||||
|
if (sub.getFilePath().startsWith(tmpDir.getAbsolutePath())) {
|
||||||
|
final String displayPath = String.format("%s%s",
|
||||||
|
dependency.getFilePath(),
|
||||||
|
sub.getActualFilePath().substring(tmpDir.getAbsolutePath().length()));
|
||||||
|
final String displayName = String.format("%s: %s",
|
||||||
|
dependency.getFileName(),
|
||||||
|
sub.getFileName());
|
||||||
|
sub.setFilePath(displayPath);
|
||||||
|
sub.setFileName(displayName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (REMOVE_FROM_ANALYSIS.accept(dependency.getActualFile())) {
|
||||||
|
addDisguisedJarsToDependencies(dependency, engine);
|
||||||
|
engine.getDependencies().remove(dependency);
|
||||||
|
}
|
||||||
Collections.sort(engine.getDependencies());
|
Collections.sort(engine.getDependencies());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If a zip file was identified as a possible JAR, this method will add the
|
||||||
|
* zip to the list of dependencies.
|
||||||
|
*
|
||||||
|
* @param dependency the zip file
|
||||||
|
* @param engine the engine
|
||||||
|
* @throws AnalysisException thrown if there is an issue
|
||||||
|
*/
|
||||||
|
private void addDisguisedJarsToDependencies(Dependency dependency, Engine engine) throws AnalysisException {
|
||||||
|
if (ZIP_FILTER.accept(dependency.getActualFile()) && isZipFileActuallyJarFile(dependency)) {
|
||||||
|
final File tempDir = getNextTempDirectory();
|
||||||
|
final String fileName = dependency.getFileName();
|
||||||
|
|
||||||
|
LOGGER.info("The zip file '{}' appears to be a JAR file, making a copy and analyzing it as a JAR.", fileName);
|
||||||
|
final File tmpLoc = new File(tempDir, fileName.substring(0, fileName.length() - 3) + "jar");
|
||||||
|
//store the archives sha1 and change it so that the engine doesn't think the zip and jar file are the same
|
||||||
|
// and add it is a related dependency.
|
||||||
|
final String archiveSha1 = dependency.getSha1sum();
|
||||||
|
try {
|
||||||
|
dependency.setSha1sum("");
|
||||||
|
org.apache.commons.io.FileUtils.copyFile(dependency.getActualFile(), tmpLoc);
|
||||||
|
final List<Dependency> dependencySet = findMoreDependencies(engine, tmpLoc);
|
||||||
|
if (dependencySet != null && !dependencySet.isEmpty()) {
|
||||||
|
for (Dependency d : dependencySet) {
|
||||||
|
//fix the dependency's display name and path
|
||||||
|
if (d.getActualFile().equals(tmpLoc)) {
|
||||||
|
d.setFilePath(dependency.getFilePath());
|
||||||
|
d.setDisplayFileName(dependency.getFileName());
|
||||||
|
} else {
|
||||||
|
for (Dependency sub : d.getRelatedDependencies()) {
|
||||||
|
if (sub.getActualFile().equals(tmpLoc)) {
|
||||||
|
sub.setFilePath(dependency.getFilePath());
|
||||||
|
sub.setDisplayFileName(dependency.getFileName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (IOException ex) {
|
||||||
|
LOGGER.debug("Unable to perform deep copy on '{}'", dependency.getActualFile().getPath(), ex);
|
||||||
|
} finally {
|
||||||
|
dependency.setSha1sum(archiveSha1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Scan the given file/folder, and return any new dependencies found.
|
||||||
|
*
|
||||||
|
* @param engine used to scan
|
||||||
|
* @param file target of scanning
|
||||||
|
* @return any dependencies that weren't known to the engine before
|
||||||
|
*/
|
||||||
|
private static List<Dependency> findMoreDependencies(Engine engine, File file) {
|
||||||
|
return engine.scan(file);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves the next temporary directory to extract an archive too.
|
* Retrieves the next temporary directory to extract an archive too.
|
||||||
*
|
*
|
||||||
@@ -228,8 +359,13 @@ public class ArchiveAnalyzer extends AbstractAnalyzer implements Analyzer {
|
|||||||
private File getNextTempDirectory() throws AnalysisException {
|
private File getNextTempDirectory() throws AnalysisException {
|
||||||
dirCount += 1;
|
dirCount += 1;
|
||||||
final File directory = new File(tempFileLocation, String.valueOf(dirCount));
|
final File directory = new File(tempFileLocation, String.valueOf(dirCount));
|
||||||
|
//getting an exception for some directories not being able to be created; might be because the directory already exists?
|
||||||
|
if (directory.exists()) {
|
||||||
|
return getNextTempDirectory();
|
||||||
|
}
|
||||||
if (!directory.mkdirs()) {
|
if (!directory.mkdirs()) {
|
||||||
throw new AnalysisException("Unable to create temp directory '" + directory.getAbsolutePath() + "'.");
|
final String msg = String.format("Unable to create temp directory '%s'.", directory.getAbsolutePath());
|
||||||
|
throw new AnalysisException(msg);
|
||||||
}
|
}
|
||||||
return directory;
|
return directory;
|
||||||
}
|
}
|
||||||
@@ -238,84 +374,233 @@ public class ArchiveAnalyzer extends AbstractAnalyzer implements Analyzer {
|
|||||||
* Extracts the contents of an archive into the specified directory.
|
* Extracts the contents of an archive into the specified directory.
|
||||||
*
|
*
|
||||||
* @param archive an archive file such as a WAR or EAR
|
* @param archive an archive file such as a WAR or EAR
|
||||||
* @param extractTo a directory to extract the contents to
|
* @param destination a directory to extract the contents to
|
||||||
* @param engine the scanning engine
|
* @param engine the scanning engine
|
||||||
* @throws AnalysisException thrown if the archive is not found
|
* @throws AnalysisException thrown if the archive is not found
|
||||||
*/
|
*/
|
||||||
private void extractFiles(File archive, File extractTo, Engine engine) throws AnalysisException {
|
private void extractFiles(File archive, File destination, Engine engine) throws AnalysisException {
|
||||||
if (archive == null || extractTo == null) {
|
if (archive != null && destination != null) {
|
||||||
|
String archiveExt = FileUtils.getFileExtension(archive.getName());
|
||||||
|
if (archiveExt == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
archiveExt = archiveExt.toLowerCase();
|
||||||
|
|
||||||
FileInputStream fis = null;
|
final FileInputStream fis;
|
||||||
//ZipInputStream zis = null;
|
|
||||||
ZipArchiveInputStream zis = null;
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
fis = new FileInputStream(archive);
|
fis = new FileInputStream(archive);
|
||||||
} catch (FileNotFoundException ex) {
|
} catch (FileNotFoundException ex) {
|
||||||
Logger.getLogger(ArchiveAnalyzer.class.getName()).log(Level.INFO, null, ex);
|
LOGGER.debug("", ex);
|
||||||
throw new AnalysisException("Archive file was not found.", ex);
|
throw new AnalysisException("Archive file was not found.", ex);
|
||||||
}
|
}
|
||||||
zis = new ZipArchiveInputStream(new BufferedInputStream(fis));
|
BufferedInputStream in = null;
|
||||||
ZipArchiveEntry entry;
|
ZipArchiveInputStream zin = null;
|
||||||
|
TarArchiveInputStream tin = null;
|
||||||
|
GzipCompressorInputStream gin = null;
|
||||||
|
BZip2CompressorInputStream bzin = null;
|
||||||
try {
|
try {
|
||||||
while ((entry = zis.getNextZipEntry()) != null) {
|
if (KNOWN_ZIP_EXT.contains(archiveExt)) {
|
||||||
if (entry.isDirectory()) {
|
in = new BufferedInputStream(fis);
|
||||||
final File d = new File(extractTo, entry.getName());
|
ensureReadableJar(archiveExt, in);
|
||||||
if (!d.mkdirs()) {
|
zin = new ZipArchiveInputStream(in);
|
||||||
throw new AnalysisException("Unable to create '" + d.getAbsolutePath() + "'.");
|
extractArchive(zin, destination, engine);
|
||||||
|
} else if ("tar".equals(archiveExt)) {
|
||||||
|
in = new BufferedInputStream(fis);
|
||||||
|
tin = new TarArchiveInputStream(in);
|
||||||
|
extractArchive(tin, destination, engine);
|
||||||
|
} else if ("gz".equals(archiveExt) || "tgz".equals(archiveExt)) {
|
||||||
|
final String uncompressedName = GzipUtils.getUncompressedFilename(archive.getName());
|
||||||
|
final File f = new File(destination, uncompressedName);
|
||||||
|
if (engine.accept(f)) {
|
||||||
|
in = new BufferedInputStream(fis);
|
||||||
|
gin = new GzipCompressorInputStream(in);
|
||||||
|
decompressFile(gin, f);
|
||||||
|
}
|
||||||
|
} else if ("bz2".equals(archiveExt) || "tbz2".equals(archiveExt)) {
|
||||||
|
final String uncompressedName = BZip2Utils.getUncompressedFilename(archive.getName());
|
||||||
|
final File f = new File(destination, uncompressedName);
|
||||||
|
if (engine.accept(f)) {
|
||||||
|
in = new BufferedInputStream(fis);
|
||||||
|
bzin = new BZip2CompressorInputStream(in);
|
||||||
|
decompressFile(bzin, f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (ArchiveExtractionException ex) {
|
||||||
|
LOGGER.warn("Exception extracting archive '{}'.", archive.getName());
|
||||||
|
LOGGER.debug("", ex);
|
||||||
|
} catch (IOException ex) {
|
||||||
|
LOGGER.warn("Exception reading archive '{}'.", archive.getName());
|
||||||
|
LOGGER.debug("", ex);
|
||||||
|
} finally {
|
||||||
|
//overly verbose and not needed... but keeping it anyway due to
|
||||||
|
//having issue with file handles being left open
|
||||||
|
FileUtils.close(fis);
|
||||||
|
FileUtils.close(in);
|
||||||
|
FileUtils.close(zin);
|
||||||
|
FileUtils.close(tin);
|
||||||
|
FileUtils.close(gin);
|
||||||
|
FileUtils.close(bzin);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the file being scanned is a JAR that begins with '#!/bin' which
|
||||||
|
* indicates it is a fully executable jar. If a fully executable JAR is
|
||||||
|
* identified the input stream will be advanced to the start of the actual
|
||||||
|
* JAR file ( skipping the script).
|
||||||
|
*
|
||||||
|
* @see
|
||||||
|
* <a href="http://docs.spring.io/spring-boot/docs/1.3.0.BUILD-SNAPSHOT/reference/htmlsingle/#deployment-install">Installing
|
||||||
|
* Spring Boot Applications</a>
|
||||||
|
* @param archiveExt the file extension
|
||||||
|
* @param in the input stream
|
||||||
|
* @throws IOException thrown if there is an error reading the stream
|
||||||
|
*/
|
||||||
|
private void ensureReadableJar(final String archiveExt, BufferedInputStream in) throws IOException {
|
||||||
|
if ("jar".equals(archiveExt) && in.markSupported()) {
|
||||||
|
in.mark(7);
|
||||||
|
final byte[] b = new byte[7];
|
||||||
|
final int read = in.read(b);
|
||||||
|
if (read == 7
|
||||||
|
&& b[0] == '#'
|
||||||
|
&& b[1] == '!'
|
||||||
|
&& b[2] == '/'
|
||||||
|
&& b[3] == 'b'
|
||||||
|
&& b[4] == 'i'
|
||||||
|
&& b[5] == 'n'
|
||||||
|
&& b[6] == '/') {
|
||||||
|
boolean stillLooking = true;
|
||||||
|
int chr;
|
||||||
|
int nxtChr;
|
||||||
|
while (stillLooking && (chr = in.read()) != -1) {
|
||||||
|
if (chr == '\n' || chr == '\r') {
|
||||||
|
in.mark(4);
|
||||||
|
if ((chr = in.read()) != -1) {
|
||||||
|
if (chr == 'P' && (chr = in.read()) != -1) {
|
||||||
|
if (chr == 'K' && (chr = in.read()) != -1) {
|
||||||
|
if ((chr == 3 || chr == 5 || chr == 7) && (nxtChr = in.read()) != -1) {
|
||||||
|
if (nxtChr == chr + 1) {
|
||||||
|
stillLooking = false;
|
||||||
|
in.reset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
final File file = new File(extractTo, entry.getName());
|
in.reset();
|
||||||
final String ext = org.owasp.dependencycheck.utils.FileUtils.getFileExtension(file.getName());
|
|
||||||
if (engine.supportsExtension(ext)) {
|
|
||||||
BufferedOutputStream bos = null;
|
|
||||||
FileOutputStream fos;
|
|
||||||
try {
|
|
||||||
fos = new FileOutputStream(file);
|
|
||||||
bos = new BufferedOutputStream(fos, BUFFER_SIZE);
|
|
||||||
int count;
|
|
||||||
final byte data[] = new byte[BUFFER_SIZE];
|
|
||||||
while ((count = zis.read(data, 0, BUFFER_SIZE)) != -1) {
|
|
||||||
bos.write(data, 0, count);
|
|
||||||
}
|
}
|
||||||
bos.flush();
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extracts files from an archive.
|
||||||
|
*
|
||||||
|
* @param input the archive to extract files from
|
||||||
|
* @param destination the location to write the files too
|
||||||
|
* @param engine the dependency-check engine
|
||||||
|
* @throws ArchiveExtractionException thrown if there is an exception
|
||||||
|
* extracting files from the archive
|
||||||
|
*/
|
||||||
|
private void extractArchive(ArchiveInputStream input, File destination, Engine engine) throws ArchiveExtractionException {
|
||||||
|
ArchiveEntry entry;
|
||||||
|
try {
|
||||||
|
while ((entry = input.getNextEntry()) != null) {
|
||||||
|
final File file = new File(destination, entry.getName());
|
||||||
|
if (entry.isDirectory()) {
|
||||||
|
if (!file.exists() && !file.mkdirs()) {
|
||||||
|
final String msg = String.format("Unable to create directory '%s'.", file.getAbsolutePath());
|
||||||
|
throw new AnalysisException(msg);
|
||||||
|
}
|
||||||
|
} else if (engine.accept(file)) {
|
||||||
|
extractAcceptedFile(input, file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (IOException | AnalysisException ex) {
|
||||||
|
throw new ArchiveExtractionException(ex);
|
||||||
|
} finally {
|
||||||
|
FileUtils.close(input);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extracts a file from an archive.
|
||||||
|
*
|
||||||
|
* @param input the archives input stream
|
||||||
|
* @param file the file to extract
|
||||||
|
* @throws AnalysisException thrown if there is an error
|
||||||
|
*/
|
||||||
|
private static void extractAcceptedFile(ArchiveInputStream input, File file) throws AnalysisException {
|
||||||
|
LOGGER.debug("Extracting '{}'", file.getPath());
|
||||||
|
final File parent = file.getParentFile();
|
||||||
|
if (!parent.isDirectory() && !parent.mkdirs()) {
|
||||||
|
final String msg = String.format("Unable to build directory '%s'.", parent.getAbsolutePath());
|
||||||
|
throw new AnalysisException(msg);
|
||||||
|
}
|
||||||
|
try (FileOutputStream fos = new FileOutputStream(file)) {
|
||||||
|
IOUtils.copy(input, fos);
|
||||||
} catch (FileNotFoundException ex) {
|
} catch (FileNotFoundException ex) {
|
||||||
Logger.getLogger(ArchiveAnalyzer.class.getName()).log(Level.FINE, null, ex);
|
LOGGER.debug("", ex);
|
||||||
throw new AnalysisException("Unable to find file '" + file.getName() + "'.", ex);
|
final String msg = String.format("Unable to find file '%s'.", file.getName());
|
||||||
} catch (IOException ex) {
|
|
||||||
Logger.getLogger(ArchiveAnalyzer.class.getName()).log(Level.FINE, null, ex);
|
|
||||||
throw new AnalysisException("IO Exception while parsing file '" + file.getName() + "'.", ex);
|
|
||||||
} finally {
|
|
||||||
if (bos != null) {
|
|
||||||
try {
|
|
||||||
bos.close();
|
|
||||||
} catch (IOException ex) {
|
|
||||||
Logger.getLogger(ArchiveAnalyzer.class.getName()).log(Level.FINEST, null, ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (IOException ex) {
|
|
||||||
final String msg = String.format("Exception reading archive '%s'.", archive.getName());
|
|
||||||
Logger.getLogger(ArchiveAnalyzer.class.getName()).log(Level.WARNING, msg);
|
|
||||||
Logger.getLogger(ArchiveAnalyzer.class.getName()).log(Level.FINE, null, ex);
|
|
||||||
throw new AnalysisException(msg, ex);
|
throw new AnalysisException(msg, ex);
|
||||||
} catch (Throwable ex) {
|
|
||||||
final String msg = String.format("Exception reading archive '%s'.", archive.getName());
|
|
||||||
Logger.getLogger(ArchiveAnalyzer.class.getName()).log(Level.WARNING, msg);
|
|
||||||
Logger.getLogger(ArchiveAnalyzer.class.getName()).log(Level.WARNING, null, ex);
|
|
||||||
throw new AnalysisException(msg, ex);
|
|
||||||
} finally {
|
|
||||||
try {
|
|
||||||
zis.close();
|
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
Logger.getLogger(ArchiveAnalyzer.class.getName()).log(Level.FINEST, null, ex);
|
LOGGER.debug("", ex);
|
||||||
|
final String msg = String.format("IO Exception while parsing file '%s'.", file.getName());
|
||||||
|
throw new AnalysisException(msg, ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decompresses a file.
|
||||||
|
*
|
||||||
|
* @param inputStream the compressed file
|
||||||
|
* @param outputFile the location to write the decompressed file
|
||||||
|
* @throws ArchiveExtractionException thrown if there is an exception
|
||||||
|
* decompressing the file
|
||||||
|
*/
|
||||||
|
private void decompressFile(CompressorInputStream inputStream, File outputFile) throws ArchiveExtractionException {
|
||||||
|
LOGGER.debug("Decompressing '{}'", outputFile.getPath());
|
||||||
|
try (FileOutputStream out = new FileOutputStream(outputFile)) {
|
||||||
|
IOUtils.copy(inputStream, out);
|
||||||
|
} catch (IOException ex) {
|
||||||
|
LOGGER.debug("", ex);
|
||||||
|
throw new ArchiveExtractionException(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attempts to determine if a zip file is actually a JAR file.
|
||||||
|
*
|
||||||
|
* @param dependency the dependency to check
|
||||||
|
* @return true if the dependency appears to be a JAR file; otherwise false
|
||||||
|
*/
|
||||||
|
private boolean isZipFileActuallyJarFile(Dependency dependency) {
|
||||||
|
boolean isJar = false;
|
||||||
|
ZipFile zip = null;
|
||||||
|
try {
|
||||||
|
zip = new ZipFile(dependency.getActualFilePath());
|
||||||
|
if (zip.getEntry("META-INF/MANIFEST.MF") != null
|
||||||
|
|| zip.getEntry("META-INF/maven") != null) {
|
||||||
|
final Enumeration<ZipArchiveEntry> entries = zip.getEntries();
|
||||||
|
while (entries.hasMoreElements()) {
|
||||||
|
final ZipArchiveEntry entry = entries.nextElement();
|
||||||
|
if (!entry.isDirectory()) {
|
||||||
|
final String name = entry.getName().toLowerCase();
|
||||||
|
if (name.endsWith(".class")) {
|
||||||
|
isJar = true;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} catch (IOException ex) {
|
||||||
|
LOGGER.debug("Unable to unzip zip file '{}'", dependency.getFilePath(), ex);
|
||||||
|
} finally {
|
||||||
|
ZipFile.closeQuietly(zip);
|
||||||
|
}
|
||||||
|
return isJar;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1,355 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of dependency-check-core.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
* Copyright (c) 2012 Jeremy Long. All Rights Reserved.
|
||||||
|
*/
|
||||||
|
package org.owasp.dependencycheck.analyzer;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileFilter;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import org.apache.commons.io.IOUtils;
|
||||||
|
import org.apache.commons.io.output.NullOutputStream;
|
||||||
|
import org.owasp.dependencycheck.Engine;
|
||||||
|
import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
|
||||||
|
import org.owasp.dependencycheck.dependency.Confidence;
|
||||||
|
import org.owasp.dependencycheck.dependency.Dependency;
|
||||||
|
import org.owasp.dependencycheck.dependency.Evidence;
|
||||||
|
import org.owasp.dependencycheck.utils.FileFilterBuilder;
|
||||||
|
import org.owasp.dependencycheck.utils.Settings;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.w3c.dom.Document;
|
||||||
|
import org.xml.sax.SAXException;
|
||||||
|
|
||||||
|
import javax.xml.parsers.DocumentBuilder;
|
||||||
|
import javax.xml.xpath.XPath;
|
||||||
|
import javax.xml.xpath.XPathExpressionException;
|
||||||
|
import javax.xml.xpath.XPathFactory;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import javax.xml.parsers.ParserConfigurationException;
|
||||||
|
import org.owasp.dependencycheck.exception.InitializationException;
|
||||||
|
import org.apache.commons.lang3.SystemUtils;
|
||||||
|
import org.owasp.dependencycheck.utils.XmlUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Analyzer for getting company, product, and version information from a .NET
|
||||||
|
* assembly.
|
||||||
|
*
|
||||||
|
* @author colezlaw
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class AssemblyAnalyzer extends AbstractFileTypeAnalyzer {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The analyzer name
|
||||||
|
*/
|
||||||
|
private static final String ANALYZER_NAME = "Assembly Analyzer";
|
||||||
|
/**
|
||||||
|
* The analysis phase
|
||||||
|
*/
|
||||||
|
private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION;
|
||||||
|
/**
|
||||||
|
* The list of supported extensions
|
||||||
|
*/
|
||||||
|
private static final String[] SUPPORTED_EXTENSIONS = {"dll", "exe"};
|
||||||
|
/**
|
||||||
|
* The temp value for GrokAssembly.exe
|
||||||
|
*/
|
||||||
|
private File grokAssemblyExe = null;
|
||||||
|
/**
|
||||||
|
* Logger
|
||||||
|
*/
|
||||||
|
private static final Logger LOGGER = LoggerFactory.getLogger(AssemblyAnalyzer.class);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Builds the beginnings of a List for ProcessBuilder
|
||||||
|
*
|
||||||
|
* @return the list of arguments to begin populating the ProcessBuilder
|
||||||
|
*/
|
||||||
|
protected List<String> buildArgumentList() {
|
||||||
|
// Use file.separator as a wild guess as to whether this is Windows
|
||||||
|
final List<String> args = new ArrayList<>();
|
||||||
|
if (!SystemUtils.IS_OS_WINDOWS) {
|
||||||
|
if (Settings.getString(Settings.KEYS.ANALYZER_ASSEMBLY_MONO_PATH) != null) {
|
||||||
|
args.add(Settings.getString(Settings.KEYS.ANALYZER_ASSEMBLY_MONO_PATH));
|
||||||
|
} else if (isInPath("mono")) {
|
||||||
|
args.add("mono");
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
args.add(grokAssemblyExe.getPath());
|
||||||
|
return args;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Performs the analysis on a single Dependency.
|
||||||
|
*
|
||||||
|
* @param dependency the dependency to analyze
|
||||||
|
* @param engine the engine to perform the analysis under
|
||||||
|
* @throws AnalysisException if anything goes sideways
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void analyzeDependency(Dependency dependency, Engine engine)
|
||||||
|
throws AnalysisException {
|
||||||
|
if (grokAssemblyExe == null) {
|
||||||
|
LOGGER.warn("GrokAssembly didn't get deployed");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final List<String> args = buildArgumentList();
|
||||||
|
if (args == null) {
|
||||||
|
LOGGER.warn("Assembly Analyzer was unable to execute");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
args.add(dependency.getActualFilePath());
|
||||||
|
final ProcessBuilder pb = new ProcessBuilder(args);
|
||||||
|
Document doc = null;
|
||||||
|
try {
|
||||||
|
final Process proc = pb.start();
|
||||||
|
final DocumentBuilder builder = XmlUtils.buildSecureDocumentBuilder();
|
||||||
|
|
||||||
|
doc = builder.parse(proc.getInputStream());
|
||||||
|
|
||||||
|
// Try evacuating the error stream
|
||||||
|
final String errorStream = IOUtils.toString(proc.getErrorStream(), "UTF-8");
|
||||||
|
if (null != errorStream && !errorStream.isEmpty()) {
|
||||||
|
LOGGER.warn("Error from GrokAssembly: {}", errorStream);
|
||||||
|
}
|
||||||
|
|
||||||
|
int rc = 0;
|
||||||
|
try {
|
||||||
|
rc = proc.waitFor();
|
||||||
|
} catch (InterruptedException ie) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (rc == 3) {
|
||||||
|
LOGGER.debug("{} is not a .NET assembly or executable and as such cannot be analyzed by dependency-check",
|
||||||
|
dependency.getActualFilePath());
|
||||||
|
return;
|
||||||
|
} else if (rc != 0) {
|
||||||
|
LOGGER.debug("Return code {} from GrokAssembly; dependency-check is unable to analyze the library: {}",
|
||||||
|
rc, dependency.getActualFilePath());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final XPath xpath = XPathFactory.newInstance().newXPath();
|
||||||
|
|
||||||
|
// First, see if there was an error
|
||||||
|
final String error = xpath.evaluate("/assembly/error", doc);
|
||||||
|
if (error != null && !error.isEmpty()) {
|
||||||
|
throw new AnalysisException(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
final String version = xpath.evaluate("/assembly/version", doc);
|
||||||
|
if (version != null) {
|
||||||
|
dependency.getVersionEvidence().addEvidence(new Evidence("grokassembly", "version",
|
||||||
|
version, Confidence.HIGHEST));
|
||||||
|
}
|
||||||
|
|
||||||
|
final String vendor = xpath.evaluate("/assembly/company", doc);
|
||||||
|
if (vendor != null) {
|
||||||
|
dependency.getVendorEvidence().addEvidence(new Evidence("grokassembly", "vendor",
|
||||||
|
vendor, Confidence.HIGH));
|
||||||
|
}
|
||||||
|
|
||||||
|
final String product = xpath.evaluate("/assembly/product", doc);
|
||||||
|
if (product != null) {
|
||||||
|
dependency.getProductEvidence().addEvidence(new Evidence("grokassembly", "product",
|
||||||
|
product, Confidence.HIGH));
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (ParserConfigurationException pce) {
|
||||||
|
throw new AnalysisException("Error initializing the assembly analyzer", pce);
|
||||||
|
} catch (IOException | XPathExpressionException ioe) {
|
||||||
|
throw new AnalysisException(ioe);
|
||||||
|
} catch (SAXException saxe) {
|
||||||
|
LOGGER.error("----------------------------------------------------");
|
||||||
|
LOGGER.error("Failed to read the Assembly Analyzer results. "
|
||||||
|
+ "On some systems mono-runtime and mono-devel need to be installed.");
|
||||||
|
LOGGER.error("----------------------------------------------------");
|
||||||
|
throw new AnalysisException("Couldn't parse Assembly Analyzer results (GrokAssembly)", saxe);
|
||||||
|
}
|
||||||
|
// This shouldn't happen
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize the analyzer. In this case, extract GrokAssembly.exe to a
|
||||||
|
* temporary location.
|
||||||
|
*
|
||||||
|
* @throws InitializationException thrown if anything goes wrong
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void initializeFileTypeAnalyzer() throws InitializationException {
|
||||||
|
final File tempFile;
|
||||||
|
final String cfg;
|
||||||
|
try {
|
||||||
|
tempFile = File.createTempFile("GKA", ".exe", Settings.getTempDirectory());
|
||||||
|
cfg = tempFile.getPath() + ".config";
|
||||||
|
} catch (IOException ex) {
|
||||||
|
setEnabled(false);
|
||||||
|
throw new InitializationException("Unable to create temporary file for the assembly analyzer", ex);
|
||||||
|
}
|
||||||
|
try (FileOutputStream fos = new FileOutputStream(tempFile);
|
||||||
|
InputStream is = AssemblyAnalyzer.class.getClassLoader().getResourceAsStream("GrokAssembly.exe");
|
||||||
|
FileOutputStream fosCfg = new FileOutputStream(cfg);
|
||||||
|
InputStream isCfg = AssemblyAnalyzer.class.getClassLoader().getResourceAsStream("GrokAssembly.exe.config")) {
|
||||||
|
IOUtils.copy(is, fos);
|
||||||
|
grokAssemblyExe = tempFile;
|
||||||
|
LOGGER.debug("Extracted GrokAssembly.exe to {}", grokAssemblyExe.getPath());
|
||||||
|
IOUtils.copy(isCfg, fosCfg);
|
||||||
|
LOGGER.debug("Extracted GrokAssembly.exe.config to {}", cfg);
|
||||||
|
} catch (IOException ioe) {
|
||||||
|
this.setEnabled(false);
|
||||||
|
LOGGER.warn("Could not extract GrokAssembly.exe: {}", ioe.getMessage());
|
||||||
|
throw new InitializationException("Could not extract GrokAssembly.exe", ioe);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now, need to see if GrokAssembly actually runs from this location.
|
||||||
|
final List<String> args = buildArgumentList();
|
||||||
|
//TODO this creates an "unreported" error - if someone doesn't look
|
||||||
|
// at the command output this could easily be missed (especially in an
|
||||||
|
// Ant or Maven build.
|
||||||
|
//
|
||||||
|
// We need to create a non-fatal warning error type that will
|
||||||
|
// get added to the report.
|
||||||
|
//TODO this idea needs to get replicated to the bundle audit analyzer.
|
||||||
|
if (args == null) {
|
||||||
|
setEnabled(false);
|
||||||
|
LOGGER.error("----------------------------------------------------");
|
||||||
|
LOGGER.error(".NET Assembly Analyzer could not be initialized and at least one "
|
||||||
|
+ "'exe' or 'dll' was scanned. The 'mono' executable could not be found on "
|
||||||
|
+ "the path; either disable the Assembly Analyzer or configure the path mono. "
|
||||||
|
+ "On some systems mono-runtime and mono-devel need to be installed.");
|
||||||
|
LOGGER.error("----------------------------------------------------");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
final ProcessBuilder pb = new ProcessBuilder(args);
|
||||||
|
final Process p = pb.start();
|
||||||
|
// Try evacuating the error stream
|
||||||
|
IOUtils.copy(p.getErrorStream(), NullOutputStream.NULL_OUTPUT_STREAM);
|
||||||
|
|
||||||
|
final DocumentBuilder builder = XmlUtils.buildSecureDocumentBuilder();
|
||||||
|
final Document doc = builder.parse(p.getInputStream());
|
||||||
|
final XPath xpath = XPathFactory.newInstance().newXPath();
|
||||||
|
final String error = xpath.evaluate("/assembly/error", doc);
|
||||||
|
if (p.waitFor() != 1 || error == null || error.isEmpty()) {
|
||||||
|
LOGGER.warn("An error occurred with the .NET AssemblyAnalyzer, please see the log for more details.");
|
||||||
|
LOGGER.debug("GrokAssembly.exe is not working properly");
|
||||||
|
grokAssemblyExe = null;
|
||||||
|
setEnabled(false);
|
||||||
|
throw new InitializationException("Could not execute .NET AssemblyAnalyzer");
|
||||||
|
}
|
||||||
|
} catch (InitializationException e) {
|
||||||
|
setEnabled(false);
|
||||||
|
throw e;
|
||||||
|
} catch (IOException | ParserConfigurationException | SAXException | XPathExpressionException | InterruptedException e) {
|
||||||
|
LOGGER.warn("An error occurred with the .NET AssemblyAnalyzer;\n"
|
||||||
|
+ "this can be ignored unless you are scanning .NET DLLs. Please see the log for more details.");
|
||||||
|
LOGGER.debug("Could not execute GrokAssembly {}", e.getMessage());
|
||||||
|
setEnabled(false);
|
||||||
|
throw new InitializationException("An error occurred with the .NET AssemblyAnalyzer", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes resources used from the local file system.
|
||||||
|
*
|
||||||
|
* @throws Exception thrown if there is a problem closing the analyzer
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void closeAnalyzer() throws Exception {
|
||||||
|
try {
|
||||||
|
if (grokAssemblyExe != null && !grokAssemblyExe.delete()) {
|
||||||
|
LOGGER.debug("Unable to delete temporary GrokAssembly.exe; attempting delete on exit");
|
||||||
|
grokAssemblyExe.deleteOnExit();
|
||||||
|
}
|
||||||
|
} catch (SecurityException se) {
|
||||||
|
LOGGER.debug("Can't delete temporary GrokAssembly.exe");
|
||||||
|
grokAssemblyExe.deleteOnExit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The File Filter used to filter supported extensions.
|
||||||
|
*/
|
||||||
|
private static final FileFilter FILTER = FileFilterBuilder.newInstance().addExtensions(
|
||||||
|
SUPPORTED_EXTENSIONS).build();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected FileFilter getFileFilter() {
|
||||||
|
return FILTER;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets this analyzer's name.
|
||||||
|
*
|
||||||
|
* @return the analyzer name
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return ANALYZER_NAME;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the phase this analyzer runs under.
|
||||||
|
*
|
||||||
|
* @return the phase this runs under
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public AnalysisPhase getAnalysisPhase() {
|
||||||
|
return ANALYSIS_PHASE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the key used in the properties file to reference the analyzer's
|
||||||
|
* enabled property.
|
||||||
|
*
|
||||||
|
* @return the analyzer's enabled property setting key
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected String getAnalyzerEnabledSettingKey() {
|
||||||
|
return Settings.KEYS.ANALYZER_ASSEMBLY_ENABLED;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests to see if a file is in the system path. <b>Note</b> - the current
|
||||||
|
* implementation only works on non-windows platforms. For purposes of the
|
||||||
|
* AssemblyAnalyzer this is okay as this is only needed on Mac/*nix.
|
||||||
|
*
|
||||||
|
* @param file the executable to look for
|
||||||
|
* @return <code>true</code> if the file exists; otherwise
|
||||||
|
* <code>false</code>
|
||||||
|
*/
|
||||||
|
private boolean isInPath(String file) {
|
||||||
|
final ProcessBuilder pb = new ProcessBuilder("which", file);
|
||||||
|
try {
|
||||||
|
final Process proc = pb.start();
|
||||||
|
final int retCode = proc.waitFor();
|
||||||
|
if (retCode == 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} catch (IOException | InterruptedException ex) {
|
||||||
|
LOGGER.debug("Path search failed for " + file, ex);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,278 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of dependency-check-core.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
* Copyright (c) 2015 Institute for Defense Analyses. All Rights Reserved.
|
||||||
|
*/
|
||||||
|
package org.owasp.dependencycheck.analyzer;
|
||||||
|
|
||||||
|
import org.apache.commons.io.FileUtils;
|
||||||
|
import org.owasp.dependencycheck.Engine;
|
||||||
|
import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
|
||||||
|
import org.owasp.dependencycheck.dependency.Confidence;
|
||||||
|
import org.owasp.dependencycheck.dependency.Dependency;
|
||||||
|
import org.owasp.dependencycheck.dependency.EvidenceCollection;
|
||||||
|
import org.owasp.dependencycheck.utils.FileFilterBuilder;
|
||||||
|
import org.owasp.dependencycheck.utils.Settings;
|
||||||
|
import org.owasp.dependencycheck.utils.UrlStringUtils;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileFilter;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.charset.Charset;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
import org.owasp.dependencycheck.exception.InitializationException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used to analyze Autoconf input files named configure.ac or configure.in.
|
||||||
|
* Files simply named "configure" are also analyzed, assuming they are generated
|
||||||
|
* by Autoconf, and contain certain special package descriptor variables.
|
||||||
|
*
|
||||||
|
* @author Dale Visser
|
||||||
|
* @see <a href="https://www.gnu.org/software/autoconf/">Autoconf - GNU Project
|
||||||
|
* - Free Software Foundation (FSF)</a>
|
||||||
|
*/
|
||||||
|
@Experimental
|
||||||
|
public class AutoconfAnalyzer extends AbstractFileTypeAnalyzer {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Autoconf output filename.
|
||||||
|
*/
|
||||||
|
private static final String CONFIGURE = "configure";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Autoconf input filename.
|
||||||
|
*/
|
||||||
|
private static final String CONFIGURE_IN = "configure.in";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Autoconf input filename.
|
||||||
|
*/
|
||||||
|
private static final String CONFIGURE_AC = "configure.ac";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The name of the analyzer.
|
||||||
|
*/
|
||||||
|
private static final String ANALYZER_NAME = "Autoconf Analyzer";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The phase that this analyzer is intended to run in.
|
||||||
|
*/
|
||||||
|
private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The set of file extensions supported by this analyzer.
|
||||||
|
*/
|
||||||
|
private static final String[] EXTENSIONS = {"ac", "in"};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Matches AC_INIT variables in the output configure script.
|
||||||
|
*/
|
||||||
|
private static final Pattern PACKAGE_VAR = Pattern.compile(
|
||||||
|
"PACKAGE_(.+?)='(.*?)'", Pattern.DOTALL | Pattern.CASE_INSENSITIVE);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Matches AC_INIT statement in configure.ac file.
|
||||||
|
*/
|
||||||
|
private static final Pattern AC_INIT_PATTERN;
|
||||||
|
|
||||||
|
static {
|
||||||
|
// each instance of param or sep_param has a capture group
|
||||||
|
final String param = "\\[{0,2}(.+?)\\]{0,2}";
|
||||||
|
final String sepParam = "\\s*,\\s*" + param;
|
||||||
|
// Group 1: Package
|
||||||
|
// Group 2: Version
|
||||||
|
// Group 3: optional
|
||||||
|
// Group 4: Bug report address (if it exists)
|
||||||
|
// Group 5: optional
|
||||||
|
// Group 6: Tarname (if it exists)
|
||||||
|
// Group 7: optional
|
||||||
|
// Group 8: URL (if it exists)
|
||||||
|
AC_INIT_PATTERN = Pattern.compile(String.format(
|
||||||
|
"AC_INIT\\(%s%s(%s)?(%s)?(%s)?\\s*\\)", param, sepParam,
|
||||||
|
sepParam, sepParam, sepParam), Pattern.DOTALL
|
||||||
|
| Pattern.CASE_INSENSITIVE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The file filter used to determine which files this analyzer supports.
|
||||||
|
*/
|
||||||
|
private static final FileFilter FILTER = FileFilterBuilder.newInstance().addFilenames(CONFIGURE).addExtensions(
|
||||||
|
EXTENSIONS).build();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the FileFilter
|
||||||
|
*
|
||||||
|
* @return the FileFilter
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected FileFilter getFileFilter() {
|
||||||
|
return FILTER;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the name of the analyzer.
|
||||||
|
*
|
||||||
|
* @return the name of the analyzer.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return ANALYZER_NAME;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the phase that the analyzer is intended to run in.
|
||||||
|
*
|
||||||
|
* @return the phase that the analyzer is intended to run in.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public AnalysisPhase getAnalysisPhase() {
|
||||||
|
return ANALYSIS_PHASE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the key used in the properties file to reference the analyzer's
|
||||||
|
* enabled property.
|
||||||
|
*
|
||||||
|
* @return the analyzer's enabled property setting key
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected String getAnalyzerEnabledSettingKey() {
|
||||||
|
return Settings.KEYS.ANALYZER_PYTHON_DISTRIBUTION_ENABLED;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void analyzeDependency(Dependency dependency, Engine engine)
|
||||||
|
throws AnalysisException {
|
||||||
|
final File actualFile = dependency.getActualFile();
|
||||||
|
final String name = actualFile.getName();
|
||||||
|
if (name.startsWith(CONFIGURE)) {
|
||||||
|
final File parent = actualFile.getParentFile();
|
||||||
|
final String parentName = parent.getName();
|
||||||
|
dependency.setDisplayFileName(parentName + "/" + name);
|
||||||
|
final boolean isOutputScript = CONFIGURE.equals(name);
|
||||||
|
if (isOutputScript || CONFIGURE_AC.equals(name)
|
||||||
|
|| CONFIGURE_IN.equals(name)) {
|
||||||
|
final String contents = getFileContents(actualFile);
|
||||||
|
if (!contents.isEmpty()) {
|
||||||
|
if (isOutputScript) {
|
||||||
|
extractConfigureScriptEvidence(dependency, name,
|
||||||
|
contents);
|
||||||
|
} else {
|
||||||
|
gatherEvidence(dependency, name, contents);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
engine.getDependencies().remove(dependency);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extracts evidence from the configuration.
|
||||||
|
*
|
||||||
|
* @param dependency the dependency being analyzed
|
||||||
|
* @param name the name of the source of evidence
|
||||||
|
* @param contents the contents to analyze for evidence
|
||||||
|
*/
|
||||||
|
private void extractConfigureScriptEvidence(Dependency dependency,
|
||||||
|
final String name, final String contents) {
|
||||||
|
final Matcher matcher = PACKAGE_VAR.matcher(contents);
|
||||||
|
while (matcher.find()) {
|
||||||
|
final String variable = matcher.group(1);
|
||||||
|
final String value = matcher.group(2);
|
||||||
|
if (!value.isEmpty()) {
|
||||||
|
if (variable.endsWith("NAME")) {
|
||||||
|
dependency.getProductEvidence().addEvidence(name, variable,
|
||||||
|
value, Confidence.HIGHEST);
|
||||||
|
} else if ("VERSION".equals(variable)) {
|
||||||
|
dependency.getVersionEvidence().addEvidence(name, variable,
|
||||||
|
value, Confidence.HIGHEST);
|
||||||
|
} else if ("BUGREPORT".equals(variable)) {
|
||||||
|
dependency.getVendorEvidence().addEvidence(name, variable,
|
||||||
|
value, Confidence.HIGH);
|
||||||
|
} else if ("URL".equals(variable)) {
|
||||||
|
dependency.getVendorEvidence().addEvidence(name, variable,
|
||||||
|
value, Confidence.HIGH);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the contents of a given file.
|
||||||
|
*
|
||||||
|
* @param actualFile the file to read
|
||||||
|
* @return the contents of the file
|
||||||
|
* @throws AnalysisException thrown if there is an IO Exception
|
||||||
|
*/
|
||||||
|
private String getFileContents(final File actualFile)
|
||||||
|
throws AnalysisException {
|
||||||
|
try {
|
||||||
|
return FileUtils.readFileToString(actualFile, Charset.defaultCharset()).trim();
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new AnalysisException(
|
||||||
|
"Problem occurred while reading dependency file.", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gathers evidence from a given file
|
||||||
|
*
|
||||||
|
* @param dependency the dependency to add evidence to
|
||||||
|
* @param name the source of the evidence
|
||||||
|
* @param contents the evidence to analyze
|
||||||
|
*/
|
||||||
|
private void gatherEvidence(Dependency dependency, final String name,
|
||||||
|
String contents) {
|
||||||
|
final Matcher matcher = AC_INIT_PATTERN.matcher(contents);
|
||||||
|
if (matcher.find()) {
|
||||||
|
final EvidenceCollection productEvidence = dependency
|
||||||
|
.getProductEvidence();
|
||||||
|
productEvidence.addEvidence(name, "Package", matcher.group(1),
|
||||||
|
Confidence.HIGHEST);
|
||||||
|
dependency.getVersionEvidence().addEvidence(name,
|
||||||
|
"Package Version", matcher.group(2), Confidence.HIGHEST);
|
||||||
|
final EvidenceCollection vendorEvidence = dependency
|
||||||
|
.getVendorEvidence();
|
||||||
|
if (null != matcher.group(3)) {
|
||||||
|
vendorEvidence.addEvidence(name, "Bug report address",
|
||||||
|
matcher.group(4), Confidence.HIGH);
|
||||||
|
}
|
||||||
|
if (null != matcher.group(5)) {
|
||||||
|
productEvidence.addEvidence(name, "Tarname", matcher.group(6),
|
||||||
|
Confidence.HIGH);
|
||||||
|
}
|
||||||
|
if (null != matcher.group(7)) {
|
||||||
|
final String url = matcher.group(8);
|
||||||
|
if (UrlStringUtils.isUrl(url)) {
|
||||||
|
vendorEvidence.addEvidence(name, "URL", url,
|
||||||
|
Confidence.HIGH);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes the file type analyzer.
|
||||||
|
*
|
||||||
|
* @throws InitializationException thrown if there is an exception during
|
||||||
|
* initialization
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected void initializeFileTypeAnalyzer() throws InitializationException {
|
||||||
|
// No initialization needed.
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,255 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of dependency-check-core.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
* Copyright (c) 2015 Institute for Defense Analyses. All Rights Reserved.
|
||||||
|
*/
|
||||||
|
package org.owasp.dependencycheck.analyzer;
|
||||||
|
|
||||||
|
import org.apache.commons.io.FileUtils;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.owasp.dependencycheck.Engine;
|
||||||
|
import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
|
||||||
|
import org.owasp.dependencycheck.dependency.Confidence;
|
||||||
|
import org.owasp.dependencycheck.dependency.Dependency;
|
||||||
|
import org.owasp.dependencycheck.utils.Checksum;
|
||||||
|
import org.owasp.dependencycheck.utils.FileFilterBuilder;
|
||||||
|
import org.owasp.dependencycheck.utils.Settings;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileFilter;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.nio.charset.Charset;
|
||||||
|
import java.security.MessageDigest;
|
||||||
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
import org.owasp.dependencycheck.exception.InitializationException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* Used to analyze CMake build files, and collect information that can be used
|
||||||
|
* to determine the associated CPE.</p>
|
||||||
|
* <p>
|
||||||
|
* Note: This analyzer catches straightforward invocations of the project
|
||||||
|
* command, plus some other observed patterns of version inclusion in real CMake
|
||||||
|
* projects. Many projects make use of older versions of CMake and/or use custom
|
||||||
|
* "homebrew" ways to insert version information. Hopefully as the newer CMake
|
||||||
|
* call pattern grows in usage, this analyzer allow more CPEs to be
|
||||||
|
* identified.</p>
|
||||||
|
*
|
||||||
|
* @author Dale Visser
|
||||||
|
*/
|
||||||
|
@Experimental
|
||||||
|
public class CMakeAnalyzer extends AbstractFileTypeAnalyzer {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The logger.
|
||||||
|
*/
|
||||||
|
private static final Logger LOGGER = LoggerFactory.getLogger(CMakeAnalyzer.class);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used when compiling file scanning regex patterns.
|
||||||
|
*/
|
||||||
|
private static final int REGEX_OPTIONS = Pattern.DOTALL
|
||||||
|
| Pattern.CASE_INSENSITIVE | Pattern.MULTILINE;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Regex to extract the product information.
|
||||||
|
*/
|
||||||
|
private static final Pattern PROJECT = Pattern.compile(
|
||||||
|
"^ *project *\\([ \\n]*(\\w+)[ \\n]*.*?\\)", REGEX_OPTIONS);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Regex to extract product and version information.
|
||||||
|
*
|
||||||
|
* Group 1: Product
|
||||||
|
*
|
||||||
|
* Group 2: Version
|
||||||
|
*/
|
||||||
|
private static final Pattern SET_VERSION = Pattern
|
||||||
|
.compile(
|
||||||
|
"^ *set\\s*\\(\\s*(\\w+)_version\\s+\"?(\\d+(?:\\.\\d+)+)[\\s\"]?\\)",
|
||||||
|
REGEX_OPTIONS);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Detects files that can be analyzed.
|
||||||
|
*/
|
||||||
|
private static final FileFilter FILTER = FileFilterBuilder.newInstance().addExtensions(".cmake")
|
||||||
|
.addFilenames("CMakeLists.txt").build();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the name of the CMake analyzer.
|
||||||
|
*
|
||||||
|
* @return the name of the analyzer
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "CMake Analyzer";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tell that we are used for information collection.
|
||||||
|
*
|
||||||
|
* @return INFORMATION_COLLECTION
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public AnalysisPhase getAnalysisPhase() {
|
||||||
|
return AnalysisPhase.INFORMATION_COLLECTION;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the set of supported file extensions.
|
||||||
|
*
|
||||||
|
* @return the set of supported file extensions
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected FileFilter getFileFilter() {
|
||||||
|
return FILTER;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes the analyzer.
|
||||||
|
*
|
||||||
|
* @throws InitializationException thrown if an exception occurs getting an
|
||||||
|
* instance of SHA1
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected void initializeFileTypeAnalyzer() throws InitializationException {
|
||||||
|
try {
|
||||||
|
getSha1MessageDigest();
|
||||||
|
} catch (IllegalStateException ex) {
|
||||||
|
setEnabled(false);
|
||||||
|
throw new InitializationException("Unable to create SHA1 MessageDigest", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Analyzes python packages and adds evidence to the dependency.
|
||||||
|
*
|
||||||
|
* @param dependency the dependency being analyzed
|
||||||
|
* @param engine the engine being used to perform the scan
|
||||||
|
* @throws AnalysisException thrown if there is an unrecoverable error
|
||||||
|
* analyzing the dependency
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected void analyzeDependency(Dependency dependency, Engine engine)
|
||||||
|
throws AnalysisException {
|
||||||
|
final File file = dependency.getActualFile();
|
||||||
|
final String parentName = file.getParentFile().getName();
|
||||||
|
final String name = file.getName();
|
||||||
|
dependency.setDisplayFileName(String.format("%s%c%s", parentName, File.separatorChar, name));
|
||||||
|
String contents;
|
||||||
|
try {
|
||||||
|
contents = FileUtils.readFileToString(file, Charset.defaultCharset()).trim();
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new AnalysisException(
|
||||||
|
"Problem occurred while reading dependency file.", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (StringUtils.isNotBlank(contents)) {
|
||||||
|
final Matcher m = PROJECT.matcher(contents);
|
||||||
|
int count = 0;
|
||||||
|
while (m.find()) {
|
||||||
|
count++;
|
||||||
|
LOGGER.debug(String.format(
|
||||||
|
"Found project command match with %d groups: %s",
|
||||||
|
m.groupCount(), m.group(0)));
|
||||||
|
final String group = m.group(1);
|
||||||
|
LOGGER.debug("Group 1: " + group);
|
||||||
|
dependency.getProductEvidence().addEvidence(name, "Project",
|
||||||
|
group, Confidence.HIGH);
|
||||||
|
}
|
||||||
|
LOGGER.debug("Found {} matches.", count);
|
||||||
|
analyzeSetVersionCommand(dependency, engine, contents);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extracts the version information from the contents. If more then one
|
||||||
|
* version is found additional dependencies are added to the dependency
|
||||||
|
* list.
|
||||||
|
*
|
||||||
|
* @param dependency the dependency being analyzed
|
||||||
|
* @param engine the dependency-check engine
|
||||||
|
* @param contents the version information
|
||||||
|
*/
|
||||||
|
@edu.umd.cs.findbugs.annotations.SuppressFBWarnings(
|
||||||
|
value = "DM_DEFAULT_ENCODING",
|
||||||
|
justification = "Default encoding is only used if UTF-8 is not available")
|
||||||
|
private void analyzeSetVersionCommand(Dependency dependency, Engine engine, String contents) {
|
||||||
|
Dependency currentDep = dependency;
|
||||||
|
|
||||||
|
final Matcher m = SET_VERSION.matcher(contents);
|
||||||
|
int count = 0;
|
||||||
|
while (m.find()) {
|
||||||
|
count++;
|
||||||
|
LOGGER.debug("Found project command match with {} groups: {}",
|
||||||
|
m.groupCount(), m.group(0));
|
||||||
|
String product = m.group(1);
|
||||||
|
final String version = m.group(2);
|
||||||
|
LOGGER.debug("Group 1: " + product);
|
||||||
|
LOGGER.debug("Group 2: " + version);
|
||||||
|
final String aliasPrefix = "ALIASOF_";
|
||||||
|
if (product.startsWith(aliasPrefix)) {
|
||||||
|
product = product.replaceFirst(aliasPrefix, "");
|
||||||
|
}
|
||||||
|
if (count > 1) {
|
||||||
|
//TODO - refactor so we do not assign to the parameter (checkstyle)
|
||||||
|
currentDep = new Dependency(dependency.getActualFile());
|
||||||
|
currentDep.setDisplayFileName(String.format("%s:%s", dependency.getDisplayFileName(), product));
|
||||||
|
final String filePath = String.format("%s:%s", dependency.getFilePath(), product);
|
||||||
|
currentDep.setFilePath(filePath);
|
||||||
|
|
||||||
|
byte[] path;
|
||||||
|
try {
|
||||||
|
path = filePath.getBytes("UTF-8");
|
||||||
|
} catch (UnsupportedEncodingException ex) {
|
||||||
|
path = filePath.getBytes();
|
||||||
|
}
|
||||||
|
final MessageDigest sha1 = getSha1MessageDigest();
|
||||||
|
currentDep.setSha1sum(Checksum.getHex(sha1.digest(path)));
|
||||||
|
engine.getDependencies().add(currentDep);
|
||||||
|
}
|
||||||
|
final String source = currentDep.getDisplayFileName();
|
||||||
|
currentDep.getProductEvidence().addEvidence(source, "Product",
|
||||||
|
product, Confidence.MEDIUM);
|
||||||
|
currentDep.getVersionEvidence().addEvidence(source, "Version",
|
||||||
|
version, Confidence.MEDIUM);
|
||||||
|
}
|
||||||
|
LOGGER.debug(String.format("Found %d matches.", count));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getAnalyzerEnabledSettingKey() {
|
||||||
|
return Settings.KEYS.ANALYZER_CMAKE_ENABLED;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the sha1 message digest.
|
||||||
|
*
|
||||||
|
* @return the sha1 message digest
|
||||||
|
*/
|
||||||
|
private MessageDigest getSha1MessageDigest() {
|
||||||
|
try {
|
||||||
|
return MessageDigest.getInstance("SHA1");
|
||||||
|
} catch (NoSuchAlgorithmException e) {
|
||||||
|
LOGGER.error(e.getMessage());
|
||||||
|
throw new IllegalStateException("Failed to obtain the SHA1 message digest.", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,18 +1,17 @@
|
|||||||
/*
|
/*
|
||||||
* This file is part of dependency-check-core.
|
* This file is part of dependency-check-core.
|
||||||
*
|
*
|
||||||
* Dependency-check-core is free software: you can redistribute it and/or modify it
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* under the terms of the GNU General Public License as published by the Free
|
* you may not use this file except in compliance with the License.
|
||||||
* Software Foundation, either version 3 of the License, or (at your option) any
|
* You may obtain a copy of the License at
|
||||||
* later version.
|
|
||||||
*
|
*
|
||||||
* Dependency-check-core is distributed in the hope that it will be useful, but
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
|
||||||
* details.
|
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License along with
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* dependency-check-core. If not, see http://www.gnu.org/licenses/.
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
*
|
*
|
||||||
* Copyright (c) 2012 Jeremy Long. All Rights Reserved.
|
* Copyright (c) 2012 Jeremy Long. All Rights Reserved.
|
||||||
*/
|
*/
|
||||||
@@ -21,76 +20,139 @@ package org.owasp.dependencycheck.analyzer;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
import java.net.URLEncoder;
|
import java.net.URLEncoder;
|
||||||
import java.sql.SQLException;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.StringTokenizer;
|
import java.util.StringTokenizer;
|
||||||
import java.util.logging.Level;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.logging.Logger;
|
import org.apache.commons.lang3.builder.CompareToBuilder;
|
||||||
import org.apache.lucene.document.Document;
|
import org.apache.lucene.document.Document;
|
||||||
import org.apache.lucene.index.CorruptIndexException;
|
import org.apache.lucene.index.CorruptIndexException;
|
||||||
import org.apache.lucene.queryparser.classic.ParseException;
|
import org.apache.lucene.queryparser.classic.ParseException;
|
||||||
import org.apache.lucene.search.ScoreDoc;
|
import org.apache.lucene.search.ScoreDoc;
|
||||||
import org.apache.lucene.search.TopDocs;
|
import org.apache.lucene.search.TopDocs;
|
||||||
import org.owasp.dependencycheck.Engine;
|
import org.owasp.dependencycheck.Engine;
|
||||||
import org.owasp.dependencycheck.data.lucene.LuceneUtils;
|
import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
|
||||||
import org.owasp.dependencycheck.dependency.Dependency;
|
import org.owasp.dependencycheck.data.cpe.CpeMemoryIndex;
|
||||||
import org.owasp.dependencycheck.dependency.Evidence;
|
|
||||||
import org.owasp.dependencycheck.dependency.Evidence.Confidence;
|
|
||||||
import org.owasp.dependencycheck.dependency.EvidenceCollection;
|
|
||||||
import org.owasp.dependencycheck.data.cpe.CpeIndexReader;
|
|
||||||
import org.owasp.dependencycheck.data.cpe.Fields;
|
import org.owasp.dependencycheck.data.cpe.Fields;
|
||||||
import org.owasp.dependencycheck.data.cpe.IndexEntry;
|
import org.owasp.dependencycheck.data.cpe.IndexEntry;
|
||||||
|
import org.owasp.dependencycheck.data.cpe.IndexException;
|
||||||
|
import org.owasp.dependencycheck.data.lucene.LuceneUtils;
|
||||||
import org.owasp.dependencycheck.data.nvdcve.CveDB;
|
import org.owasp.dependencycheck.data.nvdcve.CveDB;
|
||||||
import org.owasp.dependencycheck.data.nvdcve.DatabaseException;
|
import org.owasp.dependencycheck.data.nvdcve.DatabaseException;
|
||||||
|
import org.owasp.dependencycheck.dependency.Confidence;
|
||||||
|
import org.owasp.dependencycheck.dependency.Dependency;
|
||||||
|
import org.owasp.dependencycheck.dependency.Evidence;
|
||||||
|
import org.owasp.dependencycheck.dependency.EvidenceCollection;
|
||||||
import org.owasp.dependencycheck.dependency.Identifier;
|
import org.owasp.dependencycheck.dependency.Identifier;
|
||||||
import org.owasp.dependencycheck.dependency.VulnerableSoftware;
|
import org.owasp.dependencycheck.dependency.VulnerableSoftware;
|
||||||
|
import org.owasp.dependencycheck.exception.InitializationException;
|
||||||
import org.owasp.dependencycheck.utils.DependencyVersion;
|
import org.owasp.dependencycheck.utils.DependencyVersion;
|
||||||
import org.owasp.dependencycheck.utils.DependencyVersionUtil;
|
import org.owasp.dependencycheck.utils.DependencyVersionUtil;
|
||||||
|
import org.owasp.dependencycheck.utils.Settings;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* CPEAnalyzer is a utility class that takes a project dependency and attempts
|
* CPEAnalyzer is a utility class that takes a project dependency and attempts
|
||||||
* to discern if there is an associated CPE. It uses the evidence contained
|
* to discern if there is an associated CPE. It uses the evidence contained
|
||||||
* within the dependency to search the Lucene index.
|
* within the dependency to search the Lucene index.
|
||||||
*
|
*
|
||||||
* @author Jeremy Long (jeremy.long@owasp.org)
|
* @author Jeremy Long
|
||||||
*/
|
*/
|
||||||
public class CPEAnalyzer implements Analyzer {
|
public class CPEAnalyzer extends AbstractAnalyzer {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Logger.
|
||||||
|
*/
|
||||||
|
private static final Logger LOGGER = LoggerFactory.getLogger(CPEAnalyzer.class);
|
||||||
/**
|
/**
|
||||||
* The maximum number of query results to return.
|
* The maximum number of query results to return.
|
||||||
*/
|
*/
|
||||||
static final int MAX_QUERY_RESULTS = 25;
|
private static final int MAX_QUERY_RESULTS = 25;
|
||||||
/**
|
/**
|
||||||
* The weighting boost to give terms when constructing the Lucene query.
|
* The weighting boost to give terms when constructing the Lucene query.
|
||||||
*/
|
*/
|
||||||
static final String WEIGHTING_BOOST = "^5";
|
private static final String WEIGHTING_BOOST = "^5";
|
||||||
/**
|
/**
|
||||||
* A string representation of a regular expression defining characters
|
* A string representation of a regular expression defining characters
|
||||||
* utilized within the CPE Names.
|
* utilized within the CPE Names.
|
||||||
*/
|
*/
|
||||||
static final String CLEANSE_CHARACTER_RX = "[^A-Za-z0-9 ._-]";
|
private static final String CLEANSE_CHARACTER_RX = "[^A-Za-z0-9 ._-]";
|
||||||
/**
|
/**
|
||||||
* A string representation of a regular expression used to remove all but
|
* A string representation of a regular expression used to remove all but
|
||||||
* alpha characters.
|
* alpha characters.
|
||||||
*/
|
*/
|
||||||
static final String CLEANSE_NONALPHA_RX = "[^A-Za-z]*";
|
private static final String CLEANSE_NONALPHA_RX = "[^A-Za-z]*";
|
||||||
/**
|
/**
|
||||||
* The additional size to add to a new StringBuilder to account for extra
|
* The additional size to add to a new StringBuilder to account for extra
|
||||||
* data that will be written into the string.
|
* data that will be written into the string.
|
||||||
*/
|
*/
|
||||||
static final int STRING_BUILDER_BUFFER = 20;
|
private static final int STRING_BUILDER_BUFFER = 20;
|
||||||
/**
|
/**
|
||||||
* The CPE Index Reader.
|
* The CPE in memory index.
|
||||||
*/
|
*/
|
||||||
private CpeIndexReader cpe;
|
private CpeMemoryIndex cpe;
|
||||||
/**
|
/**
|
||||||
* The CVE Database.
|
* The CVE Database.
|
||||||
*/
|
*/
|
||||||
private CveDB cve;
|
private CveDB cve;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The URL to perform a search of the NVD CVE data at NIST.
|
||||||
|
*/
|
||||||
|
public static final String NVD_SEARCH_URL = "https://web.nvd.nist.gov/view/vuln/search-results?adv_search=true&cves=on&cpe_version=%s";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the name of this analyzer.
|
||||||
|
*
|
||||||
|
* @return the name of this analyzer.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "CPE Analyzer";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the analysis phase that this analyzer should run in.
|
||||||
|
*
|
||||||
|
* @return the analysis phase that this analyzer should run in.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public AnalysisPhase getAnalysisPhase() {
|
||||||
|
return AnalysisPhase.IDENTIFIER_ANALYSIS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The default is to support parallel processing.
|
||||||
|
*
|
||||||
|
* @return false
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean supportsParallelProcessing() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates the CPE Lucene Index.
|
||||||
|
*
|
||||||
|
* @throws InitializationException is thrown if there is an issue opening
|
||||||
|
* the index.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void initializeAnalyzer() throws InitializationException {
|
||||||
|
try {
|
||||||
|
this.open();
|
||||||
|
} catch (IOException ex) {
|
||||||
|
LOGGER.debug("Exception initializing the Lucene Index", ex);
|
||||||
|
throw new InitializationException("An exception occurred initializing the Lucene Index", ex);
|
||||||
|
} catch (DatabaseException ex) {
|
||||||
|
LOGGER.debug("Exception accessing the database", ex);
|
||||||
|
throw new InitializationException("An exception occurred accessing the database", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Opens the data source.
|
* Opens the data source.
|
||||||
*
|
*
|
||||||
@@ -100,53 +162,43 @@ public class CPEAnalyzer implements Analyzer {
|
|||||||
* usually occurs when the database is in use by another process.
|
* usually occurs when the database is in use by another process.
|
||||||
*/
|
*/
|
||||||
public void open() throws IOException, DatabaseException {
|
public void open() throws IOException, DatabaseException {
|
||||||
cpe = new CpeIndexReader();
|
if (!isOpen()) {
|
||||||
cpe.open();
|
cve = CveDB.getInstance();
|
||||||
cve = new CveDB();
|
cpe = CpeMemoryIndex.getInstance();
|
||||||
try {
|
try {
|
||||||
cve.open();
|
final long creationStart = System.currentTimeMillis();
|
||||||
} catch (SQLException ex) {
|
cpe.open(cve);
|
||||||
Logger.getLogger(CPEAnalyzer.class.getName()).log(Level.FINE, null, ex);
|
final long creationSeconds = TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis() - creationStart);
|
||||||
throw new DatabaseException("Unable to open the cve db", ex);
|
LOGGER.info("Created CPE Index ({} seconds)", creationSeconds);
|
||||||
} catch (ClassNotFoundException ex) {
|
} catch (IndexException ex) {
|
||||||
Logger.getLogger(CPEAnalyzer.class.getName()).log(Level.FINE, null, ex);
|
LOGGER.debug("IndexException", ex);
|
||||||
throw new DatabaseException("Unable to open the cve db", ex);
|
throw new DatabaseException(ex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Closes the data source.
|
* Closes the data sources.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void close() {
|
public void closeAnalyzer() {
|
||||||
if (cpe != null) {
|
|
||||||
cpe.close();
|
|
||||||
}
|
|
||||||
if (cve != null) {
|
if (cve != null) {
|
||||||
cve.close();
|
cve.close();
|
||||||
|
cve = null;
|
||||||
|
}
|
||||||
|
if (cpe != null) {
|
||||||
|
cpe.close();
|
||||||
|
cpe = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the status of the data source - is the index open.
|
* Returns whether or not the analyzer is open.
|
||||||
*
|
*
|
||||||
* @return true or false.
|
* @return <code>true</code> if the analyzer is open
|
||||||
*/
|
*/
|
||||||
public boolean isOpen() {
|
public boolean isOpen() {
|
||||||
return (cpe != null) && cpe.isOpen();
|
return cpe != null && cpe.isOpen();
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Ensures that the Lucene index is closed.
|
|
||||||
*
|
|
||||||
* @throws Throwable when a throwable is thrown.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
protected void finalize() throws Throwable {
|
|
||||||
super.finalize();
|
|
||||||
if (isOpen()) {
|
|
||||||
close();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -160,35 +212,39 @@ public class CPEAnalyzer implements Analyzer {
|
|||||||
* @throws ParseException is thrown when the Lucene query cannot be parsed.
|
* @throws ParseException is thrown when the Lucene query cannot be parsed.
|
||||||
*/
|
*/
|
||||||
protected void determineCPE(Dependency dependency) throws CorruptIndexException, IOException, ParseException {
|
protected void determineCPE(Dependency dependency) throws CorruptIndexException, IOException, ParseException {
|
||||||
Confidence vendorConf = Confidence.HIGHEST;
|
//TODO test dojo-war against this. we should get dojo-toolkit:dojo-toolkit AND dojo-toolkit:toolkit
|
||||||
Confidence productConf = Confidence.HIGHEST;
|
String vendors = "";
|
||||||
|
String products = "";
|
||||||
String vendors = addEvidenceWithoutDuplicateTerms("", dependency.getVendorEvidence(), vendorConf);
|
for (Confidence confidence : Confidence.values()) {
|
||||||
String products = addEvidenceWithoutDuplicateTerms("", dependency.getProductEvidence(), productConf);
|
if (dependency.getVendorEvidence().contains(confidence)) {
|
||||||
|
vendors = addEvidenceWithoutDuplicateTerms(vendors, dependency.getVendorEvidence(), confidence);
|
||||||
int ctr = 0;
|
LOGGER.debug("vendor search: {}", vendors);
|
||||||
do {
|
}
|
||||||
|
if (dependency.getProductEvidence().contains(confidence)) {
|
||||||
|
products = addEvidenceWithoutDuplicateTerms(products, dependency.getProductEvidence(), confidence);
|
||||||
|
LOGGER.debug("product search: {}", products);
|
||||||
|
}
|
||||||
if (!vendors.isEmpty() && !products.isEmpty()) {
|
if (!vendors.isEmpty() && !products.isEmpty()) {
|
||||||
final List<IndexEntry> entries = searchCPE(vendors, products, dependency.getProductEvidence().getWeighting(),
|
final List<IndexEntry> entries = searchCPE(vendors, products, dependency.getVendorEvidence().getWeighting(),
|
||||||
dependency.getVendorEvidence().getWeighting());
|
dependency.getProductEvidence().getWeighting());
|
||||||
|
if (entries == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
boolean identifierAdded = false;
|
||||||
for (IndexEntry e : entries) {
|
for (IndexEntry e : entries) {
|
||||||
|
LOGGER.debug("Verifying entry: {}", e);
|
||||||
if (verifyEntry(e, dependency)) {
|
if (verifyEntry(e, dependency)) {
|
||||||
final String vendor = e.getVendor();
|
final String vendor = e.getVendor();
|
||||||
final String product = e.getProduct();
|
final String product = e.getProduct();
|
||||||
determineIdentifiers(dependency, vendor, product);
|
LOGGER.debug("identified vendor/product: {}/{}", vendor, product);
|
||||||
|
identifierAdded |= determineIdentifiers(dependency, vendor, product, confidence);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (identifierAdded) {
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
vendorConf = reduceConfidence(vendorConf);
|
|
||||||
if (dependency.getVendorEvidence().contains(vendorConf)) {
|
|
||||||
vendors = addEvidenceWithoutDuplicateTerms(vendors, dependency.getVendorEvidence(), vendorConf);
|
|
||||||
}
|
|
||||||
productConf = reduceConfidence(productConf);
|
|
||||||
if (dependency.getProductEvidence().contains(productConf)) {
|
|
||||||
products = addEvidenceWithoutDuplicateTerms(products, dependency.getProductEvidence(), productConf);
|
|
||||||
}
|
|
||||||
} while ((++ctr) < 4);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -225,27 +281,12 @@ public class CPEAnalyzer implements Analyzer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reduces the given confidence by one level. This returns LOW if the
|
* <p>
|
||||||
* confidence passed in is not HIGH.
|
* Searches the Lucene CPE index to identify possible CPE entries associated
|
||||||
|
* with the supplied vendor, product, and version.</p>
|
||||||
*
|
*
|
||||||
* @param c the confidence to reduce.
|
* <p>
|
||||||
* @return One less then the confidence passed in.
|
* If either the vendorWeightings or productWeightings lists have been
|
||||||
*/
|
|
||||||
private Confidence reduceConfidence(final Confidence c) {
|
|
||||||
if (c == Confidence.HIGHEST) {
|
|
||||||
return Confidence.HIGH;
|
|
||||||
} else if (c == Confidence.HIGH) {
|
|
||||||
return Confidence.MEDIUM;
|
|
||||||
} else {
|
|
||||||
return Confidence.LOW;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>Searches the Lucene CPE index to identify possible CPE entries
|
|
||||||
* associated with the supplied vendor, product, and version.</p>
|
|
||||||
*
|
|
||||||
* <p>If either the vendorWeightings or productWeightings lists have been
|
|
||||||
* populated this data is used to add weighting factors to the search.</p>
|
* populated this data is used to add weighting factors to the search.</p>
|
||||||
*
|
*
|
||||||
* @param vendor the text used to search the vendor field
|
* @param vendor the text used to search the vendor field
|
||||||
@@ -255,20 +296,17 @@ public class CPEAnalyzer implements Analyzer {
|
|||||||
* @param productWeightings Adds a list of strings that will be used to add
|
* @param productWeightings Adds a list of strings that will be used to add
|
||||||
* weighting factors to the product search
|
* weighting factors to the product search
|
||||||
* @return a list of possible CPE values
|
* @return a list of possible CPE values
|
||||||
* @throws CorruptIndexException when the Lucene index is corrupt
|
|
||||||
* @throws IOException when the Lucene index is not found
|
|
||||||
* @throws ParseException when the generated query is not valid
|
|
||||||
*/
|
*/
|
||||||
protected List<IndexEntry> searchCPE(String vendor, String product,
|
protected List<IndexEntry> searchCPE(String vendor, String product,
|
||||||
Set<String> vendorWeightings, Set<String> productWeightings)
|
Set<String> vendorWeightings, Set<String> productWeightings) {
|
||||||
throws CorruptIndexException, IOException, ParseException {
|
|
||||||
final ArrayList<IndexEntry> ret = new ArrayList<IndexEntry>(MAX_QUERY_RESULTS);
|
final List<IndexEntry> ret = new ArrayList<>(MAX_QUERY_RESULTS);
|
||||||
|
|
||||||
final String searchString = buildSearch(vendor, product, vendorWeightings, productWeightings);
|
final String searchString = buildSearch(vendor, product, vendorWeightings, productWeightings);
|
||||||
if (searchString == null) {
|
if (searchString == null) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
try {
|
||||||
final TopDocs docs = cpe.search(searchString, MAX_QUERY_RESULTS);
|
final TopDocs docs = cpe.search(searchString, MAX_QUERY_RESULTS);
|
||||||
for (ScoreDoc d : docs.scoreDocs) {
|
for (ScoreDoc d : docs.scoreDocs) {
|
||||||
if (d.score >= 0.08) {
|
if (d.score >= 0.08) {
|
||||||
@@ -276,13 +314,6 @@ public class CPEAnalyzer implements Analyzer {
|
|||||||
final IndexEntry entry = new IndexEntry();
|
final IndexEntry entry = new IndexEntry();
|
||||||
entry.setVendor(doc.get(Fields.VENDOR));
|
entry.setVendor(doc.get(Fields.VENDOR));
|
||||||
entry.setProduct(doc.get(Fields.PRODUCT));
|
entry.setProduct(doc.get(Fields.PRODUCT));
|
||||||
// if (d.score < 0.08) {
|
|
||||||
// System.out.print(entry.getVendor());
|
|
||||||
// System.out.print(":");
|
|
||||||
// System.out.print(entry.getProduct());
|
|
||||||
// System.out.print(":");
|
|
||||||
// System.out.println(d.score);
|
|
||||||
// }
|
|
||||||
entry.setSearchScore(d.score);
|
entry.setSearchScore(d.score);
|
||||||
if (!ret.contains(entry)) {
|
if (!ret.contains(entry)) {
|
||||||
ret.add(entry);
|
ret.add(entry);
|
||||||
@@ -290,13 +321,23 @@ public class CPEAnalyzer implements Analyzer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
|
} catch (ParseException ex) {
|
||||||
|
LOGGER.warn("An error occurred querying the CPE data. See the log for more details.");
|
||||||
|
LOGGER.info("Unable to parse: {}", searchString, ex);
|
||||||
|
} catch (IOException ex) {
|
||||||
|
LOGGER.warn("An error occurred reading CPE data. See the log for more details.");
|
||||||
|
LOGGER.info("IO Error with search string: {}", searchString, ex);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>Builds a Lucene search string by properly escaping data and
|
* <p>
|
||||||
* constructing a valid search query.</p>
|
* Builds a Lucene search string by properly escaping data and constructing
|
||||||
|
* a valid search query.</p>
|
||||||
*
|
*
|
||||||
* <p>If either the possibleVendor or possibleProducts lists have been
|
* <p>
|
||||||
|
* If either the possibleVendor or possibleProducts lists have been
|
||||||
* populated this data is used to add weighting factors to the search string
|
* populated this data is used to add weighting factors to the search string
|
||||||
* generated.</p>
|
* generated.</p>
|
||||||
*
|
*
|
||||||
@@ -340,11 +381,11 @@ public class CPEAnalyzer implements Analyzer {
|
|||||||
* @return if the append was successful.
|
* @return if the append was successful.
|
||||||
*/
|
*/
|
||||||
private boolean appendWeightedSearch(StringBuilder sb, String field, String searchText, Set<String> weightedText) {
|
private boolean appendWeightedSearch(StringBuilder sb, String field, String searchText, Set<String> weightedText) {
|
||||||
sb.append(" ").append(field).append(":( ");
|
sb.append(' ').append(field).append(":( ");
|
||||||
|
|
||||||
final String cleanText = cleanseText(searchText);
|
final String cleanText = cleanseText(searchText);
|
||||||
|
|
||||||
if ("".equals(cleanText)) {
|
if (cleanText.isEmpty()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -354,20 +395,27 @@ public class CPEAnalyzer implements Analyzer {
|
|||||||
final StringTokenizer tokens = new StringTokenizer(cleanText);
|
final StringTokenizer tokens = new StringTokenizer(cleanText);
|
||||||
while (tokens.hasMoreElements()) {
|
while (tokens.hasMoreElements()) {
|
||||||
final String word = tokens.nextToken();
|
final String word = tokens.nextToken();
|
||||||
String temp = null;
|
StringBuilder temp = null;
|
||||||
for (String weighted : weightedText) {
|
for (String weighted : weightedText) {
|
||||||
final String weightedStr = cleanseText(weighted);
|
final String weightedStr = cleanseText(weighted);
|
||||||
if (equalsIgnoreCaseAndNonAlpha(word, weightedStr)) {
|
if (equalsIgnoreCaseAndNonAlpha(word, weightedStr)) {
|
||||||
temp = LuceneUtils.escapeLuceneQuery(word) + WEIGHTING_BOOST;
|
temp = new StringBuilder(word.length() + 2);
|
||||||
|
LuceneUtils.appendEscapedLuceneQuery(temp, word);
|
||||||
|
temp.append(WEIGHTING_BOOST);
|
||||||
if (!word.equalsIgnoreCase(weightedStr)) {
|
if (!word.equalsIgnoreCase(weightedStr)) {
|
||||||
temp += " " + LuceneUtils.escapeLuceneQuery(weightedStr) + WEIGHTING_BOOST;
|
temp.append(' ');
|
||||||
}
|
LuceneUtils.appendEscapedLuceneQuery(temp, weightedStr);
|
||||||
|
temp.append(WEIGHTING_BOOST);
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
sb.append(' ');
|
||||||
if (temp == null) {
|
if (temp == null) {
|
||||||
temp = LuceneUtils.escapeLuceneQuery(word);
|
LuceneUtils.appendEscapedLuceneQuery(sb, word);
|
||||||
|
} else {
|
||||||
|
sb.append(temp);
|
||||||
}
|
}
|
||||||
sb.append(" ").append(temp);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sb.append(" ) ");
|
sb.append(" ) ");
|
||||||
@@ -415,6 +463,8 @@ public class CPEAnalyzer implements Analyzer {
|
|||||||
private boolean verifyEntry(final IndexEntry entry, final Dependency dependency) {
|
private boolean verifyEntry(final IndexEntry entry, final Dependency dependency) {
|
||||||
boolean isValid = false;
|
boolean isValid = false;
|
||||||
|
|
||||||
|
//TODO - does this nullify some of the fuzzy matching that happens in the lucene search?
|
||||||
|
// for instance CPE some-component and in the evidence we have SomeComponent.
|
||||||
if (collectionContainsString(dependency.getProductEvidence(), entry.getProduct())
|
if (collectionContainsString(dependency.getProductEvidence(), entry.getProduct())
|
||||||
&& collectionContainsString(dependency.getVendorEvidence(), entry.getVendor())) {
|
&& collectionContainsString(dependency.getVendorEvidence(), entry.getVendor())) {
|
||||||
//&& collectionContainsVersion(dependency.getVersionEvidence(), entry.getVersion())
|
//&& collectionContainsVersion(dependency.getVersionEvidence(), entry.getVersion())
|
||||||
@@ -431,25 +481,18 @@ public class CPEAnalyzer implements Analyzer {
|
|||||||
* @return whether or not the EvidenceCollection contains the string
|
* @return whether or not the EvidenceCollection contains the string
|
||||||
*/
|
*/
|
||||||
private boolean collectionContainsString(EvidenceCollection ec, String text) {
|
private boolean collectionContainsString(EvidenceCollection ec, String text) {
|
||||||
|
|
||||||
//<editor-fold defaultstate="collapsed" desc="This code fold contains an old version of the code, delete once more testing is done">
|
|
||||||
// String[] splitText = text.split("[\\s_-]");
|
|
||||||
//
|
|
||||||
// for (String search : splitText) {
|
|
||||||
// //final String search = text.replaceAll("[\\s_-]", "").toLowerCase();
|
|
||||||
// if (ec.containsUsedString(search)) {
|
|
||||||
// return true;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//</editor-fold>
|
|
||||||
|
|
||||||
//TODO - likely need to change the split... not sure if this will work for CPE with special chars
|
//TODO - likely need to change the split... not sure if this will work for CPE with special chars
|
||||||
|
if (text == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
final String[] words = text.split("[\\s_-]");
|
final String[] words = text.split("[\\s_-]");
|
||||||
final List<String> list = new ArrayList<String>();
|
final List<String> list = new ArrayList<>();
|
||||||
String tempWord = null;
|
String tempWord = null;
|
||||||
for (String word : words) {
|
for (String word : words) {
|
||||||
//single letter words should be concatonated with the next word.
|
/*
|
||||||
// so { "m", "core", "sample" } -> { "mcore", "sample" }
|
single letter words should be concatenated with the next word.
|
||||||
|
so { "m", "core", "sample" } -> { "mcore", "sample" }
|
||||||
|
*/
|
||||||
if (tempWord != null) {
|
if (tempWord != null) {
|
||||||
list.add(tempWord + word);
|
list.add(tempWord + word);
|
||||||
tempWord = null;
|
tempWord = null;
|
||||||
@@ -459,9 +502,16 @@ public class CPEAnalyzer implements Analyzer {
|
|||||||
list.add(word);
|
list.add(word);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (tempWord != null && !list.isEmpty()) {
|
if (tempWord != null) {
|
||||||
|
if (!list.isEmpty()) {
|
||||||
final String tmp = list.get(list.size() - 1) + tempWord;
|
final String tmp = list.get(list.size() - 1) + tempWord;
|
||||||
list.add(tmp);
|
list.add(tmp);
|
||||||
|
} else {
|
||||||
|
list.add(tempWord);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (list.isEmpty()) {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
boolean contains = true;
|
boolean contains = true;
|
||||||
for (String word : list) {
|
for (String word : list) {
|
||||||
@@ -480,7 +530,7 @@ public class CPEAnalyzer implements Analyzer {
|
|||||||
* dependency.
|
* dependency.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void analyze(Dependency dependency, Engine engine) throws AnalysisException {
|
protected synchronized void analyzeDependency(Dependency dependency, Engine engine) throws AnalysisException {
|
||||||
try {
|
try {
|
||||||
determineCPE(dependency);
|
determineCPE(dependency);
|
||||||
} catch (CorruptIndexException ex) {
|
} catch (CorruptIndexException ex) {
|
||||||
@@ -492,57 +542,6 @@ public class CPEAnalyzer implements Analyzer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns true because this analyzer supports all dependency types.
|
|
||||||
*
|
|
||||||
* @return true.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public Set<String> getSupportedExtensions() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the name of this analyzer.
|
|
||||||
*
|
|
||||||
* @return the name of this analyzer.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public String getName() {
|
|
||||||
return "CPE Analyzer";
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns true because this analyzer supports all dependency types.
|
|
||||||
*
|
|
||||||
* @param extension the file extension of the dependency being analyzed.
|
|
||||||
* @return true.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public boolean supportsExtension(String extension) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the analysis phase that this analyzer should run in.
|
|
||||||
*
|
|
||||||
* @return the analysis phase that this analyzer should run in.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public AnalysisPhase getAnalysisPhase() {
|
|
||||||
return AnalysisPhase.IDENTIFIER_ANALYSIS;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Opens the CPE Lucene Index.
|
|
||||||
*
|
|
||||||
* @throws Exception is thrown if there is an issue opening the index.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void initialize() throws Exception {
|
|
||||||
this.open();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves a list of CPE values from the CveDB based on the vendor and
|
* Retrieves a list of CPE values from the CveDB based on the vendor and
|
||||||
* product passed in. The list is then validated to find only CPEs that are
|
* product passed in. The list is then validated to find only CPEs that are
|
||||||
@@ -553,13 +552,23 @@ public class CPEAnalyzer implements Analyzer {
|
|||||||
* @param dependency the Dependency being analyzed
|
* @param dependency the Dependency being analyzed
|
||||||
* @param vendor the vendor for the CPE being analyzed
|
* @param vendor the vendor for the CPE being analyzed
|
||||||
* @param product the product for the CPE being analyzed
|
* @param product the product for the CPE being analyzed
|
||||||
|
* @param currentConfidence the current confidence being used during
|
||||||
|
* analysis
|
||||||
|
* @return <code>true</code> if an identifier was added to the dependency;
|
||||||
|
* otherwise <code>false</code>
|
||||||
* @throws UnsupportedEncodingException is thrown if UTF-8 is not supported
|
* @throws UnsupportedEncodingException is thrown if UTF-8 is not supported
|
||||||
*/
|
*/
|
||||||
private void determineIdentifiers(Dependency dependency, String vendor, String product) throws UnsupportedEncodingException {
|
protected boolean determineIdentifiers(Dependency dependency, String vendor, String product,
|
||||||
|
Confidence currentConfidence) throws UnsupportedEncodingException {
|
||||||
final Set<VulnerableSoftware> cpes = cve.getCPEs(vendor, product);
|
final Set<VulnerableSoftware> cpes = cve.getCPEs(vendor, product);
|
||||||
DependencyVersion bestGuess = new DependencyVersion("-");
|
DependencyVersion bestGuess = new DependencyVersion("-");
|
||||||
Confidence bestGuessConf = null;
|
Confidence bestGuessConf = null;
|
||||||
final List<IdentifierMatch> collected = new ArrayList<IdentifierMatch>();
|
boolean hasBroadMatch = false;
|
||||||
|
final List<IdentifierMatch> collected = new ArrayList<>();
|
||||||
|
|
||||||
|
//TODO the following algorithm incorrectly identifies things as a lower version
|
||||||
|
// if there lower confidence evidence when the current (highest) version number
|
||||||
|
// is newer then anything in the NVD.
|
||||||
for (Confidence conf : Confidence.values()) {
|
for (Confidence conf : Confidence.values()) {
|
||||||
for (Evidence evidence : dependency.getVersionEvidence().iterator(conf)) {
|
for (Evidence evidence : dependency.getVersionEvidence().iterator(conf)) {
|
||||||
final DependencyVersion evVer = DependencyVersionUtil.parseVersion(evidence.getValue());
|
final DependencyVersion evVer = DependencyVersionUtil.parseVersion(evidence.getValue());
|
||||||
@@ -568,19 +577,23 @@ public class CPEAnalyzer implements Analyzer {
|
|||||||
}
|
}
|
||||||
for (VulnerableSoftware vs : cpes) {
|
for (VulnerableSoftware vs : cpes) {
|
||||||
DependencyVersion dbVer;
|
DependencyVersion dbVer;
|
||||||
if (vs.getRevision() != null && !vs.getRevision().isEmpty()) {
|
if (vs.getUpdate() != null && !vs.getUpdate().isEmpty()) {
|
||||||
dbVer = DependencyVersionUtil.parseVersion(vs.getVersion() + "." + vs.getRevision());
|
dbVer = DependencyVersionUtil.parseVersion(vs.getVersion() + '.' + vs.getUpdate());
|
||||||
} else {
|
} else {
|
||||||
dbVer = DependencyVersionUtil.parseVersion(vs.getVersion());
|
dbVer = DependencyVersionUtil.parseVersion(vs.getVersion());
|
||||||
}
|
}
|
||||||
if (dbVer == null //special case, no version specified - everything is vulnerable
|
if (dbVer == null) { //special case, no version specified - everything is vulnerable
|
||||||
|| evVer.equals(dbVer)) { //woot exect match
|
hasBroadMatch = true;
|
||||||
final String url = String.format("http://web.nvd.nist.gov/view/vuln/search?cpe=%s", URLEncoder.encode(vs.getName(), "UTF-8"));
|
final String url = String.format(NVD_SEARCH_URL, URLEncoder.encode(vs.getName(), "UTF-8"));
|
||||||
|
final IdentifierMatch match = new IdentifierMatch("cpe", vs.getName(), url, IdentifierConfidence.BROAD_MATCH, conf);
|
||||||
|
collected.add(match);
|
||||||
|
} else if (evVer.equals(dbVer)) { //yeah! exact match
|
||||||
|
final String url = String.format(NVD_SEARCH_URL, URLEncoder.encode(vs.getName(), "UTF-8"));
|
||||||
final IdentifierMatch match = new IdentifierMatch("cpe", vs.getName(), url, IdentifierConfidence.EXACT_MATCH, conf);
|
final IdentifierMatch match = new IdentifierMatch("cpe", vs.getName(), url, IdentifierConfidence.EXACT_MATCH, conf);
|
||||||
collected.add(match);
|
collected.add(match);
|
||||||
} else {
|
|
||||||
//TODO the following isn't quite right is it? need to think about this guessing game a bit more.
|
//TODO the following isn't quite right is it? need to think about this guessing game a bit more.
|
||||||
if (evVer.getVersionParts().size() <= dbVer.getVersionParts().size()
|
} else if (evVer.getVersionParts().size() <= dbVer.getVersionParts().size()
|
||||||
&& evVer.matchesAtLeastThreeLevels(dbVer)) {
|
&& evVer.matchesAtLeastThreeLevels(dbVer)) {
|
||||||
if (bestGuessConf == null || bestGuessConf.compareTo(conf) > 0) {
|
if (bestGuessConf == null || bestGuessConf.compareTo(conf) > 0) {
|
||||||
if (bestGuess.getVersionParts().size() < dbVer.getVersionParts().size()) {
|
if (bestGuess.getVersionParts().size() < dbVer.getVersionParts().size()) {
|
||||||
@@ -590,32 +603,57 @@ public class CPEAnalyzer implements Analyzer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
if ((bestGuessConf == null || bestGuessConf.compareTo(conf) > 0)
|
||||||
if (bestGuessConf == null || bestGuessConf.compareTo(conf) > 0) {
|
&& bestGuess.getVersionParts().size() < evVer.getVersionParts().size()) {
|
||||||
if (bestGuess.getVersionParts().size() < evVer.getVersionParts().size()) {
|
|
||||||
bestGuess = evVer;
|
bestGuess = evVer;
|
||||||
bestGuessConf = conf;
|
bestGuessConf = conf;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
final String cpeName = String.format("cpe:/a:%s:%s:%s", vendor, product, bestGuess.toString());
|
final String cpeName = String.format("cpe:/a:%s:%s:%s", vendor, product, bestGuess.toString());
|
||||||
final String url = null; //String.format("http://web.nvd.nist.gov/view/vuln/search?cpe=%s", URLEncoder.encode(cpeName, "UTF-8"));
|
String url = null;
|
||||||
if (bestGuessConf == null) {
|
if (hasBroadMatch) { //if we have a broad match we can add the URL to the best guess.
|
||||||
|
final String cpeUrlName = String.format("cpe:/a:%s:%s", vendor, product);
|
||||||
|
url = String.format(NVD_SEARCH_URL, URLEncoder.encode(cpeUrlName, "UTF-8"));
|
||||||
|
}
|
||||||
|
if (bestGuessConf
|
||||||
|
== null) {
|
||||||
bestGuessConf = Confidence.LOW;
|
bestGuessConf = Confidence.LOW;
|
||||||
}
|
}
|
||||||
final IdentifierMatch match = new IdentifierMatch("cpe", cpeName, url, IdentifierConfidence.BEST_GUESS, bestGuessConf);
|
final IdentifierMatch match = new IdentifierMatch("cpe", cpeName, url, IdentifierConfidence.BEST_GUESS, bestGuessConf);
|
||||||
|
|
||||||
collected.add(match);
|
collected.add(match);
|
||||||
|
|
||||||
Collections.sort(collected);
|
Collections.sort(collected);
|
||||||
final IdentifierConfidence bestIdentifierQuality = collected.get(0).getConfidence();
|
final IdentifierConfidence bestIdentifierQuality = collected.get(0).getConfidence();
|
||||||
final Confidence bestEvidenceQuality = collected.get(0).getEvidenceConfidence();
|
final Confidence bestEvidenceQuality = collected.get(0).getEvidenceConfidence();
|
||||||
|
boolean identifierAdded = false;
|
||||||
for (IdentifierMatch m : collected) {
|
for (IdentifierMatch m : collected) {
|
||||||
if (bestIdentifierQuality.equals(m.getConfidence())
|
if (bestIdentifierQuality.equals(m.getConfidence())
|
||||||
&& bestEvidenceQuality.equals(m.getEvidenceConfidence())) {
|
&& bestEvidenceQuality.equals(m.getEvidenceConfidence())) {
|
||||||
dependency.addIdentifier(m.getIdentifier());
|
final Identifier i = m.getIdentifier();
|
||||||
|
if (bestIdentifierQuality == IdentifierConfidence.BEST_GUESS) {
|
||||||
|
i.setConfidence(Confidence.LOW);
|
||||||
|
} else {
|
||||||
|
i.setConfidence(bestEvidenceQuality);
|
||||||
|
}
|
||||||
|
dependency.addIdentifier(i);
|
||||||
|
identifierAdded = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return identifierAdded;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* Returns the setting key to determine if the analyzer is enabled.</p>
|
||||||
|
*
|
||||||
|
* @return the key for the analyzer's enabled property
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected String getAnalyzerEnabledSettingKey() {
|
||||||
|
return Settings.KEYS.ANALYZER_CPE_ENABLED;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -630,7 +668,13 @@ public class CPEAnalyzer implements Analyzer {
|
|||||||
/**
|
/**
|
||||||
* A best guess for the CPE.
|
* A best guess for the CPE.
|
||||||
*/
|
*/
|
||||||
BEST_GUESS
|
BEST_GUESS,
|
||||||
|
/**
|
||||||
|
* The entire vendor/product group must be added (without a guess at
|
||||||
|
* version) because there is a CVE with a VS that only specifies
|
||||||
|
* vendor/product.
|
||||||
|
*/
|
||||||
|
BROAD_MATCH
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -640,7 +684,20 @@ public class CPEAnalyzer implements Analyzer {
|
|||||||
private static class IdentifierMatch implements Comparable<IdentifierMatch> {
|
private static class IdentifierMatch implements Comparable<IdentifierMatch> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs an IdentiferMatch.
|
* The confidence in the evidence used to identify this match.
|
||||||
|
*/
|
||||||
|
private Confidence evidenceConfidence;
|
||||||
|
/**
|
||||||
|
* The confidence whether this is an exact match, or a best guess.
|
||||||
|
*/
|
||||||
|
private IdentifierConfidence confidence;
|
||||||
|
/**
|
||||||
|
* The CPE identifier.
|
||||||
|
*/
|
||||||
|
private Identifier identifier;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs an IdentifierMatch.
|
||||||
*
|
*
|
||||||
* @param type the type of identifier (such as CPE)
|
* @param type the type of identifier (such as CPE)
|
||||||
* @param value the value of the identifier
|
* @param value the value of the identifier
|
||||||
@@ -655,12 +712,8 @@ public class CPEAnalyzer implements Analyzer {
|
|||||||
this.confidence = identifierConfidence;
|
this.confidence = identifierConfidence;
|
||||||
this.evidenceConfidence = evidenceConfidence;
|
this.evidenceConfidence = evidenceConfidence;
|
||||||
}
|
}
|
||||||
//<editor-fold defaultstate="collapsed" desc="Property implementations: evidenceConfidence, confidence, identifier">
|
|
||||||
/**
|
|
||||||
* The confidence in the evidence used to identify this match.
|
|
||||||
*/
|
|
||||||
private Confidence evidenceConfidence;
|
|
||||||
|
|
||||||
|
//<editor-fold defaultstate="collapsed" desc="Property implementations: evidenceConfidence, confidence, identifier">
|
||||||
/**
|
/**
|
||||||
* Get the value of evidenceConfidence
|
* Get the value of evidenceConfidence
|
||||||
*
|
*
|
||||||
@@ -678,10 +731,6 @@ public class CPEAnalyzer implements Analyzer {
|
|||||||
public void setEvidenceConfidence(Confidence evidenceConfidence) {
|
public void setEvidenceConfidence(Confidence evidenceConfidence) {
|
||||||
this.evidenceConfidence = evidenceConfidence;
|
this.evidenceConfidence = evidenceConfidence;
|
||||||
}
|
}
|
||||||
/**
|
|
||||||
* The confidence whether this is an exact match, or a best guess.
|
|
||||||
*/
|
|
||||||
private IdentifierConfidence confidence;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the value of confidence.
|
* Get the value of confidence.
|
||||||
@@ -700,10 +749,6 @@ public class CPEAnalyzer implements Analyzer {
|
|||||||
public void setConfidence(IdentifierConfidence confidence) {
|
public void setConfidence(IdentifierConfidence confidence) {
|
||||||
this.confidence = confidence;
|
this.confidence = confidence;
|
||||||
}
|
}
|
||||||
/**
|
|
||||||
* The CPE identifier.
|
|
||||||
*/
|
|
||||||
private Identifier identifier;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the value of identifier.
|
* Get the value of identifier.
|
||||||
@@ -771,10 +816,7 @@ public class CPEAnalyzer implements Analyzer {
|
|||||||
if (this.confidence != other.confidence) {
|
if (this.confidence != other.confidence) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (this.identifier != other.identifier && (this.identifier == null || !this.identifier.equals(other.identifier))) {
|
return !(this.identifier != other.identifier && (this.identifier == null || !this.identifier.equals(other.identifier)));
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
//</editor-fold>
|
//</editor-fold>
|
||||||
|
|
||||||
@@ -787,14 +829,11 @@ public class CPEAnalyzer implements Analyzer {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public int compareTo(IdentifierMatch o) {
|
public int compareTo(IdentifierMatch o) {
|
||||||
int conf = this.confidence.compareTo(o.confidence);
|
return new CompareToBuilder()
|
||||||
if (conf == 0) {
|
.append(confidence, o.confidence)
|
||||||
conf = this.evidenceConfidence.compareTo(o.evidenceConfidence);
|
.append(evidenceConfidence, o.evidenceConfidence)
|
||||||
if (conf == 0) {
|
.append(identifier, o.identifier)
|
||||||
conf = identifier.compareTo(o.identifier);
|
.toComparison();
|
||||||
}
|
|
||||||
}
|
|
||||||
return conf;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,249 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of dependency-check-core.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
* Copyright (c) 2014 Jeremy Long. All Rights Reserved.
|
||||||
|
*/
|
||||||
|
package org.owasp.dependencycheck.analyzer;
|
||||||
|
|
||||||
|
import org.apache.commons.io.FileUtils;
|
||||||
|
import org.owasp.dependencycheck.Engine;
|
||||||
|
import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
|
||||||
|
import org.owasp.dependencycheck.data.central.CentralSearch;
|
||||||
|
import org.owasp.dependencycheck.data.nexus.MavenArtifact;
|
||||||
|
import org.owasp.dependencycheck.dependency.Confidence;
|
||||||
|
import org.owasp.dependencycheck.dependency.Dependency;
|
||||||
|
import org.owasp.dependencycheck.dependency.Evidence;
|
||||||
|
import org.owasp.dependencycheck.xml.pom.PomUtils;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileFilter;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.MalformedURLException;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.util.List;
|
||||||
|
import org.owasp.dependencycheck.exception.InitializationException;
|
||||||
|
import org.owasp.dependencycheck.utils.DownloadFailedException;
|
||||||
|
import org.owasp.dependencycheck.utils.Downloader;
|
||||||
|
import org.owasp.dependencycheck.utils.FileFilterBuilder;
|
||||||
|
import org.owasp.dependencycheck.utils.InvalidSettingException;
|
||||||
|
import org.owasp.dependencycheck.utils.Settings;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Analyzer which will attempt to locate a dependency, and the GAV information,
|
||||||
|
* by querying Central for the dependency's SHA-1 digest.
|
||||||
|
*
|
||||||
|
* @author colezlaw
|
||||||
|
*/
|
||||||
|
public class CentralAnalyzer extends AbstractFileTypeAnalyzer {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The logger.
|
||||||
|
*/
|
||||||
|
private static final Logger LOGGER = LoggerFactory.getLogger(CentralAnalyzer.class);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The name of the analyzer.
|
||||||
|
*/
|
||||||
|
private static final String ANALYZER_NAME = "Central Analyzer";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The phase in which this analyzer runs.
|
||||||
|
*/
|
||||||
|
private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The types of files on which this will work.
|
||||||
|
*/
|
||||||
|
private static final String SUPPORTED_EXTENSIONS = "jar";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The analyzer should be disabled if there are errors, so this is a flag to
|
||||||
|
* determine if such an error has occurred.
|
||||||
|
*/
|
||||||
|
private volatile boolean errorFlag = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The searcher itself.
|
||||||
|
*/
|
||||||
|
private CentralSearch searcher;
|
||||||
|
/**
|
||||||
|
* Field indicating if the analyzer is enabled.
|
||||||
|
*/
|
||||||
|
private final boolean enabled = checkEnabled();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine whether to enable this analyzer or not.
|
||||||
|
*
|
||||||
|
* @return whether the analyzer should be enabled
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean isEnabled() {
|
||||||
|
return enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines if this analyzer is enabled.
|
||||||
|
*
|
||||||
|
* @return <code>true</code> if the analyzer is enabled; otherwise
|
||||||
|
* <code>false</code>
|
||||||
|
*/
|
||||||
|
private boolean checkEnabled() {
|
||||||
|
boolean retVal = false;
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (Settings.getBoolean(Settings.KEYS.ANALYZER_CENTRAL_ENABLED)) {
|
||||||
|
if (!Settings.getBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED)
|
||||||
|
|| NexusAnalyzer.DEFAULT_URL.equals(Settings.getString(Settings.KEYS.ANALYZER_NEXUS_URL))) {
|
||||||
|
LOGGER.debug("Enabling the Central analyzer");
|
||||||
|
retVal = true;
|
||||||
|
} else {
|
||||||
|
LOGGER.info("Nexus analyzer is enabled, disabling the Central Analyzer");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
LOGGER.info("Central analyzer disabled");
|
||||||
|
}
|
||||||
|
} catch (InvalidSettingException ise) {
|
||||||
|
LOGGER.warn("Invalid setting. Disabling the Central analyzer");
|
||||||
|
}
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes the analyzer once before any analysis is performed.
|
||||||
|
*
|
||||||
|
* @throws InitializationException if there's an error during initialization
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void initializeFileTypeAnalyzer() throws InitializationException {
|
||||||
|
LOGGER.debug("Initializing Central analyzer");
|
||||||
|
LOGGER.debug("Central analyzer enabled: {}", isEnabled());
|
||||||
|
if (isEnabled()) {
|
||||||
|
final String searchUrl = Settings.getString(Settings.KEYS.ANALYZER_CENTRAL_URL);
|
||||||
|
LOGGER.debug("Central Analyzer URL: {}", searchUrl);
|
||||||
|
try {
|
||||||
|
searcher = new CentralSearch(new URL(searchUrl));
|
||||||
|
} catch (MalformedURLException ex) {
|
||||||
|
setEnabled(false);
|
||||||
|
throw new InitializationException("The configured URL to Maven Central is malformed: " + searchUrl, ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the analyzer's name.
|
||||||
|
*
|
||||||
|
* @return the name of the analyzer
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return ANALYZER_NAME;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the key used in the properties file to to reference the
|
||||||
|
* analyzer's enabled property.
|
||||||
|
*
|
||||||
|
* @return the analyzer's enabled property setting key.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected String getAnalyzerEnabledSettingKey() {
|
||||||
|
return Settings.KEYS.ANALYZER_CENTRAL_ENABLED;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the analysis phase under which the analyzer runs.
|
||||||
|
*
|
||||||
|
* @return the phase under which the analyzer runs
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public AnalysisPhase getAnalysisPhase() {
|
||||||
|
return ANALYSIS_PHASE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The file filter used to determine which files this analyzer supports.
|
||||||
|
*/
|
||||||
|
private static final FileFilter FILTER = FileFilterBuilder.newInstance().addExtensions(SUPPORTED_EXTENSIONS).build();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected FileFilter getFileFilter() {
|
||||||
|
return FILTER;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Performs the analysis.
|
||||||
|
*
|
||||||
|
* @param dependency the dependency to analyze
|
||||||
|
* @param engine the engine
|
||||||
|
* @throws AnalysisException when there's an exception during analysis
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void analyzeDependency(Dependency dependency, Engine engine) throws AnalysisException {
|
||||||
|
if (errorFlag || !isEnabled()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
final List<MavenArtifact> mas = searcher.searchSha1(dependency.getSha1sum());
|
||||||
|
final Confidence confidence = mas.size() > 1 ? Confidence.HIGH : Confidence.HIGHEST;
|
||||||
|
for (MavenArtifact ma : mas) {
|
||||||
|
LOGGER.debug("Central analyzer found artifact ({}) for dependency ({})", ma, dependency.getFileName());
|
||||||
|
dependency.addAsEvidence("central", ma, confidence);
|
||||||
|
boolean pomAnalyzed = false;
|
||||||
|
for (Evidence e : dependency.getVendorEvidence()) {
|
||||||
|
if ("pom".equals(e.getSource())) {
|
||||||
|
pomAnalyzed = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!pomAnalyzed && ma.getPomUrl() != null) {
|
||||||
|
File pomFile = null;
|
||||||
|
try {
|
||||||
|
final File baseDir = Settings.getTempDirectory();
|
||||||
|
pomFile = File.createTempFile("pom", ".xml", baseDir);
|
||||||
|
if (!pomFile.delete()) {
|
||||||
|
LOGGER.warn("Unable to fetch pom.xml for {} from Central; "
|
||||||
|
+ "this could result in undetected CPE/CVEs.", dependency.getFileName());
|
||||||
|
LOGGER.debug("Unable to delete temp file");
|
||||||
|
}
|
||||||
|
LOGGER.debug("Downloading {}", ma.getPomUrl());
|
||||||
|
Downloader.fetchFile(new URL(ma.getPomUrl()), pomFile);
|
||||||
|
PomUtils.analyzePOM(dependency, pomFile);
|
||||||
|
|
||||||
|
} catch (DownloadFailedException ex) {
|
||||||
|
LOGGER.warn("Unable to download pom.xml for {} from Central; "
|
||||||
|
+ "this could result in undetected CPE/CVEs.", dependency.getFileName());
|
||||||
|
} finally {
|
||||||
|
if (pomFile != null && pomFile.exists() && !FileUtils.deleteQuietly(pomFile)) {
|
||||||
|
LOGGER.debug("Failed to delete temporary pom file {}", pomFile.toString());
|
||||||
|
pomFile.deleteOnExit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
} catch (IllegalArgumentException iae) {
|
||||||
|
LOGGER.info("invalid sha1-hash on {}", dependency.getFileName());
|
||||||
|
} catch (FileNotFoundException fnfe) {
|
||||||
|
LOGGER.debug("Artifact not found in repository: '{}", dependency.getFileName());
|
||||||
|
} catch (IOException ioe) {
|
||||||
|
LOGGER.debug("Could not connect to Central search", ioe);
|
||||||
|
errorFlag = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,205 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of dependency-check-core.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
* Copyright (c) 2016 IBM Corporation. All Rights Reserved.
|
||||||
|
*/
|
||||||
|
package org.owasp.dependencycheck.analyzer;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileFilter;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.charset.Charset;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import org.apache.commons.io.FileUtils;
|
||||||
|
import org.owasp.dependencycheck.Engine;
|
||||||
|
import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
|
||||||
|
import org.owasp.dependencycheck.dependency.Confidence;
|
||||||
|
import org.owasp.dependencycheck.dependency.Dependency;
|
||||||
|
import org.owasp.dependencycheck.dependency.EvidenceCollection;
|
||||||
|
import org.owasp.dependencycheck.utils.FileFilterBuilder;
|
||||||
|
import org.owasp.dependencycheck.utils.Settings;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This analyzer is used to analyze SWIFT and Objective-C packages by collecting
|
||||||
|
* information from .podspec files. CocoaPods dependency manager see
|
||||||
|
* https://cocoapods.org/.
|
||||||
|
*
|
||||||
|
* @author Bianca Jiang (https://twitter.com/biancajiang)
|
||||||
|
*/
|
||||||
|
@Experimental
|
||||||
|
public class CocoaPodsAnalyzer extends AbstractFileTypeAnalyzer {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The logger.
|
||||||
|
*/
|
||||||
|
// private static final Logger LOGGER = LoggerFactory.getLogger(CocoaPodsAnalyzer.class);
|
||||||
|
/**
|
||||||
|
* The name of the analyzer.
|
||||||
|
*/
|
||||||
|
private static final String ANALYZER_NAME = "CocoaPods Package Analyzer";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The phase that this analyzer is intended to run in.
|
||||||
|
*/
|
||||||
|
private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The file name to scan.
|
||||||
|
*/
|
||||||
|
public static final String PODSPEC = "podspec";
|
||||||
|
/**
|
||||||
|
* Filter that detects files named "*.podspec".
|
||||||
|
*/
|
||||||
|
private static final FileFilter PODSPEC_FILTER = FileFilterBuilder.newInstance().addExtensions(PODSPEC).build();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The capture group #1 is the block variable. e.g. "Pod::Spec.new do
|
||||||
|
* |spec|"
|
||||||
|
*/
|
||||||
|
private static final Pattern PODSPEC_BLOCK_PATTERN = Pattern.compile("Pod::Spec\\.new\\s+?do\\s+?\\|(.+?)\\|");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the FileFilter
|
||||||
|
*
|
||||||
|
* @return the FileFilter
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected FileFilter getFileFilter() {
|
||||||
|
return PODSPEC_FILTER;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void initializeFileTypeAnalyzer() {
|
||||||
|
// NO-OP
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the name of the analyzer.
|
||||||
|
*
|
||||||
|
* @return the name of the analyzer.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return ANALYZER_NAME;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the phase that the analyzer is intended to run in.
|
||||||
|
*
|
||||||
|
* @return the phase that the analyzer is intended to run in.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public AnalysisPhase getAnalysisPhase() {
|
||||||
|
return ANALYSIS_PHASE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the key used in the properties file to reference the analyzer's
|
||||||
|
* enabled property.
|
||||||
|
*
|
||||||
|
* @return the analyzer's enabled property setting key
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected String getAnalyzerEnabledSettingKey() {
|
||||||
|
return Settings.KEYS.ANALYZER_COCOAPODS_ENABLED;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void analyzeDependency(Dependency dependency, Engine engine)
|
||||||
|
throws AnalysisException {
|
||||||
|
|
||||||
|
String contents;
|
||||||
|
try {
|
||||||
|
contents = FileUtils.readFileToString(dependency.getActualFile(), Charset.defaultCharset());
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new AnalysisException(
|
||||||
|
"Problem occurred while reading dependency file.", e);
|
||||||
|
}
|
||||||
|
final Matcher matcher = PODSPEC_BLOCK_PATTERN.matcher(contents);
|
||||||
|
if (matcher.find()) {
|
||||||
|
contents = contents.substring(matcher.end());
|
||||||
|
final String blockVariable = matcher.group(1);
|
||||||
|
|
||||||
|
final EvidenceCollection vendor = dependency.getVendorEvidence();
|
||||||
|
final EvidenceCollection product = dependency.getProductEvidence();
|
||||||
|
final EvidenceCollection version = dependency.getVersionEvidence();
|
||||||
|
|
||||||
|
final String name = addStringEvidence(product, contents, blockVariable, "name", "name", Confidence.HIGHEST);
|
||||||
|
if (!name.isEmpty()) {
|
||||||
|
vendor.addEvidence(PODSPEC, "name_project", name, Confidence.HIGHEST);
|
||||||
|
}
|
||||||
|
addStringEvidence(product, contents, blockVariable, "summary", "summary", Confidence.HIGHEST);
|
||||||
|
|
||||||
|
addStringEvidence(vendor, contents, blockVariable, "author", "authors?", Confidence.HIGHEST);
|
||||||
|
addStringEvidence(vendor, contents, blockVariable, "homepage", "homepage", Confidence.HIGHEST);
|
||||||
|
addStringEvidence(vendor, contents, blockVariable, "license", "licen[cs]es?", Confidence.HIGHEST);
|
||||||
|
|
||||||
|
addStringEvidence(version, contents, blockVariable, "version", "version", Confidence.HIGHEST);
|
||||||
|
}
|
||||||
|
|
||||||
|
setPackagePath(dependency);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extracts evidence from the contents and adds it to the given evidence
|
||||||
|
* collection.
|
||||||
|
*
|
||||||
|
* @param evidences the evidence collection to update
|
||||||
|
* @param contents the text to extract evidence from
|
||||||
|
* @param blockVariable the block variable within the content to search for
|
||||||
|
* @param field the name of the field being searched for
|
||||||
|
* @param fieldPattern the field pattern within the contents to search for
|
||||||
|
* @param confidence the confidence level of the evidence if found
|
||||||
|
* @return the string that was added as evidence
|
||||||
|
*/
|
||||||
|
private String addStringEvidence(EvidenceCollection evidences, String contents,
|
||||||
|
String blockVariable, String field, String fieldPattern, Confidence confidence) {
|
||||||
|
String value = "";
|
||||||
|
|
||||||
|
//capture array value between [ ]
|
||||||
|
final Matcher arrayMatcher = Pattern.compile(
|
||||||
|
String.format("\\s*?%s\\.%s\\s*?=\\s*?\\{\\s*?(.*?)\\s*?\\}", blockVariable, fieldPattern),
|
||||||
|
Pattern.CASE_INSENSITIVE).matcher(contents);
|
||||||
|
if (arrayMatcher.find()) {
|
||||||
|
value = arrayMatcher.group(1);
|
||||||
|
} else { //capture single value between quotes
|
||||||
|
final Matcher matcher = Pattern.compile(
|
||||||
|
String.format("\\s*?%s\\.%s\\s*?=\\s*?(['\"])(.*?)\\1", blockVariable, fieldPattern),
|
||||||
|
Pattern.CASE_INSENSITIVE).matcher(contents);
|
||||||
|
if (matcher.find()) {
|
||||||
|
value = matcher.group(2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (value.length() > 0) {
|
||||||
|
evidences.addEvidence(PODSPEC, field, value, confidence);
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the package path on the given dependency.
|
||||||
|
*
|
||||||
|
* @param dep the dependency to update
|
||||||
|
*/
|
||||||
|
private void setPackagePath(Dependency dep) {
|
||||||
|
final File file = new File(dep.getFilePath());
|
||||||
|
final String parent = file.getParent();
|
||||||
|
if (parent != null) {
|
||||||
|
dep.setPackagePath(parent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,171 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of dependency-check-core.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
* Copyright (c) 2015 The OWASP Foundation. All Rights Reserved.
|
||||||
|
*/
|
||||||
|
package org.owasp.dependencycheck.analyzer;
|
||||||
|
|
||||||
|
import org.owasp.dependencycheck.Engine;
|
||||||
|
import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
|
||||||
|
import org.owasp.dependencycheck.data.composer.ComposerDependency;
|
||||||
|
import org.owasp.dependencycheck.data.composer.ComposerException;
|
||||||
|
import org.owasp.dependencycheck.data.composer.ComposerLockParser;
|
||||||
|
import org.owasp.dependencycheck.dependency.Confidence;
|
||||||
|
import org.owasp.dependencycheck.dependency.Dependency;
|
||||||
|
import org.owasp.dependencycheck.exception.InitializationException;
|
||||||
|
import org.owasp.dependencycheck.utils.Checksum;
|
||||||
|
import org.owasp.dependencycheck.utils.FileFilterBuilder;
|
||||||
|
import org.owasp.dependencycheck.utils.Settings;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.io.FileFilter;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.charset.Charset;
|
||||||
|
import java.security.MessageDigest;
|
||||||
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used to analyze a composer.lock file for a composer PHP app.
|
||||||
|
*
|
||||||
|
* @author colezlaw
|
||||||
|
*/
|
||||||
|
@Experimental
|
||||||
|
public class ComposerLockAnalyzer extends AbstractFileTypeAnalyzer {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The logger.
|
||||||
|
*/
|
||||||
|
private static final Logger LOGGER = LoggerFactory.getLogger(ComposerLockAnalyzer.class);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The analyzer name.
|
||||||
|
*/
|
||||||
|
private static final String ANALYZER_NAME = "Composer.lock analyzer";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* composer.json.
|
||||||
|
*/
|
||||||
|
private static final String COMPOSER_LOCK = "composer.lock";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The FileFilter.
|
||||||
|
*/
|
||||||
|
private static final FileFilter FILE_FILTER = FileFilterBuilder.newInstance().addFilenames(COMPOSER_LOCK).build();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the FileFilter.
|
||||||
|
*
|
||||||
|
* @return the FileFilter
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected FileFilter getFileFilter() {
|
||||||
|
return FILE_FILTER;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes the analyzer.
|
||||||
|
*
|
||||||
|
* @throws InitializationException thrown if an exception occurs getting an
|
||||||
|
* instance of SHA1
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected void initializeFileTypeAnalyzer() throws InitializationException {
|
||||||
|
try {
|
||||||
|
getSha1MessageDigest();
|
||||||
|
} catch (IllegalStateException ex) {
|
||||||
|
setEnabled(false);
|
||||||
|
throw new InitializationException("Unable to create SHA1 MessageDigest", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Entry point for the analyzer.
|
||||||
|
*
|
||||||
|
* @param dependency the dependency to analyze
|
||||||
|
* @param engine the engine scanning
|
||||||
|
* @throws AnalysisException if there's a failure during analysis
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected void analyzeDependency(Dependency dependency, Engine engine) throws AnalysisException {
|
||||||
|
try (FileInputStream fis = new FileInputStream(dependency.getActualFile())) {
|
||||||
|
final ComposerLockParser clp = new ComposerLockParser(fis);
|
||||||
|
LOGGER.info("Checking composer.lock file {}", dependency.getActualFilePath());
|
||||||
|
clp.process();
|
||||||
|
for (ComposerDependency dep : clp.getDependencies()) {
|
||||||
|
final Dependency d = new Dependency(dependency.getActualFile());
|
||||||
|
d.setDisplayFileName(String.format("%s:%s/%s", dependency.getDisplayFileName(), dep.getGroup(), dep.getProject()));
|
||||||
|
final String filePath = String.format("%s:%s/%s", dependency.getFilePath(), dep.getGroup(), dep.getProject());
|
||||||
|
final MessageDigest sha1 = getSha1MessageDigest();
|
||||||
|
d.setFilePath(filePath);
|
||||||
|
d.setSha1sum(Checksum.getHex(sha1.digest(filePath.getBytes(Charset.defaultCharset()))));
|
||||||
|
d.getVendorEvidence().addEvidence(COMPOSER_LOCK, "vendor", dep.getGroup(), Confidence.HIGHEST);
|
||||||
|
d.getProductEvidence().addEvidence(COMPOSER_LOCK, "product", dep.getProject(), Confidence.HIGHEST);
|
||||||
|
d.getVersionEvidence().addEvidence(COMPOSER_LOCK, "version", dep.getVersion(), Confidence.HIGHEST);
|
||||||
|
LOGGER.info("Adding dependency {}", d);
|
||||||
|
engine.getDependencies().add(d);
|
||||||
|
}
|
||||||
|
} catch (IOException ex) {
|
||||||
|
LOGGER.warn("Error opening dependency {}", dependency.getActualFilePath());
|
||||||
|
} catch (ComposerException ce) {
|
||||||
|
LOGGER.warn("Error parsing composer.json {}", dependency.getActualFilePath(), ce);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the key to determine whether the analyzer is enabled.
|
||||||
|
*
|
||||||
|
* @return the key specifying whether the analyzer is enabled
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected String getAnalyzerEnabledSettingKey() {
|
||||||
|
return Settings.KEYS.ANALYZER_COMPOSER_LOCK_ENABLED;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the analyzer's name.
|
||||||
|
*
|
||||||
|
* @return the analyzer's name
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return ANALYZER_NAME;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the phase this analyzer should run under.
|
||||||
|
*
|
||||||
|
* @return the analysis phase
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public AnalysisPhase getAnalysisPhase() {
|
||||||
|
return AnalysisPhase.INFORMATION_COLLECTION;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the sha1 message digest.
|
||||||
|
*
|
||||||
|
* @return the sha1 message digest
|
||||||
|
*/
|
||||||
|
private MessageDigest getSha1MessageDigest() {
|
||||||
|
try {
|
||||||
|
return MessageDigest.getInstance("SHA1");
|
||||||
|
} catch (NoSuchAlgorithmException e) {
|
||||||
|
LOGGER.error(e.getMessage());
|
||||||
|
throw new IllegalStateException("Failed to obtain the SHA1 message digest.", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,87 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of dependency-check-core.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
* Copyright (c) 2013 Jeremy Long. All Rights Reserved.
|
||||||
|
*/
|
||||||
|
package org.owasp.dependencycheck.analyzer;
|
||||||
|
|
||||||
|
import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
|
||||||
|
import org.owasp.dependencycheck.Engine;
|
||||||
|
import org.owasp.dependencycheck.dependency.Dependency;
|
||||||
|
import org.owasp.dependencycheck.utils.Settings;
|
||||||
|
import org.owasp.dependencycheck.xml.suppression.SuppressionRule;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The suppression analyzer processes an externally defined XML document that complies with the suppressions.xsd schema.
|
||||||
|
* Any identified CPE entries within the dependencies that match will be removed.
|
||||||
|
*
|
||||||
|
* @author Jeremy Long
|
||||||
|
*/
|
||||||
|
public class CpeSuppressionAnalyzer extends AbstractSuppressionAnalyzer {
|
||||||
|
|
||||||
|
//<editor-fold defaultstate="collapsed" desc="All standard implementation details of Analyzer">
|
||||||
|
/**
|
||||||
|
* The name of the analyzer.
|
||||||
|
*/
|
||||||
|
private static final String ANALYZER_NAME = "Cpe Suppression Analyzer";
|
||||||
|
/**
|
||||||
|
* The phase that this analyzer is intended to run in.
|
||||||
|
*/
|
||||||
|
private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.POST_IDENTIFIER_ANALYSIS;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the name of the analyzer.
|
||||||
|
*
|
||||||
|
* @return the name of the analyzer.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return ANALYZER_NAME;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the phase that the analyzer is intended to run in.
|
||||||
|
*
|
||||||
|
* @return the phase that the analyzer is intended to run in.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public AnalysisPhase getAnalysisPhase() {
|
||||||
|
return ANALYSIS_PHASE;
|
||||||
|
}
|
||||||
|
//</editor-fold>
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void analyzeDependency(Dependency dependency, Engine engine) throws AnalysisException {
|
||||||
|
|
||||||
|
if (getRules() == null || getRules().size() <= 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (final SuppressionRule rule : getRules()) {
|
||||||
|
rule.process(dependency);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* Returns the setting key to determine if the analyzer is enabled.</p>
|
||||||
|
*
|
||||||
|
* @return the key for the analyzer's enabled property
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected String getAnalyzerEnabledSettingKey() {
|
||||||
|
return Settings.KEYS.ANALYZER_CPE_SUPPRESSION_ENABLED;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,18 +1,17 @@
|
|||||||
/*
|
/*
|
||||||
* This file is part of dependency-check-core.
|
* This file is part of dependency-check-core.
|
||||||
*
|
*
|
||||||
* Dependency-check-core is free software: you can redistribute it and/or modify it
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* under the terms of the GNU General Public License as published by the Free
|
* you may not use this file except in compliance with the License.
|
||||||
* Software Foundation, either version 3 of the License, or (at your option) any
|
* You may obtain a copy of the License at
|
||||||
* later version.
|
|
||||||
*
|
*
|
||||||
* Dependency-check-core is distributed in the hope that it will be useful, but
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
|
||||||
* details.
|
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License along with
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* dependency-check-core. If not, see http://www.gnu.org/licenses/.
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
*
|
*
|
||||||
* Copyright (c) 2012 Jeremy Long. All Rights Reserved.
|
* Copyright (c) 2012 Jeremy Long. All Rights Reserved.
|
||||||
*/
|
*/
|
||||||
@@ -26,38 +25,59 @@ import java.util.Set;
|
|||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
import org.owasp.dependencycheck.Engine;
|
import org.owasp.dependencycheck.Engine;
|
||||||
|
import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
|
||||||
import org.owasp.dependencycheck.dependency.Dependency;
|
import org.owasp.dependencycheck.dependency.Dependency;
|
||||||
|
import org.owasp.dependencycheck.dependency.Identifier;
|
||||||
import org.owasp.dependencycheck.utils.DependencyVersion;
|
import org.owasp.dependencycheck.utils.DependencyVersion;
|
||||||
import org.owasp.dependencycheck.utils.DependencyVersionUtil;
|
import org.owasp.dependencycheck.utils.DependencyVersionUtil;
|
||||||
|
import org.owasp.dependencycheck.utils.Settings;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>This analyzer ensures dependencies that should be grouped together, to
|
* <p>
|
||||||
* remove excess noise from the report, are grouped. An example would be Spring,
|
* This analyzer ensures dependencies that should be grouped together, to remove
|
||||||
* Spring Beans, Spring MVC, etc. If they are all for the same version and have
|
* excess noise from the report, are grouped. An example would be Spring, Spring
|
||||||
* the same relative path then these should be grouped into a single dependency
|
* Beans, Spring MVC, etc. If they are all for the same version and have the
|
||||||
|
* same relative path then these should be grouped into a single dependency
|
||||||
* under the core/main library.</p>
|
* under the core/main library.</p>
|
||||||
* <p>Note, this grouping only works on dependencies with identified CVE
|
* <p>
|
||||||
|
* Note, this grouping only works on dependencies with identified CVE
|
||||||
* entries</p>
|
* entries</p>
|
||||||
*
|
*
|
||||||
* @author Jeremy Long (jeremy.long@owasp.org)
|
* @author Jeremy Long
|
||||||
*/
|
*/
|
||||||
public class DependencyBundlingAnalyzer extends AbstractAnalyzer implements Analyzer {
|
public class DependencyBundlingAnalyzer extends AbstractAnalyzer {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Logger.
|
||||||
|
*/
|
||||||
|
private static final Logger LOGGER = LoggerFactory.getLogger(DependencyBundlingAnalyzer.class);
|
||||||
|
|
||||||
//<editor-fold defaultstate="collapsed" desc="Constants and Member Variables">
|
//<editor-fold defaultstate="collapsed" desc="Constants and Member Variables">
|
||||||
/**
|
/**
|
||||||
* A pattern for obtaining the first part of a filename.
|
* A pattern for obtaining the first part of a filename.
|
||||||
*/
|
*/
|
||||||
private static final Pattern STARTING_TEXT_PATTERN = Pattern.compile("^[a-zA-Z]*");
|
private static final Pattern STARTING_TEXT_PATTERN = Pattern.compile("^[a-zA-Z0-9]*");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* a flag indicating if this analyzer has run. This analyzer only runs once.
|
* a flag indicating if this analyzer has run. This analyzer only runs once.
|
||||||
*/
|
*/
|
||||||
private boolean analyzed = false;
|
private boolean analyzed = false;
|
||||||
//</editor-fold>
|
|
||||||
//<editor-fold defaultstate="collapsed" desc="All standard implmentation details of Analyzer">
|
|
||||||
/**
|
/**
|
||||||
* The set of file extensions supported by this analyzer.
|
* Returns a flag indicating if this analyzer has run. This analyzer only
|
||||||
|
* runs once. Note this is currently only used in the unit tests.
|
||||||
|
*
|
||||||
|
* @return a flag indicating if this analyzer has run. This analyzer only
|
||||||
|
* runs once
|
||||||
*/
|
*/
|
||||||
private static final Set<String> EXTENSIONS = null;
|
protected synchronized boolean getAnalyzed() {
|
||||||
|
return analyzed;
|
||||||
|
}
|
||||||
|
|
||||||
|
//</editor-fold>
|
||||||
|
//<editor-fold defaultstate="collapsed" desc="All standard implementation details of Analyzer">
|
||||||
/**
|
/**
|
||||||
* The name of the analyzer.
|
* The name of the analyzer.
|
||||||
*/
|
*/
|
||||||
@@ -65,47 +85,52 @@ public class DependencyBundlingAnalyzer extends AbstractAnalyzer implements Anal
|
|||||||
/**
|
/**
|
||||||
* The phase that this analyzer is intended to run in.
|
* The phase that this analyzer is intended to run in.
|
||||||
*/
|
*/
|
||||||
private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.PRE_FINDING_ANALYSIS;
|
private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.FINAL;
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a list of file EXTENSIONS supported by this analyzer.
|
|
||||||
*
|
|
||||||
* @return a list of file EXTENSIONS supported by this analyzer.
|
|
||||||
*/
|
|
||||||
public Set<String> getSupportedExtensions() {
|
|
||||||
return EXTENSIONS;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the name of the analyzer.
|
* Returns the name of the analyzer.
|
||||||
*
|
*
|
||||||
* @return the name of the analyzer.
|
* @return the name of the analyzer.
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return ANALYZER_NAME;
|
return ANALYZER_NAME;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns whether or not this analyzer can process the given extension.
|
|
||||||
*
|
|
||||||
* @param extension the file extension to test for support
|
|
||||||
* @return whether or not the specified file extension is supported by this
|
|
||||||
* analyzer.
|
|
||||||
*/
|
|
||||||
public boolean supportsExtension(String extension) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the phase that the analyzer is intended to run in.
|
* Returns the phase that the analyzer is intended to run in.
|
||||||
*
|
*
|
||||||
* @return the phase that the analyzer is intended to run in.
|
* @return the phase that the analyzer is intended to run in.
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public AnalysisPhase getAnalysisPhase() {
|
public AnalysisPhase getAnalysisPhase() {
|
||||||
return ANALYSIS_PHASE;
|
return ANALYSIS_PHASE;
|
||||||
}
|
}
|
||||||
//</editor-fold>
|
//</editor-fold>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Does not support parallel processing as it only runs once and then
|
||||||
|
* operates on <em>all</em> dependencies.
|
||||||
|
*
|
||||||
|
* @return whether or not parallel processing is enabled
|
||||||
|
* @see #analyze(Dependency, Engine)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean supportsParallelProcessing() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* Returns the setting key to determine if the analyzer is enabled.</p>
|
||||||
|
*
|
||||||
|
* @return the key for the analyzer's enabled property
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected String getAnalyzerEnabledSettingKey() {
|
||||||
|
return Settings.KEYS.ANALYZER_DEPENDENCY_BUNDLING_ENABLED;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Analyzes a set of dependencies. If they have been found to have the same
|
* Analyzes a set of dependencies. If they have been found to have the same
|
||||||
* base path and the same set of identifiers they are likely related. The
|
* base path and the same set of identifiers they are likely related. The
|
||||||
@@ -117,43 +142,46 @@ public class DependencyBundlingAnalyzer extends AbstractAnalyzer implements Anal
|
|||||||
* file.
|
* file.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void analyze(Dependency ignore, Engine engine) throws AnalysisException {
|
protected synchronized void analyzeDependency(Dependency ignore, Engine engine) throws AnalysisException {
|
||||||
if (!analyzed) {
|
if (!analyzed) {
|
||||||
analyzed = true;
|
analyzed = true;
|
||||||
final Set<Dependency> dependenciesToRemove = new HashSet<Dependency>();
|
final Set<Dependency> dependenciesToRemove = new HashSet<>();
|
||||||
final ListIterator<Dependency> mainIterator = engine.getDependencies().listIterator();
|
final ListIterator<Dependency> mainIterator = engine.getDependencies().listIterator();
|
||||||
//for (Dependency nextDependency : engine.getDependencies()) {
|
//for (Dependency nextDependency : engine.getDependencies()) {
|
||||||
while (mainIterator.hasNext()) {
|
while (mainIterator.hasNext()) {
|
||||||
final Dependency dependency = mainIterator.next();
|
final Dependency dependency = mainIterator.next();
|
||||||
if (mainIterator.hasNext()) {
|
if (mainIterator.hasNext() && !dependenciesToRemove.contains(dependency)) {
|
||||||
final ListIterator<Dependency> subIterator = engine.getDependencies().listIterator(mainIterator.nextIndex());
|
final ListIterator<Dependency> subIterator = engine.getDependencies().listIterator(mainIterator.nextIndex());
|
||||||
while (subIterator.hasNext()) {
|
while (subIterator.hasNext()) {
|
||||||
final Dependency nextDependency = subIterator.next();
|
final Dependency nextDependency = subIterator.next();
|
||||||
|
if (hashesMatch(dependency, nextDependency)) {
|
||||||
if (identifiersMatch(dependency, nextDependency)
|
if (!containedInWar(dependency.getFilePath())
|
||||||
&& hasSameBasePath(dependency, nextDependency)
|
&& !containedInWar(nextDependency.getFilePath())) {
|
||||||
&& fileNameMatch(dependency, nextDependency)) {
|
if (firstPathIsShortest(dependency.getFilePath(), nextDependency.getFilePath())) {
|
||||||
|
mergeDependencies(dependency, nextDependency, dependenciesToRemove);
|
||||||
if (isCore(dependency, nextDependency)) {
|
|
||||||
dependency.addRelatedDependency(nextDependency);
|
|
||||||
//move any "related dependencies" to the new "parent" dependency
|
|
||||||
final Iterator<Dependency> i = nextDependency.getRelatedDependencies().iterator();
|
|
||||||
while (i.hasNext()) {
|
|
||||||
dependency.addRelatedDependency(i.next());
|
|
||||||
i.remove();
|
|
||||||
}
|
|
||||||
dependenciesToRemove.add(nextDependency);
|
|
||||||
} else {
|
} else {
|
||||||
if (isCore(nextDependency, dependency)) {
|
mergeDependencies(nextDependency, dependency, dependenciesToRemove);
|
||||||
nextDependency.addRelatedDependency(dependency);
|
break; //since we merged into the next dependency - skip forward to the next in mainIterator
|
||||||
//move any "related dependencies" to the new "parent" dependency
|
|
||||||
final Iterator<Dependency> i = dependency.getRelatedDependencies().iterator();
|
|
||||||
while (i.hasNext()) {
|
|
||||||
nextDependency.addRelatedDependency(i.next());
|
|
||||||
i.remove();
|
|
||||||
}
|
}
|
||||||
dependenciesToRemove.add(dependency);
|
|
||||||
}
|
}
|
||||||
|
} else if (isShadedJar(dependency, nextDependency)) {
|
||||||
|
if (dependency.getFileName().toLowerCase().endsWith("pom.xml")) {
|
||||||
|
mergeDependencies(nextDependency, dependency, dependenciesToRemove);
|
||||||
|
nextDependency.getRelatedDependencies().remove(dependency);
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
mergeDependencies(dependency, nextDependency, dependenciesToRemove);
|
||||||
|
dependency.getRelatedDependencies().remove(nextDependency);
|
||||||
|
}
|
||||||
|
} else if (cpeIdentifiersMatch(dependency, nextDependency)
|
||||||
|
&& hasSameBasePath(dependency, nextDependency)
|
||||||
|
&& vulnCountMatches(dependency, nextDependency)
|
||||||
|
&& fileNameMatch(dependency, nextDependency)) {
|
||||||
|
if (isCore(dependency, nextDependency)) {
|
||||||
|
mergeDependencies(dependency, nextDependency, dependenciesToRemove);
|
||||||
|
} else {
|
||||||
|
mergeDependencies(nextDependency, dependency, dependenciesToRemove);
|
||||||
|
break; //since we merged into the next dependency - skip forward to the next in mainIterator
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -161,10 +189,31 @@ public class DependencyBundlingAnalyzer extends AbstractAnalyzer implements Anal
|
|||||||
}
|
}
|
||||||
//removing dependencies here as ensuring correctness and avoiding ConcurrentUpdateExceptions
|
//removing dependencies here as ensuring correctness and avoiding ConcurrentUpdateExceptions
|
||||||
// was difficult because of the inner iterator.
|
// was difficult because of the inner iterator.
|
||||||
for (Dependency d : dependenciesToRemove) {
|
engine.getDependencies().removeAll(dependenciesToRemove);
|
||||||
engine.getDependencies().remove(d);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds the relatedDependency to the dependency's related dependencies.
|
||||||
|
*
|
||||||
|
* @param dependency the main dependency
|
||||||
|
* @param relatedDependency a collection of dependencies to be removed from
|
||||||
|
* the main analysis loop, this is the source of dependencies to remove
|
||||||
|
* @param dependenciesToRemove a collection of dependencies that will be
|
||||||
|
* removed from the main analysis loop, this function adds to this
|
||||||
|
* collection
|
||||||
|
*/
|
||||||
|
private void mergeDependencies(final Dependency dependency, final Dependency relatedDependency, final Set<Dependency> dependenciesToRemove) {
|
||||||
|
dependency.addRelatedDependency(relatedDependency);
|
||||||
|
final Iterator<Dependency> i = relatedDependency.getRelatedDependencies().iterator();
|
||||||
|
while (i.hasNext()) {
|
||||||
|
dependency.addRelatedDependency(i.next());
|
||||||
|
i.remove();
|
||||||
|
}
|
||||||
|
if (dependency.getSha1sum().equals(relatedDependency.getSha1sum())) {
|
||||||
|
dependency.addAllProjectReferences(relatedDependency.getProjectReferences());
|
||||||
|
}
|
||||||
|
dependenciesToRemove.add(relatedDependency);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -175,7 +224,12 @@ public class DependencyBundlingAnalyzer extends AbstractAnalyzer implements Anal
|
|||||||
* @return a string representing the base path.
|
* @return a string representing the base path.
|
||||||
*/
|
*/
|
||||||
private String getBaseRepoPath(final String path) {
|
private String getBaseRepoPath(final String path) {
|
||||||
int pos = path.indexOf("repository" + File.separator) + 11;
|
int pos;
|
||||||
|
if (path.contains("local-repo")) {
|
||||||
|
pos = path.indexOf("local-repo" + File.separator) + 11;
|
||||||
|
} else {
|
||||||
|
pos = path.indexOf("repository" + File.separator) + 11;
|
||||||
|
}
|
||||||
if (pos < 0) {
|
if (pos < 0) {
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
@@ -195,7 +249,7 @@ public class DependencyBundlingAnalyzer extends AbstractAnalyzer implements Anal
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if the file names (and version if it exists) of the two
|
* Returns true if the file names (and version if it exists) of the two
|
||||||
* dependencies are sufficiently similiar.
|
* dependencies are sufficiently similar.
|
||||||
*
|
*
|
||||||
* @param dependency1 a dependency2 to compare
|
* @param dependency1 a dependency2 to compare
|
||||||
* @param dependency2 a dependency2 to compare
|
* @param dependency2 a dependency2 to compare
|
||||||
@@ -207,34 +261,15 @@ public class DependencyBundlingAnalyzer extends AbstractAnalyzer implements Anal
|
|||||||
|| dependency2 == null || dependency2.getFileName() == null) {
|
|| dependency2 == null || dependency2.getFileName() == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
String fileName1 = dependency1.getFileName();
|
final String fileName1 = dependency1.getActualFile().getName();
|
||||||
String fileName2 = dependency2.getFileName();
|
final String fileName2 = dependency2.getActualFile().getName();
|
||||||
|
|
||||||
//update to deal with archive analyzer, the starting name maybe the same
|
|
||||||
// as this is incorrectly looking at the starting path
|
|
||||||
final File one = new File(fileName1);
|
|
||||||
final File two = new File(fileName2);
|
|
||||||
final String oneParent = one.getParent();
|
|
||||||
final String twoParent = two.getParent();
|
|
||||||
if (oneParent != null) {
|
|
||||||
if (twoParent != null && oneParent.equals(twoParent)) {
|
|
||||||
fileName1 = one.getName();
|
|
||||||
fileName2 = two.getName();
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} else if (twoParent != null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
//version check
|
//version check
|
||||||
final DependencyVersion version1 = DependencyVersionUtil.parseVersion(fileName1);
|
final DependencyVersion version1 = DependencyVersionUtil.parseVersion(fileName1);
|
||||||
final DependencyVersion version2 = DependencyVersionUtil.parseVersion(fileName2);
|
final DependencyVersion version2 = DependencyVersionUtil.parseVersion(fileName2);
|
||||||
if (version1 != null && version2 != null) {
|
if (version1 != null && version2 != null && !version1.equals(version2)) {
|
||||||
if (!version1.equals(version2)) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
//filename check
|
//filename check
|
||||||
final Matcher match1 = STARTING_TEXT_PATTERN.matcher(fileName1);
|
final Matcher match1 = STARTING_TEXT_PATTERN.matcher(fileName1);
|
||||||
@@ -247,7 +282,7 @@ public class DependencyBundlingAnalyzer extends AbstractAnalyzer implements Anal
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if the identifiers in the two supplied dependencies are
|
* Returns true if the CPE identifiers in the two supplied dependencies are
|
||||||
* equal.
|
* equal.
|
||||||
*
|
*
|
||||||
* @param dependency1 a dependency2 to compare
|
* @param dependency1 a dependency2 to compare
|
||||||
@@ -255,13 +290,49 @@ public class DependencyBundlingAnalyzer extends AbstractAnalyzer implements Anal
|
|||||||
* @return true if the identifiers in the two supplied dependencies are
|
* @return true if the identifiers in the two supplied dependencies are
|
||||||
* equal
|
* equal
|
||||||
*/
|
*/
|
||||||
private boolean identifiersMatch(Dependency dependency1, Dependency dependency2) {
|
private boolean cpeIdentifiersMatch(Dependency dependency1, Dependency dependency2) {
|
||||||
if (dependency1 == null || dependency1.getIdentifiers() == null
|
if (dependency1 == null || dependency1.getIdentifiers() == null
|
||||||
|| dependency2 == null || dependency2.getIdentifiers() == null) {
|
|| dependency2 == null || dependency2.getIdentifiers() == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return dependency1.getIdentifiers().size() > 0
|
boolean matches = false;
|
||||||
&& dependency2.getIdentifiers().equals(dependency1.getIdentifiers());
|
int cpeCount1 = 0;
|
||||||
|
int cpeCount2 = 0;
|
||||||
|
for (Identifier i : dependency1.getIdentifiers()) {
|
||||||
|
if ("cpe".equals(i.getType())) {
|
||||||
|
cpeCount1 += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (Identifier i : dependency2.getIdentifiers()) {
|
||||||
|
if ("cpe".equals(i.getType())) {
|
||||||
|
cpeCount2 += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (cpeCount1 > 0 && cpeCount1 == cpeCount2) {
|
||||||
|
for (Identifier i : dependency1.getIdentifiers()) {
|
||||||
|
if ("cpe".equals(i.getType())) {
|
||||||
|
matches |= dependency2.getIdentifiers().contains(i);
|
||||||
|
if (!matches) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
LOGGER.debug("IdentifiersMatch={} ({}, {})", matches, dependency1.getFileName(), dependency2.getFileName());
|
||||||
|
return matches;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if the two dependencies have the same vulnerability count.
|
||||||
|
*
|
||||||
|
* @param dependency1 a dependency2 to compare
|
||||||
|
* @param dependency2 a dependency2 to compare
|
||||||
|
* @return true if the two dependencies have the same vulnerability count
|
||||||
|
*/
|
||||||
|
private boolean vulnCountMatches(Dependency dependency1, Dependency dependency2) {
|
||||||
|
return dependency1.getVulnerabilities() != null && dependency2.getVulnerabilities() != null
|
||||||
|
&& dependency1.getVulnerabilities().size() == dependency2.getVulnerabilities().size();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -280,49 +351,155 @@ public class DependencyBundlingAnalyzer extends AbstractAnalyzer implements Anal
|
|||||||
final File rFile = new File(dependency2.getFilePath());
|
final File rFile = new File(dependency2.getFilePath());
|
||||||
String right = rFile.getParent();
|
String right = rFile.getParent();
|
||||||
if (left == null) {
|
if (left == null) {
|
||||||
if (right == null) {
|
return right == null;
|
||||||
return true;
|
} else if (right == null) {
|
||||||
}
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (left.equalsIgnoreCase(right)) {
|
if (left.equalsIgnoreCase(right)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (left.matches(".*[/\\\\]repository[/\\\\].*") && right.matches(".*[/\\\\]repository[/\\\\].*")) {
|
|
||||||
|
if (left.matches(".*[/\\\\](repository|local-repo)[/\\\\].*") && right.matches(".*[/\\\\](repository|local-repo)[/\\\\].*")) {
|
||||||
left = getBaseRepoPath(left);
|
left = getBaseRepoPath(left);
|
||||||
right = getBaseRepoPath(right);
|
right = getBaseRepoPath(right);
|
||||||
}
|
}
|
||||||
return left.equalsIgnoreCase(right);
|
if (left.equalsIgnoreCase(right)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
//new code
|
||||||
|
for (Dependency child : dependency2.getRelatedDependencies()) {
|
||||||
|
if (hasSameBasePath(dependency1, child)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is likely a very broken attempt at determining if the 'left'
|
* This is likely a very broken attempt at determining if the 'left'
|
||||||
* dependency is the 'core' library in comparison to the 'right' library.
|
* dependency is the 'core' library in comparison to the 'right' library.
|
||||||
*
|
*
|
||||||
* TODO - consider splitting on /\._-\s/ and checking if all of one side is
|
|
||||||
* fully contained in the other With the exception of the word "core". This
|
|
||||||
* might work even on groups when we don't have a CVE.
|
|
||||||
*
|
|
||||||
* @param left the dependency to test
|
* @param left the dependency to test
|
||||||
* @param right the dependency to test against
|
* @param right the dependency to test against
|
||||||
* @return a boolean indicating whether or not the left dependency should be
|
* @return a boolean indicating whether or not the left dependency should be
|
||||||
* considered the "core" version.
|
* considered the "core" version.
|
||||||
*/
|
*/
|
||||||
private boolean isCore(Dependency left, Dependency right) {
|
protected boolean isCore(Dependency left, Dependency right) {
|
||||||
final String leftName = left.getFileName().toLowerCase();
|
final String leftName = left.getFileName().toLowerCase();
|
||||||
final String rightName = right.getFileName().toLowerCase();
|
final String rightName = right.getFileName().toLowerCase();
|
||||||
|
|
||||||
if (rightName.contains("core") && !leftName.contains("core")) {
|
final boolean returnVal;
|
||||||
return false;
|
if (!rightName.matches(".*\\.(tar|tgz|gz|zip|ear|war).+") && leftName.matches(".*\\.(tar|tgz|gz|zip|ear|war).+")
|
||||||
} else if (!rightName.contains("core") && leftName.contains("core")) {
|
|| rightName.contains("core") && !leftName.contains("core")
|
||||||
return true;
|
|| rightName.contains("kernel") && !leftName.contains("kernel")) {
|
||||||
|
returnVal = false;
|
||||||
|
} else if (rightName.matches(".*\\.(tar|tgz|gz|zip|ear|war).+") && !leftName.matches(".*\\.(tar|tgz|gz|zip|ear|war).+")
|
||||||
|
|| !rightName.contains("core") && leftName.contains("core")
|
||||||
|
|| !rightName.contains("kernel") && leftName.contains("kernel")) {
|
||||||
|
returnVal = true;
|
||||||
} else {
|
} else {
|
||||||
//TODO should we be splitting the name on [-_(.\d)+] and seeing if the
|
/*
|
||||||
// parts are contained in the other side?
|
* considered splitting the names up and comparing the components,
|
||||||
if (leftName.length() > rightName.length()) {
|
* but decided that the file name length should be sufficient as the
|
||||||
|
* "core" component, if this follows a normal naming protocol should
|
||||||
|
* be shorter:
|
||||||
|
* axis2-saaj-1.4.1.jar
|
||||||
|
* axis2-1.4.1.jar <-----
|
||||||
|
* axis2-kernel-1.4.1.jar
|
||||||
|
*/
|
||||||
|
returnVal = leftName.length() <= rightName.length();
|
||||||
|
}
|
||||||
|
LOGGER.debug("IsCore={} ({}, {})", returnVal, left.getFileName(), right.getFileName());
|
||||||
|
return returnVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compares the SHA1 hashes of two dependencies to determine if they are
|
||||||
|
* equal.
|
||||||
|
*
|
||||||
|
* @param dependency1 a dependency object to compare
|
||||||
|
* @param dependency2 a dependency object to compare
|
||||||
|
* @return true if the sha1 hashes of the two dependencies match; otherwise
|
||||||
|
* false
|
||||||
|
*/
|
||||||
|
private boolean hashesMatch(Dependency dependency1, Dependency dependency2) {
|
||||||
|
if (dependency1 == null || dependency2 == null || dependency1.getSha1sum() == null || dependency2.getSha1sum() == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return dependency1.getSha1sum().equals(dependency2.getSha1sum());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines if the jar is shaded and the created pom.xml identified the
|
||||||
|
* same CPE as the jar - if so, the pom.xml dependency should be removed.
|
||||||
|
*
|
||||||
|
* @param dependency a dependency to check
|
||||||
|
* @param nextDependency another dependency to check
|
||||||
|
* @return true if on of the dependencies is a pom.xml and the identifiers
|
||||||
|
* between the two collections match; otherwise false
|
||||||
|
*/
|
||||||
|
private boolean isShadedJar(Dependency dependency, Dependency nextDependency) {
|
||||||
|
final String mainName = dependency.getFileName().toLowerCase();
|
||||||
|
final String nextName = nextDependency.getFileName().toLowerCase();
|
||||||
|
if (mainName.endsWith(".jar") && nextName.endsWith("pom.xml")) {
|
||||||
|
return dependency.getIdentifiers().containsAll(nextDependency.getIdentifiers());
|
||||||
|
} else if (nextName.endsWith(".jar") && mainName.endsWith("pom.xml")) {
|
||||||
|
return nextDependency.getIdentifiers().containsAll(dependency.getIdentifiers());
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines which path is shortest; if path lengths are equal then we use
|
||||||
|
* compareTo of the string method to determine if the first path is smaller.
|
||||||
|
*
|
||||||
|
* @param left the first path to compare
|
||||||
|
* @param right the second path to compare
|
||||||
|
* @return <code>true</code> if the leftPath is the shortest; otherwise
|
||||||
|
* <code>false</code>
|
||||||
|
*/
|
||||||
|
protected boolean firstPathIsShortest(String left, String right) {
|
||||||
|
if (left.contains("dctemp")) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
final String leftPath = left.replace('\\', '/');
|
||||||
|
final String rightPath = right.replace('\\', '/');
|
||||||
|
|
||||||
|
final int leftCount = countChar(leftPath, '/');
|
||||||
|
final int rightCount = countChar(rightPath, '/');
|
||||||
|
if (leftCount == rightCount) {
|
||||||
|
return leftPath.compareTo(rightPath) <= 0;
|
||||||
|
} else {
|
||||||
|
return leftCount < rightCount;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Counts the number of times the character is present in the string.
|
||||||
|
*
|
||||||
|
* @param string the string to count the characters in
|
||||||
|
* @param c the character to count
|
||||||
|
* @return the number of times the character is present in the string
|
||||||
|
*/
|
||||||
|
private int countChar(String string, char c) {
|
||||||
|
int count = 0;
|
||||||
|
final int max = string.length();
|
||||||
|
for (int i = 0; i < max; i++) {
|
||||||
|
if (c == string.charAt(i)) {
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the given file path is contained within a war or ear file.
|
||||||
|
*
|
||||||
|
* @param filePath the file path to check
|
||||||
|
* @return true if the path contains '.war\' or '.ear\'.
|
||||||
|
*/
|
||||||
|
private boolean containedInWar(String filePath) {
|
||||||
|
return filePath != null && filePath.matches(".*\\.(ear|war)[\\\\/].*");
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,283 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of dependency-check-core.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
* Copyright (c) 2012 Jeremy Long. All Rights Reserved.
|
||||||
|
*/
|
||||||
|
package org.owasp.dependencycheck.analyzer;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.ListIterator;
|
||||||
|
import java.util.Set;
|
||||||
|
import org.owasp.dependencycheck.Engine;
|
||||||
|
import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
|
||||||
|
import org.owasp.dependencycheck.dependency.Dependency;
|
||||||
|
import org.owasp.dependencycheck.utils.Settings;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* This analyzer will merge dependencies, created from different source, into a
|
||||||
|
* single dependency.</p>
|
||||||
|
*
|
||||||
|
* @author Jeremy Long
|
||||||
|
*/
|
||||||
|
public class DependencyMergingAnalyzer extends AbstractAnalyzer {
|
||||||
|
|
||||||
|
//<editor-fold defaultstate="collapsed" desc="Constants and Member Variables">
|
||||||
|
/**
|
||||||
|
* The Logger.
|
||||||
|
*/
|
||||||
|
private static final Logger LOGGER = LoggerFactory.getLogger(DependencyMergingAnalyzer.class);
|
||||||
|
/**
|
||||||
|
* a flag indicating if this analyzer has run. This analyzer only runs once.
|
||||||
|
*/
|
||||||
|
private boolean analyzed = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a flag indicating if this analyzer has run. This analyzer only
|
||||||
|
* runs once. Note this is currently only used in the unit tests.
|
||||||
|
*
|
||||||
|
* @return a flag indicating if this analyzer has run. This analyzer only
|
||||||
|
* runs once
|
||||||
|
*/
|
||||||
|
protected synchronized boolean getAnalyzed() {
|
||||||
|
return analyzed;
|
||||||
|
}
|
||||||
|
|
||||||
|
//</editor-fold>
|
||||||
|
//<editor-fold defaultstate="collapsed" desc="All standard implementation details of Analyzer">
|
||||||
|
/**
|
||||||
|
* The name of the analyzer.
|
||||||
|
*/
|
||||||
|
private static final String ANALYZER_NAME = "Dependency Merging Analyzer";
|
||||||
|
/**
|
||||||
|
* The phase that this analyzer is intended to run in.
|
||||||
|
*/
|
||||||
|
private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.POST_INFORMATION_COLLECTION;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the name of the analyzer.
|
||||||
|
*
|
||||||
|
* @return the name of the analyzer.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return ANALYZER_NAME;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the phase that the analyzer is intended to run in.
|
||||||
|
*
|
||||||
|
* @return the phase that the analyzer is intended to run in.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public AnalysisPhase getAnalysisPhase() {
|
||||||
|
return ANALYSIS_PHASE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Does not support parallel processing as it only runs once and then
|
||||||
|
* operates on <em>all</em> dependencies.
|
||||||
|
*
|
||||||
|
* @return whether or not parallel processing is enabled
|
||||||
|
* @see #analyze(Dependency, Engine)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean supportsParallelProcessing() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* Returns the setting key to determine if the analyzer is enabled.</p>
|
||||||
|
*
|
||||||
|
* @return the key for the analyzer's enabled property
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected String getAnalyzerEnabledSettingKey() {
|
||||||
|
return Settings.KEYS.ANALYZER_DEPENDENCY_MERGING_ENABLED;
|
||||||
|
}
|
||||||
|
//</editor-fold>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Analyzes a set of dependencies. If they have been found to be the same
|
||||||
|
* dependency created by more multiple FileTypeAnalyzers (i.e. a gemspec
|
||||||
|
* dependency and a dependency from the Bundle Audit Analyzer. The
|
||||||
|
* dependencies are then merged into a single reportable item.
|
||||||
|
*
|
||||||
|
* @param ignore this analyzer ignores the dependency being analyzed
|
||||||
|
* @param engine the engine that is scanning the dependencies
|
||||||
|
* @throws AnalysisException is thrown if there is an error reading the JAR
|
||||||
|
* file.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected synchronized void analyzeDependency(Dependency ignore, Engine engine) throws AnalysisException {
|
||||||
|
if (!analyzed) {
|
||||||
|
analyzed = true;
|
||||||
|
final Set<Dependency> dependenciesToRemove = new HashSet<>();
|
||||||
|
final ListIterator<Dependency> mainIterator = engine.getDependencies().listIterator();
|
||||||
|
//for (Dependency nextDependency : engine.getDependencies()) {
|
||||||
|
while (mainIterator.hasNext()) {
|
||||||
|
final Dependency dependency = mainIterator.next();
|
||||||
|
if (mainIterator.hasNext() && !dependenciesToRemove.contains(dependency)) {
|
||||||
|
final ListIterator<Dependency> subIterator = engine.getDependencies().listIterator(mainIterator.nextIndex());
|
||||||
|
while (subIterator.hasNext()) {
|
||||||
|
final Dependency nextDependency = subIterator.next();
|
||||||
|
Dependency main;
|
||||||
|
if ((main = getMainGemspecDependency(dependency, nextDependency)) != null) {
|
||||||
|
if (main == dependency) {
|
||||||
|
mergeDependencies(dependency, nextDependency, dependenciesToRemove);
|
||||||
|
} else {
|
||||||
|
mergeDependencies(nextDependency, dependency, dependenciesToRemove);
|
||||||
|
break; //since we merged into the next dependency - skip forward to the next in mainIterator
|
||||||
|
}
|
||||||
|
} else if ((main = getMainSwiftDependency(dependency, nextDependency)) != null) {
|
||||||
|
if (main == dependency) {
|
||||||
|
mergeDependencies(dependency, nextDependency, dependenciesToRemove);
|
||||||
|
} else {
|
||||||
|
mergeDependencies(nextDependency, dependency, dependenciesToRemove);
|
||||||
|
break; //since we merged into the next dependency - skip forward to the next in mainIterator
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//removing dependencies here as ensuring correctness and avoiding ConcurrentUpdateExceptions
|
||||||
|
// was difficult because of the inner iterator.
|
||||||
|
engine.getDependencies().removeAll(dependenciesToRemove);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds the relatedDependency to the dependency's related dependencies.
|
||||||
|
*
|
||||||
|
* @param dependency the main dependency
|
||||||
|
* @param relatedDependency a collection of dependencies to be removed from
|
||||||
|
* the main analysis loop, this is the source of dependencies to remove
|
||||||
|
* @param dependenciesToRemove a collection of dependencies that will be
|
||||||
|
* removed from the main analysis loop, this function adds to this
|
||||||
|
* collection
|
||||||
|
*/
|
||||||
|
private void mergeDependencies(final Dependency dependency, final Dependency relatedDependency, final Set<Dependency> dependenciesToRemove) {
|
||||||
|
LOGGER.debug("Merging '{}' into '{}'", relatedDependency.getFilePath(), dependency.getFilePath());
|
||||||
|
dependency.addRelatedDependency(relatedDependency);
|
||||||
|
dependency.getVendorEvidence().getEvidence().addAll(relatedDependency.getVendorEvidence().getEvidence());
|
||||||
|
dependency.getProductEvidence().getEvidence().addAll(relatedDependency.getProductEvidence().getEvidence());
|
||||||
|
dependency.getVersionEvidence().getEvidence().addAll(relatedDependency.getVersionEvidence().getEvidence());
|
||||||
|
|
||||||
|
final Iterator<Dependency> i = relatedDependency.getRelatedDependencies().iterator();
|
||||||
|
while (i.hasNext()) {
|
||||||
|
dependency.addRelatedDependency(i.next());
|
||||||
|
i.remove();
|
||||||
|
}
|
||||||
|
if (dependency.getSha1sum().equals(relatedDependency.getSha1sum())) {
|
||||||
|
dependency.addAllProjectReferences(relatedDependency.getProjectReferences());
|
||||||
|
}
|
||||||
|
dependenciesToRemove.add(relatedDependency);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bundling Ruby gems that are identified from different .gemspec files but
|
||||||
|
* denote the same package path. This happens when Ruby bundler installs an
|
||||||
|
* application's dependencies by running "bundle install".
|
||||||
|
*
|
||||||
|
* @param dependency1 dependency to compare
|
||||||
|
* @param dependency2 dependency to compare
|
||||||
|
* @return true if the the dependencies being analyzed appear to be the
|
||||||
|
* same; otherwise false
|
||||||
|
*/
|
||||||
|
private boolean isSameRubyGem(Dependency dependency1, Dependency dependency2) {
|
||||||
|
if (dependency1 == null || dependency2 == null
|
||||||
|
|| !dependency1.getFileName().endsWith(".gemspec")
|
||||||
|
|| !dependency2.getFileName().endsWith(".gemspec")
|
||||||
|
|| dependency1.getPackagePath() == null
|
||||||
|
|| dependency2.getPackagePath() == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return dependency1.getPackagePath().equalsIgnoreCase(dependency2.getPackagePath());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ruby gems installed by "bundle install" can have zero or more *.gemspec
|
||||||
|
* files, all of which have the same packagePath and should be grouped. If
|
||||||
|
* one of these gemspec is from <parent>/specifications/*.gemspec, because
|
||||||
|
* it is a stub with fully resolved gem meta-data created by Ruby bundler,
|
||||||
|
* this dependency should be the main one. Otherwise, use dependency2 as
|
||||||
|
* main.
|
||||||
|
*
|
||||||
|
* This method returns null if any dependency is not from *.gemspec, or the
|
||||||
|
* two do not have the same packagePath. In this case, they should not be
|
||||||
|
* grouped.
|
||||||
|
*
|
||||||
|
* @param dependency1 dependency to compare
|
||||||
|
* @param dependency2 dependency to compare
|
||||||
|
* @return the main dependency; or null if a gemspec is not included in the
|
||||||
|
* analysis
|
||||||
|
*/
|
||||||
|
private Dependency getMainGemspecDependency(Dependency dependency1, Dependency dependency2) {
|
||||||
|
if (isSameRubyGem(dependency1, dependency2)) {
|
||||||
|
final File lFile = dependency1.getActualFile();
|
||||||
|
final File left = lFile.getParentFile();
|
||||||
|
if (left != null && left.getName().equalsIgnoreCase("specifications")) {
|
||||||
|
return dependency1;
|
||||||
|
}
|
||||||
|
return dependency2;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bundling same swift dependencies with the same packagePath but identified
|
||||||
|
* by different file type analyzers.
|
||||||
|
*
|
||||||
|
* @param dependency1 dependency to test
|
||||||
|
* @param dependency2 dependency to test
|
||||||
|
* @return <code>true</code> if the dependencies appear to be the same;
|
||||||
|
* otherwise <code>false</code>
|
||||||
|
*/
|
||||||
|
private boolean isSameSwiftPackage(Dependency dependency1, Dependency dependency2) {
|
||||||
|
if (dependency1 == null || dependency2 == null
|
||||||
|
|| (!dependency1.getFileName().endsWith(".podspec")
|
||||||
|
&& !dependency1.getFileName().equals("Package.swift"))
|
||||||
|
|| (!dependency2.getFileName().endsWith(".podspec")
|
||||||
|
&& !dependency2.getFileName().equals("Package.swift"))
|
||||||
|
|| dependency1.getPackagePath() == null
|
||||||
|
|| dependency2.getPackagePath() == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return dependency1.getPackagePath().equalsIgnoreCase(dependency2.getPackagePath());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines which of the swift dependencies should be considered the
|
||||||
|
* primary.
|
||||||
|
*
|
||||||
|
* @param dependency1 the first swift dependency to compare
|
||||||
|
* @param dependency2 the second swift dependency to compare
|
||||||
|
* @return the primary swift dependency
|
||||||
|
*/
|
||||||
|
private Dependency getMainSwiftDependency(Dependency dependency1, Dependency dependency2) {
|
||||||
|
if (isSameSwiftPackage(dependency1, dependency2)) {
|
||||||
|
if (dependency1.getFileName().endsWith(".podspec")) {
|
||||||
|
return dependency1;
|
||||||
|
}
|
||||||
|
return dependency2;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of dependency-check-core.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
* Copyright (c) 2016 Jeremy Long. All Rights Reserved.
|
||||||
|
*/
|
||||||
|
package org.owasp.dependencycheck.analyzer;
|
||||||
|
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Annotation used to flag an analyzer as experimental.
|
||||||
|
*
|
||||||
|
* @author jeremy long
|
||||||
|
*/
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Target(ElementType.TYPE)
|
||||||
|
public @interface Experimental {
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,23 +1,23 @@
|
|||||||
/*
|
/*
|
||||||
* This file is part of dependency-check-core.
|
* This file is part of dependency-check-core.
|
||||||
*
|
*
|
||||||
* Dependency-check-core is free software: you can redistribute it and/or modify it
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* under the terms of the GNU General Public License as published by the Free
|
* you may not use this file except in compliance with the License.
|
||||||
* Software Foundation, either version 3 of the License, or (at your option) any
|
* You may obtain a copy of the License at
|
||||||
* later version.
|
|
||||||
*
|
*
|
||||||
* Dependency-check-core is distributed in the hope that it will be useful, but
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
|
||||||
* details.
|
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License along with
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* dependency-check-core. If not, see http://www.gnu.org/licenses/.
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
*
|
*
|
||||||
* Copyright (c) 2012 Jeremy Long. All Rights Reserved.
|
* Copyright (c) 2012 Jeremy Long. All Rights Reserved.
|
||||||
*/
|
*/
|
||||||
package org.owasp.dependencycheck.analyzer;
|
package org.owasp.dependencycheck.analyzer;
|
||||||
|
|
||||||
|
import java.io.FileFilter;
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
import java.net.URLEncoder;
|
import java.net.URLEncoder;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -26,28 +26,37 @@ import java.util.Iterator;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.ListIterator;
|
import java.util.ListIterator;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.logging.Level;
|
|
||||||
import java.util.logging.Logger;
|
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
import org.owasp.dependencycheck.Engine;
|
import org.owasp.dependencycheck.Engine;
|
||||||
|
import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
|
||||||
import org.owasp.dependencycheck.dependency.Dependency;
|
import org.owasp.dependencycheck.dependency.Dependency;
|
||||||
import org.owasp.dependencycheck.dependency.Identifier;
|
import org.owasp.dependencycheck.dependency.Identifier;
|
||||||
import org.owasp.dependencycheck.dependency.VulnerableSoftware;
|
import org.owasp.dependencycheck.dependency.VulnerableSoftware;
|
||||||
|
import org.owasp.dependencycheck.utils.FileFilterBuilder;
|
||||||
|
import org.owasp.dependencycheck.utils.Settings;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This analyzer attempts to remove some well known false positives -
|
* This analyzer attempts to remove some well known false positives -
|
||||||
* specifically regarding the java runtime.
|
* specifically regarding the java runtime.
|
||||||
*
|
*
|
||||||
* @author Jeremy Long (jeremy.long@owasp.org)
|
* @author Jeremy Long
|
||||||
*/
|
*/
|
||||||
public class FalsePositiveAnalyzer extends AbstractAnalyzer {
|
public class FalsePositiveAnalyzer extends AbstractAnalyzer {
|
||||||
|
|
||||||
//<editor-fold defaultstate="collapsed" desc="All standard implmentation details of Analyzer">
|
|
||||||
/**
|
/**
|
||||||
* The set of file extensions supported by this analyzer.
|
* The Logger.
|
||||||
*/
|
*/
|
||||||
private static final Set<String> EXTENSIONS = null;
|
private static final Logger LOGGER = LoggerFactory.getLogger(FalsePositiveAnalyzer.class);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The file filter used to find DLL and EXE.
|
||||||
|
*/
|
||||||
|
private static final FileFilter DLL_EXE_FILTER = FileFilterBuilder.newInstance().addExtensions("dll", "exe").build();
|
||||||
|
|
||||||
|
//<editor-fold defaultstate="collapsed" desc="All standard implementation details of Analyzer">
|
||||||
/**
|
/**
|
||||||
* The name of the analyzer.
|
* The name of the analyzer.
|
||||||
*/
|
*/
|
||||||
@@ -57,43 +66,36 @@ public class FalsePositiveAnalyzer extends AbstractAnalyzer {
|
|||||||
*/
|
*/
|
||||||
private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.POST_IDENTIFIER_ANALYSIS;
|
private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.POST_IDENTIFIER_ANALYSIS;
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a list of file EXTENSIONS supported by this analyzer.
|
|
||||||
*
|
|
||||||
* @return a list of file EXTENSIONS supported by this analyzer.
|
|
||||||
*/
|
|
||||||
public Set<String> getSupportedExtensions() {
|
|
||||||
return EXTENSIONS;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the name of the analyzer.
|
* Returns the name of the analyzer.
|
||||||
*
|
*
|
||||||
* @return the name of the analyzer.
|
* @return the name of the analyzer.
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return ANALYZER_NAME;
|
return ANALYZER_NAME;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns whether or not this analyzer can process the given extension.
|
|
||||||
*
|
|
||||||
* @param extension the file extension to test for support
|
|
||||||
* @return whether or not the specified file extension is supported by this
|
|
||||||
* analyzer.
|
|
||||||
*/
|
|
||||||
public boolean supportsExtension(String extension) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the phase that the analyzer is intended to run in.
|
* Returns the phase that the analyzer is intended to run in.
|
||||||
*
|
*
|
||||||
* @return the phase that the analyzer is intended to run in.
|
* @return the phase that the analyzer is intended to run in.
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public AnalysisPhase getAnalysisPhase() {
|
public AnalysisPhase getAnalysisPhase() {
|
||||||
return ANALYSIS_PHASE;
|
return ANALYSIS_PHASE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* Returns the setting key to determine if the analyzer is enabled.</p>
|
||||||
|
*
|
||||||
|
* @return the key for the analyzer's enabled property
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected String getAnalyzerEnabledSettingKey() {
|
||||||
|
return Settings.KEYS.ANALYZER_FALSE_POSITIVE_ENABLED;
|
||||||
|
}
|
||||||
//</editor-fold>
|
//</editor-fold>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -106,32 +108,72 @@ public class FalsePositiveAnalyzer extends AbstractAnalyzer {
|
|||||||
* file.
|
* file.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void analyze(Dependency dependency, Engine engine) throws AnalysisException {
|
protected void analyzeDependency(Dependency dependency, Engine engine) throws AnalysisException {
|
||||||
removeJreEntries(dependency);
|
removeJreEntries(dependency);
|
||||||
removeBadMatches(dependency);
|
removeBadMatches(dependency);
|
||||||
|
removeBadSpringMatches(dependency);
|
||||||
|
removeWrongVersionMatches(dependency);
|
||||||
removeSpuriousCPE(dependency);
|
removeSpuriousCPE(dependency);
|
||||||
|
removeDuplicativeEntriesFromJar(dependency, engine);
|
||||||
addFalseNegativeCPEs(dependency);
|
addFalseNegativeCPEs(dependency);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>Intended to remove spurious CPE entries. By spurious we mean
|
* Removes inaccurate matches on springframework CPEs.
|
||||||
* duplicate, less specific CPE entries.</p>
|
*
|
||||||
* <p>Example:</p>
|
* @param dependency the dependency to test for and remove known inaccurate
|
||||||
|
* CPE matches
|
||||||
|
*/
|
||||||
|
private void removeBadSpringMatches(Dependency dependency) {
|
||||||
|
String mustContain = null;
|
||||||
|
for (Identifier i : dependency.getIdentifiers()) {
|
||||||
|
if ("maven".contains(i.getType())
|
||||||
|
&& i.getValue() != null && i.getValue().startsWith("org.springframework.")) {
|
||||||
|
final int endPoint = i.getValue().indexOf(':', 19);
|
||||||
|
if (endPoint >= 0) {
|
||||||
|
mustContain = i.getValue().substring(19, endPoint).toLowerCase();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (mustContain
|
||||||
|
!= null) {
|
||||||
|
final Iterator<Identifier> itr = dependency.getIdentifiers().iterator();
|
||||||
|
while (itr.hasNext()) {
|
||||||
|
final Identifier i = itr.next();
|
||||||
|
if ("cpe".contains(i.getType())
|
||||||
|
&& i.getValue() != null
|
||||||
|
&& i.getValue().startsWith("cpe:/a:springsource:")
|
||||||
|
&& !i.getValue().toLowerCase().contains(mustContain)) {
|
||||||
|
itr.remove();
|
||||||
|
//dependency.getIdentifiers().remove(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* Intended to remove spurious CPE entries. By spurious we mean duplicate,
|
||||||
|
* less specific CPE entries.</p>
|
||||||
|
* <p>
|
||||||
|
* Example:</p>
|
||||||
* <code>
|
* <code>
|
||||||
* cpe:/a:some-vendor:some-product
|
* cpe:/a:some-vendor:some-product
|
||||||
* cpe:/a:some-vendor:some-product:1.5
|
* cpe:/a:some-vendor:some-product:1.5
|
||||||
* cpe:/a:some-vendor:some-product:1.5.2
|
* cpe:/a:some-vendor:some-product:1.5.2
|
||||||
* </code>
|
* </code>
|
||||||
* <p>Should be trimmed to:</p>
|
* <p>
|
||||||
|
* Should be trimmed to:</p>
|
||||||
* <code>
|
* <code>
|
||||||
* cpe:/a:some-vendor:some-product:1.5.2
|
* cpe:/a:some-vendor:some-product:1.5.2
|
||||||
* </code>
|
* </code>
|
||||||
*
|
*
|
||||||
* @param dependency the dependency being analyzed
|
* @param dependency the dependency being analyzed
|
||||||
*/
|
*/
|
||||||
|
@SuppressWarnings("null")
|
||||||
private void removeSpuriousCPE(Dependency dependency) {
|
private void removeSpuriousCPE(Dependency dependency) {
|
||||||
final List<Identifier> ids = new ArrayList<Identifier>();
|
final List<Identifier> ids = new ArrayList<>(dependency.getIdentifiers());
|
||||||
ids.addAll(dependency.getIdentifiers());
|
|
||||||
Collections.sort(ids);
|
Collections.sort(ids);
|
||||||
final ListIterator<Identifier> mainItr = ids.listIterator();
|
final ListIterator<Identifier> mainItr = ids.listIterator();
|
||||||
while (mainItr.hasNext()) {
|
while (mainItr.hasNext()) {
|
||||||
@@ -155,8 +197,7 @@ public class FalsePositiveAnalyzer extends AbstractAnalyzer {
|
|||||||
final String nextVersion = nextCpe.getVersion();
|
final String nextVersion = nextCpe.getVersion();
|
||||||
if (currentVersion == null && nextVersion == null) {
|
if (currentVersion == null && nextVersion == null) {
|
||||||
//how did we get here?
|
//how did we get here?
|
||||||
Logger.getLogger(FalsePositiveAnalyzer.class
|
LOGGER.debug("currentVersion and nextVersion are both null?");
|
||||||
.getName()).log(Level.FINE, "currentVersion and nextVersion are both null?");
|
|
||||||
} else if (currentVersion == null && nextVersion != null) {
|
} else if (currentVersion == null && nextVersion != null) {
|
||||||
dependency.getIdentifiers().remove(currentId);
|
dependency.getIdentifiers().remove(currentId);
|
||||||
} else if (nextVersion == null && currentVersion != null) {
|
} else if (nextVersion == null && currentVersion != null) {
|
||||||
@@ -165,8 +206,7 @@ public class FalsePositiveAnalyzer extends AbstractAnalyzer {
|
|||||||
if (nextVersion.startsWith(currentVersion) || "-".equals(currentVersion)) {
|
if (nextVersion.startsWith(currentVersion) || "-".equals(currentVersion)) {
|
||||||
dependency.getIdentifiers().remove(currentId);
|
dependency.getIdentifiers().remove(currentId);
|
||||||
}
|
}
|
||||||
} else {
|
} else if (currentVersion.startsWith(nextVersion) || "-".equals(nextVersion)) {
|
||||||
if (currentVersion.startsWith(nextVersion) || "-".equals(nextVersion)) {
|
|
||||||
dependency.getIdentifiers().remove(nextId);
|
dependency.getIdentifiers().remove(nextId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -174,18 +214,27 @@ public class FalsePositiveAnalyzer extends AbstractAnalyzer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
/**
|
/**
|
||||||
* Regex to identify core java libraries and a few other commonly
|
* Regex to identify core java libraries and a few other commonly
|
||||||
* misidentified ones.
|
* misidentified ones.
|
||||||
*/
|
*/
|
||||||
public static final Pattern CORE_JAVA = Pattern.compile("^cpe:/a:(sun|oracle|ibm):(j2[ems]e|"
|
public static final Pattern CORE_JAVA = Pattern.compile("^cpe:/a:(sun|oracle|ibm):(j2[ems]e|"
|
||||||
+ "java(_platfrom_micro_edition|_runtime_environment|_se|virtual_machine|se_development_kit|fx)?|"
|
+ "java(_platform_micro_edition|_runtime_environment|_se|virtual_machine|se_development_kit|fx)?|"
|
||||||
+ "jdk|jre|jsf|jsse)($|:.*)");
|
+ "jdk|jre|jsse)($|:.*)");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Regex to identify core jsf libraries.
|
||||||
|
*/
|
||||||
|
public static final Pattern CORE_JAVA_JSF = Pattern.compile("^cpe:/a:(sun|oracle|ibm):jsf($|:.*)");
|
||||||
/**
|
/**
|
||||||
* Regex to identify core java library files. This is currently incomplete.
|
* Regex to identify core java library files. This is currently incomplete.
|
||||||
*/
|
*/
|
||||||
public static final Pattern CORE_FILES = Pattern.compile("^((alt[-])?rt|jsf[-].*|jsse|jfxrt|jfr|jce|javaws|deploy|charsets)\\.jar$");
|
public static final Pattern CORE_FILES = Pattern.compile("(^|/)((alt[-])?rt|jsse|jfxrt|jfr|jce|javaws|deploy|charsets)\\.jar$");
|
||||||
|
/**
|
||||||
|
* Regex to identify core jsf java library files. This is currently
|
||||||
|
* incomplete.
|
||||||
|
*/
|
||||||
|
public static final Pattern CORE_JSF_FILES = Pattern.compile("(^|/)jsf[-][^/]*\\.jar$");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes any CPE entries for the JDK/JRE unless the filename ends with
|
* Removes any CPE entries for the JDK/JRE unless the filename ends with
|
||||||
@@ -203,27 +252,11 @@ public class FalsePositiveAnalyzer extends AbstractAnalyzer {
|
|||||||
if (coreCPE.matches() && !coreFiles.matches()) {
|
if (coreCPE.matches() && !coreFiles.matches()) {
|
||||||
itr.remove();
|
itr.remove();
|
||||||
}
|
}
|
||||||
|
final Matcher coreJsfCPE = CORE_JAVA_JSF.matcher(i.getValue());
|
||||||
//replacecd with the regex above.
|
final Matcher coreJsfFiles = CORE_JSF_FILES.matcher(dependency.getFileName());
|
||||||
// if (("cpe:/a:sun:java".equals(i.getValue())
|
if (coreJsfCPE.matches() && !coreJsfFiles.matches()) {
|
||||||
// || "cpe:/a:oracle:java".equals(i.getValue())
|
itr.remove();
|
||||||
// || "cpe:/a:ibm:java".equals(i.getValue())
|
}
|
||||||
// || "cpe:/a:sun:j2se".equals(i.getValue())
|
|
||||||
// || "cpe:/a:oracle:j2se".equals(i.getValue())
|
|
||||||
// || i.getValue().startsWith("cpe:/a:sun:java:")
|
|
||||||
// || i.getValue().startsWith("cpe:/a:sun:j2se:")
|
|
||||||
// || i.getValue().startsWith("cpe:/a:sun:java:jre")
|
|
||||||
// || i.getValue().startsWith("cpe:/a:sun:java:jdk")
|
|
||||||
// || i.getValue().startsWith("cpe:/a:sun:java_se")
|
|
||||||
// || i.getValue().startsWith("cpe:/a:oracle:java_se")
|
|
||||||
// || i.getValue().startsWith("cpe:/a:oracle:java:")
|
|
||||||
// || i.getValue().startsWith("cpe:/a:oracle:j2se:")
|
|
||||||
// || i.getValue().startsWith("cpe:/a:oracle:jre")
|
|
||||||
// || i.getValue().startsWith("cpe:/a:oracle:jdk")
|
|
||||||
// || i.getValue().startsWith("cpe:/a:ibm:java:"))
|
|
||||||
// && !dependency.getFileName().toLowerCase().endsWith("rt.jar")) {
|
|
||||||
// itr.remove();
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -242,7 +275,7 @@ public class FalsePositiveAnalyzer extends AbstractAnalyzer {
|
|||||||
try {
|
try {
|
||||||
cpe.parseName(value);
|
cpe.parseName(value);
|
||||||
} catch (UnsupportedEncodingException ex) {
|
} catch (UnsupportedEncodingException ex) {
|
||||||
Logger.getLogger(FalsePositiveAnalyzer.class.getName()).log(Level.FINEST, null, ex);
|
LOGGER.trace("", ex);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return cpe;
|
return cpe;
|
||||||
@@ -264,28 +297,96 @@ public class FalsePositiveAnalyzer extends AbstractAnalyzer {
|
|||||||
* found based on LOW confidence evidence should have a different CPE type? (this
|
* found based on LOW confidence evidence should have a different CPE type? (this
|
||||||
* might be a better solution then just removing the URL for "best-guess" matches).
|
* might be a better solution then just removing the URL for "best-guess" matches).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
//Set<Evidence> groupId = dependency.getVendorEvidence().getEvidence("pom", "groupid");
|
//Set<Evidence> groupId = dependency.getVendorEvidence().getEvidence("pom", "groupid");
|
||||||
//Set<Evidence> artifactId = dependency.getVendorEvidence().getEvidence("pom", "artifactid");
|
//Set<Evidence> artifactId = dependency.getVendorEvidence().getEvidence("pom", "artifactid");
|
||||||
|
|
||||||
while (itr.hasNext()) {
|
while (itr.hasNext()) {
|
||||||
final Identifier i = itr.next();
|
final Identifier i = itr.next();
|
||||||
//TODO move this startswith expression to a configuration file?
|
//TODO move this startsWith expression to the base suppression file
|
||||||
if ("cpe".equals(i.getType())) {
|
if ("cpe".equals(i.getType())) {
|
||||||
if ((i.getValue().matches(".*c\\+\\+.*")
|
if ((i.getValue().matches(".*c\\+\\+.*")
|
||||||
|| i.getValue().startsWith("cpe:/a:jquery:jquery")
|
|
||||||
|| i.getValue().startsWith("cpe:/a:prototypejs:prototype")
|
|
||||||
|| i.getValue().startsWith("cpe:/a:yahoo:yui")
|
|
||||||
|| i.getValue().startsWith("cpe:/a:file:file")
|
|| i.getValue().startsWith("cpe:/a:file:file")
|
||||||
|| i.getValue().startsWith("cpe:/a:mozilla:mozilla")
|
|| i.getValue().startsWith("cpe:/a:mozilla:mozilla")
|
||||||
|| i.getValue().startsWith("cpe:/a:cvs:cvs")
|
|| i.getValue().startsWith("cpe:/a:cvs:cvs")
|
||||||
|| i.getValue().startsWith("cpe:/a:ftp:ftp")
|
|| i.getValue().startsWith("cpe:/a:ftp:ftp")
|
||||||
|| i.getValue().startsWith("cpe:/a:ssh:ssh"))
|
|| i.getValue().startsWith("cpe:/a:tcp:tcp")
|
||||||
&& dependency.getFileName().toLowerCase().endsWith(".jar")) {
|
|| i.getValue().startsWith("cpe:/a:ssh:ssh")
|
||||||
|
|| i.getValue().startsWith("cpe:/a:lookup:lookup"))
|
||||||
|
&& (dependency.getFileName().toLowerCase().endsWith(".jar")
|
||||||
|
|| dependency.getFileName().toLowerCase().endsWith("pom.xml")
|
||||||
|
|| dependency.getFileName().toLowerCase().endsWith(".dll")
|
||||||
|
|| dependency.getFileName().toLowerCase().endsWith(".exe")
|
||||||
|
|| dependency.getFileName().toLowerCase().endsWith(".nuspec")
|
||||||
|
|| dependency.getFileName().toLowerCase().endsWith(".zip")
|
||||||
|
|| dependency.getFileName().toLowerCase().endsWith(".sar")
|
||||||
|
|| dependency.getFileName().toLowerCase().endsWith(".apk")
|
||||||
|
|| dependency.getFileName().toLowerCase().endsWith(".tar")
|
||||||
|
|| dependency.getFileName().toLowerCase().endsWith(".gz")
|
||||||
|
|| dependency.getFileName().toLowerCase().endsWith(".tgz")
|
||||||
|
|| dependency.getFileName().toLowerCase().endsWith(".ear")
|
||||||
|
|| dependency.getFileName().toLowerCase().endsWith(".war"))) {
|
||||||
|
itr.remove();
|
||||||
|
} else if ((i.getValue().startsWith("cpe:/a:jquery:jquery")
|
||||||
|
|| i.getValue().startsWith("cpe:/a:prototypejs:prototype")
|
||||||
|
|| i.getValue().startsWith("cpe:/a:yahoo:yui"))
|
||||||
|
&& (dependency.getFileName().toLowerCase().endsWith(".jar")
|
||||||
|
|| dependency.getFileName().toLowerCase().endsWith("pom.xml")
|
||||||
|
|| dependency.getFileName().toLowerCase().endsWith(".dll")
|
||||||
|
|| dependency.getFileName().toLowerCase().endsWith(".exe"))) {
|
||||||
|
itr.remove();
|
||||||
|
} else if ((i.getValue().startsWith("cpe:/a:microsoft:excel")
|
||||||
|
|| i.getValue().startsWith("cpe:/a:microsoft:word")
|
||||||
|
|| i.getValue().startsWith("cpe:/a:microsoft:visio")
|
||||||
|
|| i.getValue().startsWith("cpe:/a:microsoft:powerpoint")
|
||||||
|
|| i.getValue().startsWith("cpe:/a:microsoft:office")
|
||||||
|
|| i.getValue().startsWith("cpe:/a:core_ftp:core_ftp"))
|
||||||
|
&& (dependency.getFileName().toLowerCase().endsWith(".jar")
|
||||||
|
|| dependency.getFileName().toLowerCase().endsWith(".ear")
|
||||||
|
|| dependency.getFileName().toLowerCase().endsWith(".war")
|
||||||
|
|| dependency.getFileName().toLowerCase().endsWith("pom.xml"))) {
|
||||||
itr.remove();
|
itr.remove();
|
||||||
} else if (i.getValue().startsWith("cpe:/a:apache:maven")
|
} else if (i.getValue().startsWith("cpe:/a:apache:maven")
|
||||||
&& !dependency.getFileName().toLowerCase().matches("maven-core-[\\d\\.]+\\.jar")) {
|
&& !dependency.getFileName().toLowerCase().matches("maven-core-[\\d\\.]+\\.jar")) {
|
||||||
itr.remove();
|
itr.remove();
|
||||||
|
} else if (i.getValue().startsWith("cpe:/a:m-core:m-core")
|
||||||
|
&& !dependency.getEvidenceUsed().containsUsedString("m-core")) {
|
||||||
|
itr.remove();
|
||||||
|
} else if (i.getValue().startsWith("cpe:/a:jboss:jboss")
|
||||||
|
&& !dependency.getFileName().toLowerCase().matches("jboss-?[\\d\\.-]+(GA)?\\.jar")) {
|
||||||
|
itr.remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes CPE matches for the wrong version of a dependency. Currently,
|
||||||
|
* this only covers Axis 1 & 2.
|
||||||
|
*
|
||||||
|
* @param dependency the dependency to analyze
|
||||||
|
*/
|
||||||
|
private void removeWrongVersionMatches(Dependency dependency) {
|
||||||
|
final Set<Identifier> identifiers = dependency.getIdentifiers();
|
||||||
|
final Iterator<Identifier> itr = identifiers.iterator();
|
||||||
|
|
||||||
|
final String fileName = dependency.getFileName();
|
||||||
|
if (fileName != null && fileName.contains("axis2")) {
|
||||||
|
while (itr.hasNext()) {
|
||||||
|
final Identifier i = itr.next();
|
||||||
|
if ("cpe".equals(i.getType())) {
|
||||||
|
final String cpe = i.getValue();
|
||||||
|
if (cpe != null && (cpe.startsWith("cpe:/a:apache:axis:") || "cpe:/a:apache:axis".equals(cpe))) {
|
||||||
|
itr.remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (fileName != null && fileName.contains("axis")) {
|
||||||
|
while (itr.hasNext()) {
|
||||||
|
final Identifier i = itr.next();
|
||||||
|
if ("cpe".equals(i.getType())) {
|
||||||
|
final String cpe = i.getValue();
|
||||||
|
if (cpe != null && (cpe.startsWith("cpe:/a:apache:axis2:") || "cpe:/a:apache:axis2".equals(cpe))) {
|
||||||
|
itr.remove();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -300,36 +401,108 @@ public class FalsePositiveAnalyzer extends AbstractAnalyzer {
|
|||||||
* @param dependency the dependency being analyzed
|
* @param dependency the dependency being analyzed
|
||||||
*/
|
*/
|
||||||
private void addFalseNegativeCPEs(Dependency dependency) {
|
private void addFalseNegativeCPEs(Dependency dependency) {
|
||||||
final Iterator<Identifier> itr = dependency.getIdentifiers().iterator();
|
//TODO move this to the hint analyzer
|
||||||
while (itr.hasNext()) {
|
for (final Identifier identifier : dependency.getIdentifiers()) {
|
||||||
final Identifier i = itr.next();
|
if ("cpe".equals(identifier.getType()) && identifier.getValue() != null
|
||||||
if ("cpe".equals(i.getType()) && i.getValue() != null
|
&& (identifier.getValue().startsWith("cpe:/a:oracle:opensso:")
|
||||||
&& (i.getValue().startsWith("cpe:/a:oracle:opensso:")
|
|| identifier.getValue().startsWith("cpe:/a:oracle:opensso_enterprise:")
|
||||||
|| i.getValue().startsWith("cpe:/a:oracle:opensso_enterprise:")
|
|| identifier.getValue().startsWith("cpe:/a:sun:opensso_enterprise:")
|
||||||
|| i.getValue().startsWith("cpe:/a:sun:opensso_enterprise:")
|
|| identifier.getValue().startsWith("cpe:/a:sun:opensso:"))) {
|
||||||
|| i.getValue().startsWith("cpe:/a:sun:opensso:"))) {
|
final String newCpe = String.format("cpe:/a:sun:opensso_enterprise:%s", identifier.getValue().substring(22));
|
||||||
final String newCpe = String.format("cpe:/a:sun:opensso_enterprise:%s", i.getValue().substring(22));
|
final String newCpe2 = String.format("cpe:/a:oracle:opensso_enterprise:%s", identifier.getValue().substring(22));
|
||||||
final String newCpe2 = String.format("cpe:/a:oracle:opensso_enterprise:%s", i.getValue().substring(22));
|
final String newCpe3 = String.format("cpe:/a:sun:opensso:%s", identifier.getValue().substring(22));
|
||||||
final String newCpe3 = String.format("cpe:/a:sun:opensso:%s", i.getValue().substring(22));
|
final String newCpe4 = String.format("cpe:/a:oracle:opensso:%s", identifier.getValue().substring(22));
|
||||||
final String newCpe4 = String.format("cpe:/a:oracle:opensso:%s", i.getValue().substring(22));
|
|
||||||
try {
|
try {
|
||||||
dependency.addIdentifier("cpe",
|
dependency.addIdentifier("cpe",
|
||||||
newCpe,
|
newCpe,
|
||||||
String.format("http://web.nvd.nist.gov/view/vuln/search?cpe=%s", URLEncoder.encode(newCpe, "UTF-8")));
|
String.format(CPEAnalyzer.NVD_SEARCH_URL, URLEncoder.encode(newCpe, "UTF-8")));
|
||||||
dependency.addIdentifier("cpe",
|
dependency.addIdentifier("cpe",
|
||||||
newCpe2,
|
newCpe2,
|
||||||
String.format("http://web.nvd.nist.gov/view/vuln/search?cpe=%s", URLEncoder.encode(newCpe2, "UTF-8")));
|
String.format(CPEAnalyzer.NVD_SEARCH_URL, URLEncoder.encode(newCpe2, "UTF-8")));
|
||||||
dependency.addIdentifier("cpe",
|
dependency.addIdentifier("cpe",
|
||||||
newCpe3,
|
newCpe3,
|
||||||
String.format("http://web.nvd.nist.gov/view/vuln/search?cpe=%s", URLEncoder.encode(newCpe3, "UTF-8")));
|
String.format(CPEAnalyzer.NVD_SEARCH_URL, URLEncoder.encode(newCpe3, "UTF-8")));
|
||||||
dependency.addIdentifier("cpe",
|
dependency.addIdentifier("cpe",
|
||||||
newCpe4,
|
newCpe4,
|
||||||
String.format("http://web.nvd.nist.gov/view/vuln/search?cpe=%s", URLEncoder.encode(newCpe4, "UTF-8")));
|
String.format(CPEAnalyzer.NVD_SEARCH_URL, URLEncoder.encode(newCpe4, "UTF-8")));
|
||||||
} catch (UnsupportedEncodingException ex) {
|
} catch (UnsupportedEncodingException ex) {
|
||||||
Logger.getLogger(FalsePositiveAnalyzer.class
|
LOGGER.debug("", ex);
|
||||||
.getName()).log(Level.FINE, null, ex);
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes duplicate entries identified that are contained within JAR files.
|
||||||
|
* These occasionally crop up due to POM entries or other types of files
|
||||||
|
* (such as DLLs and EXEs) being contained within the JAR.
|
||||||
|
*
|
||||||
|
* @param dependency the dependency that might be a duplicate
|
||||||
|
* @param engine the engine used to scan all dependencies
|
||||||
|
*/
|
||||||
|
private synchronized void removeDuplicativeEntriesFromJar(Dependency dependency, Engine engine) {
|
||||||
|
if (dependency.getFileName().toLowerCase().endsWith("pom.xml")
|
||||||
|
|| DLL_EXE_FILTER.accept(dependency.getActualFile())) {
|
||||||
|
String parentPath = dependency.getFilePath().toLowerCase();
|
||||||
|
if (parentPath.contains(".jar")) {
|
||||||
|
parentPath = parentPath.substring(0, parentPath.indexOf(".jar") + 4);
|
||||||
|
final List<Dependency> dependencies = engine.getDependencies();
|
||||||
|
final Dependency parent = findDependency(parentPath, dependencies);
|
||||||
|
if (parent != null) {
|
||||||
|
boolean remove = false;
|
||||||
|
for (Identifier i : dependency.getIdentifiers()) {
|
||||||
|
if ("cpe".equals(i.getType())) {
|
||||||
|
final String trimmedCPE = trimCpeToVendor(i.getValue());
|
||||||
|
for (Identifier parentId : parent.getIdentifiers()) {
|
||||||
|
if ("cpe".equals(parentId.getType()) && parentId.getValue().startsWith(trimmedCPE)) {
|
||||||
|
remove |= true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!remove) { //we can escape early
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (remove) {
|
||||||
|
dependencies.remove(dependency);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves a given dependency, based on a given path, from a list of
|
||||||
|
* dependencies.
|
||||||
|
*
|
||||||
|
* @param dependencyPath the path of the dependency to return
|
||||||
|
* @param dependencies the collection of dependencies to search
|
||||||
|
* @return the dependency object for the given path, otherwise null
|
||||||
|
*/
|
||||||
|
private Dependency findDependency(String dependencyPath, List<Dependency> dependencies) {
|
||||||
|
for (Dependency d : dependencies) {
|
||||||
|
if (d.getFilePath().equalsIgnoreCase(dependencyPath)) {
|
||||||
|
return d;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Takes a full CPE and returns the CPE trimmed to include only vendor and
|
||||||
|
* product.
|
||||||
|
*
|
||||||
|
* @param value the CPE value to trim
|
||||||
|
* @return a CPE value that only includes the vendor and product
|
||||||
|
*/
|
||||||
|
private String trimCpeToVendor(String value) {
|
||||||
|
//cpe:/a:jruby:jruby:1.0.8
|
||||||
|
final int pos1 = value.indexOf(':', 7); //right of vendor
|
||||||
|
final int pos2 = value.indexOf(':', pos1 + 1); //right of product
|
||||||
|
if (pos2 < 0) {
|
||||||
|
return value;
|
||||||
|
} else {
|
||||||
|
return value.substring(0, pos2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,40 +1,43 @@
|
|||||||
/*
|
/*
|
||||||
* This file is part of dependency-check-core.
|
* This file is part of dependency-check-core.
|
||||||
*
|
*
|
||||||
* Dependency-check-core is free software: you can redistribute it and/or modify it
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* under the terms of the GNU General Public License as published by the Free
|
* you may not use this file except in compliance with the License.
|
||||||
* Software Foundation, either version 3 of the License, or (at your option) any
|
* You may obtain a copy of the License at
|
||||||
* later version.
|
|
||||||
*
|
*
|
||||||
* Dependency-check-core is distributed in the hope that it will be useful, but
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
|
||||||
* details.
|
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License along with
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* dependency-check-core. If not, see http://www.gnu.org/licenses/.
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
*
|
*
|
||||||
* Copyright (c) 2012 Jeremy Long. All Rights Reserved.
|
* Copyright (c) 2012 Jeremy Long. All Rights Reserved.
|
||||||
*/
|
*/
|
||||||
package org.owasp.dependencycheck.analyzer;
|
package org.owasp.dependencycheck.analyzer;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import org.owasp.dependencycheck.dependency.Dependency;
|
|
||||||
import org.owasp.dependencycheck.dependency.Evidence;
|
import org.apache.commons.io.FilenameUtils;
|
||||||
import java.util.Set;
|
import org.apache.commons.io.filefilter.NameFileFilter;
|
||||||
import org.owasp.dependencycheck.Engine;
|
import org.owasp.dependencycheck.Engine;
|
||||||
|
import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
|
||||||
|
import org.owasp.dependencycheck.dependency.Confidence;
|
||||||
|
import org.owasp.dependencycheck.dependency.Dependency;
|
||||||
import org.owasp.dependencycheck.utils.DependencyVersion;
|
import org.owasp.dependencycheck.utils.DependencyVersion;
|
||||||
import org.owasp.dependencycheck.utils.DependencyVersionUtil;
|
import org.owasp.dependencycheck.utils.DependencyVersionUtil;
|
||||||
|
import org.owasp.dependencycheck.utils.Settings;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* Takes a dependency and analyzes the filename and determines the hashes.
|
* Takes a dependency and analyzes the filename and determines the hashes.
|
||||||
*
|
*
|
||||||
* @author Jeremy Long (jeremy.long@owasp.org)
|
* @author Jeremy Long
|
||||||
*/
|
*/
|
||||||
public class FileNameAnalyzer extends AbstractAnalyzer implements Analyzer {
|
public class FileNameAnalyzer extends AbstractAnalyzer {
|
||||||
|
|
||||||
//<editor-fold defaultstate="collapsed" desc="All standard implmentation details of Analyzer">
|
//<editor-fold defaultstate="collapsed" desc="All standard implementation details of Analyzer">
|
||||||
/**
|
/**
|
||||||
* The name of the analyzer.
|
* The name of the analyzer.
|
||||||
*/
|
*/
|
||||||
@@ -43,50 +46,48 @@ public class FileNameAnalyzer extends AbstractAnalyzer implements Analyzer {
|
|||||||
* The phase that this analyzer is intended to run in.
|
* The phase that this analyzer is intended to run in.
|
||||||
*/
|
*/
|
||||||
private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION;
|
private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION;
|
||||||
/**
|
|
||||||
* The set of file extensions supported by this analyzer.
|
|
||||||
*/
|
|
||||||
private static final Set<String> EXTENSIONS = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a list of file EXTENSIONS supported by this analyzer.
|
|
||||||
*
|
|
||||||
* @return a list of file EXTENSIONS supported by this analyzer.
|
|
||||||
*/
|
|
||||||
public Set<String> getSupportedExtensions() {
|
|
||||||
return EXTENSIONS;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the name of the analyzer.
|
* Returns the name of the analyzer.
|
||||||
*
|
*
|
||||||
* @return the name of the analyzer.
|
* @return the name of the analyzer.
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return ANALYZER_NAME;
|
return ANALYZER_NAME;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns whether or not this analyzer can process the given extension.
|
|
||||||
*
|
|
||||||
* @param extension the file extension to test for support.
|
|
||||||
* @return whether or not the specified file extension is supported by this
|
|
||||||
* analyzer.
|
|
||||||
*/
|
|
||||||
public boolean supportsExtension(String extension) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the phase that the analyzer is intended to run in.
|
* Returns the phase that the analyzer is intended to run in.
|
||||||
*
|
*
|
||||||
* @return the phase that the analyzer is intended to run in.
|
* @return the phase that the analyzer is intended to run in.
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public AnalysisPhase getAnalysisPhase() {
|
public AnalysisPhase getAnalysisPhase() {
|
||||||
return ANALYSIS_PHASE;
|
return ANALYSIS_PHASE;
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* Returns the setting key to determine if the analyzer is enabled.</p>
|
||||||
|
*
|
||||||
|
* @return the key for the analyzer's enabled property
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected String getAnalyzerEnabledSettingKey() {
|
||||||
|
return Settings.KEYS.ANALYZER_FILE_NAME_ENABLED;
|
||||||
|
}
|
||||||
//</editor-fold>
|
//</editor-fold>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Python init files
|
||||||
|
*/
|
||||||
|
//CSOFF: WhitespaceAfter
|
||||||
|
private static final NameFileFilter IGNORED_FILES = new NameFileFilter(new String[]{
|
||||||
|
"__init__.py",
|
||||||
|
"__init__.pyc",
|
||||||
|
"__init__.pyo",});
|
||||||
|
//CSON: WhitespaceAfter
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Collects information about the file name.
|
* Collects information about the file name.
|
||||||
*
|
*
|
||||||
@@ -96,38 +97,35 @@ public class FileNameAnalyzer extends AbstractAnalyzer implements Analyzer {
|
|||||||
* file.
|
* file.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void analyze(Dependency dependency, Engine engine) throws AnalysisException {
|
protected void analyzeDependency(Dependency dependency, Engine engine) throws AnalysisException {
|
||||||
|
|
||||||
//strip any path information that may get added by ArchiveAnalyzer, etc.
|
//strip any path information that may get added by ArchiveAnalyzer, etc.
|
||||||
final File f = new File(dependency.getFileName());
|
final File f = dependency.getActualFile();
|
||||||
String fileName = f.getName();
|
final String fileName = FilenameUtils.removeExtension(f.getName());
|
||||||
|
|
||||||
//remove file extension
|
|
||||||
final int pos = fileName.lastIndexOf(".");
|
|
||||||
if (pos > 0) {
|
|
||||||
fileName = fileName.substring(0, pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
//add version evidence
|
//add version evidence
|
||||||
final DependencyVersion version = DependencyVersionUtil.parseVersion(fileName);
|
final DependencyVersion version = DependencyVersionUtil.parseVersion(fileName);
|
||||||
|
final String packageName = DependencyVersionUtil.parsePreVersion(fileName);
|
||||||
if (version != null) {
|
if (version != null) {
|
||||||
|
// If the version number is just a number like 2 or 23, reduce the confidence
|
||||||
|
// a shade. This should hopefully correct for cases like log4j.jar or
|
||||||
|
// struts2-core.jar
|
||||||
|
if (version.getVersionParts() == null || version.getVersionParts().size() < 2) {
|
||||||
|
dependency.getVersionEvidence().addEvidence("file", "version",
|
||||||
|
version.toString(), Confidence.MEDIUM);
|
||||||
|
} else {
|
||||||
|
dependency.getVersionEvidence().addEvidence("file", "version",
|
||||||
|
version.toString(), Confidence.HIGHEST);
|
||||||
|
}
|
||||||
dependency.getVersionEvidence().addEvidence("file", "name",
|
dependency.getVersionEvidence().addEvidence("file", "name",
|
||||||
version.toString(), Evidence.Confidence.HIGHEST);
|
packageName, Confidence.MEDIUM);
|
||||||
dependency.getVersionEvidence().addEvidence("file", "name",
|
|
||||||
fileName, Evidence.Confidence.MEDIUM);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//add as vendor and product evidence
|
if (!IGNORED_FILES.accept(f)) {
|
||||||
if (fileName.contains("-")) {
|
|
||||||
dependency.getProductEvidence().addEvidence("file", "name",
|
dependency.getProductEvidence().addEvidence("file", "name",
|
||||||
fileName, Evidence.Confidence.HIGHEST);
|
packageName, Confidence.HIGH);
|
||||||
dependency.getVendorEvidence().addEvidence("file", "name",
|
dependency.getVendorEvidence().addEvidence("file", "name",
|
||||||
fileName, Evidence.Confidence.HIGHEST);
|
packageName, Confidence.HIGH);
|
||||||
} else {
|
|
||||||
dependency.getProductEvidence().addEvidence("file", "name",
|
|
||||||
fileName, Evidence.Confidence.HIGH);
|
|
||||||
dependency.getVendorEvidence().addEvidence("file", "name",
|
|
||||||
fileName, Evidence.Confidence.HIGH);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,29 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of dependency-check-core.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
* Copyright (c) 2014 Jeremy Long. All Rights Reserved.
|
||||||
|
*/
|
||||||
|
package org.owasp.dependencycheck.analyzer;
|
||||||
|
|
||||||
|
import java.io.FileFilter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An Analyzer that scans specific file types.
|
||||||
|
*
|
||||||
|
* @author Jeremy Long
|
||||||
|
*/
|
||||||
|
public interface FileTypeAnalyzer extends Analyzer, FileFilter {
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,37 +1,72 @@
|
|||||||
/*
|
/*
|
||||||
* This file is part of dependency-check-core.
|
* This file is part of dependency-check-core.
|
||||||
*
|
*
|
||||||
* Dependency-check-core is free software: you can redistribute it and/or modify it
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* under the terms of the GNU General Public License as published by the Free
|
* you may not use this file except in compliance with the License.
|
||||||
* Software Foundation, either version 3 of the License, or (at your option) any
|
* You may obtain a copy of the License at
|
||||||
* later version.
|
|
||||||
*
|
*
|
||||||
* Dependency-check-core is distributed in the hope that it will be useful, but
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
|
||||||
* details.
|
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License along with
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* dependency-check-core. If not, see http://www.gnu.org/licenses/.
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
*
|
*
|
||||||
* Copyright (c) 2012 Jeremy Long. All Rights Reserved.
|
* Copyright (c) 2012 Jeremy Long. All Rights Reserved.
|
||||||
*/
|
*/
|
||||||
package org.owasp.dependencycheck.analyzer;
|
package org.owasp.dependencycheck.analyzer;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.net.MalformedURLException;
|
||||||
|
import java.net.URL;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.Set;
|
import java.util.List;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
import org.owasp.dependencycheck.Engine;
|
import org.owasp.dependencycheck.Engine;
|
||||||
|
import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
|
||||||
import org.owasp.dependencycheck.dependency.Dependency;
|
import org.owasp.dependencycheck.dependency.Dependency;
|
||||||
import org.owasp.dependencycheck.dependency.Evidence;
|
import org.owasp.dependencycheck.dependency.Evidence;
|
||||||
|
import org.owasp.dependencycheck.exception.InitializationException;
|
||||||
|
import org.owasp.dependencycheck.xml.suppression.PropertyType;
|
||||||
|
import org.owasp.dependencycheck.utils.DownloadFailedException;
|
||||||
|
import org.owasp.dependencycheck.utils.Downloader;
|
||||||
|
import org.owasp.dependencycheck.utils.FileUtils;
|
||||||
|
import org.owasp.dependencycheck.utils.Settings;
|
||||||
|
import org.owasp.dependencycheck.xml.hints.VendorDuplicatingHintRule;
|
||||||
|
import org.owasp.dependencycheck.xml.hints.HintParseException;
|
||||||
|
import org.owasp.dependencycheck.xml.hints.HintParser;
|
||||||
|
import org.owasp.dependencycheck.xml.hints.HintRule;
|
||||||
|
import org.owasp.dependencycheck.xml.hints.Hints;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.xml.sax.SAXException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* This analyzer adds evidence to dependencies to enhance the accuracy of
|
||||||
|
* library identification.
|
||||||
*
|
*
|
||||||
* @author Jeremy Long (jeremy.long@owasp.org)
|
* @author Jeremy Long
|
||||||
*/
|
*/
|
||||||
public class HintAnalyzer extends AbstractAnalyzer implements Analyzer {
|
public class HintAnalyzer extends AbstractAnalyzer {
|
||||||
|
|
||||||
//<editor-fold defaultstate="collapsed" desc="All standard implmentation details of Analyzer">
|
/**
|
||||||
|
* The Logger for use throughout the class
|
||||||
|
*/
|
||||||
|
private static final Logger LOGGER = LoggerFactory.getLogger(HintAnalyzer.class);
|
||||||
|
/**
|
||||||
|
* The name of the hint rule file
|
||||||
|
*/
|
||||||
|
private static final String HINT_RULE_FILE_NAME = "dependencycheck-base-hint.xml";
|
||||||
|
/**
|
||||||
|
* The collection of hints.
|
||||||
|
*/
|
||||||
|
private Hints hints;
|
||||||
|
|
||||||
|
//<editor-fold defaultstate="collapsed" desc="All standard implementation details of Analyzer">
|
||||||
/**
|
/**
|
||||||
* The name of the analyzer.
|
* The name of the analyzer.
|
||||||
*/
|
*/
|
||||||
@@ -40,48 +75,52 @@ public class HintAnalyzer extends AbstractAnalyzer implements Analyzer {
|
|||||||
* The phase that this analyzer is intended to run in.
|
* The phase that this analyzer is intended to run in.
|
||||||
*/
|
*/
|
||||||
private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.PRE_IDENTIFIER_ANALYSIS;
|
private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.PRE_IDENTIFIER_ANALYSIS;
|
||||||
/**
|
|
||||||
* The set of file extensions supported by this analyzer.
|
|
||||||
*/
|
|
||||||
private static final Set<String> EXTENSIONS = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a list of file EXTENSIONS supported by this analyzer.
|
|
||||||
*
|
|
||||||
* @return a list of file EXTENSIONS supported by this analyzer.
|
|
||||||
*/
|
|
||||||
public Set<String> getSupportedExtensions() {
|
|
||||||
return EXTENSIONS;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the name of the analyzer.
|
* Returns the name of the analyzer.
|
||||||
*
|
*
|
||||||
* @return the name of the analyzer.
|
* @return the name of the analyzer.
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return ANALYZER_NAME;
|
return ANALYZER_NAME;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns whether or not this analyzer can process the given extension.
|
|
||||||
*
|
|
||||||
* @param extension the file extension to test for support.
|
|
||||||
* @return whether or not the specified file extension is supported by this
|
|
||||||
* analyzer.
|
|
||||||
*/
|
|
||||||
public boolean supportsExtension(String extension) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the phase that the analyzer is intended to run in.
|
* Returns the phase that the analyzer is intended to run in.
|
||||||
*
|
*
|
||||||
* @return the phase that the analyzer is intended to run in.
|
* @return the phase that the analyzer is intended to run in.
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public AnalysisPhase getAnalysisPhase() {
|
public AnalysisPhase getAnalysisPhase() {
|
||||||
return ANALYSIS_PHASE;
|
return ANALYSIS_PHASE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* Returns the setting key to determine if the analyzer is enabled.</p>
|
||||||
|
*
|
||||||
|
* @return the key for the analyzer's enabled property
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected String getAnalyzerEnabledSettingKey() {
|
||||||
|
return Settings.KEYS.ANALYZER_HINT_ENABLED;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The initialize method does nothing for this Analyzer.
|
||||||
|
*
|
||||||
|
* @throws InitializationException thrown if there is an exception
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void initializeAnalyzer() throws InitializationException {
|
||||||
|
try {
|
||||||
|
loadHintRules();
|
||||||
|
} catch (HintParseException ex) {
|
||||||
|
LOGGER.debug("Unable to parse hint file", ex);
|
||||||
|
throw new InitializationException("Unable to parse the hint file", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
//</editor-fold>
|
//</editor-fold>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -94,51 +133,154 @@ public class HintAnalyzer extends AbstractAnalyzer implements Analyzer {
|
|||||||
* the dependency.
|
* the dependency.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void analyze(Dependency dependency, Engine engine) throws AnalysisException {
|
protected void analyzeDependency(Dependency dependency, Engine engine) throws AnalysisException {
|
||||||
final Evidence springTest1 = new Evidence("Manifest",
|
for (HintRule hint : hints.getHintRules()) {
|
||||||
"Implementation-Title",
|
boolean matchFound = false;
|
||||||
"Spring Framework",
|
for (Evidence given : hint.getGivenVendor()) {
|
||||||
Evidence.Confidence.HIGH);
|
if (dependency.getVendorEvidence().getEvidence().contains(given)) {
|
||||||
|
matchFound = true;
|
||||||
final Evidence springTest2 = new Evidence("Manifest",
|
break;
|
||||||
"Implementation-Title",
|
}
|
||||||
"org.springframework.core",
|
}
|
||||||
Evidence.Confidence.HIGH);
|
if (!matchFound) {
|
||||||
|
for (Evidence given : hint.getGivenProduct()) {
|
||||||
final Evidence springTest3 = new Evidence("Manifest",
|
if (dependency.getProductEvidence().getEvidence().contains(given)) {
|
||||||
"Bundle-Vendor",
|
matchFound = true;
|
||||||
"SpringSource",
|
break;
|
||||||
Evidence.Confidence.HIGH);
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Set<Evidence> evidence = dependency.getProductEvidence().getEvidence();
|
if (!matchFound) {
|
||||||
if (evidence.contains(springTest1) || evidence.contains(springTest2)) {
|
for (Evidence given : hint.getGivenVersion()) {
|
||||||
dependency.getProductEvidence().addEvidence("hint analyzer", "product", "springsource_spring_framework", Evidence.Confidence.HIGH);
|
if (dependency.getVersionEvidence().getEvidence().contains(given)) {
|
||||||
dependency.getVendorEvidence().addEvidence("hint analyzer", "vendor", "SpringSource", Evidence.Confidence.HIGH);
|
matchFound = true;
|
||||||
dependency.getVendorEvidence().addEvidence("hint analyzer", "vendor", "vmware", Evidence.Confidence.HIGH);
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!matchFound) {
|
||||||
|
for (PropertyType pt : hint.getFilenames()) {
|
||||||
|
if (pt.matches(dependency.getFileName())) {
|
||||||
|
matchFound = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (matchFound) {
|
||||||
|
for (Evidence e : hint.getAddVendor()) {
|
||||||
|
dependency.getVendorEvidence().addEvidence(e);
|
||||||
|
}
|
||||||
|
for (Evidence e : hint.getAddProduct()) {
|
||||||
|
dependency.getProductEvidence().addEvidence(e);
|
||||||
|
}
|
||||||
|
for (Evidence e : hint.getAddVersion()) {
|
||||||
|
dependency.getVersionEvidence().addEvidence(e);
|
||||||
|
}
|
||||||
|
for (Evidence e : hint.getRemoveVendor()) {
|
||||||
|
if (dependency.getVendorEvidence().getEvidence().contains(e)) {
|
||||||
|
dependency.getVendorEvidence().getEvidence().remove(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (Evidence e : hint.getRemoveProduct()) {
|
||||||
|
if (dependency.getProductEvidence().getEvidence().contains(e)) {
|
||||||
|
dependency.getProductEvidence().getEvidence().remove(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (Evidence e : hint.getRemoveVersion()) {
|
||||||
|
if (dependency.getVersionEvidence().getEvidence().contains(e)) {
|
||||||
|
dependency.getVersionEvidence().getEvidence().remove(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
evidence = dependency.getVendorEvidence().getEvidence();
|
|
||||||
if (evidence.contains(springTest3)) {
|
|
||||||
dependency.getProductEvidence().addEvidence("hint analyzer", "product", "springsource_spring_framework", Evidence.Confidence.HIGH);
|
|
||||||
dependency.getVendorEvidence().addEvidence("hint analyzer", "vendor", "vmware", Evidence.Confidence.HIGH);
|
|
||||||
}
|
|
||||||
final Iterator<Evidence> itr = dependency.getVendorEvidence().iterator();
|
final Iterator<Evidence> itr = dependency.getVendorEvidence().iterator();
|
||||||
final ArrayList<Evidence> newEntries = new ArrayList<Evidence>();
|
final List<Evidence> newEntries = new ArrayList<>();
|
||||||
while (itr.hasNext()) {
|
while (itr.hasNext()) {
|
||||||
final Evidence e = itr.next();
|
final Evidence e = itr.next();
|
||||||
if ("sun".equalsIgnoreCase(e.getValue(false))) {
|
for (VendorDuplicatingHintRule dhr : hints.getVendorDuplicatingHintRules()) {
|
||||||
final Evidence newEvidence = new Evidence(e.getSource() + " (hint)", e.getName(), "oracle", e.getConfidence());
|
if (dhr.getValue().equalsIgnoreCase(e.getValue(false))) {
|
||||||
newEntries.add(newEvidence);
|
newEntries.add(new Evidence(e.getSource() + " (hint)",
|
||||||
} else if ("oracle".equalsIgnoreCase(e.getValue(false))) {
|
e.getName(), dhr.getDuplicate(), e.getConfidence()));
|
||||||
final Evidence newEvidence = new Evidence(e.getSource() + " (hint)", e.getName(), "sun", e.getConfidence());
|
}
|
||||||
newEntries.add(newEvidence);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (Evidence e : newEntries) {
|
for (Evidence e : newEntries) {
|
||||||
dependency.getVendorEvidence().addEvidence(e);
|
dependency.getVendorEvidence().addEvidence(e);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads the hint rules file.
|
||||||
|
*
|
||||||
|
* @throws HintParseException thrown if the XML cannot be parsed.
|
||||||
|
*/
|
||||||
|
private void loadHintRules() throws HintParseException {
|
||||||
|
final HintParser parser = new HintParser();
|
||||||
|
File file = null;
|
||||||
|
try {
|
||||||
|
hints = parser.parseHints(this.getClass().getClassLoader().getResourceAsStream(HINT_RULE_FILE_NAME));
|
||||||
|
} catch (HintParseException | SAXException ex) {
|
||||||
|
LOGGER.error("Unable to parse the base hint data file");
|
||||||
|
LOGGER.debug("Unable to parse the base hint data file", ex);
|
||||||
|
}
|
||||||
|
final String filePath = Settings.getString(Settings.KEYS.HINTS_FILE);
|
||||||
|
if (filePath == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
boolean deleteTempFile = false;
|
||||||
|
try {
|
||||||
|
final Pattern uriRx = Pattern.compile("^(https?|file)\\:.*", Pattern.CASE_INSENSITIVE);
|
||||||
|
if (uriRx.matcher(filePath).matches()) {
|
||||||
|
deleteTempFile = true;
|
||||||
|
file = FileUtils.getTempFile("hint", "xml");
|
||||||
|
final URL url = new URL(filePath);
|
||||||
|
try {
|
||||||
|
Downloader.fetchFile(url, file, false);
|
||||||
|
} catch (DownloadFailedException ex) {
|
||||||
|
Downloader.fetchFile(url, file, true);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
file = new File(filePath);
|
||||||
|
if (!file.exists()) {
|
||||||
|
try (InputStream fromClasspath = this.getClass().getClassLoader().getResourceAsStream(filePath)) {
|
||||||
|
if (fromClasspath != null) {
|
||||||
|
deleteTempFile = true;
|
||||||
|
file = FileUtils.getTempFile("hint", "xml");
|
||||||
|
try {
|
||||||
|
org.apache.commons.io.FileUtils.copyInputStreamToFile(fromClasspath, file);
|
||||||
|
} catch (IOException ex) {
|
||||||
|
throw new HintParseException("Unable to locate hints file in classpath", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (file != null) {
|
||||||
|
try {
|
||||||
|
final Hints newHints = parser.parseHints(file);
|
||||||
|
hints.getHintRules().addAll(newHints.getHintRules());
|
||||||
|
hints.getVendorDuplicatingHintRules().addAll(newHints.getVendorDuplicatingHintRules());
|
||||||
|
LOGGER.debug("{} hint rules were loaded.", hints.getHintRules().size());
|
||||||
|
LOGGER.debug("{} duplicating hint rules were loaded.", hints.getVendorDuplicatingHintRules().size());
|
||||||
|
} catch (HintParseException ex) {
|
||||||
|
LOGGER.warn("Unable to parse hint rule xml file '{}'", file.getPath());
|
||||||
|
LOGGER.warn(ex.getMessage());
|
||||||
|
LOGGER.debug("", ex);
|
||||||
|
throw ex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (DownloadFailedException ex) {
|
||||||
|
throw new HintParseException("Unable to fetch the configured hint file", ex);
|
||||||
|
} catch (MalformedURLException ex) {
|
||||||
|
throw new HintParseException("Configured hint file has an invalid URL", ex);
|
||||||
|
} catch (IOException ex) {
|
||||||
|
throw new HintParseException("Unable to create temp file for hints", ex);
|
||||||
|
} finally {
|
||||||
|
if (deleteTempFile && file != null) {
|
||||||
|
FileUtils.delete(file);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,122 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of dependency-check-core.
|
|
||||||
*
|
|
||||||
* Dependency-check-core is free software: you can redistribute it and/or modify it
|
|
||||||
* under the terms of the GNU General Public License as published by the Free
|
|
||||||
* Software Foundation, either version 3 of the License, or (at your option) any
|
|
||||||
* later version.
|
|
||||||
*
|
|
||||||
* Dependency-check-core is distributed in the hope that it will be useful, but
|
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
|
||||||
* details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License along with
|
|
||||||
* dependency-check-core. If not, see http://www.gnu.org/licenses/.
|
|
||||||
*
|
|
||||||
* Copyright (c) 2012 Jeremy Long. All Rights Reserved.
|
|
||||||
*/
|
|
||||||
package org.owasp.dependencycheck.analyzer;
|
|
||||||
|
|
||||||
import org.owasp.dependencycheck.Engine;
|
|
||||||
import org.owasp.dependencycheck.dependency.Dependency;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.regex.Pattern;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* Used to load a JAR file and collect information that can be used to determine
|
|
||||||
* the associated CPE.
|
|
||||||
*
|
|
||||||
* @author Jeremy Long (jeremy.long@owasp.org)
|
|
||||||
*/
|
|
||||||
public class JavaScriptAnalyzer extends AbstractAnalyzer implements Analyzer {
|
|
||||||
|
|
||||||
//<editor-fold defaultstate="collapsed" desc="All standard implmentation details of Analyzer">
|
|
||||||
/**
|
|
||||||
* The name of the analyzer.
|
|
||||||
*/
|
|
||||||
private static final String ANALYZER_NAME = "JavaScript Analyzer";
|
|
||||||
/**
|
|
||||||
* The phase that this analyzer is intended to run in.
|
|
||||||
*/
|
|
||||||
private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION;
|
|
||||||
/**
|
|
||||||
* The set of file extensions supported by this analyzer.
|
|
||||||
*/
|
|
||||||
private static final Set<String> EXTENSIONS = newHashSet("js");
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a list of file EXTENSIONS supported by this analyzer.
|
|
||||||
*
|
|
||||||
* @return a list of file EXTENSIONS supported by this analyzer.
|
|
||||||
*/
|
|
||||||
public Set<String> getSupportedExtensions() {
|
|
||||||
return EXTENSIONS;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the name of the analyzer.
|
|
||||||
*
|
|
||||||
* @return the name of the analyzer.
|
|
||||||
*/
|
|
||||||
public String getName() {
|
|
||||||
return ANALYZER_NAME;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns whether or not this analyzer can process the given extension.
|
|
||||||
*
|
|
||||||
* @param extension the file extension to test for support.
|
|
||||||
* @return whether or not the specified file extension is supported by this
|
|
||||||
* analyzer.
|
|
||||||
*/
|
|
||||||
public boolean supportsExtension(String extension) {
|
|
||||||
return EXTENSIONS.contains(extension);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the phase that the analyzer is intended to run in.
|
|
||||||
*
|
|
||||||
* @return the phase that the analyzer is intended to run in.
|
|
||||||
*/
|
|
||||||
public AnalysisPhase getAnalysisPhase() {
|
|
||||||
return ANALYSIS_PHASE;
|
|
||||||
}
|
|
||||||
//</editor-fold>
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Loads a specified JAR file and collects information from the manifest and
|
|
||||||
* checksums to identify the correct CPE information.
|
|
||||||
*
|
|
||||||
* @param dependency the dependency to analyze.
|
|
||||||
* @param engine the engine that is scanning the dependencies
|
|
||||||
* @throws AnalysisException is thrown if there is an error reading the JAR
|
|
||||||
* file.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void analyze(Dependency dependency, Engine engine) throws AnalysisException {
|
|
||||||
final Pattern extractComments = Pattern.compile("(/\\*([^*]|[\\r\\n]|(\\*+([^*/]|[\\r\\n])))*\\*+/)|(//.*)");
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The initialize method does nothing for this Analyzer.
|
|
||||||
*
|
|
||||||
* @throws Exception thrown if there is an exception
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void initialize() throws Exception {
|
|
||||||
//do nothing
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The close method does nothing for this Analyzer.
|
|
||||||
*
|
|
||||||
* @throws Exception thrown if there is an exception
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void close() throws Exception {
|
|
||||||
//do nothing
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,282 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of dependency-check-core.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
* Copyright (c) 2014 Jeremy Long. All Rights Reserved.
|
||||||
|
*/
|
||||||
|
package org.owasp.dependencycheck.analyzer;
|
||||||
|
|
||||||
|
import org.apache.commons.io.FileUtils;
|
||||||
|
import org.owasp.dependencycheck.Engine;
|
||||||
|
import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
|
||||||
|
import org.owasp.dependencycheck.data.nexus.MavenArtifact;
|
||||||
|
import org.owasp.dependencycheck.data.nexus.NexusSearch;
|
||||||
|
import org.owasp.dependencycheck.dependency.Confidence;
|
||||||
|
import org.owasp.dependencycheck.dependency.Dependency;
|
||||||
|
import org.owasp.dependencycheck.dependency.Evidence;
|
||||||
|
import org.owasp.dependencycheck.xml.pom.PomUtils;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileFilter;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.MalformedURLException;
|
||||||
|
import java.net.URL;
|
||||||
|
import org.owasp.dependencycheck.exception.InitializationException;
|
||||||
|
import org.owasp.dependencycheck.utils.DownloadFailedException;
|
||||||
|
import org.owasp.dependencycheck.utils.Downloader;
|
||||||
|
import org.owasp.dependencycheck.utils.FileFilterBuilder;
|
||||||
|
import org.owasp.dependencycheck.utils.InvalidSettingException;
|
||||||
|
import org.owasp.dependencycheck.utils.Settings;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Analyzer which will attempt to locate a dependency on a Nexus service by
|
||||||
|
* SHA-1 digest of the dependency.
|
||||||
|
*
|
||||||
|
* There are two settings which govern this behavior:
|
||||||
|
*
|
||||||
|
* <ul>
|
||||||
|
* <li>{@link org.owasp.dependencycheck.utils.Settings.KEYS#ANALYZER_NEXUS_ENABLED}
|
||||||
|
* determines whether this analyzer is even enabled. This can be overridden by
|
||||||
|
* setting the system property.</li>
|
||||||
|
* <li>{@link org.owasp.dependencycheck.utils.Settings.KEYS#ANALYZER_NEXUS_URL}
|
||||||
|
* the URL to a Nexus service to search by SHA-1. There is an expected
|
||||||
|
* <code>%s</code> in this where the SHA-1 will get entered.</li>
|
||||||
|
* </ul>
|
||||||
|
*
|
||||||
|
* @author colezlaw
|
||||||
|
*/
|
||||||
|
public class NexusAnalyzer extends AbstractFileTypeAnalyzer {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The default URL - this will be used by the CentralAnalyzer to determine
|
||||||
|
* whether to enable this.
|
||||||
|
*/
|
||||||
|
public static final String DEFAULT_URL = "https://repository.sonatype.org/service/local/";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The logger.
|
||||||
|
*/
|
||||||
|
private static final Logger LOGGER = LoggerFactory.getLogger(NexusAnalyzer.class);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The name of the analyzer.
|
||||||
|
*/
|
||||||
|
private static final String ANALYZER_NAME = "Nexus Analyzer";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The phase in which the analyzer runs.
|
||||||
|
*/
|
||||||
|
private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The types of files on which this will work.
|
||||||
|
*/
|
||||||
|
private static final String SUPPORTED_EXTENSIONS = "jar";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Nexus Search to be set up for this analyzer.
|
||||||
|
*/
|
||||||
|
private NexusSearch searcher;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Field indicating if the analyzer is enabled.
|
||||||
|
*/
|
||||||
|
private final boolean enabled = checkEnabled();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines if this analyzer is enabled
|
||||||
|
*
|
||||||
|
* @return <code>true</code> if the analyzer is enabled; otherwise
|
||||||
|
* <code>false</code>
|
||||||
|
*/
|
||||||
|
private boolean checkEnabled() {
|
||||||
|
/* Enable this analyzer ONLY if the Nexus URL has been set to something
|
||||||
|
other than the default one (if it's the default one, we'll use the
|
||||||
|
central one) and it's enabled by the user.
|
||||||
|
*/
|
||||||
|
boolean retval = false;
|
||||||
|
try {
|
||||||
|
if (!DEFAULT_URL.equals(Settings.getString(Settings.KEYS.ANALYZER_NEXUS_URL))
|
||||||
|
&& Settings.getBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED)) {
|
||||||
|
LOGGER.info("Enabling Nexus analyzer");
|
||||||
|
retval = true;
|
||||||
|
} else {
|
||||||
|
LOGGER.debug("Nexus analyzer disabled, using Central instead");
|
||||||
|
}
|
||||||
|
} catch (InvalidSettingException ise) {
|
||||||
|
LOGGER.warn("Invalid setting. Disabling Nexus analyzer");
|
||||||
|
}
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine whether to enable this analyzer or not.
|
||||||
|
*
|
||||||
|
* @return whether the analyzer should be enabled
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean isEnabled() {
|
||||||
|
return enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes the analyzer once before any analysis is performed.
|
||||||
|
*
|
||||||
|
* @throws InitializationException if there's an error during initialization
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void initializeFileTypeAnalyzer() throws InitializationException {
|
||||||
|
LOGGER.debug("Initializing Nexus Analyzer");
|
||||||
|
LOGGER.debug("Nexus Analyzer enabled: {}", isEnabled());
|
||||||
|
if (isEnabled()) {
|
||||||
|
final boolean useProxy = useProxy();
|
||||||
|
final String searchUrl = Settings.getString(Settings.KEYS.ANALYZER_NEXUS_URL);
|
||||||
|
LOGGER.debug("Nexus Analyzer URL: {}", searchUrl);
|
||||||
|
try {
|
||||||
|
searcher = new NexusSearch(new URL(searchUrl), useProxy);
|
||||||
|
if (!searcher.preflightRequest()) {
|
||||||
|
setEnabled(false);
|
||||||
|
throw new InitializationException("There was an issue getting Nexus status. Disabling analyzer.");
|
||||||
|
}
|
||||||
|
} catch (MalformedURLException mue) {
|
||||||
|
setEnabled(false);
|
||||||
|
throw new InitializationException("Malformed URL to Nexus: " + searchUrl, mue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the analyzer's name.
|
||||||
|
*
|
||||||
|
* @return the name of the analyzer
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return ANALYZER_NAME;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the key used in the properties file to reference the analyzer's
|
||||||
|
* enabled property.
|
||||||
|
*
|
||||||
|
* @return the analyzer's enabled property setting key
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected String getAnalyzerEnabledSettingKey() {
|
||||||
|
return Settings.KEYS.ANALYZER_NEXUS_ENABLED;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the analysis phase under which the analyzer runs.
|
||||||
|
*
|
||||||
|
* @return the phase under which this analyzer runs
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public AnalysisPhase getAnalysisPhase() {
|
||||||
|
return ANALYSIS_PHASE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The file filter used to determine which files this analyzer supports.
|
||||||
|
*/
|
||||||
|
private static final FileFilter FILTER = FileFilterBuilder.newInstance().addExtensions(SUPPORTED_EXTENSIONS).build();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the FileFilter
|
||||||
|
*
|
||||||
|
* @return the FileFilter
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected FileFilter getFileFilter() {
|
||||||
|
return FILTER;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Performs the analysis.
|
||||||
|
*
|
||||||
|
* @param dependency the dependency to analyze
|
||||||
|
* @param engine the engine
|
||||||
|
* @throws AnalysisException when there's an exception during analysis
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void analyzeDependency(Dependency dependency, Engine engine) throws AnalysisException {
|
||||||
|
if (!isEnabled()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
final MavenArtifact ma = searcher.searchSha1(dependency.getSha1sum());
|
||||||
|
dependency.addAsEvidence("nexus", ma, Confidence.HIGH);
|
||||||
|
boolean pomAnalyzed = false;
|
||||||
|
LOGGER.debug("POM URL {}", ma.getPomUrl());
|
||||||
|
for (Evidence e : dependency.getVendorEvidence()) {
|
||||||
|
if ("pom".equals(e.getSource())) {
|
||||||
|
pomAnalyzed = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!pomAnalyzed && ma.getPomUrl() != null) {
|
||||||
|
File pomFile = null;
|
||||||
|
try {
|
||||||
|
final File baseDir = Settings.getTempDirectory();
|
||||||
|
pomFile = File.createTempFile("pom", ".xml", baseDir);
|
||||||
|
if (!pomFile.delete()) {
|
||||||
|
LOGGER.warn("Unable to fetch pom.xml for {} from Nexus repository; "
|
||||||
|
+ "this could result in undetected CPE/CVEs.", dependency.getFileName());
|
||||||
|
LOGGER.debug("Unable to delete temp file");
|
||||||
|
}
|
||||||
|
LOGGER.debug("Downloading {}", ma.getPomUrl());
|
||||||
|
Downloader.fetchFile(new URL(ma.getPomUrl()), pomFile);
|
||||||
|
PomUtils.analyzePOM(dependency, pomFile);
|
||||||
|
} catch (DownloadFailedException ex) {
|
||||||
|
LOGGER.warn("Unable to download pom.xml for {} from Nexus repository; "
|
||||||
|
+ "this could result in undetected CPE/CVEs.", dependency.getFileName());
|
||||||
|
} finally {
|
||||||
|
if (pomFile != null && pomFile.exists() && !FileUtils.deleteQuietly(pomFile)) {
|
||||||
|
LOGGER.debug("Failed to delete temporary pom file {}", pomFile.toString());
|
||||||
|
pomFile.deleteOnExit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (IllegalArgumentException iae) {
|
||||||
|
//dependency.addAnalysisException(new AnalysisException("Invalid SHA-1"));
|
||||||
|
LOGGER.info("invalid sha-1 hash on {}", dependency.getFileName());
|
||||||
|
} catch (FileNotFoundException fnfe) {
|
||||||
|
//dependency.addAnalysisException(new AnalysisException("Artifact not found on repository"));
|
||||||
|
LOGGER.debug("Artifact not found in repository '{}'", dependency.getFileName());
|
||||||
|
LOGGER.debug(fnfe.getMessage(), fnfe);
|
||||||
|
} catch (IOException ioe) {
|
||||||
|
//dependency.addAnalysisException(new AnalysisException("Could not connect to repository", ioe));
|
||||||
|
LOGGER.debug("Could not connect to nexus repository", ioe);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine if a proxy should be used.
|
||||||
|
*
|
||||||
|
* @return {@code true} if a proxy should be used
|
||||||
|
*/
|
||||||
|
public static boolean useProxy() {
|
||||||
|
try {
|
||||||
|
return Settings.getString(Settings.KEYS.PROXY_SERVER) != null
|
||||||
|
&& Settings.getBoolean(Settings.KEYS.ANALYZER_NEXUS_USES_PROXY);
|
||||||
|
} catch (InvalidSettingException ise) {
|
||||||
|
LOGGER.warn("Failed to parse proxy settings.", ise);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user