Compare commits

..

194 Commits

Author SHA1 Message Date
Jeremy Long
032620451a Updated to version 1.0.2
Former-commit-id: 2bc5dbe4cae0c2da1b3bbae36a435e6847f7d487
2013-09-03 21:13:01 -04:00
Jeremy Long
6f94faee14 fixed git merge problem
Former-commit-id: c9b325d28586a399bd666dbe235e73913f26b81e
2013-09-02 16:19:47 -04:00
Jeremy Long
c309fa8b20 fixed merge issues
Former-commit-id: 5c4fcc5d1dc5aeb0442e4083286cd5438accf657
2013-09-02 15:54:35 -04:00
Jeremy Long
303e89f4fc resolved merge conflicts
Former-commit-id: 5abb1fa1076eb1f88324600e5f6df6963d52929b
2013-09-02 15:42:24 -04:00
Jeremy Long
1d05ef7a3c updated site information
Former-commit-id: e0750d178f7c9437aa6892b8e290525421b5d3ed
2013-09-02 14:34:46 -04:00
Jeremy Long
fac7b09089 fixed base test case to ensure data exists for other tests
Former-commit-id: b728204c02eb46fa4c15490024b64584e64f9920
2013-09-02 13:03:00 -04:00
Jeremy Long
77fe8cb86d updated site
Former-commit-id: 2823d82d52a4a4525893417198afca9b7a1eb29f
2013-09-02 13:02:35 -04:00
Jeremy Long
96214259c7 ensured the properties file was closed after being read
Former-commit-id: 337a350cc728f3a39eacbd004176a526ac38968f
2013-09-02 12:48:17 -04:00
Jeremy Long
5828266e1e updated site information
Former-commit-id: 94ad0b128c5cfe4b56c10f850eb9a3be423036ec
2013-09-02 12:44:24 -04:00
Jeremy Long
7b1906384e updated site information
Former-commit-id: acb1ea4ba2e719b198465eb5b3dba1dd7bd38509
2013-09-02 12:42:44 -04:00
Jeremy Long
9f66d9432b updated documentation
Former-commit-id: 9ca3d9fcf6131d5455252ebaacd6219126bd3453
2013-09-01 15:35:53 -04:00
Jeremy Long
a82537fed9 minor checkstyle updates
Former-commit-id: 937ba487b5a25de622f81fa9bdc54daf0e15c18e
2013-09-01 15:11:49 -04:00
Jeremy Long
6ee5555594 moved test data.zip to parent so it can be used by other projects
Former-commit-id: 18eae245b1476032a07f0714b2069d8fb2a39ea9
2013-09-01 12:21:56 -04:00
Jeremy Long
250de09c49 updated Settigns to get the temp directory
Former-commit-id: e2207012b838180c9432475647f74e8a7a100196
2013-09-01 07:46:43 -04:00
Jeremy Long
22a27fb146 updated tests to utilize temp directory
Former-commit-id: 072c2f51dd0077f3e6c34c3bd6340e9da0a9360c
2013-09-01 07:27:13 -04:00
Jeremy Long
7d1fa93e98 updated to work with the new zip file and folder structure
Former-commit-id: e7e50500e644e108e5addfffd3a319021c594a93
2013-08-31 07:35:20 -04:00
Jeremy Long
abc73de1ae removed unused imports
Former-commit-id: 9b17ae3228693587083c3ef4e4eaf95893d22baf
2013-08-31 07:04:17 -04:00
Jeremy Long
b7323543b3 added a test case to test batch update without a modified url
Former-commit-id: 641a227e3a3d47ee4b9c6bc897b49c010f36adf9
2013-08-31 06:48:59 -04:00
Jeremy Long
3fe196e4ec updates to batch update mode to allow batch updates without a modified URL
Former-commit-id: 85dcff01457f6f735e37b4235c0f38ab2f8b497c
2013-08-31 06:48:10 -04:00
Jeremy Long
67e113b918 removed duplicate code by adding a public getPropertiesFile method to obtain the File
Former-commit-id: 38ea859b46d9e7d0db622033b16fa3b23e93a3de
2013-08-31 06:46:26 -04:00
Jeremy Long
0436a095b5 added test case for removeProperty
Former-commit-id: e48ae0be2da9aaab3d51c7b57dcb2919b72fbeb2
2013-08-29 17:01:47 -04:00
Jeremy Long
7143d2aab4 added ability to remove a property (for test cases)
Former-commit-id: 68d7bca4bcbc7241f3f31e669dcae78ac62319bb
2013-08-29 16:56:00 -04:00
Jeremy Long
7e15a1aa5d fixed broken test case
Former-commit-id: 56cd3dd5b4523faf383ed6d1388b57dfdf6a91cd
2013-08-29 16:50:21 -04:00
Jeremy Long
37b8433911 fixed bug due caused by moving properties from cve to data directory
Former-commit-id: b005fa577f5ebe7e8c31465e1a3a33c6f4f5c958
2013-08-29 16:49:09 -04:00
Jeremy Long
7e193d7dd1 removed duplicate test case
Former-commit-id: 10cd3b0fbfc6cac87c162faa6d6a329a978e0de7
2013-08-29 16:41:41 -04:00
Jeremy Long
df441dc581 fixed broken test case
Former-commit-id: 1abe533c3afd4c709ff5124f9abca6314628dac1
2013-08-29 16:38:08 -04:00
Jeremy Long
09f065c3af code reorganization, moved files around to better seperate functionality
Former-commit-id: 2a524807bb28ff4b60576c13b5e6737fd97f553a
2013-08-29 06:42:16 -04:00
Jeremy Long
90a3ff082f temporarily commented out broken tests
Former-commit-id: dbab786a6ea76959c489be494fb25427d5e6f59b
2013-08-29 06:41:03 -04:00
Jeremy Long
79611bef2e temporarily commented out broken tests
Former-commit-id: 0ca9b421c0f192f1ee907d67f43465e2e6b81fc4
2013-08-29 06:40:37 -04:00
Jeremy Long
ca702628f2 added to externalize the meta info about the data used
Former-commit-id: eb8f098ea94aa34c204c568df3b1c827e877377d
2013-08-29 06:15:20 -04:00
Jeremy Long
845101cda6 updated test for getFile to return the DATA_DIRECTORY
Former-commit-id: c4f3994611ad1fbe4d7443af59c8fecab133c6e7
2013-08-29 06:14:25 -04:00
Jeremy Long
717b36ae09 Updated to externalize the data properties file
Former-commit-id: 9025d12552cef11e0d02d8420bc263d217434523
2013-08-29 06:12:55 -04:00
Jeremy Long
4a51b50eb9 updated getFile to correctly get the main data directory
Former-commit-id: 5c103099848de6d452c300f9c57c22795c63bf2c
2013-08-28 06:15:24 -04:00
Jeremy Long
b1c21f875f updated how initial test data is updated
Former-commit-id: 46752322063b694c89226b0f9b658aa97e0d396f
2013-08-24 20:00:09 -04:00
Jeremy Long
39df3cf211 minor update to test class
Former-commit-id: 4b2438c53339e7c9d52151cd51359dcc0ce99b45
2013-08-24 19:59:31 -04:00
Jeremy Long
8fcd2257de updated how initial test data is updated
Former-commit-id: ac09d75ec58b38514a8be7d309382d3ef533de02
2013-08-24 19:58:54 -04:00
Jeremy Long
4e8e94cc94 minor update of annotations
Former-commit-id: 3da61d0897097921a7b82f9d48fab228adeacc7d
2013-08-24 19:57:55 -04:00
Jeremy Long
3074a2bfc8 updated how initial test data is updated
Former-commit-id: 98ba5daf343b51d25d8cbee1d7ae02e69fbad0b2
2013-08-24 19:57:14 -04:00
Jeremy Long
750d0459f4 updated database schema version so the fix to the lucene index is enforced on clients
Former-commit-id: cc27b0fa533e71b3d6b0a4a3e59b88347fda07d5
2013-08-24 19:56:13 -04:00
Jeremy Long
9b60531218 updates as the CPEAnalyzer was moved
Former-commit-id: abab1b4b82c800113316079f535f4efd27b07aab
2013-08-24 17:02:27 -04:00
Jeremy Long
c7b5620409 updates to ensure backward compatability with 1.6
Former-commit-id: be26000c68fbdc88c6c500db76b760e4d948885a
2013-08-24 17:01:39 -04:00
Jeremy Long
e33b5c36ff commiting deletions and no-ops
Former-commit-id: a83093e257e1c6d9c65db7c77b5b90a403576c12
2013-08-24 16:23:57 -04:00
Jeremy Long
794d9974c0 modified CPE Index to seperate writer/reader in prep for adding locking
Former-commit-id: 47dc4c869094f911d88d586a9a07149fcc9d8674
2013-08-24 16:21:32 -04:00
Jeremy Long
fa97966843 updated javadoc
Former-commit-id: 64cb244be2ca22599a53a07a761bcd2fd1fe8684
2013-08-18 05:55:31 -04:00
Jeremy Long
699de93a81 Added an implementation of a spin lock that can be used to lock a directory.
Former-commit-id: 97cb3752808ae32f6a9a6d5d88418350f139c1f8
2013-08-18 05:54:11 -04:00
Jeremy Long
f8f265478e made non-vulnerable jars hidden by default
Former-commit-id: c0f857102b10668339f50c98aab59950063a1559
2013-08-16 14:49:48 -04:00
Jeremy Long
465e13e55b updated jar plugin
Former-commit-id: ad7d3cb8d6215f8f4bdbb12265e4bb16d6050b59
2013-08-16 14:49:23 -04:00
Jeremy Long
fb65691b1e Merge pull request #13 from eoftedal/master
Styling and toggling on HTML-report

Former-commit-id: 2430ae830a06efa0260ffdcca923d4ed46d05d42
2013-08-16 11:22:13 -07:00
Jeremy Long
acd20c580f corrected minor issue with path to zipped test data
Former-commit-id: 862ea03dc2738dc315a82c03d514f3ce8b6f410e
2013-08-16 14:13:01 -04:00
Jeremy Long
d14bcf4541 updated the scanned test dependencies
Former-commit-id: 52362cbfdc1e97a1f3f726088033be93444abf74
2013-08-16 12:48:54 -04:00
Jeremy Long
5eebea7b7b increased the ignore list for parts of the domain that will not be used as evidence
Former-commit-id: 11b68fc6097ae96735208f4384353d7615c4572a
2013-08-16 12:48:22 -04:00
Jeremy Long
649099b297 added WAR files so that they will be analyzed
Former-commit-id: 6cdef1dafb15d01caab9d3262fa0c3602cbefc1a
2013-08-16 12:47:30 -04:00
Jeremy Long
465254cf20 updated dependencies for test cases
Former-commit-id: f498e3331736573ccaf9c44f804390d719bb394f
2013-08-16 12:46:41 -04:00
Jeremy Long
09ee6b0946 changed dependency references used during test
Former-commit-id: f351ddab7c0e0d53d8c1ab4321b2d58929cdc7ed
2013-08-16 12:06:13 -04:00
Jeremy Long
1efb65d478 removed from test resource to a test dependency
Former-commit-id: 81f78fed0481354ffe105178077f9a74882c0c44
2013-08-16 11:18:50 -04:00
Jeremy Long
eb62ddc4ef minor update to remove lib from scanned directory during test
Former-commit-id: 1fee9afdc61e16d9c4803fab4955cc69bb65677d
2013-08-16 11:18:31 -04:00
Jeremy Long
66c3985725 updated dependencies that are only scanned during tests to be provided/optional and copied them to test-classes
Former-commit-id: d75d018ea41fa6f4d43b7549b84e50da6831da1d
2013-08-16 11:17:44 -04:00
Jeremy Long
d2ace4ae6f added hazelcase-2.5.jar to the test cases
Former-commit-id: 2c905a63a708293937c142074cee722eea4f7c3c
2013-08-16 07:15:56 -04:00
Jeremy Long
f3cac80b2b fixed bug with short words at the end of a CPE were being ignored in verifyEntry. Also, added a min score of 0.08 for documents retrieved from lucene in order to prune bad matches earlier
Former-commit-id: 5f6b87fa09b0acf851e1bbef5b1b53ec667ee562
2013-08-16 07:15:10 -04:00
Jeremy Long
05c05552da added "lib" directory to engine integration test so that new dependencies to test can be added to the pom in the test scope
Former-commit-id: 5304104daad5273a2d34c4a284c498c6ab9e57c2
2013-08-16 07:13:07 -04:00
Jeremy Long
d1d5939181 updated test class path
Former-commit-id: 2536b1ed19e105412e178b9c87cbf4dbef634cdb
2013-08-16 07:12:01 -04:00
Jeremy Long
1cb952bfa9 set version to 1.0.2-SNAPSHOT
Former-commit-id: e86c94eda0fe3966f98311c36aa4726f4966ee35
2013-08-14 20:11:52 -04:00
Jeremy Long
ecc5e6ab02 upgraded to use apache commons compress instead of core java zip api to accomodate UTF-8
Former-commit-id: 2637cacd6a702268bcb7f9c31b80ac513992a5a3
2013-08-14 20:06:26 -04:00
Erlend Oftedal
7c8f45ce94 Styling and toggling on HTML-report
Former-commit-id: c4cb25f19f0899132b376caaf8351425a793f1d0
2013-08-13 16:08:25 +02:00
Jeremy Long
b031ff5b57 update
Former-commit-id: b3109f187f6700b1142e5800fe9054f1610fdd21
2013-08-07 22:49:56 -04:00
Jeremy Long
cf830a92e4 updated information and added links to gh-pages
Former-commit-id: 9a30e3fc3dc06e6681127da3689eb37b73cfe24e
2013-08-07 22:47:30 -04:00
Jeremy Long
608a2351e5 removed gpg signing
Former-commit-id: b2560a6adb245b64bd495dd091e875c975af0271
2013-08-07 22:42:32 -04:00
Jeremy Long
cf64c928bf updated readme
Former-commit-id: 664b9508056d74ec4fe1c2349b3d2981bdb75ab5
2013-08-07 22:41:29 -04:00
Jeremy Long
72e15c94c5 reverting back to v1.0.1
Former-commit-id: a6ee1b41a759002095d77b2e341502c0f66b3151
2013-08-07 22:37:35 -04:00
Jeremy Long
32ad8e8ca1 updated batch update functionality
Former-commit-id: 891c0148c081ac191258f5310d2077ed61039353
2013-08-06 19:34:11 -04:00
Jeremy Long
99bc57e75d updated tests
Former-commit-id: 7bbdf056958d82ebaa87ff5888d7eece930ce14a
2013-08-06 19:33:37 -04:00
Jeremy Long
c02345d731 added additional tests
Former-commit-id: 62c76f61dbd82734380a5607750341995a7ee0b7
2013-08-04 14:48:21 -04:00
Jeremy Long
e06b62b92a commiting initial (and likely broken) version including batch updates - commiting as I need tests done with more OSes
Former-commit-id: 71efa6c260ff58e322a82d753d943f38bd40cf0a
2013-08-04 14:47:54 -04:00
Jeremy Long
ecf2036064 attempting fix for Windows file:/// URI
Former-commit-id: 53b125270575b436626f77e15c0d0ab801d075cb
2013-08-04 14:44:53 -04:00
Jeremy Long
458f9a7a63 updated fetchFile test to remove un-needed argument
Former-commit-id: 2776f1efb6252c128fa102bc8ecc284f12cb606d
2013-08-04 10:48:10 -04:00
Jeremy Long
96b68ae49c removed some un-needed functions relating to downloading files
Former-commit-id: 487fd8cda02733a1dcb21dc678aa5a86f38ddc1c
2013-08-04 10:46:06 -04:00
Jeremy Long
33df2abc95 added new exception
Former-commit-id: 04cfddecea7d3e6755d0eeade4344e01881128e0
2013-08-04 10:34:20 -04:00
Jeremy Long
302e8439c6 moved unzip functionality to FileUtils
Former-commit-id: f40a62ac7986b99cc1daa04c734a6bfc406af611
2013-08-04 10:33:28 -04:00
Jeremy Long
f6b1546992 added a file.delete that will delete the file on JVM exit if the original delete fails
Former-commit-id: 30e9cfa154e0200566761364f67e83241d1157ae
2013-08-04 10:32:53 -04:00
Jeremy Long
6fc09eda3e removed unused properties and added BATCH_UPDATE_URL
Former-commit-id: 63610a8a2d515549cf46fac30d55807eea1b1445
2013-08-03 12:12:59 -04:00
Jeremy Long
d1ab9a5c62 removed unused property in test case
Former-commit-id: c7d83bf44121d4d922b0d2270c47308986d73753
2013-08-03 12:11:46 -04:00
Jeremy Long
49ef287d3d updated comments
Former-commit-id: 69b4f85ec0d8600abfb004b9d7c337e63ff6b613
2013-08-03 12:10:50 -04:00
Jeremy Long
7365214fb6 updated getLastModified() to support the file:// protocol
Former-commit-id: 75604221f3e38de0c877fa6e8b5048da593a2a56
2013-08-03 12:09:44 -04:00
Jeremy Long
92a8357690 made getDataDirectory static
Former-commit-id: a847b2d48cb145fc77c608d28d8cdbcddeb002b4
2013-08-03 12:07:05 -04:00
Jeremy Long
804a363f94 added application name and version properties
Former-commit-id: fe5082c37c5d24c06bc590bae257e8024abcf69b
2013-08-03 12:06:24 -04:00
Jeremy Long
f147e8a469 added application name and version properties
Former-commit-id: 852b9ac56df6f896d7a6956d889f84cca91dbf39
2013-08-03 12:05:54 -04:00
Jeremy Long
94f084290b added version to data directory path
Former-commit-id: 6f768f75adc5d81f92e031fc19303957a362edab
2013-08-02 23:41:21 -04:00
Jeremy Long
1ef0bb0e21 updated installation download urls
Former-commit-id: 02a02810652b6ed2377361839ea687a6a0d6033d
2013-08-01 11:56:15 -04:00
Jeremy Long
b209057bae version 1.0.2-SNAPSHOT
Former-commit-id: 648d39efe6e44339df453cd94b5194f1b047f5ac
2013-08-01 11:50:37 -04:00
Jeremy Long
0fdb7191bb version 1.0.1
Former-commit-id: 9a508670d0ad23510eb3805fe70b620401344214
2013-08-01 11:09:07 -04:00
Jeremy Long
59fae2b80a fixed issue with data directory and made a few other minor changes
Former-commit-id: 74ba4f4ef797bfa13d6c7c3335951f1f9b11f690
2013-08-01 10:57:44 -04:00
Jeremy Long
32aabe78b1 Updated installation instructions
Former-commit-id: cf32fe70b89db9c5b02aa09e9639453470da689d
2013-08-01 10:57:13 -04:00
Jeremy Long
a64608fc9f [maven-release-plugin] prepare for next development iteration
Former-commit-id: 42292c65f589dacdab8acabdd16786a3ac631d54
2013-07-31 15:25:50 -04:00
Jeremy Long
208e9bc501 [maven-release-plugin] prepare release dependency-check-1.0.0
Former-commit-id: 02528acd54429da280b7c3d076d0e90a3c775769
2013-07-31 15:25:26 -04:00
Jeremy Long
3ca7cb6acd snapshot 1.0.0
Former-commit-id: fd76c3dee84876b696c54e5c7c6476ec0a31ee81
2013-07-31 15:10:15 -04:00
Jeremy Long
40f4f79449 [maven-release-plugin] prepare for next development iteration
Former-commit-id: 8c650d1e6fdaeebd6f8e5ab013ab8b1c0597c56f
2013-07-31 14:41:20 -04:00
Jeremy Long
5f1043a1c9 [maven-release-plugin] prepare release dependency-check-1.0.0
Former-commit-id: 0dff0f77c78d6da05d348aa25b24f553d053fbc6
2013-07-31 11:21:09 -04:00
Jeremy Long
c3f9f16ce3 releasing updates from private repo
Former-commit-id: 064139c68ad185358d6c74a77511d9ca36229633
2013-07-31 10:21:31 -04:00
Jeremy Long
a036b9fc27 removed todo comment
Former-commit-id: f501f116076fcdec0871a1535b87b2548c5672ce
2013-06-25 22:35:34 -04:00
Jeremy Long
8323dbc7b5 improved exception handling
Former-commit-id: d47fd5bc34d2894d09a40b42040aa080748e5c6f
2013-06-25 22:31:59 -04:00
Jeremy Long
07fbf2ae3b moved jaxb generated code
Former-commit-id: f7ed014875524ef535744e4ee230f95459abe9fb
2013-06-25 22:19:40 -04:00
Jeremy Long
95b4807e35 moved jaxb generated code
Former-commit-id: 73fe1bea1c7d8914445dbf3e5753bffd14076334
2013-06-25 22:18:58 -04:00
Jeremy Long
ddb4c55222 added extra jar to analyze test to correct http false positives
Former-commit-id: b8a29c33ceb9d5d668fbc3c5289d1d911e992082
2013-06-23 22:42:40 -04:00
Jeremy Long
4fed1b4589 added correction to deal with http urls causing false positives
Former-commit-id: 086de9647c8488ca388310937c6d12360fb04a35
2013-06-23 22:40:58 -04:00
Jeremy Long
1fe345aa1d Added methods to test strings for urls and to extract important portions of the url
Former-commit-id: 3f899169cd2a9e327ab8c599205c6823a9a3b5e5
2013-06-23 22:38:45 -04:00
Jeremy Long
732c8aefcf few minor updates
Former-commit-id: 660ccce75b484f0b84e3c32fc08267d80b0fcfaf
2013-06-23 22:37:27 -04:00
Jeremy Long
dc65a90c12 added common-validator to help solve the url problem
Former-commit-id: 83f5be7375fc7fa9f58e77ccd318b90e19a15965
2013-06-23 22:34:12 -04:00
Jeremy Long
9e4e9d7b04 extracted common parts of the tokenizing filters to create the AbstractTokenizingFilter
Former-commit-id: a9e2dd8e5aaadc601b8a8efc6259ad85c0eb2617
2013-06-23 22:33:07 -04:00
Jeremy Long
1ef0c9a3ba added the AbstractTokenizingFilter
Former-commit-id: 358eed7d7dbba82b457748c2c9fe942188721daa
2013-06-23 22:30:47 -04:00
Jeremy Long
a0193825b7 added UrlTokenizingFilter
Former-commit-id: 80dbdbbbfe76399f0b66caf2cf27751213bd7fc4
2013-06-23 22:29:54 -04:00
Jeremy Long
9e25ef9721 added UrlTokenizingFilter
Former-commit-id: 4e3db0d178d5bf70b73c8f1c33538385f6f24c5c
2013-06-23 22:27:50 -04:00
Jeremy Long
acbd7cb789 fixed the addEvidenceWithoutduplicateTerms - but allowed the same term to be added multiple times
Former-commit-id: c875f6c4a8913777053fd0787009f3b708bbf589
2013-06-23 22:26:37 -04:00
Jeremy Long
caae675359 added suppertsExtension method to determine if any analyzer supports a specified extension
Former-commit-id: 4d0afb8f8a40e61f9a3fe1a23e2a770f9ee48b65
2013-06-19 23:28:08 -04:00
Jeremy Long
d8b3c504f2 updated to version 0.3.2.5-SNAPSHOT
Former-commit-id: 011c0203fd27c9a6340ebcec46cf74e834ec78a3
2013-06-17 20:44:05 -04:00
Jeremy Long
cc6f4803b9 updated to version 0.3.2.4
Former-commit-id: 9d6644482abcfb4f69f360fa60cf08370579250c
2013-06-17 20:42:07 -04:00
Jeremy Long
080ccbe7a0 updated logging
Former-commit-id: a7b76150de7f5c2fe68ad648dcb3271380887c1d
2013-06-17 20:40:29 -04:00
Jeremy Long
657891055b added message about BH Arsenal
Former-commit-id: 01821d375cccd0cd9995e16a07cb11687a965dd8
2013-06-17 20:25:40 -04:00
Jeremy Long
ce1c097136 checkstyle correction
Former-commit-id: b04b910c546a0ff7f58ca8cfe1f8a3afd06a4d62
2013-06-16 07:43:54 -04:00
Jeremy Long
f18827614d updated logging
Former-commit-id: 149530418c3807d59c93615e9c5283e4a151576f
2013-06-16 07:24:34 -04:00
Jeremy Long
a49a4ea059 updated logging
Former-commit-id: 457f15cabd21e7fc4bea0b6baaa37234fdeb1176
2013-06-16 06:36:14 -04:00
Jeremy Long
cb50651764 updated logging
Former-commit-id: d1f027c888ef83e8b2b223f3864eedbd730aa8ce
2013-06-15 23:42:45 -04:00
Jeremy Long
5a6a3dc17f fixed null pointer exception
Former-commit-id: be278e1ce8479bb28912bee00eae1f1c1c0bbdf4
2013-06-15 22:40:11 -04:00
Jeremy Long
d179b7bf3f minor updates - still no implementation though
Former-commit-id: 53b5a5ad98e02cf9b18b167205079c489c75a336
2013-06-11 06:23:05 -04:00
Jeremy Long
31e6d1e0c1 updated javadoc
Former-commit-id: d8526a7b902438a83138a677a37c709684c76ed8
2013-06-11 06:20:00 -04:00
Jeremy Long
13c239c9d4 fixed compilation issue due to changes in other classes
Former-commit-id: 171336be7223c6ebf4a416dc55b98407aeb73f19
2013-06-11 06:05:07 -04:00
Jeremy Long
e985ebff3f added a temp directory property
Former-commit-id: 97cdce3ca6be8d599c3805d3316c09512ae38694
2013-06-11 06:03:52 -04:00
Jeremy Long
3d00927033 added a getInt with a default value
Former-commit-id: 61d31f994354bfb5047432424f8d34492023a73b
2013-06-11 06:03:13 -04:00
Jeremy Long
8bdb7e239d minor update to support new analyzer
Former-commit-id: 24224a255ebe67f31041716b3e2ab8b22a9273c0
2013-06-11 06:00:09 -04:00
Jeremy Long
a5b0136897 added netbeans configuration files too
Former-commit-id: 5c0704462790b8b1394532a73f12843d7796742a
2013-06-11 05:58:06 -04:00
Jeremy Long
41ea697483 added throws clause to initialize and close as specified by the interface
Former-commit-id: dca013ac170a09297bc5bbf96ee8fecc9d2baaef
2013-06-07 22:24:01 -04:00
Jeremy Long
fb0f4dd2cf re-arranged code and improved documentation (some)
Former-commit-id: 24b983d81673b2055bef970e04a040c334a716bb
2013-06-07 22:04:35 -04:00
Jeremy Long
8eb373a612 made snapshot
Former-commit-id: 5dd3bf273a5b76342ef03d90affd11d638cc73c7
2013-06-07 22:00:36 -04:00
Jeremy Long
2933526aee v0.3.2.3
Former-commit-id: f1a80ca108a9089e26c716bab8389844faa3e3a4
2013-06-07 15:53:03 -04:00
Jeremy Long
ef2a22b216 v0.3.2.3
Former-commit-id: dc8b892541970156a95a14d11c5eb3c5d610e676
2013-06-07 15:52:24 -04:00
Jeremy Long
d4ab1a56e2 to revert
Former-commit-id: 30a068f5e6a0ef6d5a2cd8c37f4b8b3d616d16b3
2013-06-07 15:51:20 -04:00
Jeremy Long
0e351568f9 next snapshot
Former-commit-id: b1e338bf6ff18bbc55e27ef26aa31d0913cd4d50
2013-06-07 15:47:33 -04:00
Jeremy Long
4eab9d77ae removed deprecated code
Former-commit-id: 07a96fff9c7ba0d0c5a56367937e9653c1717253
2013-06-07 15:46:30 -04:00
Jeremy Long
afeecf9fa9 v0.3.2.3
Former-commit-id: 0b33ececc336e9f060168b8bece28741cf3ea75d
2013-06-07 15:46:17 -04:00
Jeremy Long
27affe8568 checkstyle fix
Former-commit-id: 193f06ad6458fe0aead3703f6019e6dc6ac37aec
2013-06-07 15:46:02 -04:00
Jeremy Long
5015686a8f checkstyle fix
Former-commit-id: 3c9c00f8c03726603f708dd94f135001f29d5f41
2013-06-07 15:45:32 -04:00
Jeremy Long
e72b97289d added vulnerable library count
Former-commit-id: f01ff6a85098e91d9cfb6f83905e939e3cf84815
2013-06-07 15:44:15 -04:00
Jeremy Long
dd497e5ffc added a new vulnerability report
Former-commit-id: f36e328929921e4d278ee8fa5a7370d228bac299
2013-06-07 15:20:38 -04:00
Jeremy Long
f100161f67 added Stupid Table Plugin
Former-commit-id: 96c30d1cc8a175b6662cebbbf8e454ce07bd08df
2013-06-07 15:20:23 -04:00
Jeremy Long
488305def1 version 0.3.2.3-SNAPSHOT
Former-commit-id: 8b26510ff5255afb97bd66a780053e1f1cdf9b33
2013-06-05 00:07:59 -04:00
Jeremy Long
dea5a6937e version 0.3.2.2
Former-commit-id: e90cf514695052e64d4f26e108c3d2e0298b03d6
2013-06-05 00:06:09 -04:00
Jeremy Long
545c324e56 checkstyle fix
Former-commit-id: deb86ab62846aa9f2d63221dca5cfe52bbf244e4
2013-06-05 00:05:46 -04:00
Jeremy Long
535d1e4aff checkstle fixes
Former-commit-id: d7f55af71bca0347b03db5fb9660c3b391619100
2013-06-04 23:47:22 -04:00
Jeremy Long
8debea384f checkstyle fixes
Former-commit-id: c903dc9e96171a07c2d1473d59f53df4a1838128
2013-06-04 23:40:37 -04:00
Jeremy Long
a0b6b66a5f updated javadoc
Former-commit-id: d98e6f3a7be907ea4e15b4e2555f7566fc5c476b
2013-06-04 23:40:11 -04:00
Jeremy Long
37d165d6cb updated javadoc
Former-commit-id: 89eab3c72a4de3c95e5debc38e937166a93ad47d
2013-06-04 23:40:02 -04:00
Jeremy Long
5b6eb13cf6 fixed bug where dependencies would get bundled even if they were different versions
Former-commit-id: 910e26ad24be705750c71738d8518abc5b83e0f3
2013-06-04 23:27:14 -04:00
Jeremy Long
5d68c9f1e1 added equals and hashCode
Former-commit-id: 42b91e996715657069c58a6edbb52588a089c0db
2013-06-04 23:06:02 -04:00
Jeremy Long
faff34a8c6 added filter to add the correct Maven namespace to the POM if it is missing
Former-commit-id: c8e02d730b9c0195fa390b3cced77a4fd4410197
2013-06-04 22:54:28 -04:00
Jeremy Long
c31be72c8a added filter to add the correct Maven namespace to the POM if it is missing
Former-commit-id: 79efc8a8a876831739874914a97ba2d764dd6a7a
2013-06-04 22:54:09 -04:00
Jeremy Long
1f0c13b7cb minor bug fix
Former-commit-id: ec12f812c5170c72f20548b0e00cb5947aacb54d
2013-06-04 05:09:04 -04:00
Jeremy Long
f06f1d1c42 checkstyle fixes (javadoc, final variables, etc)
Former-commit-id: 1f8649c19d845cf3eb80730fb91b33c089e86aae
2013-06-03 20:23:23 -04:00
Jeremy Long
2eca1f9702 added attribute to ignore a findbugs style error
Former-commit-id: 0c34765ce1e4e9825083ed8afb6cbb76e0cc73ec
2013-06-03 20:17:07 -04:00
Jeremy Long
ca6cb8811e findbugs fixes
Former-commit-id: 124207a2cf9022c8e663313da847a76f639cd355
2013-06-03 20:07:39 -04:00
Jeremy Long
ff14d8344f add jsoup to help convert the HTML, specified within nodes in the POM, into text.
Former-commit-id: c6fd21572a01d2cdf457302c9739b54d20e27b05
2013-06-02 21:45:49 -04:00
Jeremy Long
bfb6373742 added code to remove additional false positives
Former-commit-id: 1a15cccd4790fee2044de40843305762cfbefe96
2013-06-02 21:44:20 -04:00
Jeremy Long
e3f401debb added initial version filter - only supporting struts1/2 right now
Former-commit-id: 353a6fec78140b50622b4d267ddf6de34461027c
2013-05-31 22:57:04 -04:00
Jeremy Long
c515afd8eb added another manifest entry to ignore
Former-commit-id: 63a6f3bd3f2d95ac6b101520b3974fc79286ec7b
2013-05-31 22:32:56 -04:00
Jeremy Long
e028641861 added another manifest entry to ignore
Former-commit-id: 7d647e2e298fe142e5230c479b7bd6b51cab5417
2013-05-31 21:52:36 -04:00
Jeremy Long
72f9cb2ab2 fixed javadoc typo
Former-commit-id: 625b8d9958d2cf6123fb583864720d4f5c0c9e01
2013-05-31 21:24:33 -04:00
Jeremy Long
e8694de6fa fixed javadoc typo
Former-commit-id: 5d2f64e0e13f595f08b8e984b422531f8b484321
2013-05-31 21:24:06 -04:00
Jeremy Long
18d38592d4 reduced complexity around determining if the jar contains classes
Former-commit-id: cc42a0c674bc0027c9bd53b250afa9e985b59da0
2013-05-31 20:48:33 -04:00
Jeremy Long
b9767acd02 removed a reported exception for javadoc or sources jar files for not having a manifest
Former-commit-id: 8dbe960af8c2391343d779708672d97a0c530a09
2013-05-31 20:41:23 -04:00
Jeremy Long
c9060da46e minor update to text
Former-commit-id: d413abef8fd16742abb47ef046807233dafc5d16
2013-05-27 22:22:44 -04:00
Jeremy Long
ddbcea7abe v0.3.2.1-SNAPSHOT
Former-commit-id: 9c7996f097e3fad59d99624cddf64b10be4c4524
2013-05-27 22:18:20 -04:00
Jeremy Long
e488767cea 0.3.2.0
Former-commit-id: 8431f1312204c78a829f269954161d7187245493
2013-05-27 22:14:27 -04:00
Jeremy Long
85cacaf91e testing
Former-commit-id: 7fd42dc4c273eff98a8fbc3e3a14f0ce1fd26abe
2013-05-27 22:12:25 -04:00
Jeremy Long
a038bef7fe reset username and blank password
Former-commit-id: 398c0723854c8c43d674d03a6433611c8572cec5
2013-05-27 21:32:05 -04:00
Jeremy Long
539d3cbaba updated H2 version
Former-commit-id: b7193bc7c2e256ebdcabc039d573994daab47415
2013-05-27 20:47:13 -04:00
Jeremy Long
80784a44c5 added compile time support for findbugs suppress warning annotation
Former-commit-id: 83d178ebafafe8ffc1f10b91d7336490c046990b
2013-05-27 20:02:54 -04:00
Jeremy Long
b1a55e2df3 updated javadoc
Former-commit-id: 2818f04997c8fa1c81c8e9bddaea0e9370b76350
2013-05-27 20:01:47 -04:00
Jeremy Long
870d345de8 updated javadoc
Former-commit-id: 3e05f7622618e2dc27fe40cfbdb488303d5c0ec9
2013-05-27 20:01:16 -04:00
Jeremy Long
2b830dccfa added findbugs suppression for a non-issue and made a few checkstyle corrections
Former-commit-id: a4a3c3503eee772c13d567d473f7ed5126941301
2013-05-27 20:00:46 -04:00
Jeremy Long
9f08cf553b added findbugs suppress warning for a false positive
Former-commit-id: c493f8178c129cb73f023b605599dc3dfa558f58
2013-05-27 19:59:16 -04:00
Jeremy Long
7c14017db3 collapsed nested if statements
Former-commit-id: e4d466f50e76659bece83b46f8a111a3d8225353
2013-05-27 19:58:26 -04:00
Jeremy Long
e0e85c468a added supresswarnings for findbugs false positive
Former-commit-id: 7423c03adb41f92e447aba5e58bc415d27c6c957
2013-05-27 19:56:19 -04:00
Jeremy Long
6628fc3c33 updated javadoc
Former-commit-id: 591bec1e2d5a2945a9cca5bf02cd1cea1bd8a38c
2013-05-27 19:55:13 -04:00
Jeremy Long
61a1531e7b checkstyle fixes
Former-commit-id: 5281b8ecb5163ce4a0a6464fea4f6d2a4baffafd
2013-05-27 19:54:41 -04:00
Jeremy Long
933a8f8ec6 reduced size to make tests fasters
Former-commit-id: d8a3b0c2382ae28a519c2cb44fb93205015e82b0
2013-05-27 19:53:14 -04:00
Jeremy Long
f660afc6cb updated javadoc and copyright
Former-commit-id: d48d9e1deed118e9b60d37185cdbfda47898ef6f
2013-05-27 09:14:56 -04:00
Jeremy Long
a5dc79dffe Merge branch 'master' of https://github.com/jeremylong/DependencyCheck
Former-commit-id: 9189529fca392ee1ef0b810528288e243dcdb6e4
2013-05-27 09:07:18 -04:00
Steve Springett
dbc862ad39 Adding more control over data directory path
Former-commit-id: 263475fc5b3aae04f2530ea78a0456deb18686fe
2013-05-27 00:10:08 -07:00
Jeremy Long
e6efe6e610 Applied patch from Steve to change the loading of the H2 db
Former-commit-id: cfce611fadbd2a39880f01d61054dbb8f72f81dc
2013-05-25 10:56:41 -04:00
Steve Springett
9a7fbe44eb Adding more control over data directory path
Former-commit-id: 966544bd738646ba57be087f413f686ecdfcee9c
2013-05-24 23:53:24 -07:00
Steve Springett
adfc913a0e Fixed Velocity logging issues in server environment.
Former-commit-id: 429105274ee0c2e78c3398e3c019feaaa056866d
2013-05-24 16:00:10 -07:00
Steve Springett
8813652f0d Forcing the class loading of the H2 JDBC driver.
Former-commit-id: d6c11d56afc04d115bbf1d0962072c70cb205dd8
2013-05-22 01:11:02 -07:00
Jeremy Long
250444dd25 made outDir final
Former-commit-id: 7987673433e91d54efa138bfafd7fbe1a22ee089
2013-05-20 22:54:35 -04:00
Jeremy Long
a939d0c844 various updates recommended by intelliJ
Former-commit-id: 2909f6b33224c74a2984f94651f6418bf60d88fc
2013-05-20 22:50:21 -04:00
Jeremy Long
577b5ad704 various updates recommended by intelliJ
Former-commit-id: 5ec42c1470384e9acd203819daa7d688ed10e965
2013-05-20 22:17:19 -04:00
Jeremy Long
7476550356 version 0.3.1.1-snapshot
Former-commit-id: 172a258ed0804641d1c6f73cb745330213014ceb
2013-05-20 17:04:03 -04:00
323 changed files with 22482 additions and 5461 deletions

9
.gitignore vendored
View File

@@ -1,4 +1,4 @@
/target/
*/target/**
# Intellij project files
*.iml
*.ipr
@@ -6,4 +6,9 @@
.idea/
# Eclipse project files
.classpath
.project
.project
# Netbeans configuration
nb-configuration.xml
/target/
#maven-shade-plugin generated pom
dependency-reduced-pom.xml

View File

@@ -1,13 +1,14 @@
DependencyCheck
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 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 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

View File

@@ -1,25 +1,29 @@
DependencyCheck
=========
Dependency-Check
================
DependencyCheck 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..
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.
More information can be found on the [wiki].
Documentation and links to production binary releases can be found on the [github pages](http://jeremylong.github.io/DependencyCheck/). Additionally, more information about the architecture and ways to extend dependency-check can be found on the [wiki].
Usage
-
> $ mvn package
> $ cd target
> $ java -jar dependency-check-[version].jar -h
> $ java -jar dependency-check-[version].jar -a Testing -out . -scan ./test-classes -scan ./lib
Initial Usage
-------------
On *nix
```
$ mvn install
$ ./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
```
On Windows
```
> mvn install
> 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
```
Then load the resulting 'DependencyCheck-Report.html' into your favorite browser.
Mailing List
-
------------
Subscribe: [dependency-check+subscribe@googlegroups.com] [subscribe]

View File

@@ -0,0 +1,674 @@
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU General Public License is a free, copyleft license for
software and other kinds of works.
The licenses for most software and other practical works are designed
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
share and change all versions of a program--to make sure it remains free
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
any other work released this way by its authors. You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
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
free programs, and that you know you can do these things.
To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. You must make sure that they, too, receive
or can get the source code. And you must show them these terms so they
know their rights.
Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.
For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software. For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so. This is fundamentally incompatible with the aim of
protecting users' freedom to change the software. The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we
have designed this version of the GPL to prohibit the practice for those
products. If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
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
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
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
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
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
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
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.>
Copyright (C) <year> <name of author>
This program 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.
This program 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 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>.

View File

@@ -0,0 +1,29 @@
-----------------------------
---begin dependency-check----
-----------------------------
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
-----------------------------
---end dependency-check------
-----------------------------
Notices below are from dependent libraries and have been included via maven-shade-plugin.
-----------------------------

View File

@@ -0,0 +1,25 @@
Dependency-Check Ant Task
=========
Dependency-Check Ant Task can be used to check the project dependencies for published security vulnerabilities. The checks
performed are a "best effort" and as such, there could be false positives as well as false negatives. However,
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).
Documentation and links to production binary releases can be found on the [github pages](http://jeremylong.github.io/DependencyCheck/dependency-check-ant/installation.html).
Mailing List
------------
Subscribe: [dependency-check+subscribe@googlegroups.com](mailto:dependency-check+subscribe@googlegroups.com)
Post: [dependency-check@googlegroups.com](mailto:dependency-check@googlegroups.com)
Copyright & License
-------------------
Dependency-Check is Copyright (c) 2012-2013 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.
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.

View File

@@ -15,7 +15,7 @@
<property name="severity" value="error"/>
<module name="SuppressionFilter">
<property name="file" value="src/main/config/checkstyle-suppressions.xml"/>
<property name="file" value="${checkstyle.suppressions.file}"/>
</module>
<module name="JavadocPackage">
@@ -40,7 +40,7 @@
</module>
<module name="RegexpHeader">
<property name="headerFile" value="src/main/config/checkstyle-header.txt"/>
<property name="headerFile" value="${checkstyle.header.file}"/>
<property name="fileExtensions" value="java"/>
<property name="id" value="header"/>
</module>

View File

@@ -0,0 +1,19 @@
^/\*\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

View File

@@ -0,0 +1,9 @@
<?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>

View File

@@ -0,0 +1,453 @@
<!--
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 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.
-->
<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>
<parent>
<groupId>org.owasp</groupId>
<artifactId>dependency-check-parent</artifactId>
<version>1.0.2</version>
</parent>
<artifactId>dependency-check-ant</artifactId>
<packaging>jar</packaging>
<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>
<!-- begin copy from http://minds.coremedia.com/2012/09/11/problem-solved-deploy-multi-module-maven-project-site-as-github-pages/ -->
<distributionManagement>
<site>
<id>github-pages-site</id>
<name>Deployment through GitHub's site deployment plugin</name>
<url>${basedir}/../target/site/${project.version}/dependency-check-ant</url>
</site>
</distributionManagement>
<!-- end copy -->
<build>
<resources>
<resource>
<directory>${basedir}/src/main/resources</directory>
<includes>
<include>**/*.properties</include>
</includes>
<filtering>true</filtering>
</resource>
<resource>
<directory>${basedir}</directory>
<targetPath>META-INF</targetPath>
<includes>
<include>LICENSE.txt</include>
<include>NOTICE.txt</include>
</includes>
</resource>
</resources>
<testResources>
<testResource>
<directory>${basedir}/src/test/resources</directory>
<includes>
<include>**/*.xml</include>
</includes>
<filtering>true</filtering>
</testResource>
</testResources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>2.6</version>
<configuration>
<escapeWindowsPaths>false</escapeWindowsPaths>
</configuration>
<executions>
<!-- the following executions are solely to setup the test environment -->
<execution>
<id>copy-test-data.zip</id>
<phase>validate</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/test-classes</outputDirectory>
<resources>
<resource>
<directory>${basedir}/../src/test/resources</directory>
<filtering>false</filtering>
<includes>
<include>data.zip</include>
</includes>
</resource>
</resources>
</configuration>
</execution>
<execution>
<id>copy-test-resources-1</id>
<phase>validate</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/test-classes/lib</outputDirectory>
<resources>
<resource>
<directory>${basedir}/../src/test/resources</directory>
<filtering>false</filtering>
<includes>
<include>org.mortbay.*.jar</include>
</includes>
</resource>
</resources>
</configuration>
</execution>
<execution>
<id>copy-test-resources-2</id>
<phase>validate</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/test-classes/jars</outputDirectory>
<resources>
<resource>
<directory>${basedir}/../src/test/resources</directory>
<filtering>false</filtering>
<includes>
<include>axis-1.4.jar</include>
</includes>
</resource>
</resources>
</configuration>
</execution>
<execution>
<id>copy-test-resources-3</id>
<phase>validate</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/test-classes/webroot</outputDirectory>
<resources>
<resource>
<directory>${basedir}/../src/test/resources</directory>
<filtering>false</filtering>
<includes>
<include>struts.jar</include>
</includes>
</resource>
</resources>
</configuration>
</execution>
<execution>
<id>copy-test-resources-4</id>
<phase>validate</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/test-classes/list</outputDirectory>
<resources>
<resource>
<directory>${basedir}/../src/test/resources</directory>
<filtering>false</filtering>
<includes>
<include>org.mortbay.jetty.jar</include>
</includes>
</resource>
</resources>
</configuration>
</execution>
<execution>
<id>copy-data</id>
<phase>validate</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/test-classes</outputDirectory>
<resources>
<resource>
<directory>${basedir}/../src/test/resources</directory>
<filtering>false</filtering>
<includes>
<include>db.cve.zip</include>
<include>index.cpe.zip</include>
</includes>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.1</version>
<configuration>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer" />
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/NOTICE.txt</resource>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.DontIncludeResourceTransformer">
<resource>META-INF/NOTICE</resource>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.DontIncludeResourceTransformer">
<resource>META-INF/LICENSE</resource>
</transformer>
</transformers>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
</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>
<groupId>org.codehaus.mojo</groupId>
<artifactId>cobertura-maven-plugin</artifactId>
<version>2.5.2</version>
<configuration>
<check>
<branchRate>85</branchRate>
<lineRate>85</lineRate>
<haltOnFailure>false</haltOnFailure>
<totalBranchRate>85</totalBranchRate>
<totalLineRate>85</totalLineRate>
<packageLineRate>85</packageLineRate>
<packageBranchRate>85</packageBranchRate>
<regexes>
<regex>
<pattern>.*\$.*</pattern>
<branchRate>0</branchRate>
<lineRate>0</lineRate>
</regex>
</regexes>
</check>
</configuration>
<executions>
<execution>
<goals>
<goal>clean</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.14</version>
<configuration>
<systemProperties>
<property>
<name>net.sourceforge.cobertura.datafile</name>
<value>${project.build.directory}/cobertura/cobertura.ser</value>
<workingDirectory>target</workingDirectory>
</property>
<property>
<name>data.directory</name>
<value>${project.build.directory}/dependency-check-data</value>
</property>
</systemProperties>
</configuration>
</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>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>findbugs-maven-plugin</artifactId>
<version>2.5.2</version>
</plugin>
</reportPlugins>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.owasp</groupId>
<artifactId>dependency-check-core</artifactId>
<version>${project.parent.version}</version>
</dependency>
<dependency>
<groupId>org.owasp</groupId>
<artifactId>dependency-check-core</artifactId>
<version>${project.parent.version}</version>
<type>test-jar</type>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.ant</groupId>
<artifactId>ant</artifactId>
<version>1.9.1</version>
</dependency>
<dependency>
<groupId>org.apache.ant</groupId>
<artifactId>ant-testutil</artifactId>
<version>1.9.1</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,30 @@
<?xml version="1.0" encoding="UTF-8"?>
<assembly
xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2
http://maven.apache.org/xsd/assembly-1.1.2.xsd
"
>
<id>release</id>
<formats>
<format>zip</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<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>

View File

@@ -0,0 +1,525 @@
/*
* 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;
}
}
}

View File

@@ -0,0 +1,11 @@
/**
* <html>
* <head>
* <title>org.owasp.dependencycheck.taskdefs</title>
* </head>
* <body>
* This package includes the Ant task definitions.
* </body>
* </html>
*/
package org.owasp.dependencycheck.taskdefs;

View File

@@ -1,5 +1,4 @@
handlers=java.util.logging.ConsoleHandler
#, java.util.logging.FileHandler
handlers=java.util.logging.ConsoleHandler, java.util.logging.FileHandler
# logging levels
# FINEST, FINER, FINE, CONFIG, INFO, WARNING and SEVERE.
@@ -7,7 +6,7 @@ handlers=java.util.logging.ConsoleHandler
# Configure the ConsoleHandler.
java.util.logging.ConsoleHandler.level=WARNING
org.owasp.dependencycheck.data.nvdcve.xml
#org.owasp.dependencycheck.data.nvdcve.xml
# Configure the FileHandler.
#java.util.logging.FileHandler.formatter=java.util.logging.SimpleFormatter
@@ -21,4 +20,4 @@ org.owasp.dependencycheck.data.nvdcve.xml
# %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%u.log
#java.util.logging.FileHandler.pattern=./target/dependency-check.log

View File

@@ -0,0 +1,2 @@
# the path to the data directory
data.directory=dependency-check-data

View File

@@ -0,0 +1,3 @@
# define custom tasks here
dependencycheck=org.owasp.dependencycheck.taskdefs.DependencyCheckTask

View File

@@ -0,0 +1,35 @@
Configuration
====================
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)
such as a [FileSet](http://ant.apache.org/manual/Types/fileset.html), [DirSet](http://ant.apache.org/manual/Types/dirset.html),
or [FileList](http://ant.apache.org/manual/Types/filelist.html) that includes
the project's dependencies.
```xml
<target name="dependency-check" description="Dependency-Check Analysis">
<dependency-check applicationname="Hello World"
reportoutputdirectory="${basedir}"
reportformat="ALL">
<fileset dir="lib">
<include name="**/*.jar"/>
</fileset>
</dependency-check>
</target>
```
The following table lists the configurable properties:
Property | Description | Requirement
----------------------|-------------|---------
ApplicationName | The name of the application to use in the generated report. | Required
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

View File

@@ -0,0 +1,13 @@
Installation
====================
Download dependency-check-ant from [bintray here](http://dl.bintray.com/jeremy-long/owasp/dependency-check-ant-1.0.0.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.

View File

@@ -0,0 +1,25 @@
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.

View File

@@ -0,0 +1,36 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<!--
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.
-->
<project name="dependency-check-ant">
<bannerLeft>
<name>dependency-check-ant</name>
</bannerLeft>
<body>
<breadcrumbs>
<item name="dependency-check" href="../index.html"/>
</breadcrumbs>
<menu name="Getting Started">
<item name="Installation" href="installation.html"/>
<item name="Usage" href="usage.html"/>
<item name="Configuration" href="configuration.html"/>
</menu>
<menu ref="Project Documentation" />
<menu ref="reports" />
</body>
</project>

View File

@@ -0,0 +1,123 @@
/*
* 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 static junit.framework.TestCase.assertTrue;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.apache.tools.ant.BuildFileTest;
import org.owasp.dependencycheck.data.nvdcve.BaseDBTestCase;
/**
*
* @author Jeremy Long (jeremy.long@owasp.org)
*/
public class DependencyCheckTaskTest extends BuildFileTest {
public DependencyCheckTaskTest() {
}
@BeforeClass
public static void setUpClass() {
}
@AfterClass
public static void tearDownClass() {
}
@Before
@Override
public void setUp() throws Exception {
BaseDBTestCase.ensureDBExists();
final String buildFile = this.getClass().getClassLoader().getResource("build.xml").getPath();
configureProject(buildFile);
}
@After
@Override
public void tearDown() {
//no cleanup...
//executeTarget("cleanup");
}
/**
* Test of addFileSet method, of class DependencyCheckTask.
*/
@Test
public void testAddFileSet() throws Exception {
File report = new File("target/DependencyCheck-Report.html");
if (report.exists()) {
if (!report.delete()) {
throw new Exception("Unable to delete 'target/DependencyCheck-Report.html' prior to test.");
}
}
executeTarget("test.fileset");
assertTrue("DependencyCheck report was not generated", report.exists());
}
/**
* Test of addFileList method, of class DependencyCheckTask.
*
* @throws Exception
*/
@Test
public void testAddFileList() throws Exception {
File report = new File("target/DependencyCheck-Report.xml");
if (report.exists()) {
if (!report.delete()) {
throw new Exception("Unable to delete 'target/DependencyCheck-Report.xml' prior to test.");
}
}
executeTarget("test.filelist");
assertTrue("DependencyCheck report was not generated", report.exists());
}
/**
* Test of addDirSet method, of class DependencyCheckTask.
*
* @throws Exception
*/
@Test
public void testAddDirSet() throws Exception {
File report = new File("target/DependencyCheck-Vulnerability.html");
if (report.exists()) {
if (!report.delete()) {
throw new Exception("Unable to delete 'target/DependencyCheck-Vulnerability.html' prior to test.");
}
}
executeTarget("test.dirset");
assertTrue("DependencyCheck report was not generated", report.exists());
}
/**
* Test of getFailBuildOnCVSS method, of class DependencyCheckTask.
*/
@Test
public void testGetFailBuildOnCVSS() {
expectBuildException("failCVSS", "asdfasdfscore");
System.out.println(this.getOutput());
}
}

View File

@@ -0,0 +1,71 @@
<?xml version="1.0" encoding="UTF-8"?>
<project name="Dependency-Check Test Build" default="test.fileset" basedir=".">
<taskdef name="dependency-check" classname="org.owasp.dependencycheck.taskdefs.DependencyCheckTask" />
<target name="test.fileset">
<dependency-check
applicationName="My Project"
reportOutputDirectory="${project.build.directory}"
autoupdate="false"
reportFormat="HTML">
<!-- Scan a single file -->
<fileset dir="${project.build.directory}/test-classes/jars">
<include name="axis-1.4.jar"/>
</fileset>
<!-- Scan for all jar/war/ear in the webroot dir and all sub directories -->
<fileset dir="${project.build.directory}/test-classes/webroot">
<include name="**/*.jar"/>
<include name="**/*.war"/>
<include name="**/*.ear"/>
</fileset>
</dependency-check>
</target>
<target name="test.filelist">
<dependency-check
applicationName="My Project"
reportOutputDirectory="${project.build.directory}"
autoupdate="false"
reportFormat="XML">
<!-- Scan specific files -->
<filelist
dir="${project.build.directory}/test-classes/list"
files="jetty-6.1.0.jar,org.mortbay.jetty.jar"/>
</dependency-check>
</target>
<target name="test.dirset">
<dependency-check
applicationName="My Project"
reportOutputDirectory="${project.build.directory}"
autoupdate="false"
reportFormat="VULN">
<!-- Scan a specific directory -->
<dirset dir="${project.build.directory}/test-classes">
<include name="lib"/>
</dirset>
</dependency-check>
</target>
<target name="formatBAD">
<dependency-check
applicationName="test formatBAD"
reportOutputDirectory="${project.build.directory}"
autoupdate="false"
reportFormat="BAD">
</dependency-check>
</target>
<target name="failCVSS">
<dependency-check
applicationName="test formatBAD"
reportOutputDirectory="${project.build.directory}"
reportFormat="XML"
autoupdate="false"
failBuildOnCVSS="8">
</dependency-check>
</target>
</project>

View File

@@ -0,0 +1,674 @@
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU General Public License is a free, copyleft license for
software and other kinds of works.
The licenses for most software and other practical works are designed
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
share and change all versions of a program--to make sure it remains free
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
any other work released this way by its authors. You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
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
free programs, and that you know you can do these things.
To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. You must make sure that they, too, receive
or can get the source code. And you must show them these terms so they
know their rights.
Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.
For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software. For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so. This is fundamentally incompatible with the aim of
protecting users' freedom to change the software. The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we
have designed this version of the GPL to prohibit the practice for those
products. If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
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
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
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
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
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
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
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.>
Copyright (C) <year> <name of author>
This program 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.
This program 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 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>.

View File

@@ -0,0 +1,18 @@
dependency-check-cli
Copyright (c) 2013 Jeremy Long. All Rights Reserved.
The licenses for the software listed below can be found in the licenses.
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

View File

@@ -0,0 +1,24 @@
Dependency-Check Command Line
================
Dependency-Check Command Line can be used to check project dependencies for published security vulnerabilities. The checks
performed are a "best effort" and as such, there could be false positives as well as false negatives. However,
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).
Documentation and links to production binary releases can be found on the [github pages](http://jeremylong.github.io/DependencyCheck/dependency-check-cli/installation.html).
Mailing List
------------
Subscribe: [dependency-check+subscribe@googlegroups.com](mailto:dependency-check+subscribe@googlegroups.com)
Post: [dependency-check@googlegroups.com](mailto:dependency-check@googlegroups.com)
Copyright & License
------------
Dependency-Check is Copyright (c) 2012-2013 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.
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.

View File

@@ -0,0 +1,223 @@
<?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>

View File

@@ -0,0 +1,19 @@
^/\*\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

View File

@@ -0,0 +1,9 @@
<?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>

View File

@@ -0,0 +1,340 @@
<!--
This file is part of Dependency-Check.
Dependency-Check 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 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. If not, see <http://www.gnu.org/licenses />.
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">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.owasp</groupId>
<artifactId>dependency-check-parent</artifactId>
<version>1.0.2</version>
</parent>
<artifactId>dependency-check-cli</artifactId>
<packaging>jar</packaging>
<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>
<!-- begin copy from http://minds.coremedia.com/2012/09/11/problem-solved-deploy-multi-module-maven-project-site-as-github-pages/ -->
<distributionManagement>
<site>
<id>github-pages-site</id>
<name>Deployment through GitHub's site deployment plugin</name>
<url>${basedir}/../target/site/${project.version}/dependency-check-cli</url>
</site>
</distributionManagement>
<!-- end copy -->
<build>
<finalName>dependency-check-${project.version}</finalName>
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.properties</include>
</includes>
<filtering>true</filtering>
</resource>
<resource>
<directory>${basedir}</directory>
<targetPath>META-INF</targetPath>
<includes>
<include>LICENSE.txt</include>
<include>NOTICE.txt</include>
</includes>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.4</version>
<configuration>
<archive>
<manifest>
<mainClass>org.owasp.dependencycheck.App</mainClass>
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
</manifest>
</archive>
<excludes>
<exclude>**/checkstyle*</exclude>
</excludes>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>cobertura-maven-plugin</artifactId>
<version>2.5.2</version>
<configuration>
<check>
<branchRate>85</branchRate>
<lineRate>85</lineRate>
<haltOnFailure>false</haltOnFailure>
<totalBranchRate>85</totalBranchRate>
<totalLineRate>85</totalLineRate>
<packageLineRate>85</packageLineRate>
<packageBranchRate>85</packageBranchRate>
<regexes>
<regex>
<pattern>.*\$.*</pattern>
<branchRate>0</branchRate>
<lineRate>0</lineRate>
</regex>
<regex>
<pattern>org.owasp.dependencycheck.App</pattern>
<branchRate>0</branchRate>
<lineRate>0</lineRate>
</regex>
</regexes>
</check>
</configuration>
<executions>
<execution>
<goals>
<goal>clean</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.14</version>
<configuration>
<systemProperties>
<property>
<name>net.sourceforge.cobertura.datafile</name>
<value>${project.build.directory}/cobertura/cobertura.ser</value>
<workingDirectory>target</workingDirectory>
</property>
<property>
<name>cpe</name>
<value>data/cpe</value>
<workingDirectory>target</workingDirectory>
</property>
<property>
<name>cve</name>
<value>data/cpe</value>
<workingDirectory>target</workingDirectory>
</property>
</systemProperties>
</configuration>
</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>
<groupId>org.codehaus.mojo</groupId>
<artifactId>appassembler-maven-plugin</artifactId>
<version>1.4</version>
<configuration>
<programs>
<program>
<mainClass>org.owasp.dependencycheck.App</mainClass>
<name>dependency-check</name>
</program>
</programs>
<assembleDirectory>${project.build.directory}/release</assembleDirectory>
<licenseHeaderFile>${basedir}/src/main/assembly/license.txt</licenseHeaderFile>
<binFileExtensions>
<unix>.sh</unix>
</binFileExtensions>
</configuration>
<executions>
<execution>
<id>assemble</id>
<goals>
<goal>assemble</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<attach>false</attach> <!-- don't install/deploy this archive -->
</configuration>
<executions>
<execution>
<id>create-distribution</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<descriptors>
<descriptor>src/main/assembly/release.xml</descriptor>
</descriptors>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>commons-cli</groupId>
<artifactId>commons-cli</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>org.owasp</groupId>
<artifactId>dependency-check-core</artifactId>
<version>${project.parent.version}</version>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,15 @@
Copyright (c) 2012-2013 Jeremy Long. All rights reserved.
Licensed under the GPL License, Version 3; you may not use this work
except in compliance with the License. You may obtain a copy of the
License in the LICENSE.txt file, or at:
http://www.gnu.org/licenses/gpl-3.0.txt
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.
----------------------------------------------------------------------------

View File

@@ -0,0 +1,60 @@
<?xml version="1.0" encoding="UTF-8"?>
<assembly
xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2
http://maven.apache.org/xsd/assembly-1.1.2.xsd
"
>
<id>release</id>
<formats>
<format>zip</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<fileSets>
<fileSet>
<outputDirectory>/</outputDirectory>
<directory>${project.build.directory}/release</directory>
</fileSet>
<fileSet>
<includes>
<include>LICENSE*</include>
<include>NOTICE*</include>
</includes>
</fileSet>
<fileSet>
<outputDirectory>licenses</outputDirectory>
<directory>${basedir}/src/main/resources/META-INF/licenses</directory>
</fileSet>
<fileSet>
<outputDirectory>licenses</outputDirectory>
<directory>${basedir}/../dependency-check-core/src/main/resources/META-INF/licenses</directory>
</fileSet>
<fileSet>
<outputDirectory>/</outputDirectory>
<directory>${basedir}</directory>
<includes>
<include>README.md</include>
<include>LICENSE.txt</include>
</includes>
</fileSet>
</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>

View File

@@ -1,23 +1,24 @@
/*
* This file is part of Dependency-Check.
* This file is part of dependency-check-cli.
*
* Dependency-Check is free software: you can redistribute it and/or modify it
* 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 is distributed in the hope that it will be useful, but
* 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. If not, see http://www.gnu.org/licenses/.
* dependency-check-cli. If not, see http://www.gnu.org/licenses/.
*
* Copyright (c) 2012 Jeremy Long. All Rights Reserved.
*/
package org.owasp.dependencycheck;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
@@ -28,7 +29,7 @@ import java.util.logging.Logger;
import org.apache.commons.cli.ParseException;
import org.owasp.dependencycheck.reporting.ReportGenerator;
import org.owasp.dependencycheck.dependency.Dependency;
import org.owasp.dependencycheck.utils.CliParser;
import org.owasp.dependencycheck.cli.CliParser;
import org.owasp.dependencycheck.utils.Settings;
/*
@@ -58,7 +59,7 @@ public class App {
/**
* The location of the log properties configuration file.
*/
private static final String LOG_PROPERTIES_FILE = "configuration/log.properties";
private static final String LOG_PROPERTIES_FILE = "log.properties";
/**
* The main method for the application.
@@ -81,16 +82,16 @@ public class App {
LogManager.getLogManager().reset();
LogManager.getLogManager().readConfiguration(in);
} catch (IOException ex) {
System.err.println(ex.toString());
Logger.getLogger(App.class.getName()).log(Level.SEVERE, null, 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.SEVERE, null, ex);
Logger.getLogger(App.class.getName()).log(Level.FINE, "Error preparing the logger", ex);
} finally {
try {
in.close();
} catch (Exception ex) {
//ignore
in = null;
if (in != null) {
try {
in.close();
} catch (Exception ex) {
Logger.getLogger(App.class.getName()).log(Level.FINEST, "Error closing resource stream", ex);
}
}
}
}
@@ -108,19 +109,17 @@ public class App {
} catch (FileNotFoundException ex) {
System.err.println(ex.getMessage());
cli.printHelp();
Logger.getLogger(App.class.getName()).log(Level.WARNING, null, ex);
return;
} catch (ParseException ex) {
System.err.println(ex.getMessage());
cli.printHelp();
Logger.getLogger(App.class.getName()).log(Level.INFO, null, ex);
return;
}
if (cli.isGetVersion()) {
cli.printVersionInfo();
} else if (cli.isRunScan()) {
updateSettings(cli.isAutoUpdate(), cli.isDeepScan(), cli.getConnectionTimeout(), cli.getProxyUrl(), cli.getProxyPort());
updateSettings(cli.isAutoUpdate(), cli.getConnectionTimeout(), cli.getProxyUrl(), cli.getProxyPort(), cli.getDataDirectory());
runScan(cli.getReportDirectory(), cli.getReportFormat(), cli.getApplicationName(), cli.getScanFiles());
} else {
cli.printHelp();
@@ -151,23 +150,41 @@ public class App {
try {
report.generateReports(reportDirectory, outputFormat);
} catch (IOException ex) {
Logger.getLogger(App.class.getName()).log(Level.SEVERE, null, ex);
Logger.getLogger(App.class.getName()).log(Level.SEVERE, "There was an IO error while attempting to generate the report.");
Logger.getLogger(App.class.getName()).log(Level.INFO, null, ex);
} catch (Exception ex) {
Logger.getLogger(App.class.getName()).log(Level.SEVERE, null, ex);
Logger.getLogger(App.class.getName()).log(Level.SEVERE, "There was an error while attempting to generate the report.");
Logger.getLogger(App.class.getName()).log(Level.INFO, null, ex);
}
}
/**
* Updates the global Settings.
*
* @param autoUpdate whether or not to update cached web data sources
* @param deepScan whether or not to perform a deep scan (increases false positives, but may reduce false negatives)
* @param connectionTimeout the timeout to use when downloading resources (null or blank will use default)
* @param connectionTimeout the timeout to use when downloading resources
* (null or blank will use default)
* @param proxyUrl the proxy url (null or blank means no proxy will be used)
* @param proxyPort the proxy port (null or blank means no port will be used)
* @param proxyPort the proxy port (null or blank means no port will be
* used)
* @param dataDirectory the directory to store/retrieve persistent data from
*/
private void updateSettings(boolean autoUpdate, boolean deepScan, String connectionTimeout, String proxyUrl, String proxyPort) {
private void updateSettings(boolean autoUpdate, String connectionTimeout, String proxyUrl, String proxyPort, String dataDirectory) {
if (dataDirectory != null) {
Settings.setString(Settings.KEYS.DATA_DIRECTORY, dataDirectory);
} else if (System.getProperty("basedir") != null) {
final File dataDir = new File(System.getProperty("basedir"), "data");
Settings.setString(Settings.KEYS.DATA_DIRECTORY, dataDir.getAbsolutePath());
} else {
final File jarPath = new File(App.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);
Settings.setBoolean(Settings.KEYS.PERFORM_DEEP_SCAN, deepScan);
if (proxyUrl != null && !proxyUrl.isEmpty()) {
Settings.setString(Settings.KEYS.PROXY_URL, proxyUrl);
}

View File

@@ -1,22 +1,22 @@
/*
* This file is part of Dependency-Check.
* This file is part of dependency-check-cli.
*
* Dependency-Check is free software: you can redistribute it and/or modify it
* 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 is distributed in the hope that it will be useful, but
* 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. If not, see http://www.gnu.org/licenses/.
* dependency-check-cli. If not, see http://www.gnu.org/licenses/.
*
* Copyright (c) 2012 Jeremy Long. All Rights Reserved.
*/
package org.owasp.dependencycheck.utils;
package org.owasp.dependencycheck.cli;
import java.io.File;
import java.io.FileNotFoundException;
@@ -29,6 +29,8 @@ 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.
@@ -44,7 +46,7 @@ public final class CliParser {
/**
* The options for the command line parser.
*/
private Options options = createCommandLineOptions();
private final Options options = createCommandLineOptions();
/**
* Indicates whether the arguments are valid.
*/
@@ -75,8 +77,7 @@ public final class CliParser {
*/
private CommandLine parseArgs(String[] args) throws ParseException {
final CommandLineParser parser = new PosixParser();
final CommandLine ln = parser.parse(options, args);
return ln;
return parser.parse(options, args);
}
/**
@@ -84,34 +85,23 @@ public final class CliParser {
*
* @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.
* @throws ParseException is thrown if there is an exception parsing the
* command line.
*/
private void validateArgs() throws FileNotFoundException, ParseException {
if (isRunScan()) {
validatePathExists(getScanFiles());
if (!line.hasOption(ArgumentName.OUT)) {
//TODO - need a new exception type here, this isn't really a ParseException.
throw new ParseException("Scan cannot be run without specifying a directory "
+ "to write the reports to via the 'out' argument.");
} else {
final String p = line.getOptionValue(ArgumentName.OUT, "");
final File f = new File(p);
if ("".equals(p) || !(f.exists() && f.isDirectory())) {
//TODO - need a new exception type here, this isn't really a ParseException.
throw new ParseException("A valid directory name must be specified for "
+ "the 'out' argument.");
}
}
if (!line.hasOption(ArgumentName.APPNAME)) {
throw new ParseException("Scan cannot be run without specifying an application "
+ "name via the 'app' argument.");
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);
if (!("ALL".equalsIgnoreCase(format)
|| "XML".equalsIgnoreCase(format)
|| "HTML".equalsIgnoreCase(format))) {
throw new ParseException("Supported output formats are XML, HTML, or ALL");
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);
}
}
}
@@ -123,12 +113,13 @@ public final class CliParser {
* 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) throws FileNotFoundException {
private void validatePathExists(String[] paths, String optType) throws FileNotFoundException {
for (String path : paths) {
validatePathExists(path);
validatePathExists(path, optType);
}
}
@@ -138,14 +129,16 @@ public final class CliParser {
* 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) throws FileNotFoundException {
private void validatePathExists(String path, String optType) throws FileNotFoundException {
final File f = new File(path);
if (!f.exists()) {
isValid = false;
throw new FileNotFoundException("Invalid file argument: " + path);
final String msg = String.format("Invalid '%s' argument: '%s'", optType, path);
throw new FileNotFoundException(msg);
}
}
@@ -158,47 +151,48 @@ public final class CliParser {
@SuppressWarnings("static-access")
private Options createCommandLineOptions() {
final Option help = new Option(ArgumentName.HELP_SHORT, ArgumentName.HELP, false,
"print this message.");
final Option deepScan = new Option(ArgumentName.PERFORM_DEEP_SCAN_SHORT, ArgumentName.PERFORM_DEEP_SCAN, false,
"extracts extra information from dependencies that may increase false positives, but also decrease false negatives.");
"Print this message.");
final Option version = new Option(ArgumentName.VERSION_SHORT, ArgumentName.VERSION,
false, "print the version information.");
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 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.APPNAME)
.withDescription("the name of the application being scanned.")
.create(ArgumentName.APPNAME_SHORT);
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.")
.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.")
.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.")
.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.")
.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.")
.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.")
.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, ALL).")
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();
@@ -207,13 +201,13 @@ public final class CliParser {
final Options opts = new Options();
opts.addOptionGroup(og);
opts.addOption(out);
opts.addOption(outputformat);
opts.addOption(appname);
opts.addOption(outputFormat);
opts.addOption(appName);
opts.addOption(version);
opts.addOption(help);
opts.addOption(noupdate);
opts.addOption(deepScan);
opts.addOption(noUpdate);
opts.addOption(props);
opts.addOption(data);
opts.addOption(proxyPort);
opts.addOption(proxyUrl);
opts.addOption(connectionTimeout);
@@ -282,12 +276,12 @@ public final class CliParser {
* @return the path to the reports directory.
*/
public String getReportDirectory() {
return line.getOptionValue(ArgumentName.OUT);
return line.getOptionValue(ArgumentName.OUT, ".");
}
/**
* Returns the output format specified on the command line. Defaults to
* HTML if no format was specified.
* Returns the output format specified on the command line. Defaults to HTML
* if no format was specified.
*
* @return the output format name.
*/
@@ -301,11 +295,12 @@ public final class CliParser {
* @return the application name.
*/
public String getApplicationName() {
return line.getOptionValue(ArgumentName.APPNAME);
return line.getOptionValue(ArgumentName.APP_NAME);
}
/**
* Returns the connection timeout.
*
* @return the connection timeout
*/
public String getConnectionTimeout() {
@@ -314,6 +309,7 @@ public final class CliParser {
/**
* Returns the proxy url.
*
* @return the proxy url
*/
public String getProxyUrl() {
@@ -322,12 +318,22 @@ public final class CliParser {
/**
* 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>
@@ -350,13 +356,6 @@ public final class CliParser {
return (line == null) || !line.hasOption(ArgumentName.DISABLE_AUTO_UPDATE);
}
/**
* Checks if a deep scan of the dependencies was requested.
* @return whether a deep scan of the evidence within the dependencies was requested.
*/
public boolean isDeepScan() {
return (line != null) && line.hasOption(ArgumentName.PERFORM_DEEP_SCAN);
}
/**
* A collection of static final strings that represent the possible command
* line arguments.
@@ -405,12 +404,12 @@ public final class CliParser {
* The long CLI argument name specifying the name of the application to
* be scanned.
*/
public static final String APPNAME = "app";
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 APPNAME_SHORT = "a";
public static final String APP_NAME_SHORT = "a";
/**
* The long CLI argument name asking for help.
*/
@@ -451,16 +450,6 @@ public final class CliParser {
* The CLI argument name indicating the proxy url.
*/
public static final String CONNECTION_TIMEOUT = "connectiontimeout";
/**
* The short CLI argument name indicating a deep scan of the dependencies
* should be performed.
*/
public static final String PERFORM_DEEP_SCAN_SHORT = "d";
/**
* The CLI argument name indicating a deep scan of the dependencies
* should be performed.
*/
public static final String PERFORM_DEEP_SCAN = "deepscan";
/**
* The short CLI argument name for setting the location of an additional
* properties file.
@@ -471,5 +460,14 @@ public final class CliParser {
* 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";
}
}

View File

@@ -0,0 +1,12 @@
/**
* <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;

View File

@@ -0,0 +1,24 @@
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

View File

@@ -0,0 +1,16 @@
Installation & Usage
--------------------
Downlod the dependency-check command line tool [here](http://dl.bintray.com/jeremy-long/owasp/dependency-check-1.0.0-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"

View File

@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<!--
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) 2013 Jeremy Long. All Rights Reserved.
-->
<project name="dependency-check-cli">
<bannerLeft>
<name>dependency-check-cli</name>
</bannerLeft>
<body>
<breadcrumbs>
<item name="dependency-check" href="../index.html"/>
</breadcrumbs>
<menu name="Getting Started">
<item name="Installation" href="installation.html"/>
</menu>
<menu ref="Project Documentation" />
<menu ref="reports" />
</body>
</project>

View File

@@ -16,9 +16,9 @@
*
* Copyright (c) 2012 Jeremy Long. All Rights Reserved.
*/
package org.owasp.dependencycheck.utils;
package org.owasp.dependencycheck.cli;
import org.owasp.dependencycheck.utils.CliParser;
import org.owasp.dependencycheck.cli.CliParser;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
@@ -56,6 +56,7 @@ public class CliParserTest {
/**
* Test of parse method, of class CliParser.
*
* @throws Exception thrown when an exception occurs.
*/
@Test
@@ -77,6 +78,7 @@ public class CliParserTest {
/**
* Test of parse method with help arg, of class CliParser.
*
* @throws Exception thrown when an exception occurs.
*/
@Test
@@ -95,6 +97,7 @@ public class CliParserTest {
/**
* Test of parse method with version arg, of class CliParser.
*
* @throws Exception thrown when an exception occurs.
*/
@Test
@@ -112,6 +115,7 @@ public class CliParserTest {
/**
* Test of parse method with jar and cpe args, of class CliParser.
*
* @throws Exception thrown when an exception occurs.
*/
@Test
@@ -140,6 +144,7 @@ public class CliParserTest {
/**
* Test of parse method with scan arg, of class CliParser.
*
* @throws Exception thrown when an exception occurs.
*/
@Test
@@ -162,6 +167,7 @@ public class CliParserTest {
/**
* Test of parse method with jar arg, of class CliParser.
*
* @throws Exception thrown when an exception occurs.
*/
@Test
@@ -173,7 +179,7 @@ public class CliParserTest {
try {
instance.parse(args);
} catch (FileNotFoundException ex) {
Assert.assertTrue(ex.getMessage().contains("Invalid file argument"));
Assert.assertTrue(ex.getMessage().contains("Invalid 'scan' argument"));
}
Assert.assertFalse(instance.isGetVersion());
@@ -183,6 +189,7 @@ public class CliParserTest {
/**
* Test of parse method with jar arg, of class CliParser.
*
* @throws Exception thrown when an exception occurs.
*/
@Test
@@ -202,6 +209,7 @@ public class CliParserTest {
/**
* Test of printVersionInfo, of class CliParser.
*
* @throws Exception thrown when an exception occurs.
*/
@Test
@@ -230,6 +238,7 @@ public class CliParserTest {
/**
* Test of printHelp, of class CliParser.
*
* @throws Exception thrown when an exception occurs.
*/
@Test

View File

@@ -0,0 +1,223 @@
<?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>

View File

@@ -0,0 +1,19 @@
^/\*\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

View File

@@ -9,7 +9,4 @@
<suppress checks=".*" files=".*org[\\/]owasp[\\/]dependencycheck[\\/]utils[\\/]Filter.java" />
<suppress checks=".*" files=".*org[\\/]owasp[\\/]dependencycheck[\\/]utils[\\/]Checksum.java" />
<suppress checks=".*" files=".*[\\/]generated[\\/].*.java" />
<suppress checks="MagicNumberCheck"
files="org[\\/]owasp[\\/]dependencycheck[\\/]data[\\/]cpe/Entry.java"
lines="376"/>
</suppressions>

View File

@@ -0,0 +1,564 @@
<!--
Copyright (c) 2012 - Jeremy Long
This file is part of Dependency-Check.
Dependency-Check 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 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. 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">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.owasp</groupId>
<artifactId>dependency-check-parent</artifactId>
<version>1.0.2</version>
</parent>
<artifactId>dependency-check-core</artifactId>
<packaging>jar</packaging>
<name>Dependency-Check Core</name>
<!-- begin copy from http://minds.coremedia.com/2012/09/11/problem-solved-deploy-multi-module-maven-project-site-as-github-pages/ -->
<distributionManagement>
<site>
<id>github-pages-site</id>
<name>Deployment through GitHub's site deployment plugin</name>
<url>${basedir}/../target/site/${project.version}/dependency-check-core</url>
</site>
</distributionManagement>
<!-- end copy -->
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.properties</include>
</includes>
<filtering>true</filtering>
</resource>
<resource>
<directory>${basedir}/..</directory>
<targetPath>META-INF</targetPath>
<includes>
<include>LICENSE.txt</include>
<include>NOTICE.txt</include>
</includes>
</resource>
<resource>
<directory>src/main/resources</directory>
<excludes>
<exclude>**/*.properties</exclude>
<exclude>**/*.gif</exclude>
<exclude>**/*.js</exclude>
<exclude>**/schema/**/*.xsd</exclude>
<exclude>**/schema/**/*.xml</exclude>
<exclude>**/schema/**/*.bat</exclude>
<exclude>**/schema/**/*.sh</exclude>
</excludes>
<filtering>false</filtering>
</resource>
</resources>
<testResources>
<testResource>
<directory>${basedir}/../src/test/resources</directory>
<filtering>false</filtering>
</testResource>
<testResource>
<directory>${basedir}/src/test/resources</directory>
<filtering>false</filtering>
</testResource>
</testResources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.8</version>
<executions>
<execution>
<phase>generate-resources</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/test-classes</outputDirectory>
<includeScope>provided</includeScope>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.4</version>
<executions>
<execution>
<id>jar</id>
<phase>package</phase>
<goals>
<goal>jar</goal>
</goals>
</execution>
<execution>
<id>test-jar</id>
<phase>package</phase>
<goals>
<goal>test-jar</goal>
</goals>
</execution>
</executions>
<configuration>
<archive>
<manifest>
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
</manifest>
</archive>
<excludes>
<exclude>**/checkstyle*</exclude>
</excludes>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>cobertura-maven-plugin</artifactId>
<version>2.5.2</version>
<configuration>
<instrumentation>
<ignores>
<ignore>.*\$KEYS\.class</ignore>
<ignore>.*\$Element\.class</ignore>
</ignores>
<excludes>
<exclude>.*\$KEYS\.class</exclude>
<exclude>.*\$Element\.class</exclude>
</excludes>
</instrumentation>
<check>
<branchRate>85</branchRate>
<lineRate>85</lineRate>
<haltOnFailure>false</haltOnFailure>
<totalBranchRate>85</totalBranchRate>
<totalLineRate>85</totalLineRate>
<packageLineRate>85</packageLineRate>
<packageBranchRate>85</packageBranchRate>
<regexes>
<regex>
<pattern>.*\$.*</pattern>
<branchRate>0</branchRate>
<lineRate>0</lineRate>
</regex>
<regex>
<pattern>org.owasp.dependencycheck.data.cpe.Fields</pattern>
<branchRate>0</branchRate>
<lineRate>0</lineRate>
</regex>
<regex>
<pattern>org.owasp.dependencycheck.App</pattern>
<branchRate>0</branchRate>
<lineRate>0</lineRate>
</regex>
</regexes>
</check>
</configuration>
<executions>
<execution>
<goals>
<goal>clean</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.14</version>
<configuration>
<systemProperties>
<property>
<name>net.sourceforge.cobertura.datafile</name>
<value>${project.build.directory}/cobertura/cobertura.ser</value>
<workingDirectory>target</workingDirectory>
</property>
<property>
<name>data.directory</name>
<value>${project.build.directory}/data</value>
</property>
<property>
<name>temp.directory</name>
<value>${project.build.directory}/temp</value>
</property>
</systemProperties>
<excludes>
<exclude>**/*IntegrationTest.java</exclude>
</excludes>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.14</version>
<configuration>
<systemProperties>
<property>
<name>data.directory</name>
<value>${project.build.directory}/data</value>
</property>
</systemProperties>
<includes>
<include>**/*IntegrationTest.java</include>
</includes>
</configuration>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
</execution>
</executions>
</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>
<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>
</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>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<showDeprecation>false</showDeprecation>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-test-framework</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>
</dependency>
<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.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>2.5.5</version>
<scope>provided</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.hazelcast</groupId>
<artifactId>hazelcast</artifactId>
<version>2.5</version>
<scope>provided</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache-core</artifactId>
<version>2.2.0</version>
<scope>provided</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-core</artifactId>
<version>2.1.2</version>
<scope>provided</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.mortbay.jetty</groupId>
<artifactId>jetty</artifactId>
<version>6.1.0</version>
<scope>provided</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.apache.axis2</groupId>
<artifactId>axis2-spring</artifactId>
<version>1.4.1</version>
<scope>provided</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.apache.axis2</groupId>
<artifactId>axis2-adb</artifactId>
<version>1.4.1</version>
<scope>provided</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>provided</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.glassfish.main.admingui</groupId>
<artifactId>war</artifactId>
<version>4.0</version>
<type>war</type>
<scope>provided</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.dojotoolkit</groupId>
<artifactId>dojo-war</artifactId>
<version>1.3.0</version>
<type>war</type>
<scope>provided</scope>
<optional>true</optional>
</dependency>
</dependencies>
</project>

View File

@@ -1,18 +1,18 @@
/*
* This file is part of Dependency-Check.
* This file is part of dependency-check-core.
*
* Dependency-Check is free software: you can redistribute it and/or modify it
* 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 is distributed in the hope that it will be useful, but
* 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. If not, see http://www.gnu.org/licenses/.
* dependency-check-core. If not, see http://www.gnu.org/licenses/.
*
* Copyright (c) 2012 Jeremy Long. All Rights Reserved.
*/
@@ -52,28 +52,28 @@ public class Engine {
/**
* The list of dependencies.
*/
private List<Dependency> dependencies = new ArrayList<Dependency>();
private final List<Dependency> dependencies = new ArrayList<Dependency>();
/**
* A Map of analyzers grouped by Analysis phase.
*/
private EnumMap<AnalysisPhase, List<Analyzer>> analyzers =
private final EnumMap<AnalysisPhase, List<Analyzer>> analyzers =
new EnumMap<AnalysisPhase, List<Analyzer>>(AnalysisPhase.class);
/**
* A set of extensions supported by the analyzers.
*/
private Set<String> extensions = new HashSet<String>();
private final Set<String> extensions = new HashSet<String>();
/**
* Creates a new Engine.
*/
public Engine() {
boolean autoupdate = true;
boolean autoUpdate = true;
try {
autoupdate = Settings.getBoolean(Settings.KEYS.AUTO_UPDATE);
autoUpdate = Settings.getBoolean(Settings.KEYS.AUTO_UPDATE);
} catch (InvalidSettingException ex) {
Logger.getLogger(Engine.class.getName()).log(Level.WARNING, "Invalid setting for auto-update.");
Logger.getLogger(Engine.class.getName()).log(Level.FINE, "Invalid setting for auto-update; using true.");
}
if (autoupdate) {
if (autoUpdate) {
doUpdates();
}
loadAnalyzers();
@@ -83,8 +83,9 @@ public class Engine {
* Creates a new Engine.
*
* @param autoUpdate indicates whether or not data should be updated from
* the Internet.
* @deprecated this function should no longer be used; the autoupdate flag should be set using
* the Internet
* @deprecated This function should no longer be used; the autoupdate flag
* should be set using:
* <code>Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, value);</code>
*/
@Deprecated
@@ -135,6 +136,22 @@ public class Engine {
return dependencies;
}
/**
* 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.
*
* @since v0.3.2.5
*
* @param paths an array of paths to files or directories to be analyzed.
*/
public void scan(String[] paths) {
for (String path : paths) {
final File file = new File(path);
scan(file);
}
}
/**
* Scans a given file or directory. If a directory is specified, it will be
* scanned recursively. Any dependencies identified are added to the
@@ -144,6 +161,64 @@ public class Engine {
*/
public void scan(String path) {
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.
*
* @since v0.3.2.5
*
* @param files an array of paths to files or directories to be analyzed.
*/
public void scan(File[] files) {
for (File file : files) {
scan(file);
}
}
/**
* Scans a list of files or directories. If a directory is specified, it
* will be scanned recursively. Any dependencies identified are added to the
* dependency collection.
*
* @since v0.3.2.5
*
* @param files a set of paths to files or directories to be analyzed.
*/
public void scan(Set<File> files) {
for (File file : files) {
scan(file);
}
}
/**
* Scans a list of files or directories. If a directory is specified, it
* will be scanned recursively. Any dependencies identified are added to the
* dependency collection.
*
* @since v0.3.2.5
*
* @param files a set of paths to files or directories to be analyzed.
*/
public void scan(List<File> files) {
for (File file : files) {
scan(file);
}
}
/**
* 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.
*
* @since v0.3.2.4
*
* @param file the path to a file or directory to be analyzed.
*/
public void scan(File file) {
if (file.exists()) {
if (file.isDirectory()) {
scanDirectory(file);
@@ -161,11 +236,13 @@ public class Engine {
*/
protected void scanDirectory(File dir) {
final File[] files = dir.listFiles();
for (File f : files) {
if (f.isDirectory()) {
scanDirectory(f);
} else {
scanFile(f);
if (files != null) {
for (File f : files) {
if (f.isDirectory()) {
scanDirectory(f);
} else {
scanFile(f);
}
}
}
}
@@ -178,8 +255,9 @@ public class Engine {
*/
protected void scanFile(File file) {
if (!file.isFile()) {
final String msg = String.format("Path passed to scanFile(File) is not a file: %s.", file.toString());
Logger.getLogger(Engine.class.getName()).log(Level.WARNING, msg);
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);
@@ -206,12 +284,13 @@ public class Engine {
try {
a.initialize();
} catch (Exception ex) {
Logger.getLogger(Engine.class.getName()).log(Level.SEVERE,
"Exception occurred initializing " + a.getName() + ".", ex);
final String msg = String.format("\"Exception occurred initializing \"%s\".\"", a.getName());
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.FINER, null, ex1);
Logger.getLogger(Engine.class.getName()).log(Level.FINEST, null, ex1);
}
}
}
@@ -222,8 +301,10 @@ public class Engine {
final List<Analyzer> analyzerList = analyzers.get(phase);
for (Analyzer a : analyzerList) {
//need to create a copy of the collection because some of the
// analyzers may modify it. This prevents ConcurrentModificationExceptions.
/* need to create a copy of the collection because some of the
* 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) {
@@ -245,14 +326,15 @@ public class Engine {
try {
a.close();
} catch (Exception ex) {
Logger.getLogger(Engine.class.getName()).log(Level.WARNING, null, ex);
Logger.getLogger(Engine.class.getName()).log(Level.FINEST, null, ex);
}
}
}
}
/**
* Cycles through the cached web data sources and calls update on all of them.
* Cycles through the cached web data sources and calls update on all of
* them.
*/
private void doUpdates() {
final UpdateService service = UpdateService.getInstance();
@@ -264,16 +346,16 @@ public class Engine {
} 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.INFO,
String.format("Unable to update details for %s",
source.getClass().getName()), ex);
Logger.getLogger(Engine.class.getName()).log(Level.FINE,
String.format("Unable to update details for %s", source.getClass().getName()), ex);
}
}
}
/**
* Returns a full list of all of the analyzers. This is useful
* for reporting which analyzers where used.
* Returns a full list of all of the analyzers. This is useful for reporting
* which analyzers where used.
*
* @return a list of Analyzers
*/
public List<Analyzer> getAnalyzers() {
@@ -284,4 +366,26 @@ public class Engine {
}
return ret;
}
/**
* Checks all analyzers to see if an extension is supported.
*
* @param ext a file extension
* @return true or false depending on whether or not the file extension is
* supported
*/
public boolean supportsExtension(String ext) {
if (ext == null) {
return false;
}
for (AnalysisPhase phase : AnalysisPhase.values()) {
final List<Analyzer> analyzerList = analyzers.get(phase);
for (Analyzer a : analyzerList) {
if (a.getSupportedExtensions() != null && a.supportsExtension(ext)) {
return true;
}
}
}
return false;
}
}

View File

@@ -1,18 +1,18 @@
/*
* This file is part of Dependency-Check.
* This file is part of dependency-check-core.
*
* Dependency-Check is free software: you can redistribute it and/or modify it
* 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 is distributed in the hope that it will be useful, but
* 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. If not, see http://www.gnu.org/licenses/.
* dependency-check-core. If not, see http://www.gnu.org/licenses/.
*
* Copyright (c) 2012 Jeremy Long. All Rights Reserved.
*/
@@ -29,10 +29,12 @@ import java.util.Set;
public abstract class AbstractAnalyzer implements Analyzer {
/**
* 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.<br/><br/>
* 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.<br/><br/>
*
* This implementation was copied from http://stackoverflow.com/questions/2041778/initialize-java-hashset-values-by-construction
* 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.
@@ -44,18 +46,23 @@ public abstract class AbstractAnalyzer implements Analyzer {
return set;
}
/**
* The initialize method does nothing for this Analyzer.
*
* @throws Exception thrown if there is an exception
*/
public void initialize() {
@Override
public void initialize() throws Exception {
//do nothing
}
/**
* The close method does nothing for this Analyzer.
*
* @throws Exception thrown if there is an exception
*/
public void close() {
@Override
public void close() throws Exception {
//do nothing
}
}

View File

@@ -1,18 +1,18 @@
/*
* This file is part of Dependency-Check.
* This file is part of dependency-check-core.
*
* Dependency-Check is free software: you can redistribute it and/or modify it
* 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 is distributed in the hope that it will be useful, but
* 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. If not, see http://www.gnu.org/licenses/.
* dependency-check-core. If not, see http://www.gnu.org/licenses/.
*
* Copyright (c) 2012 Jeremy Long. All Rights Reserved.
*/

View File

@@ -1,18 +1,18 @@
/*
* This file is part of Dependency-Check.
* This file is part of dependency-check-core.
*
* Dependency-Check is free software: you can redistribute it and/or modify it
* 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 is distributed in the hope that it will be useful, but
* 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. If not, see http://www.gnu.org/licenses/.
* dependency-check-core. If not, see http://www.gnu.org/licenses/.
*
* Copyright (c) 2012 Jeremy Long. All Rights Reserved.
*/

View File

@@ -1,18 +1,18 @@
/*
* This file is part of Dependency-Check.
* This file is part of dependency-check-core.
*
* Dependency-Check is free software: you can redistribute it and/or modify it
* 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 is distributed in the hope that it will be useful, but
* 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. If not, see http://www.gnu.org/licenses/.
* dependency-check-core. If not, see http://www.gnu.org/licenses/.
*
* Copyright (c) 2012 Jeremy Long. All Rights Reserved.
*/
@@ -38,8 +38,8 @@ public interface Analyzer {
* description or license information for the dependency it should be added.
*
* @param dependency a dependency to analyze.
* @param engine the engine that is scanning the dependencies - this is useful
* if we need to check other dependencies
* @param engine the engine that is scanning the dependencies - this is
* useful if we need to check other dependencies
* @throws AnalysisException is thrown if there is an error analyzing the
* dependency file
*/

View File

@@ -1,18 +1,18 @@
/*
* This file is part of Dependency-Check.
* This file is part of dependency-check-core.
*
* Dependency-Check is free software: you can redistribute it and/or modify it
* 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 is distributed in the hope that it will be useful, but
* 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. If not, see http://www.gnu.org/licenses/.
* dependency-check-core. If not, see http://www.gnu.org/licenses/.
*
* Copyright (c) 2012 Jeremy Long. All Rights Reserved.
*/

View File

@@ -0,0 +1,321 @@
/*
* 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) 2013 Jeremy Long. All Rights Reserved.
*/
package org.owasp.dependencycheck.analyzer;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
//import java.util.zip.ZipEntry;
//import java.util.zip.ZipException;
//import java.util.zip.ZipInputStream;
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipArchiveInputStream;
import org.h2.store.fs.FileUtils;
import org.owasp.dependencycheck.Engine;
import org.owasp.dependencycheck.dependency.Dependency;
import org.owasp.dependencycheck.utils.Settings;
/**
* <p>An analyzer that works on archive files:
* <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.
*/
private static final int BUFFER_SIZE = 4096;
/**
* The count of directories created during analysis. This is used for
* creating temporary directories.
*/
private static int dirCount = 0;
/**
* The parent directory for the individual directories per archive.
*/
private File tempFileLocation = null;
/**
* The max scan depth that the analyzer will recursively extract nested
* archives.
*/
private static final int MAX_SCAN_DEPTH = Settings.getInt("archive.scan.depth", 3);
/**
* Tracks the current scan/extraction depth for nested archives.
*/
private int scanDepth = 0;
//<editor-fold defaultstate="collapsed" desc="All standard implmentation details of Analyzer">
/**
* The name of the analyzer.
*/
private static final String ANALYZER_NAME = "Archive Analyzer";
/**
* The phase that this analyzer is intended to run in.
*/
private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INITIAL;
/**
* The set of file extensions supported by this analyzer.
*/
private static final Set<String> EXTENSIONS = newHashSet("zip", "ear", "war");
/**
* 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>
/**
* The initialize method does nothing for this Analyzer.
*
* @throws Exception is thrown if there is an exception deleting or creating
* temporary files
*/
@Override
public void initialize() throws Exception {
final File baseDir = Settings.getTempDirectory();
if (!baseDir.exists()) {
baseDir.mkdirs();
}
tempFileLocation = File.createTempFile("check", "tmp", baseDir);
if (!tempFileLocation.delete()) {
throw new AnalysisException("Unable to delete temporary file '" + tempFileLocation.getAbsolutePath() + "'.");
}
if (!tempFileLocation.mkdirs()) {
throw new AnalysisException("Unable to create directory '" + tempFileLocation.getAbsolutePath() + "'.");
}
}
/**
* The close method does nothing for this Analyzer.
*
* @throws Exception thrown if there is an exception deleting temporary
* files
*/
@Override
public void close() throws Exception {
if (tempFileLocation != null && tempFileLocation.exists()) {
FileUtils.deleteRecursive(tempFileLocation.getAbsolutePath(), true);
}
}
/**
* 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 void analyze(Dependency dependency, Engine engine) throws AnalysisException {
final File f = new File(dependency.getActualFilePath());
final File tmpDir = getNextTempDirectory();
extractFiles(f, tmpDir, engine);
//make a copy
final List<Dependency> dependencies = new ArrayList<Dependency>(engine.getDependencies());
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);
for (Dependency d : dependencySet) {
//fix the dependency's display name and path
final String displayPath = String.format("%s%s",
dependency.getFilePath(),
d.getActualFilePath().substring(tmpDir.getAbsolutePath().length()));
final String displayName = String.format("%s%s%s",
dependency.getFileName(),
File.separator,
d.getFileName());
d.setFilePath(displayPath);
d.setFileName(displayName);
//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.
if (this.supportsExtension(d.getFileExtension()) && scanDepth < MAX_SCAN_DEPTH) {
scanDepth += 1;
analyze(d, engine);
scanDepth -= 1;
}
}
}
Collections.sort(engine.getDependencies());
}
/**
* Retrieves the next temporary directory to extract an archive too.
*
* @return a directory
* @throws AnalysisException thrown if unable to create temporary directory
*/
private File getNextTempDirectory() throws AnalysisException {
dirCount += 1;
final File directory = new File(tempFileLocation, String.valueOf(dirCount));
if (!directory.mkdirs()) {
throw new AnalysisException("Unable to create temp directory '" + directory.getAbsolutePath() + "'.");
}
return directory;
}
/**
* Extracts the contents of an archive into the specified directory.
*
* @param archive an archive file such as a WAR or EAR
* @param extractTo a directory to extract the contents to
* @param engine the scanning engine
* @throws AnalysisException thrown if the archive is not found
*/
private void extractFiles(File archive, File extractTo, Engine engine) throws AnalysisException {
if (archive == null || extractTo == null) {
return;
}
FileInputStream fis = null;
//ZipInputStream zis = null;
ZipArchiveInputStream zis = null;
try {
fis = new FileInputStream(archive);
} catch (FileNotFoundException ex) {
Logger.getLogger(ArchiveAnalyzer.class.getName()).log(Level.INFO, null, ex);
throw new AnalysisException("Archive file was not found.", ex);
}
zis = new ZipArchiveInputStream(new BufferedInputStream(fis));
ZipArchiveEntry entry;
try {
while ((entry = zis.getNextZipEntry()) != null) {
if (entry.isDirectory()) {
final File d = new File(extractTo, entry.getName());
if (!d.mkdirs()) {
throw new AnalysisException("Unable to create '" + d.getAbsolutePath() + "'.");
}
} else {
final File file = new File(extractTo, entry.getName());
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();
} catch (FileNotFoundException ex) {
Logger.getLogger(ArchiveAnalyzer.class.getName()).log(Level.FINE, null, ex);
throw new AnalysisException("Unable to find file '" + file.getName() + "'.", ex);
} 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);
} 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) {
Logger.getLogger(ArchiveAnalyzer.class.getName()).log(Level.FINEST, null, ex);
}
}
}
}

View File

@@ -0,0 +1,800 @@
/*
* 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 java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.lucene.document.Document;
import org.apache.lucene.index.CorruptIndexException;
import org.apache.lucene.queryparser.classic.ParseException;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TopDocs;
import org.owasp.dependencycheck.Engine;
import org.owasp.dependencycheck.data.lucene.LuceneUtils;
import org.owasp.dependencycheck.dependency.Dependency;
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.IndexEntry;
import org.owasp.dependencycheck.data.nvdcve.CveDB;
import org.owasp.dependencycheck.data.nvdcve.DatabaseException;
import org.owasp.dependencycheck.dependency.Identifier;
import org.owasp.dependencycheck.dependency.VulnerableSoftware;
import org.owasp.dependencycheck.utils.DependencyVersion;
import org.owasp.dependencycheck.utils.DependencyVersionUtil;
/**
* 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
* within the dependency to search the Lucene index.
*
* @author Jeremy Long (jeremy.long@owasp.org)
*/
public class CPEAnalyzer implements Analyzer {
/**
* The maximum number of query results to return.
*/
static final int MAX_QUERY_RESULTS = 25;
/**
* The weighting boost to give terms when constructing the Lucene query.
*/
static final String WEIGHTING_BOOST = "^5";
/**
* A string representation of a regular expression defining characters
* utilized within the CPE Names.
*/
static final String CLEANSE_CHARACTER_RX = "[^A-Za-z0-9 ._-]";
/**
* A string representation of a regular expression used to remove all but
* alpha characters.
*/
static final String CLEANSE_NONALPHA_RX = "[^A-Za-z]*";
/**
* The additional size to add to a new StringBuilder to account for extra
* data that will be written into the string.
*/
static final int STRING_BUILDER_BUFFER = 20;
/**
* The CPE Index Reader.
*/
private CpeIndexReader cpe;
/**
* The CVE Database.
*/
private CveDB cve;
/**
* Opens the data source.
*
* @throws IOException when the Lucene directory to be queried does not
* exist or is corrupt.
* @throws DatabaseException when the database throws an exception. This
* usually occurs when the database is in use by another process.
*/
public void open() throws IOException, DatabaseException {
cpe = new CpeIndexReader();
cpe.open();
cve = new CveDB();
try {
cve.open();
} catch (SQLException ex) {
Logger.getLogger(CPEAnalyzer.class.getName()).log(Level.FINE, null, ex);
throw new DatabaseException("Unable to open the cve db", ex);
} catch (ClassNotFoundException ex) {
Logger.getLogger(CPEAnalyzer.class.getName()).log(Level.FINE, null, ex);
throw new DatabaseException("Unable to open the cve db", ex);
}
}
/**
* Closes the data source.
*/
@Override
public void close() {
if (cpe != null) {
cpe.close();
}
if (cve != null) {
cve.close();
}
}
/**
* Returns the status of the data source - is the index open.
*
* @return true or false.
*/
public boolean 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();
}
}
/**
* Searches the data store of CPE entries, trying to identify the CPE for
* the given dependency based on the evidence contained within. The
* dependency passed in is updated with any identified CPE values.
*
* @param dependency the dependency to search for CPE entries on.
* @throws CorruptIndexException is thrown when the Lucene index is corrupt.
* @throws IOException is thrown when an IOException occurs.
* @throws ParseException is thrown when the Lucene query cannot be parsed.
*/
protected void determineCPE(Dependency dependency) throws CorruptIndexException, IOException, ParseException {
Confidence vendorConf = Confidence.HIGHEST;
Confidence productConf = Confidence.HIGHEST;
String vendors = addEvidenceWithoutDuplicateTerms("", dependency.getVendorEvidence(), vendorConf);
String products = addEvidenceWithoutDuplicateTerms("", dependency.getProductEvidence(), productConf);
int ctr = 0;
do {
if (!vendors.isEmpty() && !products.isEmpty()) {
final List<IndexEntry> entries = searchCPE(vendors, products, dependency.getProductEvidence().getWeighting(),
dependency.getVendorEvidence().getWeighting());
for (IndexEntry e : entries) {
if (verifyEntry(e, dependency)) {
final String vendor = e.getVendor();
final String product = e.getProduct();
determineIdentifiers(dependency, vendor, product);
}
}
}
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);
}
/**
* Returns the text created by concatenating the text and the values from
* the EvidenceCollection (filtered for a specific confidence). This
* attempts to prevent duplicate terms from being added.<br/<br/> Note, if
* the evidence is longer then 200 characters it will be truncated.
*
* @param text the base text.
* @param ec an EvidenceCollection
* @param confidenceFilter a Confidence level to filter the evidence by.
* @return the new evidence text
*/
private String addEvidenceWithoutDuplicateTerms(final String text, final EvidenceCollection ec, Confidence confidenceFilter) {
final String txt = (text == null) ? "" : text;
final StringBuilder sb = new StringBuilder(txt.length() + (20 * ec.size()));
sb.append(' ').append(txt).append(' ');
for (Evidence e : ec.iterator(confidenceFilter)) {
String value = e.getValue();
//hack to get around the fact that lucene does a really good job of recognizing domains and not
// splitting them. TODO - put together a better lucene analyzer specific to the domain.
if (value.startsWith("http://")) {
value = value.substring(7).replaceAll("\\.", " ");
}
if (value.startsWith("https://")) {
value = value.substring(8).replaceAll("\\.", " ");
}
if (sb.indexOf(" " + value + " ") < 0) {
sb.append(value).append(' ');
}
}
return sb.toString().trim();
}
/**
* Reduces the given confidence by one level. This returns LOW if the
* confidence passed in is not HIGH.
*
* @param c the confidence to reduce.
* @return One less then the confidence passed in.
*/
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>
*
* @param vendor the text used to search the vendor field
* @param product the text used to search the product field
* @param vendorWeightings a list of strings to use to add weighting factors
* to the vendor field
* @param productWeightings Adds a list of strings that will be used to add
* weighting factors to the product search
* @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,
Set<String> vendorWeightings, Set<String> productWeightings)
throws CorruptIndexException, IOException, ParseException {
final ArrayList<IndexEntry> ret = new ArrayList<IndexEntry>(MAX_QUERY_RESULTS);
final String searchString = buildSearch(vendor, product, vendorWeightings, productWeightings);
if (searchString == null) {
return ret;
}
final TopDocs docs = cpe.search(searchString, MAX_QUERY_RESULTS);
for (ScoreDoc d : docs.scoreDocs) {
if (d.score >= 0.08) {
final Document doc = cpe.getDocument(d.doc);
final IndexEntry entry = new IndexEntry();
entry.setVendor(doc.get(Fields.VENDOR));
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);
if (!ret.contains(entry)) {
ret.add(entry);
}
}
}
return ret;
}
/**
* <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
* populated this data is used to add weighting factors to the search string
* generated.</p>
*
* @param vendor text to search the vendor field
* @param product text to search the product field
* @param vendorWeighting a list of strings to apply to the vendor to boost
* the terms weight
* @param productWeightings a list of strings to apply to the product to
* boost the terms weight
* @return the Lucene query
*/
protected String buildSearch(String vendor, String product,
Set<String> vendorWeighting, Set<String> productWeightings) {
final String v = vendor; //.replaceAll("[^\\w\\d]", " ");
final String p = product; //.replaceAll("[^\\w\\d]", " ");
final StringBuilder sb = new StringBuilder(v.length() + p.length()
+ Fields.PRODUCT.length() + Fields.VENDOR.length() + STRING_BUILDER_BUFFER);
if (!appendWeightedSearch(sb, Fields.PRODUCT, p, productWeightings)) {
return null;
}
sb.append(" AND ");
if (!appendWeightedSearch(sb, Fields.VENDOR, v, vendorWeighting)) {
return null;
}
return sb.toString();
}
/**
* This method constructs a Lucene query for a given field. The searchText
* is split into separate words and if the word is within the list of
* weighted words then an additional weighting is applied to the term as it
* is appended into the query.
*
* @param sb a StringBuilder that the query text will be appended to.
* @param field the field within the Lucene index that the query is
* searching.
* @param searchText text used to construct the query.
* @param weightedText a list of terms that will be considered higher
* importance when searching.
* @return if the append was successful.
*/
private boolean appendWeightedSearch(StringBuilder sb, String field, String searchText, Set<String> weightedText) {
sb.append(" ").append(field).append(":( ");
final String cleanText = cleanseText(searchText);
if ("".equals(cleanText)) {
return false;
}
if (weightedText == null || weightedText.isEmpty()) {
LuceneUtils.appendEscapedLuceneQuery(sb, cleanText);
} else {
final StringTokenizer tokens = new StringTokenizer(cleanText);
while (tokens.hasMoreElements()) {
final String word = tokens.nextToken();
String temp = null;
for (String weighted : weightedText) {
final String weightedStr = cleanseText(weighted);
if (equalsIgnoreCaseAndNonAlpha(word, weightedStr)) {
temp = LuceneUtils.escapeLuceneQuery(word) + WEIGHTING_BOOST;
if (!word.equalsIgnoreCase(weightedStr)) {
temp += " " + LuceneUtils.escapeLuceneQuery(weightedStr) + WEIGHTING_BOOST;
}
}
}
if (temp == null) {
temp = LuceneUtils.escapeLuceneQuery(word);
}
sb.append(" ").append(temp);
}
}
sb.append(" ) ");
return true;
}
/**
* Removes characters from the input text that are not used within the CPE
* index.
*
* @param text is the text to remove the characters from.
* @return the text having removed some characters.
*/
private String cleanseText(String text) {
return text.replaceAll(CLEANSE_CHARACTER_RX, " ");
}
/**
* Compares two strings after lower casing them and removing the non-alpha
* characters.
*
* @param l string one to compare.
* @param r string two to compare.
* @return whether or not the two strings are similar.
*/
private boolean equalsIgnoreCaseAndNonAlpha(String l, String r) {
if (l == null || r == null) {
return false;
}
final String left = l.replaceAll(CLEANSE_NONALPHA_RX, "");
final String right = r.replaceAll(CLEANSE_NONALPHA_RX, "");
return left.equalsIgnoreCase(right);
}
/**
* Ensures that the CPE Identified matches the dependency. This validates
* that the product, vendor, and version information for the CPE are
* contained within the dependencies evidence.
*
* @param entry a CPE entry.
* @param dependency the dependency that the CPE entries could be for.
* @return whether or not the entry is valid.
*/
private boolean verifyEntry(final IndexEntry entry, final Dependency dependency) {
boolean isValid = false;
if (collectionContainsString(dependency.getProductEvidence(), entry.getProduct())
&& collectionContainsString(dependency.getVendorEvidence(), entry.getVendor())) {
//&& collectionContainsVersion(dependency.getVersionEvidence(), entry.getVersion())
isValid = true;
}
return isValid;
}
/**
* Used to determine if the EvidenceCollection contains a specific string.
*
* @param ec an EvidenceCollection
* @param text the text to search for
* @return whether or not the EvidenceCollection contains the string
*/
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
final String[] words = text.split("[\\s_-]");
final List<String> list = new ArrayList<String>();
String tempWord = null;
for (String word : words) {
//single letter words should be concatonated with the next word.
// so { "m", "core", "sample" } -> { "mcore", "sample" }
if (tempWord != null) {
list.add(tempWord + word);
tempWord = null;
} else if (word.length() <= 2) {
tempWord = word;
} else {
list.add(word);
}
}
if (tempWord != null && !list.isEmpty()) {
String tmp = list.get(list.size() - 1) + tempWord;
list.add(tmp);
}
boolean contains = true;
for (String word : list) {
contains &= ec.containsUsedString(word);
}
return contains;
}
/**
* Analyzes a dependency and attempts to determine if there are any CPE
* identifiers for this dependency.
*
* @param dependency The Dependency to analyze.
* @param engine The analysis engine
* @throws AnalysisException is thrown if there is an issue analyzing the
* dependency.
*/
@Override
public void analyze(Dependency dependency, Engine engine) throws AnalysisException {
try {
determineCPE(dependency);
} catch (CorruptIndexException ex) {
throw new AnalysisException("CPE Index is corrupt.", ex);
} catch (IOException ex) {
throw new AnalysisException("Failure opening the CPE Index.", ex);
} catch (ParseException ex) {
throw new AnalysisException("Unable to parse the generated Lucene query for this dependency.", ex);
}
}
/**
* 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
* product passed in. The list is then validated to find only CPEs that are
* valid for the given dependency. It is possible that the CPE identified is
* a best effort "guess" based on the vendor, product, and version
* information.
*
* @param dependency the Dependency being analyzed
* @param vendor the vendor for the CPE being analyzed
* @param product the product for the CPE being analyzed
* @throws UnsupportedEncodingException is thrown if UTF-8 is not supported
*/
private void determineIdentifiers(Dependency dependency, String vendor, String product) throws UnsupportedEncodingException {
final Set<VulnerableSoftware> cpes = cve.getCPEs(vendor, product);
DependencyVersion bestGuess = new DependencyVersion("-");
Confidence bestGuessConf = null;
final List<IdentifierMatch> collected = new ArrayList<IdentifierMatch>();
for (Confidence conf : Confidence.values()) {
for (Evidence evidence : dependency.getVersionEvidence().iterator(conf)) {
final DependencyVersion evVer = DependencyVersionUtil.parseVersion(evidence.getValue());
if (evVer == null) {
continue;
}
for (VulnerableSoftware vs : cpes) {
DependencyVersion dbVer;
if (vs.getRevision() != null && !vs.getRevision().isEmpty()) {
dbVer = DependencyVersionUtil.parseVersion(vs.getVersion() + "." + vs.getRevision());
} else {
dbVer = DependencyVersionUtil.parseVersion(vs.getVersion());
}
if (dbVer == null //special case, no version specified - everything is vulnerable
|| evVer.equals(dbVer)) { //woot exect match
final String url = String.format("http://web.nvd.nist.gov/view/vuln/search?cpe=%s", URLEncoder.encode(vs.getName(), "UTF-8"));
final IdentifierMatch match = new IdentifierMatch("cpe", vs.getName(), url, IdentifierConfidence.EXACT_MATCH, conf);
collected.add(match);
} else {
//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()
&& evVer.matchesAtLeastThreeLevels(dbVer)) {
if (bestGuessConf == null || bestGuessConf.compareTo(conf) > 0) {
if (bestGuess.getVersionParts().size() < dbVer.getVersionParts().size()) {
bestGuess = dbVer;
bestGuessConf = conf;
}
}
}
}
}
if (bestGuessConf == null || bestGuessConf.compareTo(conf) > 0) {
if (bestGuess.getVersionParts().size() < evVer.getVersionParts().size()) {
bestGuess = evVer;
bestGuessConf = conf;
}
}
}
}
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"));
if (bestGuessConf == null) {
bestGuessConf = Confidence.LOW;
}
final IdentifierMatch match = new IdentifierMatch("cpe", cpeName, url, IdentifierConfidence.BEST_GUESS, bestGuessConf);
collected.add(match);
Collections.sort(collected);
final IdentifierConfidence bestIdentifierQuality = collected.get(0).getConfidence();
final Confidence bestEvidenceQuality = collected.get(0).getEvidenceConfidence();
for (IdentifierMatch m : collected) {
if (bestIdentifierQuality.equals(m.getConfidence())
&& bestEvidenceQuality.equals(m.getEvidenceConfidence())) {
dependency.addIdentifier(m.getIdentifier());
}
}
}
/**
* The confidence whether the identifier is an exact match, or a best guess.
*/
private enum IdentifierConfidence {
/**
* An exact match for the CPE.
*/
EXACT_MATCH,
/**
* A best guess for the CPE.
*/
BEST_GUESS
}
/**
* A simple object to hold an identifier and carry information about the
* confidence in the identifier.
*/
private static class IdentifierMatch implements Comparable<IdentifierMatch> {
/**
* Constructs an IdentiferMatch.
*
* @param type the type of identifier (such as CPE)
* @param value the value of the identifier
* @param url the URL of the identifier
* @param identifierConfidence the confidence in the identifier: best
* guess or exact match
* @param evidenceConfidence the confidence of the evidence used to find
* the identifier
*/
IdentifierMatch(String type, String value, String url, IdentifierConfidence identifierConfidence, Confidence evidenceConfidence) {
this.identifier = new Identifier(type, value, url);
this.confidence = identifierConfidence;
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;
/**
* Get the value of evidenceConfidence
*
* @return the value of evidenceConfidence
*/
public Confidence getEvidenceConfidence() {
return evidenceConfidence;
}
/**
* Set the value of evidenceConfidence
*
* @param evidenceConfidence new value of evidenceConfidence
*/
public void setEvidenceConfidence(Confidence evidenceConfidence) {
this.evidenceConfidence = evidenceConfidence;
}
/**
* The confidence whether this is an exact match, or a best guess.
*/
private IdentifierConfidence confidence;
/**
* Get the value of confidence.
*
* @return the value of confidence
*/
public IdentifierConfidence getConfidence() {
return confidence;
}
/**
* Set the value of confidence.
*
* @param confidence new value of confidence
*/
public void setConfidence(IdentifierConfidence confidence) {
this.confidence = confidence;
}
/**
* The CPE identifier.
*/
private Identifier identifier;
/**
* Get the value of identifier.
*
* @return the value of identifier
*/
public Identifier getIdentifier() {
return identifier;
}
/**
* Set the value of identifier.
*
* @param identifier new value of identifier
*/
public void setIdentifier(Identifier identifier) {
this.identifier = identifier;
}
//</editor-fold>
//<editor-fold defaultstate="collapsed" desc="Standard implementations of toString, hashCode, and equals">
/**
* Standard toString() implementation.
*
* @return the string representation of the object
*/
@Override
public String toString() {
return "IdentifierMatch{" + "evidenceConfidence=" + evidenceConfidence
+ ", confidence=" + confidence + ", identifier=" + identifier + '}';
}
/**
* Standard hashCode() implementation.
*
* @return the hashCode
*/
@Override
public int hashCode() {
int hash = 5;
hash = 97 * hash + (this.evidenceConfidence != null ? this.evidenceConfidence.hashCode() : 0);
hash = 97 * hash + (this.confidence != null ? this.confidence.hashCode() : 0);
hash = 97 * hash + (this.identifier != null ? this.identifier.hashCode() : 0);
return hash;
}
/**
* Standard equals implementation.
*
* @param obj the object to compare
* @return true if the objects are equal, otherwise false
*/
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final IdentifierMatch other = (IdentifierMatch) obj;
if (this.evidenceConfidence != other.evidenceConfidence) {
return false;
}
if (this.confidence != other.confidence) {
return false;
}
if (this.identifier != other.identifier && (this.identifier == null || !this.identifier.equals(other.identifier))) {
return false;
}
return true;
}
//</editor-fold>
/**
* Standard implementation of compareTo that compares identifier
* confidence, evidence confidence, and then the identifier.
*
* @param o the IdentifierMatch to compare to
* @return the natural ordering of IdentifierMatch
*/
@Override
public int compareTo(IdentifierMatch o) {
int conf = this.confidence.compareTo(o.confidence);
if (conf == 0) {
conf = this.evidenceConfidence.compareTo(o.evidenceConfidence);
if (conf == 0) {
conf = identifier.compareTo(o.identifier);
}
}
return conf;
}
}
}

View File

@@ -1,18 +1,18 @@
/*
* This file is part of Dependency-Check.
* This file is part of dependency-check-core.
*
* Dependency-Check is free software: you can redistribute it and/or modify it
* 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 is distributed in the hope that it will be useful, but
* 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. If not, see http://www.gnu.org/licenses/.
* dependency-check-core. If not, see http://www.gnu.org/licenses/.
*
* Copyright (c) 2012 Jeremy Long. All Rights Reserved.
*/
@@ -23,8 +23,12 @@ import java.util.HashSet;
import java.util.Iterator;
import java.util.ListIterator;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.owasp.dependencycheck.Engine;
import org.owasp.dependencycheck.dependency.Dependency;
import org.owasp.dependencycheck.utils.DependencyVersion;
import org.owasp.dependencycheck.utils.DependencyVersionUtil;
/**
* <p>This analyzer ensures dependencies that should be grouped together, to
@@ -39,6 +43,17 @@ import org.owasp.dependencycheck.dependency.Dependency;
*/
public class DependencyBundlingAnalyzer extends AbstractAnalyzer implements Analyzer {
//<editor-fold defaultstate="collapsed" desc="Constants and Member Variables">
/**
* A pattern for obtaining the first part of a filename.
*/
private static final Pattern STARTING_TEXT_PATTERN = Pattern.compile("^[a-zA-Z]*");
/**
* a flag indicating if this analyzer has run. This analyzer only runs once.
*/
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.
*/
@@ -89,10 +104,7 @@ public class DependencyBundlingAnalyzer extends AbstractAnalyzer implements Anal
public AnalysisPhase getAnalysisPhase() {
return ANALYSIS_PHASE;
}
/**
* a flag indicating if this analyzer has run. This analyzer only runs once.
*/
private boolean analyzed = false;
//</editor-fold>
/**
* Analyzes a set of dependencies. If they have been found to have the same
@@ -104,6 +116,7 @@ public class DependencyBundlingAnalyzer extends AbstractAnalyzer implements Anal
* @throws AnalysisException is thrown if there is an error reading the JAR
* file.
*/
@Override
public void analyze(Dependency ignore, Engine engine) throws AnalysisException {
if (!analyzed) {
analyzed = true;
@@ -118,7 +131,8 @@ public class DependencyBundlingAnalyzer extends AbstractAnalyzer implements Anal
final Dependency nextDependency = subIterator.next();
if (identifiersMatch(dependency, nextDependency)
&& hasSameBasePath(dependency, nextDependency)) {
&& hasSameBasePath(dependency, nextDependency)
&& fileNameMatch(dependency, nextDependency)) {
if (isCore(dependency, nextDependency)) {
dependency.addRelatedDependency(nextDependency);
@@ -155,7 +169,7 @@ public class DependencyBundlingAnalyzer extends AbstractAnalyzer implements Anal
/**
* Attempts to trim a maven repo to a common base path. This is typically
* [drive]\[repolocation\repository\[path1]\[path2].
* [drive]\[repo_location]\repository\[path1]\[path2].
*
* @param path the path to trim
* @return a string representing the base path.
@@ -180,10 +194,66 @@ public class DependencyBundlingAnalyzer extends AbstractAnalyzer implements Anal
}
/**
* Returns true if the identifiers in the two supplied dependencies are equal.
* Returns true if the file names (and version if it exists) of the two
* dependencies are sufficiently similiar.
*
* @param dependency1 a dependency2 to compare
* @param dependency2 a dependency2 to compare
* @return true if the identifiers in the two supplied dependencies are equal
* @return true if the identifiers in the two supplied dependencies are
* equal
*/
private boolean fileNameMatch(Dependency dependency1, Dependency dependency2) {
if (dependency1 == null || dependency1.getFileName() == null
|| dependency2 == null || dependency2.getFileName() == null) {
return false;
}
String fileName1 = dependency1.getFileName();
String fileName2 = dependency2.getFileName();
//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
final DependencyVersion version1 = DependencyVersionUtil.parseVersion(fileName1);
final DependencyVersion version2 = DependencyVersionUtil.parseVersion(fileName2);
if (version1 != null && version2 != null) {
if (!version1.equals(version2)) {
return false;
}
}
//filename check
final Matcher match1 = STARTING_TEXT_PATTERN.matcher(fileName1);
final Matcher match2 = STARTING_TEXT_PATTERN.matcher(fileName2);
if (match1.find() && match2.find()) {
return match1.group().equals(match2.group());
}
return false;
}
/**
* Returns true if the identifiers in the two supplied dependencies are
* equal.
*
* @param dependency1 a dependency2 to compare
* @param dependency2 a dependency2 to compare
* @return true if the identifiers in the two supplied dependencies are
* equal
*/
private boolean identifiersMatch(Dependency dependency1, Dependency dependency2) {
if (dependency1 == null || dependency1.getIdentifiers() == null
@@ -196,6 +266,7 @@ public class DependencyBundlingAnalyzer extends AbstractAnalyzer implements Anal
/**
* Determines if the two dependencies have the same base path.
*
* @param dependency1 a Dependency object
* @param dependency2 a Dependency object
* @return true if the base paths of the dependencies are identical
@@ -228,8 +299,9 @@ public class DependencyBundlingAnalyzer extends AbstractAnalyzer implements Anal
* This is likely a very broken attempt at determining if the 'left'
* 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.
* 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 right the dependency to test against

View File

@@ -0,0 +1,329 @@
/*
* 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 java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.owasp.dependencycheck.Engine;
import org.owasp.dependencycheck.dependency.Dependency;
import org.owasp.dependencycheck.dependency.Identifier;
import org.owasp.dependencycheck.dependency.VulnerableSoftware;
/**
* This analyzer attempts to remove some well known false positives -
* specifically regarding the java runtime.
*
* @author Jeremy Long (jeremy.long@owasp.org)
*/
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.
*/
private static final Set<String> EXTENSIONS = null;
/**
* The name of the analyzer.
*/
private static final String ANALYZER_NAME = "False Positive Analyzer";
/**
* The phase that this analyzer is intended to run in.
*/
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.
*
* @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 true;
}
/**
* 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>
/**
* Analyzes the dependencies and removes bad/incorrect CPE associations
* based on various heuristics.
*
* @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 {
removeJreEntries(dependency);
removeBadMatches(dependency);
removeSpuriousCPE(dependency);
addFalseNegativeCPEs(dependency);
}
/**
* <p>Intended to remove spurious CPE entries. By spurious we mean
* duplicate, less specific CPE entries.</p>
* <p>Example:</p>
* <code>
* cpe:/a:some-vendor:some-product
* cpe:/a:some-vendor:some-product:1.5
* cpe:/a:some-vendor:some-product:1.5.2
* </code>
* <p>Should be trimmed to:</p>
* <code>
* cpe:/a:some-vendor:some-product:1.5.2
* </code>
*
* @param dependency the dependency being analyzed
*/
private void removeSpuriousCPE(Dependency dependency) {
final List<Identifier> ids = new ArrayList<Identifier>();
ids.addAll(dependency.getIdentifiers());
Collections.sort(ids);
final ListIterator<Identifier> mainItr = ids.listIterator();
while (mainItr.hasNext()) {
final Identifier currentId = mainItr.next();
final VulnerableSoftware currentCpe = parseCpe(currentId.getType(), currentId.getValue());
if (currentCpe == null) {
continue;
}
final ListIterator<Identifier> subItr = ids.listIterator(mainItr.nextIndex());
while (subItr.hasNext()) {
final Identifier nextId = subItr.next();
final VulnerableSoftware nextCpe = parseCpe(nextId.getType(), nextId.getValue());
if (nextCpe == null) {
continue;
}
//TODO fix the version problem below
if (currentCpe.getVendor().equals(nextCpe.getVendor())) {
if (currentCpe.getProduct().equals(nextCpe.getProduct())) {
// see if one is contained in the other.. remove the contained one from dependency.getIdentifier
final String currentVersion = currentCpe.getVersion();
final String nextVersion = nextCpe.getVersion();
if (currentVersion == null && nextVersion == null) {
//how did we get here?
} else if (currentVersion == null && nextVersion != null) {
dependency.getIdentifiers().remove(currentId);
} else if (nextVersion == null && currentVersion != null) {
dependency.getIdentifiers().remove(nextId);
} else if (currentVersion.length() < nextVersion.length()) {
if (nextVersion.startsWith(currentVersion) || "-".equals(currentVersion)) {
dependency.getIdentifiers().remove(currentId);
}
} else {
if (currentVersion.startsWith(nextVersion) || "-".equals(nextVersion)) {
dependency.getIdentifiers().remove(nextId);
}
}
}
}
}
}
}
/**
* Regex to identify core java libraries and a few other commonly
* misidentified ones.
*/
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)?|"
+ "jdk|jre|jsf|jsse)($|:.*)");
/**
* 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$");
/**
* Removes any CPE entries for the JDK/JRE unless the filename ends with
* rt.jar
*
* @param dependency the dependency to remove JRE CPEs from
*/
private void removeJreEntries(Dependency dependency) {
final Set<Identifier> identifiers = dependency.getIdentifiers();
final Iterator<Identifier> itr = identifiers.iterator();
while (itr.hasNext()) {
final Identifier i = itr.next();
final Matcher coreCPE = CORE_JAVA.matcher(i.getValue());
final Matcher coreFiles = CORE_FILES.matcher(dependency.getFileName());
if (coreCPE.matches() && !coreFiles.matches()) {
itr.remove();
}
//replacecd with the regex above.
// if (("cpe:/a:sun:java".equals(i.getValue())
// || "cpe:/a:oracle:java".equals(i.getValue())
// || "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();
// }
}
}
/**
* Parses a CPE string into an IndexEntry.
*
* @param type the type of identifier
* @param value the cpe identifier to parse
* @return an VulnerableSoftware object constructed from the identifier
*/
private VulnerableSoftware parseCpe(String type, String value) {
if (!"cpe".equals(type)) {
return null;
}
final VulnerableSoftware cpe = new VulnerableSoftware();
try {
cpe.parseName(value);
} catch (UnsupportedEncodingException ex) {
Logger.getLogger(FalsePositiveAnalyzer.class.getName()).log(Level.FINEST, null, ex);
return null;
}
return cpe;
}
/**
* Removes bad CPE matches for a dependency. Unfortunately, right now these
* are hard-coded patches for specific problems identified when testing this
* on a LARGE volume of jar files.
*
* @param dependency the dependency to analyze
*/
private void removeBadMatches(Dependency dependency) {
final Set<Identifier> identifiers = dependency.getIdentifiers();
final Iterator<Identifier> itr = identifiers.iterator();
/* TODO - can we utilize the pom's groupid and artifactId to filter??? most of
* these are due to low quality data. Other idea would be to say any CPE
* 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).
*/
//Set<Evidence> groupId = dependency.getVendorEvidence().getEvidence("pom", "groupid");
//Set<Evidence> artifactId = dependency.getVendorEvidence().getEvidence("pom", "artifactid");
while (itr.hasNext()) {
final Identifier i = itr.next();
//TODO move this startswith expression to a configuration file?
if ("cpe".equals(i.getType())) {
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"))
&& dependency.getFileName().toLowerCase().endsWith(".jar")) {
itr.remove();
} else if (i.getValue().startsWith("cpe:/a:file:file")
|| i.getValue().startsWith("cpe:/a:mozilla:mozilla")
|| i.getValue().startsWith("cpe:/a:ssh:ssh")) {
itr.remove();
}
}
}
}
/**
* There are some known CPE entries, specifically regarding sun and oracle
* products due to the acquisition and changes in product names, that based
* on given evidence we can add the related CPE entries to ensure a complete
* list of CVE entries.
*
* @param dependency the dependency being analyzed
*/
private void addFalseNegativeCPEs(Dependency dependency) {
final Iterator<Identifier> itr = dependency.getIdentifiers().iterator();
while (itr.hasNext()) {
final Identifier i = itr.next();
if ("cpe".equals(i.getType()) && i.getValue() != null
&& (i.getValue().startsWith("cpe:/a:oracle:opensso:")
|| i.getValue().startsWith("cpe:/a:oracle:opensso_enterprise:")
|| i.getValue().startsWith("cpe:/a:sun:opensso_enterprise:")
|| i.getValue().startsWith("cpe:/a:sun:opensso:"))) {
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", i.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", i.getValue().substring(22));
try {
dependency.addIdentifier("cpe",
newCpe,
String.format("http://web.nvd.nist.gov/view/vuln/search?cpe=%s", URLEncoder.encode(newCpe, "UTF-8")));
dependency.addIdentifier("cpe",
newCpe2,
String.format("http://web.nvd.nist.gov/view/vuln/search?cpe=%s", URLEncoder.encode(newCpe2, "UTF-8")));
dependency.addIdentifier("cpe",
newCpe3,
String.format("http://web.nvd.nist.gov/view/vuln/search?cpe=%s", URLEncoder.encode(newCpe3, "UTF-8")));
dependency.addIdentifier("cpe",
newCpe4,
String.format("http://web.nvd.nist.gov/view/vuln/search?cpe=%s", URLEncoder.encode(newCpe4, "UTF-8")));
} catch (UnsupportedEncodingException ex) {
Logger.getLogger(FalsePositiveAnalyzer.class
.getName()).log(Level.FINE, null, ex);
}
}
}
}
}

View File

@@ -1,27 +1,30 @@
/*
* This file is part of Dependency-Check.
* This file is part of dependency-check-core.
*
* Dependency-Check is free software: you can redistribute it and/or modify it
* 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 is distributed in the hope that it will be useful, but
* 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. If not, see http://www.gnu.org/licenses/.
* 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 java.io.File;
import org.owasp.dependencycheck.dependency.Dependency;
import org.owasp.dependencycheck.dependency.Evidence;
import java.util.Set;
import org.owasp.dependencycheck.Engine;
import org.owasp.dependencycheck.utils.DependencyVersion;
import org.owasp.dependencycheck.utils.DependencyVersionUtil;
/**
*
@@ -31,6 +34,7 @@ import org.owasp.dependencycheck.Engine;
*/
public class FileNameAnalyzer extends AbstractAnalyzer implements Analyzer {
//<editor-fold defaultstate="collapsed" desc="All standard implmentation details of Analyzer">
/**
* The name of the analyzer.
*/
@@ -81,6 +85,7 @@ public class FileNameAnalyzer extends AbstractAnalyzer implements Analyzer {
public AnalysisPhase getAnalysisPhase() {
return ANALYSIS_PHASE;
}
//</editor-fold>
/**
* Collects information about the file name.
@@ -90,22 +95,38 @@ public class FileNameAnalyzer extends AbstractAnalyzer implements Analyzer {
* @throws AnalysisException is thrown if there is an error reading the JAR
* file.
*/
@Override
public void analyze(Dependency dependency, Engine engine) throws AnalysisException {
String fileName = dependency.getFileName();
//strip any path information that may get added by ArchiveAnalyzer, etc.
final File f = new File(dependency.getFileName());
String fileName = f.getName();
//remove file extension
final int pos = fileName.lastIndexOf(".");
if (pos > 0) {
fileName = fileName.substring(0, pos);
}
dependency.getProductEvidence().addEvidence("file", "name",
fileName, Evidence.Confidence.HIGH);
dependency.getVendorEvidence().addEvidence("file", "name",
fileName, Evidence.Confidence.HIGH);
if (fileName.matches(".*\\d.*")) {
//add version evidence
final DependencyVersion version = DependencyVersionUtil.parseVersion(fileName);
if (version != null) {
dependency.getVersionEvidence().addEvidence("file", "name",
version.toString(), Evidence.Confidence.HIGHEST);
dependency.getVersionEvidence().addEvidence("file", "name",
fileName, Evidence.Confidence.MEDIUM);
}
//add as vendor and product evidence
if (fileName.contains("-")) {
dependency.getProductEvidence().addEvidence("file", "name",
fileName, Evidence.Confidence.HIGHEST);
dependency.getVendorEvidence().addEvidence("file", "name",
fileName, Evidence.Confidence.HIGHEST);
} else {
dependency.getProductEvidence().addEvidence("file", "name",
fileName, Evidence.Confidence.HIGH);
dependency.getVendorEvidence().addEvidence("file", "name",
fileName, Evidence.Confidence.HIGH);
}
}

View File

@@ -1,23 +1,25 @@
/*
* This file is part of Dependency-Check.
* This file is part of dependency-check-core.
*
* Dependency-Check is free software: you can redistribute it and/or modify it
* 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 is distributed in the hope that it will be useful, but
* 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. If not, see http://www.gnu.org/licenses/.
* 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 java.util.ArrayList;
import java.util.Iterator;
import java.util.Set;
import org.owasp.dependencycheck.Engine;
import org.owasp.dependencycheck.dependency.Dependency;
@@ -29,6 +31,7 @@ import org.owasp.dependencycheck.dependency.Evidence;
*/
public class HintAnalyzer extends AbstractAnalyzer implements Analyzer {
//<editor-fold defaultstate="collapsed" desc="All standard implmentation details of Analyzer">
/**
* The name of the analyzer.
*/
@@ -79,14 +82,18 @@ public class HintAnalyzer extends AbstractAnalyzer implements Analyzer {
public AnalysisPhase getAnalysisPhase() {
return ANALYSIS_PHASE;
}
//</editor-fold>
/**
* The HintAnalyzer uses knowledge about a dependency to add additional information
* to help in identification of identifiers or vulnerabilities.
* The HintAnalyzer uses knowledge about a dependency to add additional
* information to help in identification of identifiers or vulnerabilities.
*
* @param dependency The dependency being analyzed
* @param engine The scanning engine
* @throws AnalysisException is thrown if there is an exception analyzing the dependency.
* @throws AnalysisException is thrown if there is an exception analyzing
* the dependency.
*/
@Override
public void analyze(Dependency dependency, Engine engine) throws AnalysisException {
final Evidence springTest1 = new Evidence("Manifest",
"Implementation-Title",
@@ -106,16 +113,32 @@ public class HintAnalyzer extends AbstractAnalyzer implements Analyzer {
Set<Evidence> evidence = dependency.getProductEvidence().getEvidence();
if (evidence.contains(springTest1) || evidence.contains(springTest2)) {
dependency.getProductEvidence().addEvidence("a priori", "product", "springsource_spring_framework", Evidence.Confidence.HIGH);
dependency.getVendorEvidence().addEvidence("a priori", "vendor", "SpringSource", Evidence.Confidence.HIGH);
dependency.getVendorEvidence().addEvidence("a priori", "vendor", "vmware", Evidence.Confidence.HIGH);
dependency.getProductEvidence().addEvidence("hint analyzer", "product", "springsource_spring_framework", Evidence.Confidence.HIGH);
dependency.getVendorEvidence().addEvidence("hint analyzer", "vendor", "SpringSource", Evidence.Confidence.HIGH);
dependency.getVendorEvidence().addEvidence("hint analyzer", "vendor", "vmware", Evidence.Confidence.HIGH);
}
evidence = dependency.getVendorEvidence().getEvidence();
if (evidence.contains(springTest3)) {
dependency.getProductEvidence().addEvidence("a priori", "product", "springsource_spring_framework", Evidence.Confidence.HIGH);
dependency.getVendorEvidence().addEvidence("a priori", "vendor", "vmware", Evidence.Confidence.HIGH);
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 ArrayList<Evidence> newEntries = new ArrayList<Evidence>();
while (itr.hasNext()) {
final Evidence e = itr.next();
if ("sun".equalsIgnoreCase(e.getValue(false))) {
final Evidence newEvidence = new Evidence(e.getSource() + " (hint)", e.getName(), "oracle", e.getConfidence());
newEntries.add(newEvidence);
} else if ("oracle".equalsIgnoreCase(e.getValue(false))) {
final Evidence newEvidence = new Evidence(e.getSource() + " (hint)", e.getName(), "sun", e.getConfidence());
newEntries.add(newEvidence);
}
}
for (Evidence e : newEntries) {
dependency.getVendorEvidence().addEvidence(e);
}
}
}

View File

@@ -1,18 +1,18 @@
/*
* This file is part of Dependency-Check.
* This file is part of dependency-check-core.
*
* Dependency-Check is free software: you can redistribute it and/or modify it
* 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 is distributed in the hope that it will be useful, but
* 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. If not, see http://www.gnu.org/licenses/.
* dependency-check-core. If not, see http://www.gnu.org/licenses/.
*
* Copyright (c) 2012 Jeremy Long. All Rights Reserved.
*/
@@ -32,10 +32,7 @@ import java.util.regex.Pattern;
*/
public class JavaScriptAnalyzer extends AbstractAnalyzer implements Analyzer {
/**
* The system independent newline character.
*/
private static final String NEWLINE = System.getProperty("line.separator");
//<editor-fold defaultstate="collapsed" desc="All standard implmentation details of Analyzer">
/**
* The name of the analyzer.
*/
@@ -86,6 +83,7 @@ public class JavaScriptAnalyzer extends AbstractAnalyzer implements Analyzer {
public AnalysisPhase getAnalysisPhase() {
return ANALYSIS_PHASE;
}
//</editor-fold>
/**
* Loads a specified JAR file and collects information from the manifest and
@@ -96,37 +94,29 @@ public class JavaScriptAnalyzer extends AbstractAnalyzer implements Analyzer {
* @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])))*\\*+/)|(//.*)");
}
/**
* Adds license information to the given dependency.
*
* @param d the dependency
* @param license the license
*/
private void addLicense(Dependency d, String license) {
if (d.getLicense() == null) {
d.setLicense(license);
} else if (!d.getLicense().contains(license)) {
d.setLicense(d.getLicense() + NEWLINE + license);
}
}
/**
* The initialize method does nothing for this Analyzer.
*
* @throws Exception thrown if there is an exception
*/
public void initialize() {
@Override
public void initialize() throws Exception {
//do nothing
}
/**
* The close method does nothing for this Analyzer.
*
* @throws Exception thrown if there is an exception
*/
public void close() {
@Override
public void close() throws Exception {
//do nothing
}
}

View File

@@ -1,34 +1,34 @@
/*
* This file is part of Dependency-Check.
* This file is part of dependency-check-core.
*
* Dependency-Check is free software: you can redistribute it and/or modify it
* 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 is distributed in the hope that it will be useful, but
* 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. If not, see http://www.gnu.org/licenses/.
* dependency-check-core. If not, see http://www.gnu.org/licenses/.
*
* Copyright (c) 2012 Jeremy Long. All Rights Reserved.
*/
package org.owasp.dependencycheck.data.nvdcve;
package org.owasp.dependencycheck.analyzer;
import java.io.IOException;
import java.sql.SQLException;
import java.util.List;
import java.util.Set;
import org.owasp.dependencycheck.Engine;
import org.owasp.dependencycheck.analyzer.AnalysisException;
import org.owasp.dependencycheck.analyzer.AnalysisPhase;
import org.owasp.dependencycheck.dependency.Dependency;
import org.owasp.dependencycheck.dependency.Vulnerability;
import org.owasp.dependencycheck.dependency.Identifier;
import org.owasp.dependencycheck.analyzer.Analyzer;
import org.owasp.dependencycheck.data.nvdcve.CveDB;
import org.owasp.dependencycheck.data.nvdcve.DatabaseException;
/**
* NvdCveAnalyzer is a utility class that takes a project dependency and
* attempts to discern if there is an associated CVEs. It uses the the
@@ -53,8 +53,10 @@ public class NvdCveAnalyzer implements Analyzer {
* @throws SQLException thrown when there is a SQL Exception
* @throws IOException thrown when there is an IO Exception
* @throws DatabaseException thrown when there is a database exceptions
* @throws ClassNotFoundException thrown if the h2 database driver cannot be
* loaded
*/
public void open() throws SQLException, IOException, DatabaseException {
public void open() throws SQLException, IOException, DatabaseException, ClassNotFoundException {
cveDB = new CveDB();
cveDB.open();
}
@@ -104,9 +106,14 @@ public class NvdCveAnalyzer implements Analyzer {
try {
final String value = id.getValue();
final List<Vulnerability> vulns = cveDB.getVulnerabilities(value);
for (Vulnerability v : vulns) {
dependency.addVulnerability(v);
}
dependency.getVulnerabilities().addAll(vulns);
//TODO - remove this comment block after additional testing is completed
//note - valid match functionality has been moved into the CveDB class.
//// for (Vulnerability v : vulns) {
//// if (isValidMatch(dependency, v)) {
//// dependency.addVulnerability(v);
//// }
//// }
} catch (DatabaseException ex) {
throw new AnalysisException(ex);
}
@@ -159,4 +166,57 @@ public class NvdCveAnalyzer implements Analyzer {
public void initialize() throws Exception {
this.open();
}
//TODO - remove this comment block after additional testing is completed
// The following check has been moved into the CveDB class.
//// /**
//// * <p>Determines if this is a valid vulnerability match for the given
//// * dependency. Specifically, this is concerned with ensuring the version
//// * numbers are correct.</p>
//// * <p>Currently, this is focused on the issues with the versions for Struts
//// * 1 and Struts 2. In the future this will due better matching on more
//// * version numbers.</p>
//// *
//// * @param dependency the dependency
//// * @param v the vulnerability
//// * @return returns true if the vulnerability is for the given dependency
//// */
//// private boolean isValidMatch(final Dependency dependency, final Vulnerability v) {
//// //right now I only know of the issue with Struts1/2
//// // start with fixing this problem.
////
//// //TODO extend this solution to do better version matching for the vulnerable software.
//// boolean struts1 = false;
//// boolean struts2 = false;
//// for (Identifier i : dependency.getIdentifiers()) {
//// if (i.getValue().startsWith("cpe:/a:apache:struts:")) {
//// final char version = i.getValue().charAt(21);
//// if (version == '1') {
//// struts1 = true;
//// }
//// if (version == '2') {
//// struts2 = true;
//// }
//// }
//// }
//// if (!struts1 && !struts2) {
//// return true; //we are not looking at struts, so return true.
//// }
//// if (struts1 && struts2) {
//// return true; //there is a mismatch here, but we can't solve it here so we return valid.
//// }
//// if (struts1) {
//// boolean hasStruts1Vuln = false;
//// boolean hasStruts2PreviousVersion = false;
//// for (VulnerableSoftware vs : v.getVulnerableSoftware()) {
//// //TODO FIX THIS
//// //hasStruts2PreviousVersion |= vs.hasPreviousVersion() && vs.getName().charAt(21) == '2';
//// //hasStruts1Vuln |= vs.getName().charAt(21) == '1';
//// }
//// if (!hasStruts1Vuln && hasStruts2PreviousVersion) {
//// return false;
//// }
//// }
////
//// return true;
//// }
}

View File

@@ -0,0 +1,13 @@
/**
* <html>
* <head>
* <title>org.owasp.dependencycheck.analyzer</title>
* </head>
* <body>
* Analyzers are used to inspect the identified dependencies, collect Evidence,
* and process the dependencies.
* </body>
* </html>
*/
package org.owasp.dependencycheck.analyzer;

View File

@@ -0,0 +1,67 @@
/*
* 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) 2013 Jeremy Long. All Rights Reserved.
*/
package org.owasp.dependencycheck.concurrency;
/**
* If thrown, indicates that a problem occurred when locking a directory.
*
* @author Jeremy Long (jeremy.long@owasp.org)
*/
public class DirectoryLockException extends Exception {
/**
* Default serial version UID.
*/
private static final long serialVersionUID = 1L;
/**
* Constructs a new Directory Lock Exception.
*/
public DirectoryLockException() {
super();
}
/**
* Constructs a new Directory Lock Exception.
*
* @param msg the message describing the exception
*/
public DirectoryLockException(String msg) {
super(msg);
}
/**
* Constructs a new Directory Lock Exception.
*
* @param ex the cause of the exception
*/
public DirectoryLockException(Throwable ex) {
super(ex);
}
/**
* Constructs a new Directory Lock Exception.
*
* @param msg the message describing the exception
* @param ex the cause of the exception
*/
public DirectoryLockException(String msg, Throwable ex) {
super(msg, ex);
}
}

View File

@@ -0,0 +1,267 @@
/*
* 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) 2013 Jeremy Long. All Rights Reserved.
*/
package org.owasp.dependencycheck.concurrency;
import java.io.Closeable;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.channels.AsynchronousCloseException;
import java.nio.channels.ClosedChannelException;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;
import java.nio.channels.FileLockInterruptionException;
import java.nio.channels.NonWritableChannelException;
import java.nio.channels.OverlappingFileLockException;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* Implements a spin lock on a given directory. If the lock cannot be obtained,
* the process will "spin" waiting for an opportunity to obtain the lock
* requested.
*
* @author Jeremy Long (jeremy.long@owasp.org)
*/
public class DirectorySpinLock implements Closeable /*, AutoCloseable*/ {
/**
* The name of the lock file.
*/
public static final String LOCK_NAME = "data.lock";
/**
* The maximum wait period used when attempting to obtain a lock.
*/
public static final int MAX_SPIN = 100;
/**
* The file channel used to perform the lock.
*/
private FileChannel channel = null;
/**
* The file used to perform the lock.
*/
private File lockFile = null;
/**
* The lock object.
*/
private FileLock lock = null;
/**
* The maximum number of seconds that the spin lock will wait while trying
* to obtain a lock.
*/
private long maxWait = MAX_SPIN;
/**
* Get the maximum wait time, in seconds, that the spin lock will wait while
* trying to obtain a lock.
*
* @return the number of seconds the spin lock will wait
*/
public long getMaxWait() {
return maxWait / 2; //sleep is for 500, so / 2
}
/**
* Set the maximum wait time, in seconds, that the spin lock will wait while
* trying to obtain a lock.
*
* @param maxWait the number of seconds the spin lock will wait
*/
public void setMaxWait(long maxWait) {
this.maxWait = maxWait * 2; //sleep is for 500, so * 2
}
/**
* Constructs a new spin lock on the given directory.
*
* @param directory the directory to monitor/lock
* @throws InvalidDirectoryException thrown if there is an issue with the
* directory provided
* @throws DirectoryLockException thrown there is an issue obtaining a
* handle to the lock file
*/
public DirectorySpinLock(File directory) throws InvalidDirectoryException, DirectoryLockException {
checkDirectory(directory);
lockFile = new File(directory, LOCK_NAME);
RandomAccessFile file = null;
try {
file = new RandomAccessFile(lockFile, "rw");
} catch (FileNotFoundException ex) {
throw new DirectoryLockException("Lock file not found", ex);
}
channel = file.getChannel();
}
/**
* Attempts to obtain an exclusive lock; an exception is thrown if the lock
* could not be obtained. This method may block for a few seconds if a lock
* cannot be obtained.
*
* @throws DirectoryLockException thrown if there is an exception obtaining
* the lock
*/
public void obtainSharedLock() throws DirectoryLockException {
obtainLock(true);
}
/**
* Attempts to obtain an exclusive lock; an exception is thrown if the lock
* could not be obtained. This method may block for a few seconds if a lock
* cannot be obtained.
*
* @throws DirectoryLockException thrown if there is an exception obtaining
* the lock
*/
public void obtainExclusiveLock() throws DirectoryLockException {
obtainLock(false);
}
/**
* Attempts to obtain a lock; an exception is thrown if the lock could not
* be obtained. This method may block for a few seconds if a lock cannot be
* obtained.
*
* @param shared true if the lock is shared, otherwise false
* @param maxWait the maximum time to wait, in seconds, while trying to
* obtain the lock
* @throws DirectoryLockException thrown if there is an exception obtaining
* the lock
*/
protected void obtainLock(boolean shared, long maxWait) throws DirectoryLockException {
setMaxWait(maxWait);
obtainLock(shared);
}
/**
* Attempts to obtain a lock; an exception is thrown if the lock could not
* be obtained. This method may block for a few seconds if a lock cannot be
* obtained.
*
* @param shared true if the lock is shared, otherwise false
* @throws DirectoryLockException thrown if there is an exception obtaining
* the lock
*/
protected void obtainLock(boolean shared) throws DirectoryLockException {
if (lock != null) {
release();
}
if (channel == null) {
throw new DirectoryLockException("Unable to create lock, no file channel exists");
}
int count = 0;
Exception lastException = null;
while (lock == null && count++ < maxWait) {
try {
lock = channel.lock(0, Long.MAX_VALUE, shared);
} catch (AsynchronousCloseException ex) {
lastException = ex;
} catch (ClosedChannelException ex) {
lastException = ex;
} catch (FileLockInterruptionException ex) {
lastException = ex;
} catch (OverlappingFileLockException ex) {
lastException = ex;
} catch (NonWritableChannelException ex) {
lastException = ex;
} catch (IOException ex) {
lastException = ex;
}
try {
Thread.sleep(500);
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
}
}
if (lock == null) {
if (lastException == null) {
throw new DirectoryLockException("Unable to obtain lock");
} else {
throw new DirectoryLockException("Unable to obtain lock", lastException);
}
}
}
/**
* Performs a few simple rudimentary checks on the specified directory.
* Specifically, does the file exist and is it a directory.
*
* @param directory the File object to inspect
* @throws InvalidDirectoryException thrown if the directory is null or is
* not a directory
*/
private void checkDirectory(File directory) throws InvalidDirectoryException {
if (directory == null) {
throw new InvalidDirectoryException("Unable to obtain lock on a null File");
}
if (!directory.isDirectory()) {
final String msg = String.format("File, '%s', does not exist or is not a directory", directory.getAbsolutePath());
throw new InvalidDirectoryException(msg);
}
}
/**
* Releases any locks and closes the underlying channel.
*
* @throws IOException if an IO Exception occurs
*/
@Override
public void close() throws IOException {
release();
// TODO uncomment this once support for 1.6 is dropped.
// if (lock != null) {
// try {
// lock.close();
// } catch (IOException ex) {
// Logger.getLogger(DirectorySpinLock.class.getName()).log(Level.FINEST, "Unable to close file lock due to IO Exception", ex);
// }
// }
if (channel != null) {
try {
channel.close();
} catch (IOException ex) {
Logger.getLogger(DirectorySpinLock.class.getName()).log(Level.FINEST, "Unable to close the channel for the file lock", ex);
}
}
if (lockFile != null) {
if (lockFile.exists()) {
/* yes, this delete could fail which is totally fine. The other
* thread holding the lock while delete it.
*/
lockFile.delete();
}
}
}
/**
* Releases the lock. Any exceptions that are thrown by the underlying lock
* during the release are ignored.
*/
public void release() {
if (lock != null) {
try {
lock.release();
} catch (ClosedChannelException ex) {
Logger.getLogger(DirectorySpinLock.class.getName()).log(Level.FINEST, "Uable to release file lock", ex);
} catch (IOException ex) {
Logger.getLogger(DirectorySpinLock.class.getName()).log(Level.FINEST, "Unable to release file lock due to IO Exception", ex);
}
}
}
}

View File

@@ -0,0 +1,67 @@
/*
* 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) 2013 Jeremy Long. All Rights Reserved.
*/
package org.owasp.dependencycheck.concurrency;
/**
* If thrown, indicates that there is a problem with a directory.
*
* @author Jeremy Long (jeremy.long@owasp.org)
*/
public class InvalidDirectoryException extends Exception {
/**
* Default serial version UID.
*/
private static final long serialVersionUID = 1L;
/**
* Constructs a new Invalid Directory Exception.
*/
public InvalidDirectoryException() {
super();
}
/**
* Constructs a new Invalid Directory Exception.
*
* @param msg the message describing the exception
*/
public InvalidDirectoryException(String msg) {
super(msg);
}
/**
* Constructs a new Invalid Directory Exception.
*
* @param ex the cause of the exception
*/
public InvalidDirectoryException(Throwable ex) {
super(ex);
}
/**
* Constructs a new Invalid Directory Exception.
*
* @param msg the message describing the exception
* @param ex the cause of the exception
*/
public InvalidDirectoryException(String msg, Throwable ex) {
super(msg, ex);
}
}

View File

@@ -0,0 +1,11 @@
/**
* <html>
* <head>
* <title>org.owasp.dependencycheck.concurrency</title>
* </head>
* <body>
* Contains classes used to create shared and exclusive locks on directories.
* </body>
* </html>
*/
package org.owasp.dependencycheck.concurrency;

View File

@@ -1,18 +1,18 @@
/*
* This file is part of Dependency-Check.
* This file is part of dependency-check-core.
*
* Dependency-Check is free software: you can redistribute it and/or modify it
* 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 is distributed in the hope that it will be useful, but
* 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. If not, see http://www.gnu.org/licenses/.
* dependency-check-core. If not, see http://www.gnu.org/licenses/.
*
* Copyright (c) 2012 Jeremy Long. All Rights Reserved.
*/

View File

@@ -1,18 +1,18 @@
/*
* This file is part of Dependency-Check.
* This file is part of dependency-check-core.
*
* Dependency-Check is free software: you can redistribute it and/or modify it
* 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 is distributed in the hope that it will be useful, but
* 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. If not, see http://www.gnu.org/licenses/.
* dependency-check-core. If not, see http://www.gnu.org/licenses/.
*
* Copyright (c) 2012 Jeremy Long. All Rights Reserved.
*/

View File

@@ -1,18 +1,18 @@
/*
* This file is part of Dependency-Check.
* This file is part of dependency-check-core.
*
* Dependency-Check is free software: you can redistribute it and/or modify it
* 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 is distributed in the hope that it will be useful, but
* 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. If not, see http://www.gnu.org/licenses/.
* dependency-check-core. If not, see http://www.gnu.org/licenses/.
*
* Copyright (c) 2012 Jeremy Long. All Rights Reserved.
*/

View File

@@ -0,0 +1,117 @@
/*
* 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) 2013 Jeremy Long. All Rights Reserved.
*/
package org.owasp.dependencycheck.data.cpe;
import java.io.File;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.owasp.dependencycheck.utils.Settings;
/**
* The Base Index class used to access the CPE Index.
*
* @author Jeremy Long (jeremy.long@owasp.org)
*/
public abstract class BaseIndex {
/**
* The Lucene directory containing the index.
*/
private Directory directory;
/**
* Indicates whether or not the Lucene Index is open.
*/
private boolean indexOpen = false;
/**
* Gets the directory.
*
* @return the directory
*/
public Directory getDirectory() {
return directory;
}
/**
* Opens the CPE Index.
*
* @throws IOException is thrown if an IOException occurs opening the index.
*/
public void open() throws IOException {
directory = this.openDirectory();
indexOpen = true;
}
/**
* Closes the CPE Index.
*/
public void close() {
try {
directory.close();
} catch (IOException ex) {
final String msg = "Unable to update database due to an IO error.";
Logger.getLogger(BaseIndex.class.getName()).log(Level.SEVERE, msg);
Logger.getLogger(BaseIndex.class.getName()).log(Level.FINE, null, ex);
} finally {
directory = null;
}
indexOpen = false;
}
/**
* Returns the status of the data source - is the index open.
*
* @return true or false.
*/
public boolean isOpen() {
return indexOpen;
}
/**
* Returns the Lucene directory object for the CPE Index.
*
* @return the Lucene Directory object for the CPE Index.
* @throws IOException is thrown if an IOException occurs.
*/
protected Directory openDirectory() throws IOException {
final File path = getDataDirectory();
return FSDirectory.open(path);
}
/**
* Retrieves the directory that the JAR file exists in so that we can ensure
* we always use a common data directory.
*
* @return the data directory for this index.
* @throws IOException is thrown if an IOException occurs of course...
*/
public static File getDataDirectory() throws IOException {
final File path = Settings.getFile(Settings.KEYS.CPE_DATA_DIRECTORY);
if (!path.exists()) {
if (!path.mkdirs()) {
throw new IOException("Unable to create CPE Data directory");
}
}
return path;
}
}

View File

@@ -0,0 +1,179 @@
/*
* 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) 2013 Jeremy Long. All Rights Reserved.
*/
package org.owasp.dependencycheck.data.cpe;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.core.KeywordAnalyzer;
import org.apache.lucene.analysis.miscellaneous.PerFieldAnalyzerWrapper;
import org.apache.lucene.document.Document;
import org.apache.lucene.index.CorruptIndexException;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.queryparser.classic.ParseException;
import org.apache.lucene.queryparser.classic.QueryParser;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.util.Version;
import org.owasp.dependencycheck.data.lucene.FieldAnalyzer;
import org.owasp.dependencycheck.data.lucene.SearchFieldAnalyzer;
/**
*
* @author Jeremy Long (jeremy.long@owasp.org)
*/
public class CpeIndexReader extends BaseIndex {
/**
* The Lucene IndexReader.
*/
private IndexReader indexReader;
/**
* The Lucene IndexSearcher.
*/
private IndexSearcher indexSearcher;
/**
* The Lucene Analyzer used for Searching.
*/
private Analyzer searchingAnalyzer;
/**
* The Lucene QueryParser used for Searching.
*/
private QueryParser queryParser;
/**
* The search field analyzer for the product field.
*/
private SearchFieldAnalyzer productSearchFieldAnalyzer;
/**
* The search field analyzer for the vendor field.
*/
private SearchFieldAnalyzer vendorSearchFieldAnalyzer;
/**
* Opens the CPE Index.
*
* @throws IOException is thrown if an IOException occurs opening the index.
*/
@Override
public void open() throws IOException {
//TODO add spinlock (shared)
super.open();
indexReader = DirectoryReader.open(getDirectory());
indexSearcher = new IndexSearcher(indexReader);
searchingAnalyzer = createSearchingAnalyzer();
queryParser = new QueryParser(Version.LUCENE_43, Fields.DOCUMENT_KEY, searchingAnalyzer);
}
/**
* Closes the CPE Index.
*/
@Override
public void close() {
//TODO remove spinlock (shared)
if (searchingAnalyzer != null) {
searchingAnalyzer.close();
searchingAnalyzer = null;
}
if (indexReader != null) {
try {
indexReader.close();
} catch (IOException ex) {
Logger.getLogger(CpeIndexReader.class.getName()).log(Level.FINEST, null, ex);
}
indexReader = null;
}
queryParser = null;
indexSearcher = null;
super.close();
}
/**
* Searches the index using the given search string.
*
* @param searchString the query text
* @param maxQueryResults the maximum number of documents to return
* @return the TopDocs found by the search
* @throws ParseException thrown when the searchString is invalid
* @throws IOException is thrown if there is an issue with the underlying
* Index
*/
public TopDocs search(String searchString, int maxQueryResults) throws ParseException, IOException {
final Query query = queryParser.parse(searchString);
return indexSearcher.search(query, maxQueryResults);
}
/**
* Searches the index using the given query.
*
* @param query the query used to search the index
* @param maxQueryResults the max number of results to return
* @return the TopDocs found be the query
* @throws CorruptIndexException thrown if the Index is corrupt
* @throws IOException thrown if there is an IOException
*/
public TopDocs search(Query query, int maxQueryResults) throws CorruptIndexException, IOException {
resetSearchingAnalyzer();
return indexSearcher.search(query, maxQueryResults);
}
/**
* Retrieves a document from the Index.
*
* @param documentId the id of the document to retrieve
* @return the Document
* @throws IOException thrown if there is an IOException
*/
public Document getDocument(int documentId) throws IOException {
return indexSearcher.doc(documentId);
}
/**
* Creates an Analyzer for searching the CPE Index.
*
* @return the CPE Analyzer.
*/
@SuppressWarnings("unchecked")
private Analyzer createSearchingAnalyzer() {
final Map fieldAnalyzers = new HashMap();
fieldAnalyzers.put(Fields.DOCUMENT_KEY, new KeywordAnalyzer());
productSearchFieldAnalyzer = new SearchFieldAnalyzer(Version.LUCENE_43);
vendorSearchFieldAnalyzer = new SearchFieldAnalyzer(Version.LUCENE_43);
fieldAnalyzers.put(Fields.PRODUCT, productSearchFieldAnalyzer);
fieldAnalyzers.put(Fields.VENDOR, vendorSearchFieldAnalyzer);
return new PerFieldAnalyzerWrapper(new FieldAnalyzer(Version.LUCENE_43), fieldAnalyzers);
}
/**
* Resets the searching analyzers
*/
private void resetSearchingAnalyzer() {
if (productSearchFieldAnalyzer != null) {
productSearchFieldAnalyzer.clear();
}
if (vendorSearchFieldAnalyzer != null) {
vendorSearchFieldAnalyzer.clear();
}
}
}

View File

@@ -0,0 +1,149 @@
/*
* 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) 2013 Jeremy Long. All Rights Reserved.
*/
package org.owasp.dependencycheck.data.cpe;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.core.KeywordAnalyzer;
import org.apache.lucene.analysis.miscellaneous.PerFieldAnalyzerWrapper;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.StringField;
import org.apache.lucene.document.TextField;
import org.apache.lucene.index.CorruptIndexException;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.index.Term;
import org.apache.lucene.util.Version;
import org.owasp.dependencycheck.data.lucene.FieldAnalyzer;
/**
*
* @author Jeremy Long (jeremy.long@owasp.org)
*/
public class CpeIndexWriter extends BaseIndex {
/**
* The IndexWriter for the Lucene index.
*/
private IndexWriter indexWriter;
/**
* The Lucene Analyzer used for Indexing.
*/
private Analyzer indexingAnalyzer;
/**
* Opens the CPE Index.
*
* @throws IOException is thrown if an IOException occurs opening the index.
*/
@Override
public void open() throws IOException {
//TODO add spinlock
super.open();
indexingAnalyzer = createIndexingAnalyzer();
final IndexWriterConfig conf = new IndexWriterConfig(Version.LUCENE_43, indexingAnalyzer);
indexWriter = new IndexWriter(getDirectory(), conf);
}
/**
* Closes the CPE Index.
*/
@Override
public void close() {
//TODO remove spinlock
if (indexWriter != null) {
commit();
try {
indexWriter.close(true);
} catch (CorruptIndexException ex) {
final String msg = "Unable to update database, there is a corrupt index.";
Logger.getLogger(CpeIndexWriter.class.getName()).log(Level.SEVERE, msg);
Logger.getLogger(CpeIndexWriter.class.getName()).log(Level.FINE, null, ex);
} catch (IOException ex) {
final String msg = "Unable to update database due to an IO error.";
Logger.getLogger(CpeIndexWriter.class.getName()).log(Level.SEVERE, msg);
Logger.getLogger(CpeIndexWriter.class.getName()).log(Level.FINE, null, ex);
} finally {
indexWriter = null;
}
}
if (indexingAnalyzer != null) {
indexingAnalyzer.close();
indexingAnalyzer = null;
}
super.close();
}
/**
* Commits any pending changes.
*/
public void commit() {
if (indexWriter != null) {
try {
indexWriter.forceMerge(1);
indexWriter.commit();
} catch (CorruptIndexException ex) {
final String msg = "Unable to update database, there is a corrupt index.";
Logger.getLogger(CpeIndexWriter.class.getName()).log(Level.SEVERE, msg);
Logger.getLogger(CpeIndexWriter.class.getName()).log(Level.FINE, null, ex);
} catch (IOException ex) {
final String msg = "Unable to update database due to an IO error.";
Logger.getLogger(CpeIndexWriter.class.getName()).log(Level.SEVERE, msg);
Logger.getLogger(CpeIndexWriter.class.getName()).log(Level.FINE, null, ex);
}
}
}
/**
* Creates the indexing analyzer for the CPE Index.
*
* @return the CPE Analyzer.
*/
@SuppressWarnings("unchecked")
private Analyzer createIndexingAnalyzer() {
final Map fieldAnalyzers = new HashMap();
fieldAnalyzers.put(Fields.DOCUMENT_KEY, new KeywordAnalyzer());
return new PerFieldAnalyzerWrapper(new FieldAnalyzer(Version.LUCENE_43), fieldAnalyzers);
}
/**
* Saves a CPE IndexEntry into the Lucene index.
*
* @param entry a CPE entry.
* @throws CorruptIndexException is thrown if the index is corrupt.
* @throws IOException is thrown if an IOException occurs.
*/
public void saveEntry(IndexEntry entry) throws CorruptIndexException, IOException {
final Document doc = new Document();
final Field documentKey = new StringField(Fields.DOCUMENT_KEY, entry.getDocumentId(), Field.Store.NO);
final Field vendor = new TextField(Fields.VENDOR, entry.getVendor(), Field.Store.YES);
final Field product = new TextField(Fields.PRODUCT, entry.getProduct(), Field.Store.YES);
doc.add(documentKey);
doc.add(vendor);
doc.add(product);
final Term term = new Term(Fields.DOCUMENT_KEY, entry.getDocumentId());
indexWriter.updateDocument(term, doc);
}
}

View File

@@ -1,18 +1,18 @@
/*
* This file is part of Dependency-Check.
* This file is part of dependency-check-core.
*
* Dependency-Check is free software: you can redistribute it and/or modify it
* 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 is distributed in the hope that it will be useful, but
* 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. If not, see http://www.gnu.org/licenses/.
* dependency-check-core. If not, see http://www.gnu.org/licenses/.
*
* Copyright (c) 2012 Jeremy Long. All Rights Reserved.
*/
@@ -27,9 +27,9 @@ package org.owasp.dependencycheck.data.cpe;
public abstract class Fields {
/**
* The key for the name field.
* The key for the name document id.
*/
public static final String NAME = "name";
public static final String DOCUMENT_KEY = "id";
/**
* The key for the vendor field.
*/
@@ -41,6 +41,4 @@ public abstract class Fields {
/**
* The key for the version field.
*/
public static final String VERSION = "version";
//public static final String REVISION = "revision";
}

View File

@@ -1,18 +1,18 @@
/*
* This file is part of Dependency-Check.
* This file is part of dependency-check-core.
*
* Dependency-Check is free software: you can redistribute it and/or modify it
* 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 is distributed in the hope that it will be useful, but
* 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. If not, see http://www.gnu.org/licenses/.
* dependency-check-core. If not, see http://www.gnu.org/licenses/.
*
* Copyright (c) 2012 Jeremy Long. All Rights Reserved.
*/
@@ -21,65 +21,47 @@ package org.owasp.dependencycheck.data.cpe;
import java.io.Serializable;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.lucene.document.Document;
/**
* A CPE entry containing the name, vendor, product, and version.
*
* @author Jeremy Long (jeremy.long@owasp.org)
*/
public class Entry implements Serializable {
public class IndexEntry implements Serializable {
/**
* the serial version uid.
*/
static final long serialVersionUID = 8011924485946326934L;
/**
* This parse method does not fully convert a Lucene Document into a CPE
* Entry; it only sets the Entry.Name.
*
* @param doc a Lucene Document.
* @return a CPE Entry.
*/
public static Entry parse(Document doc) {
final Entry entry = new Entry();
try {
entry.parseName(doc.get(Fields.NAME));
} catch (UnsupportedEncodingException ex) {
Logger.getLogger(Entry.class.getName()).log(Level.SEVERE, null, ex);
entry.name = doc.get(Fields.NAME);
}
return entry;
}
/**
* The name of the CPE entry.
*/
private String name;
/**
* Get the value of name.
*
* @return the value of name
*/
public String getName() {
return name;
}
/**
* Set the value of name.
*
* @param name new value of name
*/
public void setName(String name) {
this.name = name;
}
/**
* The vendor name.
*/
private String vendor;
/**
* The documentId.
*/
private String documentId;
/**
* Get the value of documentId.
*
* @return the value of documentId
*/
public String getDocumentId() {
if (documentId == null && vendor != null && product != null) {
documentId = vendor + ":" + product;
}
return documentId;
}
/**
* Set the value of documentId.
*
* @param documentId new value of documentId
*/
public void setDocumentId(String documentId) {
this.documentId = documentId;
}
/**
* Get the value of vendor.
@@ -120,50 +102,6 @@ public class Entry implements Serializable {
public void setProduct(String product) {
this.product = product;
}
/**
* The product version.
*/
private String version;
/**
* Get the value of version.
*
* @return the value of version
*/
public String getVersion() {
return version;
}
/**
* Set the value of version.
*
* @param version new value of version
*/
public void setVersion(String version) {
this.version = version;
}
/**
* The product revision.
*/
private String revision;
/**
* Get the value of revision.
*
* @return the value of revision
*/
public String getRevision() {
return revision;
}
/**
* Set the value of revision.
*
* @param revision new value of revision
*/
public void setRevision(String revision) {
this.revision = revision;
}
/**
* The search score.
*/
@@ -189,36 +127,38 @@ public class Entry implements Serializable {
/**
* <p>Parses a name attribute value, from the cpe.xml, into its
* corresponding parts: vendor, product, version, revision.</p>
* corresponding parts: vendor, product.</p>
* <p>Example:</p>
* <code>&nbsp;&nbsp;&nbsp;cpe:/a:apache:struts:1.1:rc2</code>
* <code>nbsp;nbsp;nbsp;cpe:/a:apache:struts:1.1:rc2</code>
*
* <p>Results in:</p> <ul> <li>Vendor: apache</li> <li>Product: struts</li>
* <li>Version: 1.1</li> <li>Revision: rc2</li> </ul>
* </ul>
* <p>If it is necessary to parse the CPE into more parts (i.e. to include
* version and revision) then you should use the
* {@link org.owasp.dependencycheck.dependency.VulnerableSoftware#parseName VulnerableSoftware.parseName()}.
*
* @param cpeName the cpe name
* @throws UnsupportedEncodingException should never be thrown...
*/
public void parseName(String cpeName) throws UnsupportedEncodingException {
this.name = cpeName;
if (cpeName != null && cpeName.length() > 7) {
final String[] data = cpeName.substring(7).split(":");
if (data.length >= 1) {
vendor = URLDecoder.decode(data[0], "UTF-8").replaceAll("[_-]", " ");
vendor = URLDecoder.decode(data[0].replace("+", "%2B"), "UTF-8");
if (data.length >= 2) {
product = URLDecoder.decode(data[1], "UTF-8").replaceAll("[_-]", " ");
if (data.length >= 3) {
version = URLDecoder.decode(data[2], "UTF-8");
if (data.length >= 4) {
revision = URLDecoder.decode(data[3], "UTF-8");
}
//ignore edition and language fields.. don't really see them used in the a:
}
product = URLDecoder.decode(data[1].replace("+", "%2B"), "UTF-8");
}
}
}
}
@Override
public int hashCode() {
int hash = 7;
hash = 97 * hash + (this.getDocumentId() != null ? this.getDocumentId().hashCode() : 0);
return hash;
}
@Override
public boolean equals(Object obj) {
if (obj == null) {
@@ -227,17 +167,23 @@ public class Entry implements Serializable {
if (getClass() != obj.getClass()) {
return false;
}
final Entry other = (Entry) obj;
if ((this.name == null) ? (other.name != null) : !this.name.equals(other.name)) {
final IndexEntry other = (IndexEntry) obj;
if ((this.vendor == null) ? (other.vendor != null) : !this.vendor.equals(other.vendor)) {
return false;
}
if ((this.product == null) ? (other.product != null) : !this.product.equals(other.product)) {
return false;
}
return true;
}
/**
* Standard implementation of toString showing vendor and product.
*
* @return the string representation of the object
*/
@Override
public int hashCode() {
int hash = 5;
hash = 83 * hash + (this.name != null ? this.name.hashCode() : 0);
return hash;
public String toString() {
return "IndexEntry{" + "vendor=" + vendor + ", product=" + product + '}';
}
}

View File

@@ -1,18 +1,18 @@
/*
* This file is part of Dependency-Check.
* This file is part of dependency-check-core.
*
* Dependency-Check is free software: you can redistribute it and/or modify it
* 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 is distributed in the hope that it will be useful, but
* 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. If not, see http://www.gnu.org/licenses/.
* dependency-check-core. If not, see http://www.gnu.org/licenses/.
*
* Copyright (c) 2012 Jeremy Long. All Rights Reserved.
*/
@@ -53,19 +53,19 @@ public final class CweDB {
final String filePath = "data/cwe.hashmap.serialized";
final InputStream input = CweDB.class.getClassLoader().getResourceAsStream(filePath);
oin = new ObjectInputStream(input);
@SuppressWarnings("unchecked")
final HashMap<String, String> data = (HashMap<String, String>) oin.readObject();
return data;
return (HashMap<String, String>) oin.readObject();
} catch (ClassNotFoundException ex) {
Logger.getLogger(CweDB.class.getName()).log(Level.SEVERE, null, ex);
Logger.getLogger(CweDB.class.getName()).log(Level.WARNING, "Unable to load CWE data. This should not be an issue.");
Logger.getLogger(CweDB.class.getName()).log(Level.FINE, null, ex);
} catch (IOException ex) {
Logger.getLogger(CweDB.class.getName()).log(Level.SEVERE, null, ex);
Logger.getLogger(CweDB.class.getName()).log(Level.WARNING, "Unable to load CWE data due to an IO Error. This should not be an issue.");
Logger.getLogger(CweDB.class.getName()).log(Level.FINE, null, ex);
} finally {
if (oin != null) {
try {
oin.close();
} catch (IOException ex) {
Logger.getLogger(CweDB.class.getName()).log(Level.SEVERE, null, ex);
Logger.getLogger(CweDB.class.getName()).log(Level.FINEST, null, ex);
}
}
}
@@ -74,6 +74,7 @@ public final class CweDB {
/**
* <p>Returns the full CWE name from the CWE ID.</p>
*
* @param cweId the CWE ID
* @return the full name of the CWE
*/

View File

@@ -1,18 +1,18 @@
/*
* This file is part of Dependency-Check.
* This file is part of dependency-check-core.
*
* Dependency-Check is free software: you can redistribute it and/or modify it
* 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 is distributed in the hope that it will be useful, but
* 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. If not, see http://www.gnu.org/licenses/.
* dependency-check-core. If not, see http://www.gnu.org/licenses/.
*
* Copyright (c) 2012 Jeremy Long. All Rights Reserved.
*/
@@ -33,10 +33,11 @@ public class CweHandler extends DefaultHandler {
/**
* a HashMap containing the CWE data.
*/
private HashMap<String, String> cwe = new HashMap<String, String>();
private final HashMap<String, String> cwe = new HashMap<String, String>();
/**
* Returns the HashMap of CWE entries (CWE-ID, Full CWE Name).
*
* @return a HashMap of CWE entries <String, String>
*/
public HashMap<String, String> getCwe() {

View File

@@ -0,0 +1,85 @@
/*
* 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) 2013 Jeremy Long. All Rights Reserved.
*/
package org.owasp.dependencycheck.data.lucene;
import java.util.LinkedList;
import org.apache.lucene.analysis.TokenFilter;
import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
/**
* An abstract tokenizing filter that can be used as the base for a tokenizing
* filter.
*
* @author Jeremy Long (jeremy.long@owasp.org)
*/
public abstract class AbstractTokenizingFilter extends TokenFilter {
/**
* The char term attribute.
*/
private final CharTermAttribute termAtt = addAttribute(CharTermAttribute.class);
/**
* Gets the CharTermAttribute.
*
* @return the CharTermAttribute
*/
protected CharTermAttribute getTermAtt() {
return termAtt;
}
/**
* A collection of tokens to add to the stream.
*/
private final LinkedList<String> tokens;
/**
* Gets the list of tokens.
*
* @return the list of tokens
*/
protected LinkedList<String> getTokens() {
return tokens;
}
/**
* Constructs a new AbstractTokenizingFilter.
*
* @param stream the TokenStream that this filter will process
*/
public AbstractTokenizingFilter(TokenStream stream) {
super(stream);
tokens = new LinkedList<String>();
}
/**
* Adds a term, if one exists, from the tokens collection.
*
* @return whether or not a new term was added
*/
protected boolean addTerm() {
final boolean termAdded = tokens.size() > 0;
if (termAdded) {
final String term = tokens.pop();
clearAttributes();
termAtt.append(term);
}
return termAdded;
}
}

View File

@@ -0,0 +1,64 @@
/*
* 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) 2013 Jeremy Long. All Rights Reserved.
*/
package org.owasp.dependencycheck.data.lucene;
import java.io.Reader;
import org.apache.lucene.analysis.util.CharTokenizer;
import org.apache.lucene.util.Version;
/**
* Tokenizes the input breaking it into tokens when non-alpha/numeric characters
* are found.
*
* @author Jeremy Long (jeremy.long@owasp.org)
*/
public class AlphaNumericTokenizer extends CharTokenizer {
/**
* Constructs a new AlphaNumericTokenizer.
*
* @param matchVersion the lucene version
* @param in the Reader
*/
public AlphaNumericTokenizer(Version matchVersion, Reader in) {
super(matchVersion, in);
}
/**
* Constructs a new AlphaNumericTokenizer.
*
* @param matchVersion the lucene version
* @param factory the AttributeFactory
* @param in the Reader
*/
public AlphaNumericTokenizer(Version matchVersion, AttributeFactory factory, Reader in) {
super(matchVersion, factory, in);
}
/**
* Determines if the char passed in is part of a token.
*
* @param c the char being analyzed
* @return true if the char is a letter or digit, otherwise false
*/
@Override
protected boolean isTokenChar(int c) {
return Character.isLetter(c) || Character.isDigit(c);
}
}

View File

@@ -1,18 +1,18 @@
/*
* This file is part of Dependency-Check.
* This file is part of dependency-check-core.
*
* Dependency-Check is free software: you can redistribute it and/or modify it
* 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 is distributed in the hope that it will be useful, but
* 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. If not, see http://www.gnu.org/licenses/.
* dependency-check-core. If not, see http://www.gnu.org/licenses/.
*
* Copyright (c) 2012 Jeremy Long. All Rights Reserved.
*/

View File

@@ -1,18 +1,18 @@
/*
* This file is part of Dependency-Check.
* This file is part of dependency-check-core.
*
* Dependency-Check is free software: you can redistribute it and/or modify it
* 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 is distributed in the hope that it will be useful, but
* 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. If not, see http://www.gnu.org/licenses/.
* dependency-check-core. If not, see http://www.gnu.org/licenses/.
*
* Copyright (c) 2012 Jeremy Long. All Rights Reserved.
*/
@@ -22,7 +22,6 @@ import java.io.Reader;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.analysis.Tokenizer;
import org.apache.lucene.analysis.core.WhitespaceTokenizer;
import org.apache.lucene.analysis.core.LowerCaseFilter;
import org.apache.lucene.analysis.core.StopAnalyzer;
import org.apache.lucene.analysis.core.StopFilter;
@@ -30,9 +29,9 @@ import org.apache.lucene.analysis.miscellaneous.WordDelimiterFilter;
import org.apache.lucene.util.Version;
/**
* <p>A Lucene Analyzer that utilizes the WhitespaceTokenizer, WordDelimiterFilter,
* LowerCaseFilter, and StopFilter. The intended purpose of this Analyzer is
* to index the CPE fields vendor and product.</p>
* <p>A Lucene Analyzer that utilizes the WhitespaceTokenizer,
* WordDelimiterFilter, LowerCaseFilter, and StopFilter. The intended purpose of
* this Analyzer is to index the CPE fields vendor and product.</p>
*
* @author Jeremy Long (jeremy.long@owasp.org)
*/
@@ -41,7 +40,7 @@ public class FieldAnalyzer extends Analyzer {
/**
* The Lucene Version used.
*/
private Version version;
private final Version version;
/**
* Creates a new FieldAnalyzer.
@@ -61,7 +60,7 @@ public class FieldAnalyzer extends Analyzer {
*/
@Override
protected TokenStreamComponents createComponents(String fieldName, Reader reader) {
final Tokenizer source = new WhitespaceTokenizer(version, reader);
final Tokenizer source = new AlphaNumericTokenizer(version, reader);
TokenStream stream = source;

View File

@@ -1,18 +1,18 @@
/*
* This file is part of Dependency-Check.
* This file is part of dependency-check-core.
*
* Dependency-Check is free software: you can redistribute it and/or modify it
* 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 is distributed in the hope that it will be useful, but
* 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. If not, see http://www.gnu.org/licenses/.
* dependency-check-core. If not, see http://www.gnu.org/licenses/.
*
* Copyright (c) 2012 Jeremy Long. All Rights Reserved.
*/
@@ -40,6 +40,9 @@ public final class LuceneUtils {
* @param text the data to be escaped
*/
@SuppressWarnings("fallthrough")
@edu.umd.cs.findbugs.annotations.SuppressWarnings(
value = "SF_SWITCH_NO_DEFAULT",
justification = "The switch below does have a default.")
public static void appendEscapedLuceneQuery(StringBuilder buf,
final CharSequence text) {

View File

@@ -1,18 +1,18 @@
/*
* This file is part of Dependency-Check.
* This file is part of dependency-check-core.
*
* Dependency-Check is free software: you can redistribute it and/or modify it
* 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 is distributed in the hope that it will be useful, but
* 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. If not, see http://www.gnu.org/licenses/.
* dependency-check-core. If not, see http://www.gnu.org/licenses/.
*
* Copyright (c) 2012 Jeremy Long. All Rights Reserved.
*/
@@ -22,7 +22,6 @@ import java.io.Reader;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.analysis.Tokenizer;
import org.apache.lucene.analysis.core.WhitespaceTokenizer;
import org.apache.lucene.analysis.core.LowerCaseFilter;
import org.apache.lucene.analysis.core.StopAnalyzer;
import org.apache.lucene.analysis.core.StopFilter;
@@ -39,10 +38,10 @@ public class SearchFieldAnalyzer extends Analyzer {
/**
* The Lucene Version used.
*/
private Version version;
private final Version version;
/**
* A local reference to the TokenPairConcatenatingFilter so that we
* can clear any left over state if this analyzer is re-used.
* A local reference to the TokenPairConcatenatingFilter so that we can
* clear any left over state if this analyzer is re-used.
*/
private TokenPairConcatenatingFilter concatenatingFilter;
@@ -57,13 +56,14 @@ public class SearchFieldAnalyzer extends Analyzer {
/**
* Creates a the TokenStreamComponents used to analyze the stream.
*
* @param fieldName the field that this lucene analyzer will process
* @param reader a reader containing the tokens
* @return the token stream filter chain
*/
@Override
protected TokenStreamComponents createComponents(String fieldName, Reader reader) {
final Tokenizer source = new WhitespaceTokenizer(version, reader);
final Tokenizer source = new AlphaNumericTokenizer(version, reader);
TokenStream stream = source;
@@ -76,6 +76,7 @@ public class SearchFieldAnalyzer extends Analyzer {
| WordDelimiterFilter.STEM_ENGLISH_POSSESSIVE, null);
stream = new LowerCaseFilter(version, stream);
stream = new UrlTokenizingFilter(stream);
concatenatingFilter = new TokenPairConcatenatingFilter(stream);
stream = concatenatingFilter;
stream = new StopFilter(version, stream, StopAnalyzer.ENGLISH_STOP_WORDS_SET);
@@ -84,11 +85,14 @@ public class SearchFieldAnalyzer extends Analyzer {
}
/**
* <p>Resets the analyzer and clears any internal state data that may
* have been left-over from previous uses of the analyzer.</p>
* <p><b>If this analyzer is re-used this method must be called between uses.</b></p>
* <p>Resets the analyzer and clears any internal state data that may have
* been left-over from previous uses of the analyzer.</p>
* <p><b>If this analyzer is re-used this method must be called between
* uses.</b></p>
*/
public void clear() {
concatenatingFilter.clear();
if (concatenatingFilter != null) {
concatenatingFilter.clear();
}
}
}

View File

@@ -1,18 +1,18 @@
/*
* This file is part of Dependency-Check.
* This file is part of dependency-check-core.
*
* Dependency-Check is free software: you can redistribute it and/or modify it
* 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 is distributed in the hope that it will be useful, but
* 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. If not, see http://www.gnu.org/licenses/.
* dependency-check-core. If not, see http://www.gnu.org/licenses/.
*
* Copyright (c) 2012 Jeremy Long. All Rights Reserved.
*/
@@ -27,10 +27,13 @@ import org.apache.lucene.analysis.core.WhitespaceTokenizer;
import org.apache.lucene.util.Version;
/**
* SearchVersionAnalyzer is a Lucene Analyzer used to analyze version information.
* SearchVersionAnalyzer is a Lucene Analyzer used to analyze version
* information.
*
* @author Jeremy Long (jeremy.long@owasp.org)
* @deprecated version information is no longer stored in lucene
*/
@Deprecated
public class SearchVersionAnalyzer extends Analyzer {
//TODO consider implementing payloads/custom attributes...
// use custom attributes for major, minor, x, x, x, rcx
@@ -42,7 +45,7 @@ public class SearchVersionAnalyzer extends Analyzer {
/**
* The Lucene Version used.
*/
private Version version;
private final Version version;
/**
* Creates a new SearchVersionAnalyzer.

View File

@@ -1,18 +1,18 @@
/*
* This file is part of Dependency-Check.
* This file is part of dependency-check-core.
*
* Dependency-Check is free software: you can redistribute it and/or modify it
* 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 is distributed in the hope that it will be useful, but
* 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. If not, see http://www.gnu.org/licenses/.
* dependency-check-core. If not, see http://www.gnu.org/licenses/.
*
* Copyright (c) 2012 Jeremy Long. All Rights Reserved.
*/
@@ -23,7 +23,6 @@ import java.util.LinkedList;
import org.apache.lucene.analysis.TokenFilter;
import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
import org.apache.lucene.analysis.tokenattributes.PositionIncrementAttribute;
/**
* <p>Takes a TokenStream and adds additional tokens by concatenating pairs of
@@ -39,10 +38,6 @@ public final class TokenPairConcatenatingFilter extends TokenFilter {
* The char term attribute.
*/
private final CharTermAttribute termAtt = addAttribute(CharTermAttribute.class);
/**
* The position increment attribute.
*/
private final PositionIncrementAttribute posIncAtt = addAttribute(PositionIncrementAttribute.class);
/**
* The previous word parsed.
*/
@@ -50,7 +45,7 @@ public final class TokenPairConcatenatingFilter extends TokenFilter {
/**
* A list of words parsed.
*/
private LinkedList<String> words;
private final LinkedList<String> words;
/**
* Constructs a new TokenPairConcatenatingFilter.
@@ -85,7 +80,6 @@ public final class TokenPairConcatenatingFilter extends TokenFilter {
final String word = words.getFirst();
clearAttributes();
termAtt.append(previousWord).append(word);
posIncAtt.setPositionIncrement(0);
previousWord = null;
return true;
}

View File

@@ -0,0 +1,85 @@
/*
* 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) 2013 Jeremy Long. All Rights Reserved.
*/
package org.owasp.dependencycheck.data.lucene;
import java.io.IOException;
import java.net.MalformedURLException;
import java.util.LinkedList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
import org.owasp.dependencycheck.utils.UrlStringUtils;
/**
* <p>Takes a TokenStream and splits or adds tokens to correctly index version
* numbers.</p>
* <p><b>Example:</b> "3.0.0.RELEASE" -> "3 3.0 3.0.0 RELEASE
* 3.0.0.RELEASE".</p>
*
* @author Jeremy Long (jeremy.long@owasp.org)
*/
public final class UrlTokenizingFilter extends AbstractTokenizingFilter {
/**
* Constructs a new VersionTokenizingFilter.
*
* @param stream the TokenStream that this filter will process
*/
public UrlTokenizingFilter(TokenStream stream) {
super(stream);
}
/**
* Increments the underlying TokenStream and sets CharTermAttributes to
* construct an expanded set of tokens by concatenating tokens with the
* previous token.
*
* @return whether or not we have hit the end of the TokenStream
* @throws IOException is thrown when an IOException occurs
*/
@Override
public boolean incrementToken() throws IOException {
final LinkedList<String> tokens = getTokens();
final CharTermAttribute termAtt = getTermAtt();
if (tokens.size() == 0 && input.incrementToken()) {
final String text = new String(termAtt.buffer(), 0, termAtt.length());
if (UrlStringUtils.containsUrl(text)) {
final String[] parts = text.split("\\s");
for (String part : parts) {
if (UrlStringUtils.isUrl(part)) {
try {
final List<String> data = UrlStringUtils.extractImportantUrlData(part);
tokens.addAll(data);
} catch (MalformedURLException ex) {
Logger.getLogger(UrlTokenizingFilter.class.getName()).log(Level.INFO, "error parsing " + part, ex);
tokens.add(part);
}
} else {
tokens.add(part);
}
}
} else {
tokens.add(text);
}
}
return addTerm();
}
}

View File

@@ -1,18 +1,18 @@
/*
* This file is part of Dependency-Check.
* This file is part of dependency-check-core.
*
* Dependency-Check is free software: you can redistribute it and/or modify it
* 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 is distributed in the hope that it will be useful, but
* 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. If not, see http://www.gnu.org/licenses/.
* dependency-check-core. If not, see http://www.gnu.org/licenses/.
*
* Copyright (c) 2012 Jeremy Long. All Rights Reserved.
*/
@@ -30,7 +30,9 @@ import org.apache.lucene.util.Version;
* VersionAnalyzer is a Lucene Analyzer used to analyze version information.
*
* @author Jeremy Long (jeremy.long@owasp.org)
* @deprecated version information is no longer stored in lucene
*/
@Deprecated
public class VersionAnalyzer extends Analyzer {
//TODO consider implementing payloads/custom attributes...
// use custom attributes for major, minor, x, x, x, rcx
@@ -42,7 +44,7 @@ public class VersionAnalyzer extends Analyzer {
/**
* The Lucene Version used.
*/
private Version version;
private final Version version;
/**
* Creates a new VersionAnalyzer.

View File

@@ -1,18 +1,18 @@
/*
* This file is part of Dependency-Check.
* This file is part of dependency-check-core.
*
* Dependency-Check is free software: you can redistribute it and/or modify it
* 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 is distributed in the hope that it will be useful, but
* 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. If not, see http://www.gnu.org/licenses/.
* dependency-check-core. If not, see http://www.gnu.org/licenses/.
*
* Copyright (c) 2012 Jeremy Long. All Rights Reserved.
*/
@@ -20,7 +20,6 @@ package org.owasp.dependencycheck.data.lucene;
import java.io.IOException;
import java.util.LinkedList;
import org.apache.lucene.analysis.TokenFilter;
import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
@@ -31,17 +30,10 @@ import org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
* 3.0.0.RELEASE".</p>
*
* @author Jeremy Long (jeremy.long@owasp.org)
* @deprecated version information is no longer stored in lucene
*/
public final class VersionTokenizingFilter extends TokenFilter {
/**
* The char term attribute.
*/
private final CharTermAttribute termAtt = addAttribute(CharTermAttribute.class);
/**
* A collection of tokens to add to the stream.
*/
private LinkedList<String> tokens;
@Deprecated
public final class VersionTokenizingFilter extends AbstractTokenizingFilter {
/**
* Constructs a new VersionTokenizingFilter.
@@ -50,7 +42,6 @@ public final class VersionTokenizingFilter extends TokenFilter {
*/
public VersionTokenizingFilter(TokenStream stream) {
super(stream);
tokens = new LinkedList<String>();
}
/**
@@ -63,6 +54,8 @@ public final class VersionTokenizingFilter extends TokenFilter {
*/
@Override
public boolean incrementToken() throws IOException {
final LinkedList<String> tokens = getTokens();
final CharTermAttribute termAtt = getTermAtt();
if (tokens.size() == 0 && input.incrementToken()) {
final String version = new String(termAtt.buffer(), 0, termAtt.length());
final String[] toAnalyze = version.split("[_-]");
@@ -75,21 +68,6 @@ public final class VersionTokenizingFilter extends TokenFilter {
return addTerm();
}
/**
* Adds a term, if one exists, from the tokens collection.
*
* @return whether or not a new term was added
*/
private boolean addTerm() {
final boolean termAdded = tokens.size() > 0;
if (termAdded) {
final String version = tokens.pop();
clearAttributes();
termAtt.append(version);
}
return termAdded;
}
/**
* <p>Analyzes the version and adds several copies of the version as
* different tokens. For example, the version 1.2.7 would create the tokens
@@ -104,6 +82,7 @@ public final class VersionTokenizingFilter extends TokenFilter {
private void analyzeVersion(String version) {
//todo should we also be splitting on dash or underscore? we would need
// to incorporate the dash or underscore back in...
final LinkedList<String> tokens = getTokens();
final String[] versionParts = version.split("\\.");
String dottedVersion = null;
for (String current : versionParts) {

View File

@@ -1,26 +1,26 @@
/*
* This file is part of Dependency-Check.
* This file is part of dependency-check-core.
*
* Dependency-Check is free software: you can redistribute it and/or modify it
* 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 is distributed in the hope that it will be useful, but
* 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. If not, see http://www.gnu.org/licenses/.
* dependency-check-core. If not, see http://www.gnu.org/licenses/.
*
* Copyright (c) 2012 Jeremy Long. All Rights Reserved.
*/
package org.owasp.dependencycheck.data.nvdcve;
/**
* An exception used to indicate the db4o database is corrupt.
* This could be due to invalid data or a complete failure of the db.
* An exception used to indicate the db4o database is corrupt. This could be due
* to invalid data or a complete failure of the db.
*
* @author Jeremy Long (jeremy.long@owasp.org)
*/

View File

@@ -0,0 +1,720 @@
/*
* 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.data.nvdcve;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.owasp.dependencycheck.data.cwe.CweDB;
import org.owasp.dependencycheck.dependency.Reference;
import org.owasp.dependencycheck.dependency.Vulnerability;
import org.owasp.dependencycheck.dependency.VulnerableSoftware;
import org.owasp.dependencycheck.utils.DependencyVersion;
import org.owasp.dependencycheck.utils.DependencyVersionUtil;
import org.owasp.dependencycheck.utils.Settings;
/**
* The database holding information about the NVD CVE data.
*
* @author Jeremy Long (jeremy.long@owasp.org)
*/
public class CveDB {
/**
* Resource location for SQL file used to create the database schema.
*/
public static final String DB_STRUCTURE_RESOURCE = "data/initialize.sql";
/**
* The version of the current DB Schema.
*/
public static final String DB_SCHEMA_VERSION = "2.6";
/**
* Database connection
*/
private Connection conn;
//<editor-fold defaultstate="collapsed" desc="Constants to create, maintain, and retrieve data from the CVE Database">
/**
* SQL Statement to delete references by vulnerability ID.
*/
public static final String DELETE_REFERENCE = "DELETE FROM reference WHERE cveid = ?";
/**
* SQL Statement to delete software by vulnerability ID.
*/
public static final String DELETE_SOFTWARE = "DELETE FROM software WHERE cveid = ?";
/**
* SQL Statement to delete a vulnerability by CVE.
*/
public static final String DELETE_VULNERABILITY = "DELETE FROM vulnerability WHERE cve = ?";
/**
* SQL Statement to cleanup orphan entries. Yes, the db schema could be a
* little tighter, but what we have works well to keep the data file size
* down a bit.
*/
public static final String CLEANUP_ORPHANS = "DELETE FROM CpeEntry WHERE id not in (SELECT CPEEntryId FROM Software); ";
/**
* SQL Statement to insert a new reference.
*/
public static final String INSERT_REFERENCE = "INSERT INTO reference (cveid, name, url, source) VALUES (?, ?, ?, ?)";
/**
* SQL Statement to insert a new software.
*/
public static final String INSERT_SOFTWARE = "INSERT INTO software (cveid, cpeEntryId, previousVersion) VALUES (?, ?, ?)";
/**
* SQL Statement to insert a new cpe.
*/
public static final String INSERT_CPE = "INSERT INTO cpeEntry (cpe, vendor, product) VALUES (?, ?, ?)";
/**
* SQL Statement to get a CPEProductID.
*/
public static final String SELECT_CPE_ID = "SELECT id FROM cpeEntry WHERE cpe = ?";
/**
* SQL Statement to insert a new vulnerability.
*/
public static final String INSERT_VULNERABILITY = "INSERT INTO vulnerability (cve, description, cwe, cvssScore, cvssAccessVector, "
+ "cvssAccessComplexity, cvssAuthentication, cvssConfidentialityImpact, cvssIntegrityImpact, cvssAvailabilityImpact) "
+ "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
/**
* SQL Statement to update a vulnerability.
*/
public static final String UPDATE_VULNERABILITY = "UPDATE vulnerability SET description=?, cwe=?, cvssScore=?, cvssAccessVector=?, "
+ "cvssAccessComplexity=?, cvssAuthentication=?, cvssConfidentialityImpact=?, cvssIntegrityImpact=?, cvssAvailabilityImpact=? "
+ "WHERE id=?";
/**
* SQL Statement to find CVE entries based on CPE data.
*/
public static final String SELECT_CVE_FROM_SOFTWARE = "SELECT cve, cpe, previousVersion "
+ "FROM software INNER JOIN vulnerability ON vulnerability.id = software.cveId "
+ "INNER JOIN cpeEntry ON cpeEntry.id = software.cpeEntryId "
+ "WHERE vendor = ? AND product = ?";
//unfortunately, the version info is too complicated to do in a select. Need to filter this afterwards
// + " AND (version = '-' OR previousVersion IS NOT NULL OR version=?)";
//
/**
* SQL Statement to find the CPE entry based on the vendor and product.
*/
public static final String SELECT_CPE_ENTRIES = "SELECT cpe FROM cpeEntry WHERE vendor = ? AND product = ?";
/**
* SQL Statement to select references by CVEID.
*/
public static final String SELECT_REFERENCE = "SELECT source, name, url FROM reference WHERE cveid = ?";
/**
* SQL Statement to select software by CVEID.
*/
public static final String SELECT_SOFTWARE = "SELECT cpe, previousVersion "
+ "FROM software INNER JOIN cpeEntry ON software.cpeEntryId = cpeEntry.id WHERE cveid = ?";
// public static final String SELECT_SOFTWARE = "SELECT part, vendor, product, version, revision, previousVersion "
// + "FROM software INNER JOIN cpeProduct ON cpeProduct.id = software.cpeProductId LEFT JOIN cpeVersion ON "
// + "software.cpeVersionId = cpeVersion.id LEFT JOIN Version ON cpeVersion.versionId = version.id WHERE cveid = ?";
/**
* SQL Statement to select a vulnerability by CVEID.
*/
public static final String SELECT_VULNERABILITY = "SELECT id, description, cwe, cvssScore, cvssAccessVector, cvssAccessComplexity, "
+ "cvssAuthentication, cvssConfidentialityImpact, cvssIntegrityImpact, cvssAvailabilityImpact FROM vulnerability WHERE cve = ?";
/**
* SQL Statement to select a vulnerability's primary key.
*/
public static final String SELECT_VULNERABILITY_ID = "SELECT id FROM vulnerability WHERE cve = ?";
//</editor-fold>
/**
* Opens the database connection. If the database does not exist, it will
* create a new one.
*
* @throws IOException thrown if there is an IO Exception
* @throws SQLException thrown if there is a SQL Exception
* @throws DatabaseException thrown if there is an error initializing a new
* database
* @throws ClassNotFoundException thrown if the h2 database driver cannot be
* loaded
*/
@edu.umd.cs.findbugs.annotations.SuppressWarnings(
value = "DMI_EMPTY_DB_PASSWORD",
justification = "Yes, I know... Blank password.")
public void open() throws IOException, SQLException, DatabaseException, ClassNotFoundException {
final String fileName = CveDB.getDataDirectory().getCanonicalPath();
final File f = new File(fileName, "cve." + DB_SCHEMA_VERSION);
final File check = new File(f.getAbsolutePath() + ".h2.db");
final boolean createTables = !check.exists();
final String connStr = String.format("jdbc:h2:file:%s;AUTO_SERVER=TRUE", f.getAbsolutePath());
Class.forName("org.h2.Driver");
conn = DriverManager.getConnection(connStr, "sa", "");
if (createTables) {
createTables();
}
}
/**
* Commits all completed transactions.
*
* @throws SQLException thrown if a SQL Exception occurs
*/
public void commit() throws SQLException {
if (conn != null) {
conn.commit();
}
}
/**
* Cleans up the object and ensures that "close" has been called.
*
* @throws Throwable thrown if there is a problem
*/
@Override
protected void finalize() throws Throwable {
close();
super.finalize(); //not necessary if extending Object.
}
/**
* Closes the DB4O database. Close should be called on this object when it
* is done being used.
*/
public void close() {
if (conn != null) {
try {
conn.close();
} catch (SQLException ex) {
final String msg = "There was an error attempting to close the CveDB, see the log for more details.";
Logger.getLogger(CveDB.class.getName()).log(Level.SEVERE, msg, ex);
Logger.getLogger(CveDB.class.getName()).log(Level.FINE, null, ex);
}
conn = null;
}
}
/**
* Searches the CPE entries in the database and retrieves all entries for a
* given vendor and product combination. The returned list will include all
* versions of the product that are registered in the NVD CVE data.
*
* @param vendor the identified vendor name of the dependency being analyzed
* @param product the identified name of the product of the dependency being
* analyzed
* @return a set of vulnerable software
*/
public Set<VulnerableSoftware> getCPEs(String vendor, String product) {
final Set<VulnerableSoftware> cpe = new HashSet<VulnerableSoftware>();
ResultSet rs = null;
PreparedStatement ps = null;
try {
ps = conn.prepareStatement(SELECT_CPE_ENTRIES);
ps.setString(1, vendor);
ps.setString(2, product);
rs = ps.executeQuery();
while (rs.next()) {
final VulnerableSoftware vs = new VulnerableSoftware();
vs.setCpe(rs.getString(1));
cpe.add(vs);
}
} catch (SQLException ex) {
Logger.getLogger(CveDB.class.getName()).log(Level.SEVERE, null, ex);
} finally {
closeResultSet(rs);
closeStatement(ps);
}
return cpe;
}
/**
* Retrieves the vulnerabilities associated with the specified CPE.
*
* @param cpeStr the CPE name
* @return a list of Vulnerabilities
* @throws DatabaseException thrown if there is an exception retrieving data
*/
public List<Vulnerability> getVulnerabilities(String cpeStr) throws DatabaseException {
ResultSet rs = null;
final VulnerableSoftware cpe = new VulnerableSoftware();
try {
cpe.parseName(cpeStr);
} catch (UnsupportedEncodingException ex) {
Logger.getLogger(CveDB.class.getName()).log(Level.FINEST, null, ex);
}
final DependencyVersion detectedVersion = parseDependencyVersion(cpe);
final List<Vulnerability> vulnerabilities = new ArrayList<Vulnerability>();
PreparedStatement ps;
final HashSet<String> cveEntries = new HashSet<String>();
try {
ps = conn.prepareStatement(SELECT_CVE_FROM_SOFTWARE);
ps.setString(1, cpe.getVendor());
ps.setString(2, cpe.getProduct());
rs = ps.executeQuery();
while (rs.next()) {
final String cveId = rs.getString(1);
final String cpeId = rs.getString(2);
final String previous = rs.getString(3);
if (!cveEntries.contains(cveId) && isAffected(cpe.getVendor(), cpe.getProduct(), detectedVersion, cpeId, previous)) {
cveEntries.add(cveId);
}
}
closeResultSet(rs);
closeStatement(ps);
for (String cve : cveEntries) {
final Vulnerability v = getVulnerability(cve);
vulnerabilities.add(v);
}
} catch (SQLException ex) {
throw new DatabaseException("Exception retrieving vulnerability for " + cpeStr, ex);
} finally {
closeResultSet(rs);
}
return vulnerabilities;
}
/**
* Gets a vulnerability for the provided CVE.
*
* @param cve the CVE to lookup
* @return a vulnerability object
* @throws DatabaseException if an exception occurs
*/
private Vulnerability getVulnerability(String cve) throws DatabaseException {
PreparedStatement psV = null;
PreparedStatement psR = null;
PreparedStatement psS = null;
ResultSet rsV = null;
ResultSet rsR = null;
ResultSet rsS = null;
Vulnerability vuln = null;
try {
psV = conn.prepareStatement(SELECT_VULNERABILITY);
psV.setString(1, cve);
rsV = psV.executeQuery();
if (rsV.next()) {
vuln = new Vulnerability();
vuln.setName(cve);
vuln.setDescription(rsV.getString(2));
String cwe = rsV.getString(3);
if (cwe != null) {
final String name = CweDB.getCweName(cwe);
if (name != null) {
cwe += " " + name;
}
}
final int cveId = rsV.getInt(1);
vuln.setCwe(cwe);
vuln.setCvssScore(rsV.getFloat(4));
vuln.setCvssAccessVector(rsV.getString(5));
vuln.setCvssAccessComplexity(rsV.getString(6));
vuln.setCvssAuthentication(rsV.getString(7));
vuln.setCvssConfidentialityImpact(rsV.getString(8));
vuln.setCvssIntegrityImpact(rsV.getString(9));
vuln.setCvssAvailabilityImpact(rsV.getString(10));
psR = conn.prepareStatement(SELECT_REFERENCE);
psR.setInt(1, cveId);
rsR = psR.executeQuery();
while (rsR.next()) {
vuln.addReference(rsR.getString(1), rsR.getString(2), rsR.getString(3));
}
psS = conn.prepareStatement(SELECT_SOFTWARE);
psS.setInt(1, cveId);
rsS = psS.executeQuery();
while (rsS.next()) {
final String cpe = rsS.getString(1);
final String prevVersion = rsS.getString(2);
if (prevVersion == null) {
vuln.addVulnerableSoftware(cpe);
} else {
vuln.addVulnerableSoftware(cpe, prevVersion);
}
}
}
} catch (SQLException ex) {
throw new DatabaseException("Error retrieving " + cve, ex);
} finally {
closeResultSet(rsV);
closeResultSet(rsR);
closeResultSet(rsS);
closeStatement(psV);
closeStatement(psR);
closeStatement(psS);
}
return vuln;
}
/**
* Updates the vulnerability within the database. If the vulnerability does
* not exist it will be added.
*
* @param vuln the vulnerability to add to the database
* @throws DatabaseException is thrown if the database
*/
public void updateVulnerability(Vulnerability vuln) throws DatabaseException {
PreparedStatement selectVulnerabilityId = null;
PreparedStatement deleteReferences = null;
PreparedStatement deleteSoftware = null;
PreparedStatement updateVulnerability = null;
PreparedStatement insertVulnerability = null;
PreparedStatement insertReference = null;
PreparedStatement selectCpeId = null;
PreparedStatement insertCpe = null;
PreparedStatement insertSoftware = null;
try {
selectVulnerabilityId = conn.prepareStatement(SELECT_VULNERABILITY_ID);
deleteReferences = conn.prepareStatement(DELETE_REFERENCE);
deleteSoftware = conn.prepareStatement(DELETE_SOFTWARE);
updateVulnerability = conn.prepareStatement(UPDATE_VULNERABILITY);
insertVulnerability = conn.prepareStatement(INSERT_VULNERABILITY, Statement.RETURN_GENERATED_KEYS);
insertReference = conn.prepareStatement(INSERT_REFERENCE);
selectCpeId = conn.prepareStatement(SELECT_CPE_ID);
insertCpe = conn.prepareStatement(INSERT_CPE, Statement.RETURN_GENERATED_KEYS);
insertSoftware = conn.prepareStatement(INSERT_SOFTWARE);
int vulnerabilityId = 0;
selectVulnerabilityId.setString(1, vuln.getName());
ResultSet rs = selectVulnerabilityId.executeQuery();
if (rs.next()) {
vulnerabilityId = rs.getInt(1);
// first delete any existing vulnerability info. We don't know what was updated. yes, slower but atm easier.
deleteReferences.setInt(1, vulnerabilityId);
deleteReferences.execute();
deleteSoftware.setInt(1, vulnerabilityId);
deleteSoftware.execute();
}
closeResultSet(rs);
rs = null;
if (vulnerabilityId != 0) {
updateVulnerability.setString(1, vuln.getDescription());
updateVulnerability.setString(2, vuln.getCwe());
updateVulnerability.setFloat(3, vuln.getCvssScore());
updateVulnerability.setString(4, vuln.getCvssAccessVector());
updateVulnerability.setString(5, vuln.getCvssAccessComplexity());
updateVulnerability.setString(6, vuln.getCvssAuthentication());
updateVulnerability.setString(7, vuln.getCvssConfidentialityImpact());
updateVulnerability.setString(8, vuln.getCvssIntegrityImpact());
updateVulnerability.setString(9, vuln.getCvssAvailabilityImpact());
updateVulnerability.setInt(10, vulnerabilityId);
updateVulnerability.executeUpdate();
} else {
insertVulnerability.setString(1, vuln.getName());
insertVulnerability.setString(2, vuln.getDescription());
insertVulnerability.setString(3, vuln.getCwe());
insertVulnerability.setFloat(4, vuln.getCvssScore());
insertVulnerability.setString(5, vuln.getCvssAccessVector());
insertVulnerability.setString(6, vuln.getCvssAccessComplexity());
insertVulnerability.setString(7, vuln.getCvssAuthentication());
insertVulnerability.setString(8, vuln.getCvssConfidentialityImpact());
insertVulnerability.setString(9, vuln.getCvssIntegrityImpact());
insertVulnerability.setString(10, vuln.getCvssAvailabilityImpact());
insertVulnerability.execute();
try {
rs = insertVulnerability.getGeneratedKeys();
rs.next();
vulnerabilityId = rs.getInt(1);
} catch (SQLException ex) {
final String msg = String.format("Unable to retrieve id for new vulnerability for '%s'", vuln.getName());
throw new DatabaseException(msg, ex);
} finally {
closeResultSet(rs);
rs = null;
}
}
insertReference.setInt(1, vulnerabilityId);
for (Reference r : vuln.getReferences()) {
insertReference.setString(2, r.getName());
insertReference.setString(3, r.getUrl());
insertReference.setString(4, r.getSource());
insertReference.execute();
}
for (VulnerableSoftware s : vuln.getVulnerableSoftware()) {
int cpeProductId = 0;
selectCpeId.setString(1, s.getName());
try {
rs = selectCpeId.executeQuery();
if (rs.next()) {
cpeProductId = rs.getInt(1);
}
} catch (SQLException ex) {
throw new DatabaseException("Unable to get primary key for new cpe: " + s.getName(), ex);
} finally {
closeResultSet(rs);
rs = null;
}
if (cpeProductId == 0) {
insertCpe.setString(1, s.getName());
insertCpe.setString(2, s.getVendor());
insertCpe.setString(3, s.getProduct());
insertCpe.executeUpdate();
cpeProductId = getGeneratedKey(insertCpe);
}
if (cpeProductId == 0) {
throw new DatabaseException("Unable to retrieve cpeProductId - no data returned");
}
insertSoftware.setInt(1, vulnerabilityId);
insertSoftware.setInt(2, cpeProductId);
if (s.getPreviousVersion() == null) {
insertSoftware.setNull(3, java.sql.Types.VARCHAR);
} else {
insertSoftware.setString(3, s.getPreviousVersion());
}
insertSoftware.execute();
}
} catch (SQLException ex) {
final String msg = String.format("Error updating '%s'", vuln.getName());
Logger.getLogger(CveDB.class.getName()).log(Level.FINE, null, ex);
throw new DatabaseException(msg, ex);
} finally {
closeStatement(selectVulnerabilityId);
closeStatement(deleteReferences);
closeStatement(deleteSoftware);
closeStatement(updateVulnerability);
closeStatement(insertVulnerability);
closeStatement(insertReference);
closeStatement(selectCpeId);
closeStatement(insertCpe);
closeStatement(insertSoftware);
}
}
/**
* Retrieves the directory that the JAR file exists in so that we can ensure
* we always use a common data directory.
*
* @return the data directory for this index.
* @throws IOException is thrown if an IOException occurs of course...
*/
public static File getDataDirectory() throws IOException {
final File path = Settings.getFile(Settings.KEYS.CVE_DATA_DIRECTORY);
if (!path.exists()) {
if (!path.mkdirs()) {
throw new IOException("Unable to create NVD CVE Data directory");
}
}
return path;
}
/**
* It is possible that orphaned rows may be generated during database
* updates. This should be called after all updates have been completed to
* ensure orphan entries are removed.
*/
public void cleanupDatabase() {
PreparedStatement ps = null;
try {
ps = conn.prepareStatement(CLEANUP_ORPHANS);
if (ps != null) {
ps.executeUpdate();
}
} catch (SQLException ex) {
Logger.getLogger(CveDB.class.getName()).log(Level.SEVERE, null, ex);
} finally {
closeStatement(ps);
}
}
/**
* Creates the database structure (tables and indexes) to store the CVE data
*
* @throws SQLException thrown if there is a sql exception
* @throws DatabaseException thrown if there is a database exception
*/
protected void createTables() throws SQLException, DatabaseException {
InputStream is;
InputStreamReader reader;
BufferedReader in = null;
try {
is = this.getClass().getClassLoader().getResourceAsStream(DB_STRUCTURE_RESOURCE);
reader = new InputStreamReader(is, "UTF-8");
in = new BufferedReader(reader);
final StringBuilder sb = new StringBuilder(2110);
String tmp;
while ((tmp = in.readLine()) != null) {
sb.append(tmp);
}
Statement statement = null;
try {
statement = conn.createStatement();
statement.execute(sb.toString());
} finally {
closeStatement(statement);
}
} catch (IOException ex) {
throw new DatabaseException("Unable to create database schema", ex);
} finally {
if (in != null) {
try {
in.close();
} catch (IOException ex) {
Logger.getLogger(CveDB.class
.getName()).log(Level.FINEST, null, ex);
}
}
}
}
/**
* Closes the given statement object ignoring any exceptions that occur.
*
* @param statement a Statement object
*/
private void closeStatement(Statement statement) {
if (statement != null) {
try {
statement.close();
} catch (SQLException ex) {
Logger.getLogger(CveDB.class
.getName()).log(Level.FINEST, statement.toString(), ex);
}
}
}
/**
* Closes the result set capturing and ignoring any SQLExceptions that
* occur.
*
* @param rs a ResultSet to close
*/
private void closeResultSet(ResultSet rs) {
if (rs != null) {
try {
rs.close();
} catch (SQLException ex) {
Logger.getLogger(CveDB.class
.getName()).log(Level.FINEST, rs.toString(), ex);
}
}
}
/**
* Returns the generated integer primary key for a newly inserted row.
*
* @param statement a prepared statement that just executed an insert
* @return a primary key
* @throws DatabaseException thrown if there is an exception obtaining the
* key
*/
private int getGeneratedKey(PreparedStatement statement) throws DatabaseException {
ResultSet rs = null;
int id = 0;
try {
rs = statement.getGeneratedKeys();
rs.next();
id = rs.getInt(1);
} catch (SQLException ex) {
throw new DatabaseException("Unable to get primary key for inserted row");
} finally {
closeResultSet(rs);
}
return id;
}
/**
* Determines if the given identifiedVersion is affected by the given cpeId
* and previous version flag. A non-null, non-empty string passed to the
* previous version argument indicates that all previous versions are
* affected.
*
* @param vendor the vendor of the dependency being analyzed
* @param product the product name of the dependency being analyzed
* @param identifiedVersion the identified version of the dependency being
* analyzed
* @param cpeId the cpe identifier of software that has a known
* vulnerability
* @param previous a flag indicating if previous versions of the product are
* vulnerable
* @return true if the identified version is affected, otherwise false
*/
private boolean isAffected(String vendor, String product, DependencyVersion identifiedVersion, String cpeId, String previous) {
boolean affected = false;
final boolean isStruts = "apache".equals(vendor) && "struts".equals(product);
final DependencyVersion v = parseDependencyVersion(cpeId);
final boolean prevAffected = previous == null ? false : !previous.isEmpty();
if (identifiedVersion == null || "-".equals(identifiedVersion.toString())) {
if (v == null || "-".equals(v.toString())) {
affected = true;
}
} else if (identifiedVersion.equals(v) || (prevAffected && identifiedVersion.compareTo(v) < 0)) {
if (isStruts) { //struts 2 vulns don't affect struts 1
if (identifiedVersion.getVersionParts().get(0).equals(v.getVersionParts().get(0))) {
affected = true;
}
} else {
affected = true;
}
}
/*
* TODO consider utilizing the matchThreeVersion method to get additional results. However, this
* might also introduce false positives.
*/
return affected;
}
/**
* Parses the version (including revision) from a CPE identifier. If no
* version is identified then a '-' is returned.
*
* @param cpeStr a cpe identifier
* @return a dependency version
*/
private DependencyVersion parseDependencyVersion(String cpeStr) {
final VulnerableSoftware cpe = new VulnerableSoftware();
try {
cpe.parseName(cpeStr);
} catch (UnsupportedEncodingException ex) {
//never going to happen.
Logger.getLogger(CveDB.class.getName()).log(Level.FINEST, null, ex);
}
return parseDependencyVersion(cpe);
}
/**
* Takes a CPE and parses out the version number. If no version is
* identified then a '-' is returned.
*
* @param cpe a cpe object
* @return a dependency version
*/
private DependencyVersion parseDependencyVersion(VulnerableSoftware cpe) {
DependencyVersion cpeVersion;
if (cpe.getVersion() != null && cpe.getVersion().length() > 0) {
String versionText;
if (cpe.getRevision() != null && cpe.getRevision().length() > 0) {
versionText = String.format("%s.%s", cpe.getVersion(), cpe.getRevision());
} else {
versionText = cpe.getVersion();
}
cpeVersion = DependencyVersionUtil.parseVersion(versionText);
} else {
cpeVersion = new DependencyVersion("-");
}
return cpeVersion;
}
}

View File

@@ -1,18 +1,18 @@
/*
* This file is part of Dependency-Check.
* This file is part of dependency-check-core.
*
* Dependency-Check is free software: you can redistribute it and/or modify it
* 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 is distributed in the hope that it will be useful, but
* 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. If not, see http://www.gnu.org/licenses/.
* dependency-check-core. If not, see http://www.gnu.org/licenses/.
*
* Copyright (c) 2012 Jeremy Long. All Rights Reserved.
*/
@@ -24,6 +24,7 @@ package org.owasp.dependencycheck.data.nvdcve;
* @author Jeremy Long (jeremy.long@owasp.org)
*/
public class DatabaseException extends Exception {
/**
* the serial version uid.
*/

View File

@@ -1,22 +1,22 @@
/*
* This file is part of Dependency-Check.
* This file is part of dependency-check-core.
*
* Dependency-Check is free software: you can redistribute it and/or modify it
* 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 is distributed in the hope that it will be useful, but
* 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. If not, see http://www.gnu.org/licenses/.
* dependency-check-core. If not, see http://www.gnu.org/licenses/.
*
* Copyright (c) 2012 Jeremy Long. All Rights Reserved.
*/
package org.owasp.dependencycheck.data.nvdcve.xml;
package org.owasp.dependencycheck.data.nvdcve;
/**
* An InvalidDataDataException is a generic exception used when trying to load
@@ -25,6 +25,7 @@ package org.owasp.dependencycheck.data.nvdcve.xml;
* @author Jeremy Long (jeremy.long@owasp.org)
*/
public class InvalidDataException extends Exception {
/**
* the serial version uid.
*/

View File

@@ -1,22 +1,22 @@
/*
* This file is part of Dependency-Check.
* This file is part of dependency-check-core.
*
* Dependency-Check is free software: you can redistribute it and/or modify it
* 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 is distributed in the hope that it will be useful, but
* 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. If not, see http://www.gnu.org/licenses/.
* dependency-check-core. If not, see http://www.gnu.org/licenses/.
*
* Copyright (c) 2012 Jeremy Long. All Rights Reserved.
*/
package org.owasp.dependencycheck.data.nvdcve.xml;
package org.owasp.dependencycheck.data.nvdcve;
import java.util.ArrayList;
import java.util.HashMap;
@@ -32,7 +32,8 @@ import org.xml.sax.helpers.DefaultHandler;
* A SAX Handler that will parse the NVD CVE XML (schema version 1.2). This
* parses the xml and retrieves a listing of CPEs that have previous versions
* specified. The previous version information is not in the 2.0 version of the
* schema and is useful to ensure accurate identification (or at least complete).
* schema and is useful to ensure accurate identification (or at least
* complete).
*
* @author Jeremy Long (jeremy.long@owasp.org)
*/
@@ -69,7 +70,7 @@ public class NvdCve12Handler extends DefaultHandler {
/**
* The current element.
*/
private Element current = new Element();
private final Element current = new Element();
/**
* a map of vulnerabilities.
*/
@@ -112,8 +113,8 @@ public class NvdCve12Handler extends DefaultHandler {
final String num = attributes.getValue("num");
/*yes yes, this may not actually be an "a" - it could be an OS, etc. but for our
purposes this is good enough as we won't use this if we don't find a corresponding "a"
in the nvd cve 2.0. */
purposes this is good enough as we won't use this if we don't find a corresponding "a"
in the nvd cve 2.0. */
String cpe = "cpe:/a:" + vendor + ":" + product;
if (num != null) {
cpe += ":" + num;

View File

@@ -1,22 +1,22 @@
/*
* This file is part of Dependency-Check.
* This file is part of dependency-check-core.
*
* Dependency-Check is free software: you can redistribute it and/or modify it
* 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 is distributed in the hope that it will be useful, but
* 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. If not, see http://www.gnu.org/licenses/.
* dependency-check-core. If not, see http://www.gnu.org/licenses/.
*
* Copyright (c) 2012 Jeremy Long. All Rights Reserved.
*/
package org.owasp.dependencycheck.data.nvdcve.xml;
package org.owasp.dependencycheck.data.nvdcve;
import java.io.IOException;
import java.util.List;
@@ -24,9 +24,7 @@ import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.lucene.index.CorruptIndexException;
import org.owasp.dependencycheck.data.cpe.Index;
import org.owasp.dependencycheck.data.nvdcve.CveDB;
import org.owasp.dependencycheck.data.nvdcve.DatabaseException;
import org.owasp.dependencycheck.data.cpe.CpeIndexWriter;
import org.owasp.dependencycheck.dependency.Reference;
import org.owasp.dependencycheck.dependency.Vulnerability;
import org.owasp.dependencycheck.dependency.VulnerableSoftware;
@@ -49,7 +47,7 @@ public class NvdCve20Handler extends DefaultHandler {
/**
* the current element.
*/
private Element current = new Element();
private final Element current = new Element();
/**
* the text of the node.
*/
@@ -66,7 +64,6 @@ public class NvdCve20Handler extends DefaultHandler {
* flag indicating whether the application has a cpe.
*/
private boolean hasApplicationCpe = false;
/**
* The total number of entries parsed.
*/
@@ -80,7 +77,6 @@ public class NvdCve20Handler extends DefaultHandler {
public int getTotalNumberOfEntries() {
return totalNumberOfEntries;
}
/**
* The total number of application entries parsed.
*/
@@ -172,7 +168,8 @@ public class NvdCve20Handler extends DefaultHandler {
final float score = Float.parseFloat(nodeText.toString());
vulnerability.setCvssScore(score);
} catch (NumberFormatException ex) {
Logger.getLogger(NvdCve20Handler.class.getName()).log(Level.SEVERE, null, ex);
Logger.getLogger(NvdCve20Handler.class.getName()).log(Level.SEVERE, "Error parsing CVSS Score.");
Logger.getLogger(NvdCve20Handler.class.getName()).log(Level.FINE, null, ex);
}
nodeText = null;
} else if (current.isCVSSAccessVectorNode()) {
@@ -228,14 +225,16 @@ public class NvdCve20Handler extends DefaultHandler {
cveDB = db;
}
/**
* A list of CVE entries and associated VulnerableSoftware entries that contain
* previous entries.
* A list of CVE entries and associated VulnerableSoftware entries that
* contain previous entries.
*/
private Map<String, List<VulnerableSoftware>> prevVersionVulnMap;
/**
* Sets the prevVersionVulnMap.
* @param map the map of vulnerable software with previous versions being vulnerable
*
* @param map the map of vulnerable software with previous versions being
* vulnerable
*/
public void setPrevVersionVulnMap(Map<String, List<VulnerableSoftware>> map) {
prevVersionVulnMap = map;
@@ -243,10 +242,12 @@ public class NvdCve20Handler extends DefaultHandler {
/**
* Saves a vulnerability to the CVE Database. This is a callback method
* called by the Sax Parser Handler {@link org.owasp.dependencycheck.data.nvdcve.xml.NvdCve20Handler}.
* called by the Sax Parser Handler
* {@link org.owasp.dependencycheck.data.nvdcve.xml.NvdCve20Handler}.
*
* @param vuln the vulnerability to store in the database
* @throws DatabaseException thrown if there is an error writing to the database
* @throws DatabaseException thrown if there is an error writing to the
* database
* @throws CorruptIndexException is thrown if the CPE Index is corrupt
* @throws IOException thrown if there is an IOException with the CPE Index
*/
@@ -271,14 +272,14 @@ public class NvdCve20Handler extends DefaultHandler {
/**
* the cpe index.
*/
private Index cpeIndex;
private CpeIndexWriter cpeIndex;
/**
* Sets the cpe index.
* Sets the cpe index writer.
*
* @param index the CPE Lucene Index
*/
void setCpeIndex(Index index) {
public void setCpeIndex(CpeIndexWriter index) {
cpeIndex = index;
}
@@ -349,7 +350,6 @@ public class NvdCve20Handler extends DefaultHandler {
* A node type in the NVD CVE Schema 2.0
*/
public static final String CVSS_AVAILABILITY_IMPACT = "cvss:availability-impact";
/**
* The current node.
*/
@@ -444,6 +444,7 @@ public class NvdCve20Handler extends DefaultHandler {
public boolean isVulnCWENode() {
return VULN_CWE.equals(node);
}
/**
* Checks if the handler is at the CVSS_SCORE node.
*
@@ -452,6 +453,7 @@ public class NvdCve20Handler extends DefaultHandler {
public boolean isCVSSScoreNode() {
return CVSS_SCORE.equals(node);
}
/**
* Checks if the handler is at the CVSS_ACCESS_VECTOR node.
*
@@ -460,6 +462,7 @@ public class NvdCve20Handler extends DefaultHandler {
public boolean isCVSSAccessVectorNode() {
return CVSS_ACCESS_VECTOR.equals(node);
}
/**
* Checks if the handler is at the CVSS_ACCESS_COMPLEXITY node.
*
@@ -468,6 +471,7 @@ public class NvdCve20Handler extends DefaultHandler {
public boolean isCVSSAccessComplexityNode() {
return CVSS_ACCESS_COMPLEXITY.equals(node);
}
/**
* Checks if the handler is at the CVSS_AUTHENTICATION node.
*
@@ -476,6 +480,7 @@ public class NvdCve20Handler extends DefaultHandler {
public boolean isCVSSAuthenticationNode() {
return CVSS_AUTHENTICATION.equals(node);
}
/**
* Checks if the handler is at the CVSS_CONFIDENTIALITY_IMPACT node.
*
@@ -484,6 +489,7 @@ public class NvdCve20Handler extends DefaultHandler {
public boolean isCVSSConfidentialityImpactNode() {
return CVSS_CONFIDENTIALITY_IMPACT.equals(node);
}
/**
* Checks if the handler is at the CVSS_INTEGRITY_IMPACT node.
*
@@ -492,6 +498,7 @@ public class NvdCve20Handler extends DefaultHandler {
public boolean isCVSSIntegrityImpactNode() {
return CVSS_INTEGRITY_IMPACT.equals(node);
}
/**
* Checks if the handler is at the CVSS_AVAILABILITY_IMPACT node.
*
@@ -500,7 +507,6 @@ public class NvdCve20Handler extends DefaultHandler {
public boolean isCVSSAvailabilityImpactNode() {
return CVSS_AVAILABILITY_IMPACT.equals(node);
}
}
// </editor-fold>
}

View File

@@ -0,0 +1,241 @@
/*
* 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) 2013 Jeremy Long. All Rights Reserved.
*/
package org.owasp.dependencycheck.data.update;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.util.Properties;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.owasp.dependencycheck.data.UpdateException;
import org.owasp.dependencycheck.data.nvdcve.CveDB;
import org.owasp.dependencycheck.utils.Settings;
/**
*
* @author Jeremy Long (jeremy.long@owasp.org)
*/
public class DataStoreMetaInfo {
/**
* Batch key word, used as key to store information about batch mode.
*/
public static final String BATCH = "batch";
/**
* Modified key word, used as a key to store information about the modified
* file (i.e. the containing the last 8 days of updates)..
*/
public static final String MODIFIED = "modified";
/**
* The name of the properties file containing the timestamp of the last
* update.
*/
private static final String UPDATE_PROPERTIES_FILE = "data.properties";
/**
* The properties file key for the last updated field - used to store the
* last updated time of the Modified NVD CVE xml file.
*/
public static final String LAST_UPDATED = "lastupdated.modified";
/**
* Stores the last updated time for each of the NVD CVE files. These
* timestamps should be updated if we process the modified file within 7
* days of the last update.
*/
public static final String LAST_UPDATED_BASE = "lastupdated.";
/**
* A collection of properties about the data.
*/
private Properties properties = new Properties();
/**
* Indicates whether or not the updates are using a batch update mode or
* not.
*/
private boolean batchUpdateMode;
/**
* Get the value of batchUpdateMode.
*
* @return the value of batchUpdateMode
*/
protected boolean isBatchUpdateMode() {
return batchUpdateMode;
}
/**
* Set the value of batchUpdateMode.
*
* @param batchUpdateMode new value of batchUpdateMode
*/
protected void setBatchUpdateMode(boolean batchUpdateMode) {
this.batchUpdateMode = batchUpdateMode;
}
/**
* Constructs a new data properties object.
*/
public DataStoreMetaInfo() {
batchUpdateMode = !Settings.getString(Settings.KEYS.BATCH_UPDATE_URL, "").isEmpty();
loadProperties();
}
/**
* Loads the data's meta properties.
*/
private void loadProperties() {
final File file = getPropertiesFile();
if (file.exists()) {
InputStream is = null;
try {
is = new FileInputStream(file);
} catch (FileNotFoundException ignore) {
//we will never get here as we check for existence above.
Logger.getLogger(DataStoreMetaInfo.class.getName()).log(Level.FINEST, null, ignore);
}
try {
properties.load(is);
} catch (IOException ex) {
final String msg = String.format("Unable to load properties file '%s'", file.getPath());
Logger.getLogger(DataStoreMetaInfo.class.getName()).log(Level.WARNING, msg);
Logger.getLogger(DataStoreMetaInfo.class.getName()).log(Level.FINE, null, ex);
} finally {
if (is != null) {
try {
is.close();
} catch (IOException ex) {
final String msg = String.format("Unable to close properties file '%s'", file.getPath());
Logger.getLogger(DataStoreMetaInfo.class.getName()).log(Level.WARNING, msg);
Logger.getLogger(DataStoreMetaInfo.class.getName()).log(Level.FINE, null, ex);
}
}
}
}
}
/**
* Returns whether or not any properties are set.
*
* @return whether or not any properties are set
*/
public boolean isEmpty() {
return properties.isEmpty();
}
/**
* Writes a properties file containing the last updated date to the
* VULNERABLE_CPE directory.
*
* @param updatedValue the updated nvdcve entry
* @throws UpdateException is thrown if there is an update exception
*/
public void save(NvdCveInfo updatedValue) throws UpdateException {
if (updatedValue == null) {
return;
}
final File cveProp = getPropertiesFile();
final Properties prop = new Properties();
if (cveProp.exists()) {
FileInputStream in = null;
try {
in = new FileInputStream(cveProp);
prop.load(in);
} catch (Exception ignoreMe) {
Logger.getLogger(DataStoreMetaInfo.class.getName()).log(Level.FINEST, null, ignoreMe);
} finally {
if (in != null) {
try {
in.close();
} catch (Exception ignoreMeToo) {
Logger.getLogger(DataStoreMetaInfo.class.getName()).log(Level.FINEST, null, ignoreMeToo);
}
}
}
}
prop.put("version", CveDB.DB_SCHEMA_VERSION);
prop.put(LAST_UPDATED_BASE + updatedValue.getId(), String.valueOf(updatedValue.getTimestamp()));
OutputStream os = null;
OutputStreamWriter out = null;
try {
os = new FileOutputStream(cveProp);
out = new OutputStreamWriter(os, "UTF-8");
prop.store(out, "Meta data about data and data sources used by dependency-check");
} catch (FileNotFoundException ex) {
Logger.getLogger(DataStoreMetaInfo.class.getName()).log(Level.FINE, null, ex);
throw new UpdateException("Unable to find last updated properties file.", ex);
} catch (IOException ex) {
Logger.getLogger(DataStoreMetaInfo.class.getName()).log(Level.FINE, null, ex);
throw new UpdateException("Unable to update last updated properties file.", ex);
} finally {
if (out != null) {
try {
out.close();
} catch (IOException ex) {
Logger.getLogger(DataStoreMetaInfo.class.getName()).log(Level.FINEST, null, ex);
}
}
if (os != null) {
try {
os.close();
} catch (IOException ex) {
Logger.getLogger(DataStoreMetaInfo.class.getName()).log(Level.FINEST, null, ex);
}
}
}
}
/**
* Returns the property value for the given key. If the key is not contained
* in the underlying properties null is returned.
*
* @param key the property key
* @return the value of the property
*/
public String getProperty(String key) {
return properties.getProperty(key);
}
/**
* Returns the property value for the given key. If the key is not contained
* in the underlying properties the default value is returned.
*
* @param key the property key
* @param defaultValue the default value
* @return the value of the property
*/
public String getProperty(String key, String defaultValue) {
return properties.getProperty(key, defaultValue);
}
/**
* Retrieves the properties file.
*
* @return the properties file
*/
public static File getPropertiesFile() {
final File dataDirectory = Settings.getFile(Settings.KEYS.DATA_DIRECTORY);
final File file = new File(dataDirectory, UPDATE_PROPERTIES_FILE);
return file;
}
}

View File

@@ -0,0 +1,572 @@
/*
* 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.data.update;
import org.owasp.dependencycheck.data.nvdcve.NvdCve12Handler;
import org.owasp.dependencycheck.data.nvdcve.NvdCve20Handler;
import org.owasp.dependencycheck.data.nvdcve.InvalidDataException;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import javax.xml.parsers.ParserConfigurationException;
import org.xml.sax.SAXException;
import org.owasp.dependencycheck.data.CachedWebDataSource;
import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.net.URL;
import java.sql.SQLException;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.owasp.dependencycheck.data.UpdateException;
import org.owasp.dependencycheck.data.cpe.CpeIndexWriter;
import org.owasp.dependencycheck.data.nvdcve.CveDB;
import org.owasp.dependencycheck.dependency.VulnerableSoftware;
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.data.nvdcve.DatabaseException;
import org.owasp.dependencycheck.utils.InvalidSettingException;
import static org.owasp.dependencycheck.data.update.DataStoreMetaInfo.BATCH;
import static org.owasp.dependencycheck.data.update.DataStoreMetaInfo.MODIFIED;
/**
* Class responsible for updating the CPE and NVDCVE data stores.
*
* @author Jeremy Long (jeremy.long@owasp.org)
*/
public class DatabaseUpdater implements CachedWebDataSource {
/**
* Utility to read and write meta-data about the data.
*/
private DataStoreMetaInfo properties = null;
/**
* Reference to the Cve Database.
*/
private CveDB cveDB = null;
/**
* Reference to the Cpe Index.
*/
private CpeIndexWriter cpeIndex = null;
/**
* A flag indicating whether or not the batch update should be performed.
*/
private boolean doBatchUpdate;
/**
* Get the value of doBatchUpdate
*
* @return the value of doBatchUpdate
*/
protected boolean isDoBatchUpdate() {
return doBatchUpdate;
}
/**
* Set the value of doBatchUpdate
*
* @param doBatchUpdate new value of doBatchUpdate
*/
protected void setDoBatchUpdate(boolean doBatchUpdate) {
this.doBatchUpdate = doBatchUpdate;
}
/**
* <p>Downloads the latest NVD CVE XML file from the web and imports it into
* the current CVE Database.</p>
*
* @throws UpdateException is thrown if there is an error updating the
* database
*/
@Override
public void update() throws UpdateException {
doBatchUpdate = false;
properties = new DataStoreMetaInfo();
try {
final Map<String, NvdCveInfo> update = updateNeeded();
int maxUpdates = 0;
for (NvdCveInfo cve : update.values()) {
if (cve.getNeedsUpdate()) {
maxUpdates += 1;
}
}
if (maxUpdates > 3 && !properties.isBatchUpdateMode()) {
Logger.getLogger(DatabaseUpdater.class.getName()).log(Level.INFO,
"NVD CVE requires several updates; this could take a couple of minutes.");
}
if (maxUpdates > 0 && !isDoBatchUpdate()) {
openDataStores();
}
if (properties.isBatchUpdateMode() && isDoBatchUpdate()) {
try {
performBatchUpdate();
openDataStores();
} catch (IOException ex) {
throw new UpdateException("Unable to perform batch update", ex);
}
}
int count = 0;
for (NvdCveInfo cve : update.values()) {
if (cve.getNeedsUpdate()) {
count += 1;
Logger.getLogger(DatabaseUpdater.class.getName()).log(Level.INFO,
"Updating NVD CVE ({0} of {1})", new Object[]{count, maxUpdates});
URL url = new URL(cve.getUrl());
File outputPath = null;
File outputPath12 = null;
try {
Logger.getLogger(DatabaseUpdater.class.getName()).log(Level.INFO,
"Downloading {0}", cve.getUrl());
outputPath = File.createTempFile("cve" + cve.getId() + "_", ".xml");
Downloader.fetchFile(url, outputPath);
url = new URL(cve.getOldSchemaVersionUrl());
outputPath12 = File.createTempFile("cve_1_2_" + cve.getId() + "_", ".xml");
Downloader.fetchFile(url, outputPath12);
Logger.getLogger(DatabaseUpdater.class.getName()).log(Level.INFO,
"Processing {0}", cve.getUrl());
importXML(outputPath, outputPath12);
cveDB.commit();
cpeIndex.commit();
properties.save(cve);
Logger.getLogger(DatabaseUpdater.class.getName()).log(Level.INFO,
"Completed update {0} of {1}", new Object[]{count, maxUpdates});
} catch (FileNotFoundException ex) {
throw new UpdateException(ex);
} catch (ParserConfigurationException ex) {
throw new UpdateException(ex);
} catch (SAXException ex) {
throw new UpdateException(ex);
} catch (IOException ex) {
throw new UpdateException(ex);
} catch (SQLException ex) {
throw new UpdateException(ex);
} catch (DatabaseException ex) {
throw new UpdateException(ex);
} catch (ClassNotFoundException ex) {
throw new UpdateException(ex);
} finally {
boolean deleted = false;
try {
if (outputPath != null && outputPath.exists()) {
deleted = outputPath.delete();
}
} finally {
if (outputPath != null && (outputPath.exists() || !deleted)) {
outputPath.deleteOnExit();
}
}
try {
deleted = false;
if (outputPath12 != null && outputPath12.exists()) {
deleted = outputPath12.delete();
}
} finally {
if (outputPath12 != null && (outputPath12.exists() || !deleted)) {
outputPath12.deleteOnExit();
}
}
}
}
}
if (maxUpdates >= 1) { //ensure the modified file date gets written
properties.save(update.get(MODIFIED));
cveDB.cleanupDatabase();
}
if (update.get(BATCH) != null) {
properties.save(update.get(BATCH));
}
} catch (MalformedURLException ex) {
throw new UpdateException(ex);
} catch (DownloadFailedException ex) {
throw new UpdateException(ex);
} finally {
closeDataStores();
}
}
/**
* Imports the NVD CVE XML File into the Lucene Index.
*
* @param file the file containing the NVD CVE XML
* @param oldVersion contains the file containing the NVD CVE XML 1.2
* @throws ParserConfigurationException is thrown if there is a parser
* configuration exception
* @throws SAXException is thrown if there is a SAXException
* @throws IOException is thrown if there is a IO Exception
* @throws SQLException is thrown if there is a SQL exception
* @throws DatabaseException is thrown if there is a database exception
* @throws ClassNotFoundException thrown if the h2 database driver cannot be
* loaded
*/
private void importXML(File file, File oldVersion)
throws ParserConfigurationException, SAXException, IOException, SQLException, DatabaseException, ClassNotFoundException {
final SAXParserFactory factory = SAXParserFactory.newInstance();
final SAXParser saxParser = factory.newSAXParser();
final NvdCve12Handler cve12Handler = new NvdCve12Handler();
saxParser.parse(oldVersion, cve12Handler);
final Map<String, List<VulnerableSoftware>> prevVersionVulnMap = cve12Handler.getVulnerabilities();
final NvdCve20Handler cve20Handler = new NvdCve20Handler();
cve20Handler.setCveDB(cveDB);
cve20Handler.setPrevVersionVulnMap(prevVersionVulnMap);
cve20Handler.setCpeIndex(cpeIndex);
saxParser.parse(file, cve20Handler);
}
/**
* Deletes the existing data directories.
*
* @throws IOException thrown if the directory cannot be deleted
*/
protected void deleteExistingData() throws IOException {
File data = Settings.getFile(Settings.KEYS.CVE_DATA_DIRECTORY);
if (data.exists()) {
FileUtils.delete(data);
}
data = Settings.getFile(Settings.KEYS.CPE_DATA_DIRECTORY);
if (data.exists()) {
FileUtils.delete(data);
}
data = DataStoreMetaInfo.getPropertiesFile();
if (data.exists()) {
FileUtils.delete(data);
}
}
/**
* Performs the batch update based on the configured batch update URL.
*
* @throws UpdateException thrown if there is an exception during the update
* process
*/
private void performBatchUpdate() throws UpdateException {
if (properties.isBatchUpdateMode() && doBatchUpdate) {
final String batchSrc = Settings.getString(Settings.KEYS.BATCH_UPDATE_URL);
File tmp = null;
try {
deleteExistingData();
final File dataDirectory = CveDB.getDataDirectory().getParentFile();
final URL batchUrl = new URL(batchSrc);
if ("file".equals(batchUrl.getProtocol())) {
try {
tmp = new File(batchUrl.toURI());
} catch (URISyntaxException ex) {
final String msg = String.format("Invalid batch update URI: %s", batchSrc);
throw new UpdateException(msg, ex);
}
} else if ("http".equals(batchUrl.getProtocol())
|| "https".equals(batchUrl.getProtocol())) {
tmp = File.createTempFile("batch_", ".zip");
Downloader.fetchFile(batchUrl, tmp);
}
//TODO add FTP?
FileUtils.extractFiles(tmp, dataDirectory);
} catch (IOException ex) {
final String msg = String.format("IO Exception Occured performing batch update using: %s", batchSrc);
throw new UpdateException(msg, ex);
} finally {
if (tmp != null && !tmp.delete()) {
tmp.deleteOnExit();
}
}
}
}
/**
* Closes the CVE and CPE data stores.
*/
private void closeDataStores() {
if (cveDB != null) {
try {
cveDB.close();
} catch (Exception ignore) {
Logger.getLogger(DatabaseUpdater.class.getName()).log(Level.FINEST, "Error closing the cveDB", ignore);
}
}
if (cpeIndex != null) {
try {
cpeIndex.close();
} catch (Exception ignore) {
Logger.getLogger(DatabaseUpdater.class.getName()).log(Level.FINEST, "Error closing the cpeIndex", ignore);
}
}
}
/**
* Opens the CVE and CPE data stores.
*
* @throws UpdateException thrown if a data store cannot be opened
*/
private void openDataStores() throws UpdateException {
//open the cve and cpe data stores
try {
cveDB = new CveDB();
cveDB.open();
cpeIndex = new CpeIndexWriter();
cpeIndex.open();
} catch (IOException ex) {
closeDataStores();
Logger.getLogger(DatabaseUpdater.class.getName()).log(Level.FINE, "IO Error opening databases", ex);
throw new UpdateException("Error updating the CPE/CVE data, please see the log file for more details.");
} catch (SQLException ex) {
closeDataStores();
Logger.getLogger(DatabaseUpdater.class.getName()).log(Level.FINE, "SQL Exception opening databases", ex);
throw new UpdateException("Error updating the CPE/CVE data, please see the log file for more details.");
} catch (DatabaseException ex) {
closeDataStores();
Logger.getLogger(DatabaseUpdater.class.getName()).log(Level.FINE, "Database Exception opening databases", ex);
throw new UpdateException("Error updating the CPE/CVE data, please see the log file for more details.");
} catch (ClassNotFoundException ex) {
closeDataStores();
Logger.getLogger(DatabaseUpdater.class.getName()).log(Level.FINE, "Class not found exception opening databases", ex);
throw new UpdateException("Error updating the CPE/CVE data, please see the log file for more details.");
}
}
/**
* Determines if the index needs to be updated. This is done by fetching the
* NVD CVE meta data and checking the last update date. If the data needs to
* be refreshed this method will return the NvdCveUrl for the files that
* need to be updated.
*
* @return the NvdCveUrl of the files that need to be updated.
* @throws MalformedURLException is thrown if the URL for the NVD CVE Meta
* data is incorrect.
* @throws DownloadFailedException is thrown if there is an error.
* downloading the NVD CVE download data file.
* @throws UpdateException Is thrown if there is an issue with the last
* updated properties file.
*/
private Map<String, NvdCveInfo> updateNeeded() throws MalformedURLException, DownloadFailedException, UpdateException {
Map<String, NvdCveInfo> currentlyPublished;
try {
currentlyPublished = retrieveCurrentTimestampsFromWeb();
} catch (InvalidDataException ex) {
final String msg = "Unable to retrieve valid timestamp from nvd cve downloads page";
Logger.getLogger(DataStoreMetaInfo.class.getName()).log(Level.FINE, msg, ex);
throw new DownloadFailedException(msg, ex);
} catch (InvalidSettingException ex) {
Logger.getLogger(DataStoreMetaInfo.class.getName()).log(Level.FINE, "Invalid setting found when retrieving timestamps", ex);
throw new DownloadFailedException("Invalid settings", ex);
}
if (currentlyPublished == null) {
throw new DownloadFailedException("Unable to retrieve the timestamps of the currently published NVD CVE data");
}
// final File cpeDataDirectory;
// try {
// cpeDataDirectory = CveDB.getDataDirectory();
// } catch (IOException ex) {
// String msg;
// try {
// msg = String.format("Unable to create the CVE Data Directory '%s'",
// Settings.getFile(Settings.KEYS.CVE_DATA_DIRECTORY).getCanonicalPath());
// } catch (IOException ex1) {
// msg = String.format("Unable to create the CVE Data Directory, this is likely a configuration issue: '%s%s%s'",
// Settings.getString(Settings.KEYS.DATA_DIRECTORY, ""),
// File.separator,
// Settings.getString(Settings.KEYS.CVE_DATA_DIRECTORY, ""));
// }
// throw new UpdateException(msg, ex);
// }
if (!properties.isEmpty()) {
try {
boolean deleteAndRecreate = false;
float version;
if (properties.getProperty("version") == null) {
deleteAndRecreate = true;
} else {
try {
version = Float.parseFloat(properties.getProperty("version"));
final float currentVersion = Float.parseFloat(CveDB.DB_SCHEMA_VERSION);
if (currentVersion > version) {
deleteAndRecreate = true;
}
} catch (NumberFormatException ex) {
deleteAndRecreate = true;
}
}
final NvdCveInfo batchInfo = currentlyPublished.get(BATCH);
if (properties.isBatchUpdateMode() && batchInfo != null) {
final long lastUpdated = Long.parseLong(properties.getProperty(DataStoreMetaInfo.BATCH, "0"));
if (lastUpdated != batchInfo.getTimestamp()) {
deleteAndRecreate = true;
}
}
if (deleteAndRecreate) {
setDoBatchUpdate(properties.isBatchUpdateMode());
try {
deleteExistingData();
} catch (IOException ex) {
final String msg = "Unable to delete existing data";
Logger.getLogger(DatabaseUpdater.class.getName()).log(Level.WARNING, msg);
Logger.getLogger(DatabaseUpdater.class.getName()).log(Level.FINE, null, ex);
}
return currentlyPublished;
}
final long lastUpdated = Long.parseLong(properties.getProperty(DataStoreMetaInfo.LAST_UPDATED, "0"));
final Date now = new Date();
final int days = Settings.getInt(Settings.KEYS.CVE_MODIFIED_VALID_FOR_DAYS, 7);
final int start = Settings.getInt(Settings.KEYS.CVE_START_YEAR, 2002);
final int end = Calendar.getInstance().get(Calendar.YEAR);
if (lastUpdated == currentlyPublished.get(MODIFIED).getTimestamp()) {
currentlyPublished.clear(); //we don't need to update anything.
setDoBatchUpdate(properties.isBatchUpdateMode());
} else if (withinRange(lastUpdated, now.getTime(), days)) {
currentlyPublished.get(MODIFIED).setNeedsUpdate(true);
if (properties.isBatchUpdateMode()) {
setDoBatchUpdate(false);
} else {
for (int i = start; i <= end; i++) {
currentlyPublished.get(String.valueOf(i)).setNeedsUpdate(false);
}
}
} else if (properties.isBatchUpdateMode()) {
currentlyPublished.get(MODIFIED).setNeedsUpdate(true);
setDoBatchUpdate(true);
} else { //we figure out which of the several XML files need to be downloaded.
currentlyPublished.get(MODIFIED).setNeedsUpdate(false);
for (int i = start; i <= end; i++) {
final NvdCveInfo cve = currentlyPublished.get(String.valueOf(i));
long currentTimestamp = 0;
try {
currentTimestamp = Long.parseLong(properties.getProperty(DataStoreMetaInfo.LAST_UPDATED_BASE + String.valueOf(i), "0"));
} catch (NumberFormatException ex) {
final String msg = String.format("Error parsing '%s' '%s' from nvdcve.lastupdated",
DataStoreMetaInfo.LAST_UPDATED_BASE, String.valueOf(i));
Logger.getLogger(DataStoreMetaInfo.class.getName()).log(Level.FINE, msg, ex);
}
if (currentTimestamp == cve.getTimestamp()) {
cve.setNeedsUpdate(false); //they default to true.
}
}
}
} catch (NumberFormatException ex) {
final String msg = "An invalid schema version or timestamp exists in the data.properties file.";
Logger.getLogger(DataStoreMetaInfo.class.getName()).log(Level.WARNING, msg);
Logger.getLogger(DataStoreMetaInfo.class.getName()).log(Level.FINE, null, ex);
setDoBatchUpdate(properties.isBatchUpdateMode());
}
} else {
setDoBatchUpdate(properties.isBatchUpdateMode());
}
return currentlyPublished;
}
/**
* Determines if the epoch date is within the range specified of the
* compareTo epoch time. This takes the (compareTo-date)/1000/60/60/24 to
* get the number of days. If the calculated days is less then the range the
* date is considered valid.
*
* @param date the date to be checked.
* @param compareTo the date to compare to.
* @param range the range in days to be considered valid.
* @return whether or not the date is within the range.
*/
private boolean withinRange(long date, long compareTo, int range) {
final double differenceInDays = (compareTo - date) / 1000.0 / 60.0 / 60.0 / 24.0;
return differenceInDays < range;
}
/**
* Retrieves the timestamps from the NVD CVE meta data file.
*
* @return the timestamp from the currently published nvdcve downloads page
* @throws MalformedURLException thrown if the URL for the NVD CCE Meta data
* is incorrect.
* @throws DownloadFailedException thrown if there is an error downloading
* the nvd cve meta data file
* @throws InvalidDataException thrown if there is an exception parsing the
* timestamps
* @throws InvalidSettingException thrown if the settings are invalid
*/
private Map<String, NvdCveInfo> retrieveCurrentTimestampsFromWeb()
throws MalformedURLException, DownloadFailedException, InvalidDataException, InvalidSettingException {
final Map<String, NvdCveInfo> map = new TreeMap<String, NvdCveInfo>();
String retrieveUrl = Settings.getString(Settings.KEYS.CVE_MODIFIED_20_URL);
if (retrieveUrl == null && properties.isBatchUpdateMode()) {
final NvdCveInfo item = new NvdCveInfo();
retrieveUrl = Settings.getString(Settings.KEYS.BATCH_UPDATE_URL);
if (retrieveUrl == null) {
final String msg = "Invalid configuration - neither the modified or batch update URLs are specified in the configuration.";
Logger.getLogger(DataStoreMetaInfo.class.getName()).log(Level.SEVERE, msg);
throw new InvalidSettingException(msg);
}
item.setTimestamp(Downloader.getLastModified(new URL(retrieveUrl)));
item.setId(BATCH);
item.setNeedsUpdate(false);
map.put(BATCH, item);
} else {
NvdCveInfo item = new NvdCveInfo();
item.setNeedsUpdate(false); //the others default to true, to make life easier later this should default to false.
item.setId(MODIFIED);
item.setUrl(retrieveUrl);
item.setOldSchemaVersionUrl(Settings.getString(Settings.KEYS.CVE_MODIFIED_12_URL));
item.setTimestamp(Downloader.getLastModified(new URL(retrieveUrl)));
map.put(MODIFIED, item);
//only add these urls if we are not in batch mode
if (!properties.isBatchUpdateMode()) {
final int start = Settings.getInt(Settings.KEYS.CVE_START_YEAR);
final int end = Calendar.getInstance().get(Calendar.YEAR);
final String baseUrl20 = Settings.getString(Settings.KEYS.CVE_SCHEMA_2_0);
final String baseUrl12 = Settings.getString(Settings.KEYS.CVE_SCHEMA_1_2);
for (int i = start; i <= end; i++) {
retrieveUrl = String.format(baseUrl20, i);
item = new NvdCveInfo();
item.setId(Integer.toString(i));
item.setUrl(retrieveUrl);
item.setOldSchemaVersionUrl(String.format(baseUrl12, i));
item.setTimestamp(Downloader.getLastModified(new URL(retrieveUrl)));
map.put(item.getId(), item);
}
}
}
return map;
}
}

Some files were not shown because too many files have changed in this diff Show More