Includes rudimentary support for getting slices from FMap's and for
interacting with libclamav's context structure.
For now will use a Cisco-Talos org fork of the onenote_parser
until the feature to read open a onenote section from a slice (instead
of from a filepath) is added to the upstream.
| ... | ... |
@@ -10,9 +10,9 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" |
| 10 | 10 |
|
| 11 | 11 |
[[package]] |
| 12 | 12 |
name = "aho-corasick" |
| 13 |
-version = "1.0.5" |
|
| 13 |
+version = "1.1.2" |
|
| 14 | 14 |
source = "registry+https://github.com/rust-lang/crates.io-index" |
| 15 |
-checksum = "0c378d78423fdad8089616f827526ee33c19f2fddbd5de1629152c9593ba4783" |
|
| 15 |
+checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" |
|
| 16 | 16 |
dependencies = [ |
| 17 | 17 |
"memchr", |
| 18 | 18 |
] |
| ... | ... |
@@ -25,9 +25,9 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" |
| 25 | 25 |
|
| 26 | 26 |
[[package]] |
| 27 | 27 |
name = "base64" |
| 28 |
-version = "0.21.3" |
|
| 28 |
+version = "0.21.5" |
|
| 29 | 29 |
source = "registry+https://github.com/rust-lang/crates.io-index" |
| 30 |
-checksum = "414dcefbc63d77c526a76b3afcf6fbb9b5e2791c19c3aa2297733208750c6e53" |
|
| 30 |
+checksum = "35636a1494ede3b646cc98f74f8e62c773a38a659ebc777a2cf26b9b74171df9" |
|
| 31 | 31 |
|
| 32 | 32 |
[[package]] |
| 33 | 33 |
name = "bindgen" |
| ... | ... |
@@ -48,7 +48,7 @@ dependencies = [ |
| 48 | 48 |
"regex", |
| 49 | 49 |
"rustc-hash", |
| 50 | 50 |
"shlex", |
| 51 |
- "syn 2.0.31", |
|
| 51 |
+ "syn 2.0.38", |
|
| 52 | 52 |
"which", |
| 53 | 53 |
] |
| 54 | 54 |
|
| ... | ... |
@@ -66,9 +66,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" |
| 66 | 66 |
|
| 67 | 67 |
[[package]] |
| 68 | 68 |
name = "bitflags" |
| 69 |
-version = "2.4.0" |
|
| 69 |
+version = "2.4.1" |
|
| 70 | 70 |
source = "registry+https://github.com/rust-lang/crates.io-index" |
| 71 |
-checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635" |
|
| 71 |
+checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" |
|
| 72 | 72 |
|
| 73 | 73 |
[[package]] |
| 74 | 74 |
name = "block-buffer" |
| ... | ... |
@@ -80,12 +80,6 @@ dependencies = [ |
| 80 | 80 |
] |
| 81 | 81 |
|
| 82 | 82 |
[[package]] |
| 83 |
-name = "bumpalo" |
|
| 84 |
-version = "3.13.0" |
|
| 85 |
-source = "registry+https://github.com/rust-lang/crates.io-index" |
|
| 86 |
-checksum = "a3e2c3daef883ecc1b5d58c15adae93470a91d425f3532ba1695849656af3fc1" |
|
| 87 |
- |
|
| 88 |
-[[package]] |
|
| 89 | 83 |
name = "bytemuck" |
| 90 | 84 |
version = "1.14.0" |
| 91 | 85 |
source = "registry+https://github.com/rust-lang/crates.io-index" |
| ... | ... |
@@ -93,9 +87,15 @@ checksum = "374d28ec25809ee0e23827c2ab573d729e293f281dfe393500e7ad618baa61c6" |
| 93 | 93 |
|
| 94 | 94 |
[[package]] |
| 95 | 95 |
name = "byteorder" |
| 96 |
-version = "1.4.3" |
|
| 96 |
+version = "1.5.0" |
|
| 97 |
+source = "registry+https://github.com/rust-lang/crates.io-index" |
|
| 98 |
+checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" |
|
| 99 |
+ |
|
| 100 |
+[[package]] |
|
| 101 |
+name = "bytes" |
|
| 102 |
+version = "1.5.0" |
|
| 97 | 103 |
source = "registry+https://github.com/rust-lang/crates.io-index" |
| 98 |
-checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" |
|
| 104 |
+checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" |
|
| 99 | 105 |
|
| 100 | 106 |
[[package]] |
| 101 | 107 |
name = "cbindgen" |
| ... | ... |
@@ -116,15 +116,6 @@ dependencies = [ |
| 116 | 116 |
] |
| 117 | 117 |
|
| 118 | 118 |
[[package]] |
| 119 |
-name = "cc" |
|
| 120 |
-version = "1.0.83" |
|
| 121 |
-source = "registry+https://github.com/rust-lang/crates.io-index" |
|
| 122 |
-checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" |
|
| 123 |
-dependencies = [ |
|
| 124 |
- "libc", |
|
| 125 |
-] |
|
| 126 |
- |
|
| 127 |
-[[package]] |
|
| 128 | 119 |
name = "cexpr" |
| 129 | 120 |
version = "0.6.0" |
| 130 | 121 |
source = "registry+https://github.com/rust-lang/crates.io-index" |
| ... | ... |
@@ -148,10 +139,12 @@ dependencies = [ |
| 148 | 148 |
"cbindgen", |
| 149 | 149 |
"flate2", |
| 150 | 150 |
"hex", |
| 151 |
+ "hex-literal", |
|
| 151 | 152 |
"image", |
| 152 | 153 |
"libc", |
| 153 | 154 |
"log", |
| 154 | 155 |
"num-traits", |
| 156 |
+ "onenote_parser", |
|
| 155 | 157 |
"rustdct", |
| 156 | 158 |
"sha1", |
| 157 | 159 |
"sha2", |
| ... | ... |
@@ -180,9 +173,9 @@ checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" |
| 180 | 180 |
|
| 181 | 181 |
[[package]] |
| 182 | 182 |
name = "cpufeatures" |
| 183 |
-version = "0.2.9" |
|
| 183 |
+version = "0.2.11" |
|
| 184 | 184 |
source = "registry+https://github.com/rust-lang/crates.io-index" |
| 185 |
-checksum = "a17b76ff3a4162b0b27f354a0c87015ddad39d35f9c0c36607a3bdd175dde1f1" |
|
| 185 |
+checksum = "ce420fe07aecd3e67c5f910618fe65e94158f6dcc0adf44e00d69ce2bdfe0fd0" |
|
| 186 | 186 |
dependencies = [ |
| 187 | 187 |
"libc", |
| 188 | 188 |
] |
| ... | ... |
@@ -197,16 +190,6 @@ dependencies = [ |
| 197 | 197 |
] |
| 198 | 198 |
|
| 199 | 199 |
[[package]] |
| 200 |
-name = "crossbeam-channel" |
|
| 201 |
-version = "0.5.8" |
|
| 202 |
-source = "registry+https://github.com/rust-lang/crates.io-index" |
|
| 203 |
-checksum = "a33c2bf77f2df06183c3aa30d1e96c0695a313d4f9c453cc3762a6db39f99200" |
|
| 204 |
-dependencies = [ |
|
| 205 |
- "cfg-if", |
|
| 206 |
- "crossbeam-utils", |
|
| 207 |
-] |
|
| 208 |
- |
|
| 209 |
-[[package]] |
|
| 210 | 200 |
name = "crossbeam-deque" |
| 211 | 201 |
version = "0.8.3" |
| 212 | 202 |
source = "registry+https://github.com/rust-lang/crates.io-index" |
| ... | ... |
@@ -272,31 +255,40 @@ source = "registry+https://github.com/rust-lang/crates.io-index" |
| 272 | 272 |
checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" |
| 273 | 273 |
|
| 274 | 274 |
[[package]] |
| 275 |
-name = "errno" |
|
| 276 |
-version = "0.3.3" |
|
| 275 |
+name = "encoding_rs" |
|
| 276 |
+version = "0.8.33" |
|
| 277 | 277 |
source = "registry+https://github.com/rust-lang/crates.io-index" |
| 278 |
-checksum = "136526188508e25c6fef639d7927dfb3e0e3084488bf202267829cf7fc23dbdd" |
|
| 278 |
+checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1" |
|
| 279 | 279 |
dependencies = [ |
| 280 |
- "errno-dragonfly", |
|
| 281 |
- "libc", |
|
| 282 |
- "windows-sys", |
|
| 280 |
+ "cfg-if", |
|
| 283 | 281 |
] |
| 284 | 282 |
|
| 285 | 283 |
[[package]] |
| 286 |
-name = "errno-dragonfly" |
|
| 287 |
-version = "0.1.2" |
|
| 284 |
+name = "enum-primitive-derive" |
|
| 285 |
+version = "0.2.2" |
|
| 286 |
+source = "registry+https://github.com/rust-lang/crates.io-index" |
|
| 287 |
+checksum = "c375b9c5eadb68d0a6efee2999fef292f45854c3444c86f09d8ab086ba942b0e" |
|
| 288 |
+dependencies = [ |
|
| 289 |
+ "num-traits", |
|
| 290 |
+ "quote", |
|
| 291 |
+ "syn 1.0.109", |
|
| 292 |
+] |
|
| 293 |
+ |
|
| 294 |
+[[package]] |
|
| 295 |
+name = "errno" |
|
| 296 |
+version = "0.3.5" |
|
| 288 | 297 |
source = "registry+https://github.com/rust-lang/crates.io-index" |
| 289 |
-checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" |
|
| 298 |
+checksum = "ac3e13f66a2f95e32a39eaa81f6b95d42878ca0e1db0c7543723dfe12557e860" |
|
| 290 | 299 |
dependencies = [ |
| 291 |
- "cc", |
|
| 292 | 300 |
"libc", |
| 301 |
+ "windows-sys", |
|
| 293 | 302 |
] |
| 294 | 303 |
|
| 295 | 304 |
[[package]] |
| 296 | 305 |
name = "exr" |
| 297 |
-version = "1.7.0" |
|
| 306 |
+version = "1.71.0" |
|
| 298 | 307 |
source = "registry+https://github.com/rust-lang/crates.io-index" |
| 299 |
-checksum = "d1e481eb11a482815d3e9d618db8c42a93207134662873809335a92327440c18" |
|
| 308 |
+checksum = "832a761f35ab3e6664babfbdc6cef35a4860e816ec3916dcfd0882954e98a8a8" |
|
| 300 | 309 |
dependencies = [ |
| 301 | 310 |
"bit_field", |
| 302 | 311 |
"flume", |
| ... | ... |
@@ -310,24 +302,24 @@ dependencies = [ |
| 310 | 310 |
|
| 311 | 311 |
[[package]] |
| 312 | 312 |
name = "fastrand" |
| 313 |
-version = "2.0.0" |
|
| 313 |
+version = "2.0.1" |
|
| 314 | 314 |
source = "registry+https://github.com/rust-lang/crates.io-index" |
| 315 |
-checksum = "6999dc1837253364c2ebb0704ba97994bd874e8f195d665c50b7548f6ea92764" |
|
| 315 |
+checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" |
|
| 316 | 316 |
|
| 317 | 317 |
[[package]] |
| 318 | 318 |
name = "fdeflate" |
| 319 |
-version = "0.3.0" |
|
| 319 |
+version = "0.3.1" |
|
| 320 | 320 |
source = "registry+https://github.com/rust-lang/crates.io-index" |
| 321 |
-checksum = "d329bdeac514ee06249dabc27877490f17f5d371ec693360768b838e19f3ae10" |
|
| 321 |
+checksum = "64d6dafc854908ff5da46ff3f8f473c6984119a2876a383a860246dd7841a868" |
|
| 322 | 322 |
dependencies = [ |
| 323 | 323 |
"simd-adler32", |
| 324 | 324 |
] |
| 325 | 325 |
|
| 326 | 326 |
[[package]] |
| 327 | 327 |
name = "flate2" |
| 328 |
-version = "1.0.27" |
|
| 328 |
+version = "1.0.28" |
|
| 329 | 329 |
source = "registry+https://github.com/rust-lang/crates.io-index" |
| 330 |
-checksum = "c6c98ee8095e9d1dcbf2fcc6d95acccb90d1c81db1e44725c6a984b1dbdfb010" |
|
| 330 |
+checksum = "46303f565772937ffe1d394a4fac6f411c6013172fadde9dcdb1e147a086940e" |
|
| 331 | 331 |
dependencies = [ |
| 332 | 332 |
"crc32fast", |
| 333 | 333 |
"miniz_oxide", |
| ... | ... |
@@ -335,30 +327,14 @@ dependencies = [ |
| 335 | 335 |
|
| 336 | 336 |
[[package]] |
| 337 | 337 |
name = "flume" |
| 338 |
-version = "0.10.14" |
|
| 338 |
+version = "0.11.0" |
|
| 339 | 339 |
source = "registry+https://github.com/rust-lang/crates.io-index" |
| 340 |
-checksum = "1657b4441c3403d9f7b3409e47575237dac27b1b5726df654a6ecbf92f0f7577" |
|
| 340 |
+checksum = "55ac459de2512911e4b674ce33cf20befaba382d05b62b008afc1c8b57cbf181" |
|
| 341 | 341 |
dependencies = [ |
| 342 |
- "futures-core", |
|
| 343 |
- "futures-sink", |
|
| 344 |
- "nanorand", |
|
| 345 |
- "pin-project", |
|
| 346 | 342 |
"spin", |
| 347 | 343 |
] |
| 348 | 344 |
|
| 349 | 345 |
[[package]] |
| 350 |
-name = "futures-core" |
|
| 351 |
-version = "0.3.28" |
|
| 352 |
-source = "registry+https://github.com/rust-lang/crates.io-index" |
|
| 353 |
-checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" |
|
| 354 |
- |
|
| 355 |
-[[package]] |
|
| 356 |
-name = "futures-sink" |
|
| 357 |
-version = "0.3.28" |
|
| 358 |
-source = "registry+https://github.com/rust-lang/crates.io-index" |
|
| 359 |
-checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e" |
|
| 360 |
- |
|
| 361 |
-[[package]] |
|
| 362 | 346 |
name = "generic-array" |
| 363 | 347 |
version = "0.14.7" |
| 364 | 348 |
source = "registry+https://github.com/rust-lang/crates.io-index" |
| ... | ... |
@@ -369,19 +345,6 @@ dependencies = [ |
| 369 | 369 |
] |
| 370 | 370 |
|
| 371 | 371 |
[[package]] |
| 372 |
-name = "getrandom" |
|
| 373 |
-version = "0.2.10" |
|
| 374 |
-source = "registry+https://github.com/rust-lang/crates.io-index" |
|
| 375 |
-checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" |
|
| 376 |
-dependencies = [ |
|
| 377 |
- "cfg-if", |
|
| 378 |
- "js-sys", |
|
| 379 |
- "libc", |
|
| 380 |
- "wasi", |
|
| 381 |
- "wasm-bindgen", |
|
| 382 |
-] |
|
| 383 |
- |
|
| 384 |
-[[package]] |
|
| 385 | 372 |
name = "gif" |
| 386 | 373 |
version = "0.12.0" |
| 387 | 374 |
source = "registry+https://github.com/rust-lang/crates.io-index" |
| ... | ... |
@@ -419,18 +382,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" |
| 419 | 419 |
checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" |
| 420 | 420 |
|
| 421 | 421 |
[[package]] |
| 422 |
-name = "hermit-abi" |
|
| 423 |
-version = "0.3.2" |
|
| 424 |
-source = "registry+https://github.com/rust-lang/crates.io-index" |
|
| 425 |
-checksum = "443144c8cdadd93ebf52ddb4056d257f5b52c04d3c804e657d19eb73fc33668b" |
|
| 426 |
- |
|
| 427 |
-[[package]] |
|
| 428 | 422 |
name = "hex" |
| 429 | 423 |
version = "0.4.3" |
| 430 | 424 |
source = "registry+https://github.com/rust-lang/crates.io-index" |
| 431 | 425 |
checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" |
| 432 | 426 |
|
| 433 | 427 |
[[package]] |
| 428 |
+name = "hex-literal" |
|
| 429 |
+version = "0.4.1" |
|
| 430 |
+source = "registry+https://github.com/rust-lang/crates.io-index" |
|
| 431 |
+checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" |
|
| 432 |
+ |
|
| 433 |
+[[package]] |
|
| 434 | 434 |
name = "home" |
| 435 | 435 |
version = "0.5.5" |
| 436 | 436 |
source = "registry+https://github.com/rust-lang/crates.io-index" |
| ... | ... |
@@ -469,6 +432,15 @@ dependencies = [ |
| 469 | 469 |
] |
| 470 | 470 |
|
| 471 | 471 |
[[package]] |
| 472 |
+name = "itertools" |
|
| 473 |
+version = "0.10.5" |
|
| 474 |
+source = "registry+https://github.com/rust-lang/crates.io-index" |
|
| 475 |
+checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" |
|
| 476 |
+dependencies = [ |
|
| 477 |
+ "either", |
|
| 478 |
+] |
|
| 479 |
+ |
|
| 480 |
+[[package]] |
|
| 472 | 481 |
name = "itoa" |
| 473 | 482 |
version = "1.0.9" |
| 474 | 483 |
source = "registry+https://github.com/rust-lang/crates.io-index" |
| ... | ... |
@@ -484,15 +456,6 @@ dependencies = [ |
| 484 | 484 |
] |
| 485 | 485 |
|
| 486 | 486 |
[[package]] |
| 487 |
-name = "js-sys" |
|
| 488 |
-version = "0.3.64" |
|
| 489 |
-source = "registry+https://github.com/rust-lang/crates.io-index" |
|
| 490 |
-checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a" |
|
| 491 |
-dependencies = [ |
|
| 492 |
- "wasm-bindgen", |
|
| 493 |
-] |
|
| 494 |
- |
|
| 495 |
-[[package]] |
|
| 496 | 487 |
name = "lazy_static" |
| 497 | 488 |
version = "1.4.0" |
| 498 | 489 |
source = "registry+https://github.com/rust-lang/crates.io-index" |
| ... | ... |
@@ -512,9 +475,9 @@ checksum = "03087c2bad5e1034e8cace5926dec053fb3790248370865f5117a7d0213354c8" |
| 512 | 512 |
|
| 513 | 513 |
[[package]] |
| 514 | 514 |
name = "libc" |
| 515 |
-version = "0.2.147" |
|
| 515 |
+version = "0.2.149" |
|
| 516 | 516 |
source = "registry+https://github.com/rust-lang/crates.io-index" |
| 517 |
-checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" |
|
| 517 |
+checksum = "a08173bc88b7955d1b3145aa561539096c421ac8debde8cbc3612ec635fee29b" |
|
| 518 | 518 |
|
| 519 | 519 |
[[package]] |
| 520 | 520 |
name = "libloading" |
| ... | ... |
@@ -528,15 +491,15 @@ dependencies = [ |
| 528 | 528 |
|
| 529 | 529 |
[[package]] |
| 530 | 530 |
name = "linux-raw-sys" |
| 531 |
-version = "0.4.5" |
|
| 531 |
+version = "0.4.10" |
|
| 532 | 532 |
source = "registry+https://github.com/rust-lang/crates.io-index" |
| 533 |
-checksum = "57bcfdad1b858c2db7c38303a6d2ad4dfaf5eb53dfeb0910128b2c26d6158503" |
|
| 533 |
+checksum = "da2479e8c062e40bf0066ffa0bc823de0a9368974af99c9f6df941d2c231e03f" |
|
| 534 | 534 |
|
| 535 | 535 |
[[package]] |
| 536 | 536 |
name = "lock_api" |
| 537 |
-version = "0.4.10" |
|
| 537 |
+version = "0.4.11" |
|
| 538 | 538 |
source = "registry+https://github.com/rust-lang/crates.io-index" |
| 539 |
-checksum = "c1cc9717a20b1bb222f333e6a92fd32f7d8a18ddc5a3191a11af45dcbf4dcd16" |
|
| 539 |
+checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" |
|
| 540 | 540 |
dependencies = [ |
| 541 | 541 |
"autocfg", |
| 542 | 542 |
"scopeguard", |
| ... | ... |
@@ -550,9 +513,9 @@ checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" |
| 550 | 550 |
|
| 551 | 551 |
[[package]] |
| 552 | 552 |
name = "memchr" |
| 553 |
-version = "2.6.3" |
|
| 553 |
+version = "2.6.4" |
|
| 554 | 554 |
source = "registry+https://github.com/rust-lang/crates.io-index" |
| 555 |
-checksum = "8f232d6ef707e1956a43342693d2a31e72989554d58299d7a88738cc95b0d35c" |
|
| 555 |
+checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" |
|
| 556 | 556 |
|
| 557 | 557 |
[[package]] |
| 558 | 558 |
name = "memoffset" |
| ... | ... |
@@ -580,15 +543,6 @@ dependencies = [ |
| 580 | 580 |
] |
| 581 | 581 |
|
| 582 | 582 |
[[package]] |
| 583 |
-name = "nanorand" |
|
| 584 |
-version = "0.7.0" |
|
| 585 |
-source = "registry+https://github.com/rust-lang/crates.io-index" |
|
| 586 |
-checksum = "6a51313c5820b0b02bd422f4b44776fbf47961755c74ce64afc73bfad10226c3" |
|
| 587 |
-dependencies = [ |
|
| 588 |
- "getrandom", |
|
| 589 |
-] |
|
| 590 |
- |
|
| 591 |
-[[package]] |
|
| 592 | 583 |
name = "nom" |
| 593 | 584 |
version = "7.1.3" |
| 594 | 585 |
source = "registry+https://github.com/rust-lang/crates.io-index" |
| ... | ... |
@@ -630,54 +584,46 @@ dependencies = [ |
| 630 | 630 |
|
| 631 | 631 |
[[package]] |
| 632 | 632 |
name = "num-traits" |
| 633 |
-version = "0.2.16" |
|
| 633 |
+version = "0.2.17" |
|
| 634 | 634 |
source = "registry+https://github.com/rust-lang/crates.io-index" |
| 635 |
-checksum = "f30b0abd723be7e2ffca1272140fac1a2f084c77ec3e123c192b66af1ee9e6c2" |
|
| 635 |
+checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" |
|
| 636 | 636 |
dependencies = [ |
| 637 | 637 |
"autocfg", |
| 638 | 638 |
] |
| 639 | 639 |
|
| 640 | 640 |
[[package]] |
| 641 |
-name = "num_cpus" |
|
| 642 |
-version = "1.16.0" |
|
| 643 |
-source = "registry+https://github.com/rust-lang/crates.io-index" |
|
| 644 |
-checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" |
|
| 645 |
-dependencies = [ |
|
| 646 |
- "hermit-abi", |
|
| 647 |
- "libc", |
|
| 648 |
-] |
|
| 649 |
- |
|
| 650 |
-[[package]] |
|
| 651 | 641 |
name = "once_cell" |
| 652 | 642 |
version = "1.18.0" |
| 653 | 643 |
source = "registry+https://github.com/rust-lang/crates.io-index" |
| 654 | 644 |
checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" |
| 655 | 645 |
|
| 656 | 646 |
[[package]] |
| 657 |
-name = "peeking_take_while" |
|
| 658 |
-version = "0.1.2" |
|
| 659 |
-source = "registry+https://github.com/rust-lang/crates.io-index" |
|
| 660 |
-checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" |
|
| 647 |
+name = "onenote_parser" |
|
| 648 |
+version = "0.3.1" |
|
| 649 |
+source = "git+https://github.com/Cisco-Talos/onenote.rs.git?branch=CLAM-2329-new-from-slice#8b450447e58143004b68dd21c11b710fdb79be92" |
|
| 650 |
+dependencies = [ |
|
| 651 |
+ "bytes", |
|
| 652 |
+ "encoding_rs", |
|
| 653 |
+ "enum-primitive-derive", |
|
| 654 |
+ "itertools", |
|
| 655 |
+ "num-traits", |
|
| 656 |
+ "paste", |
|
| 657 |
+ "thiserror", |
|
| 658 |
+ "uuid", |
|
| 659 |
+ "widestring", |
|
| 660 |
+] |
|
| 661 | 661 |
|
| 662 | 662 |
[[package]] |
| 663 |
-name = "pin-project" |
|
| 664 |
-version = "1.1.3" |
|
| 663 |
+name = "paste" |
|
| 664 |
+version = "1.0.14" |
|
| 665 | 665 |
source = "registry+https://github.com/rust-lang/crates.io-index" |
| 666 |
-checksum = "fda4ed1c6c173e3fc7a83629421152e01d7b1f9b7f65fb301e490e8cfc656422" |
|
| 667 |
-dependencies = [ |
|
| 668 |
- "pin-project-internal", |
|
| 669 |
-] |
|
| 666 |
+checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" |
|
| 670 | 667 |
|
| 671 | 668 |
[[package]] |
| 672 |
-name = "pin-project-internal" |
|
| 673 |
-version = "1.1.3" |
|
| 669 |
+name = "peeking_take_while" |
|
| 670 |
+version = "0.1.2" |
|
| 674 | 671 |
source = "registry+https://github.com/rust-lang/crates.io-index" |
| 675 |
-checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" |
|
| 676 |
-dependencies = [ |
|
| 677 |
- "proc-macro2", |
|
| 678 |
- "quote", |
|
| 679 |
- "syn 2.0.31", |
|
| 680 |
-] |
|
| 672 |
+checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" |
|
| 681 | 673 |
|
| 682 | 674 |
[[package]] |
| 683 | 675 |
name = "png" |
| ... | ... |
@@ -699,7 +645,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" |
| 699 | 699 |
checksum = "ae005bd773ab59b4725093fd7df83fd7892f7d8eafb48dbd7de6e024e4215f9d" |
| 700 | 700 |
dependencies = [ |
| 701 | 701 |
"proc-macro2", |
| 702 |
- "syn 2.0.31", |
|
| 702 |
+ "syn 2.0.38", |
|
| 703 | 703 |
] |
| 704 | 704 |
|
| 705 | 705 |
[[package]] |
| ... | ... |
@@ -713,9 +659,9 @@ dependencies = [ |
| 713 | 713 |
|
| 714 | 714 |
[[package]] |
| 715 | 715 |
name = "proc-macro2" |
| 716 |
-version = "1.0.66" |
|
| 716 |
+version = "1.0.69" |
|
| 717 | 717 |
source = "registry+https://github.com/rust-lang/crates.io-index" |
| 718 |
-checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9" |
|
| 718 |
+checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" |
|
| 719 | 719 |
dependencies = [ |
| 720 | 720 |
"unicode-ident", |
| 721 | 721 |
] |
| ... | ... |
@@ -740,9 +686,9 @@ dependencies = [ |
| 740 | 740 |
|
| 741 | 741 |
[[package]] |
| 742 | 742 |
name = "rayon" |
| 743 |
-version = "1.7.0" |
|
| 743 |
+version = "1.8.0" |
|
| 744 | 744 |
source = "registry+https://github.com/rust-lang/crates.io-index" |
| 745 |
-checksum = "1d2df5196e37bcc87abebc0053e20787d73847bb33134a69841207dd0a47f03b" |
|
| 745 |
+checksum = "9c27db03db7734835b3f53954b534c91069375ce6ccaa2e065441e07d9b6cdb1" |
|
| 746 | 746 |
dependencies = [ |
| 747 | 747 |
"either", |
| 748 | 748 |
"rayon-core", |
| ... | ... |
@@ -750,30 +696,28 @@ dependencies = [ |
| 750 | 750 |
|
| 751 | 751 |
[[package]] |
| 752 | 752 |
name = "rayon-core" |
| 753 |
-version = "1.11.0" |
|
| 753 |
+version = "1.12.0" |
|
| 754 | 754 |
source = "registry+https://github.com/rust-lang/crates.io-index" |
| 755 |
-checksum = "4b8f95bd6966f5c87776639160a66bd8ab9895d9d4ab01ddba9fc60661aebe8d" |
|
| 755 |
+checksum = "5ce3fb6ad83f861aac485e76e1985cd109d9a3713802152be56c3b1f0e0658ed" |
|
| 756 | 756 |
dependencies = [ |
| 757 |
- "crossbeam-channel", |
|
| 758 | 757 |
"crossbeam-deque", |
| 759 | 758 |
"crossbeam-utils", |
| 760 |
- "num_cpus", |
|
| 761 | 759 |
] |
| 762 | 760 |
|
| 763 | 761 |
[[package]] |
| 764 | 762 |
name = "redox_syscall" |
| 765 |
-version = "0.3.5" |
|
| 763 |
+version = "0.4.1" |
|
| 766 | 764 |
source = "registry+https://github.com/rust-lang/crates.io-index" |
| 767 |
-checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" |
|
| 765 |
+checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" |
|
| 768 | 766 |
dependencies = [ |
| 769 | 767 |
"bitflags 1.3.2", |
| 770 | 768 |
] |
| 771 | 769 |
|
| 772 | 770 |
[[package]] |
| 773 | 771 |
name = "regex" |
| 774 |
-version = "1.9.5" |
|
| 772 |
+version = "1.10.2" |
|
| 775 | 773 |
source = "registry+https://github.com/rust-lang/crates.io-index" |
| 776 |
-checksum = "697061221ea1b4a94a624f67d0ae2bfe4e22b8a17b6a192afb11046542cc8c47" |
|
| 774 |
+checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343" |
|
| 777 | 775 |
dependencies = [ |
| 778 | 776 |
"aho-corasick", |
| 779 | 777 |
"memchr", |
| ... | ... |
@@ -783,9 +727,9 @@ dependencies = [ |
| 783 | 783 |
|
| 784 | 784 |
[[package]] |
| 785 | 785 |
name = "regex-automata" |
| 786 |
-version = "0.3.8" |
|
| 786 |
+version = "0.4.3" |
|
| 787 | 787 |
source = "registry+https://github.com/rust-lang/crates.io-index" |
| 788 |
-checksum = "c2f401f4955220693b56f8ec66ee9c78abffd8d1c4f23dc41a23839eb88f0795" |
|
| 788 |
+checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f" |
|
| 789 | 789 |
dependencies = [ |
| 790 | 790 |
"aho-corasick", |
| 791 | 791 |
"memchr", |
| ... | ... |
@@ -794,9 +738,9 @@ dependencies = [ |
| 794 | 794 |
|
| 795 | 795 |
[[package]] |
| 796 | 796 |
name = "regex-syntax" |
| 797 |
-version = "0.7.5" |
|
| 797 |
+version = "0.8.2" |
|
| 798 | 798 |
source = "registry+https://github.com/rust-lang/crates.io-index" |
| 799 |
-checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da" |
|
| 799 |
+checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" |
|
| 800 | 800 |
|
| 801 | 801 |
[[package]] |
| 802 | 802 |
name = "rustc-hash" |
| ... | ... |
@@ -830,11 +774,11 @@ dependencies = [ |
| 830 | 830 |
|
| 831 | 831 |
[[package]] |
| 832 | 832 |
name = "rustix" |
| 833 |
-version = "0.38.11" |
|
| 833 |
+version = "0.38.21" |
|
| 834 | 834 |
source = "registry+https://github.com/rust-lang/crates.io-index" |
| 835 |
-checksum = "c0c3dde1fc030af041adc40e79c0e7fbcf431dd24870053d187d7c66e4b87453" |
|
| 835 |
+checksum = "2b426b0506e5d50a7d8dafcf2e81471400deb602392c7dd110815afb4eaf02a3" |
|
| 836 | 836 |
dependencies = [ |
| 837 |
- "bitflags 2.4.0", |
|
| 837 |
+ "bitflags 2.4.1", |
|
| 838 | 838 |
"errno", |
| 839 | 839 |
"libc", |
| 840 | 840 |
"linux-raw-sys", |
| ... | ... |
@@ -855,29 +799,29 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" |
| 855 | 855 |
|
| 856 | 856 |
[[package]] |
| 857 | 857 |
name = "serde" |
| 858 |
-version = "1.0.188" |
|
| 858 |
+version = "1.0.190" |
|
| 859 | 859 |
source = "registry+https://github.com/rust-lang/crates.io-index" |
| 860 |
-checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e" |
|
| 860 |
+checksum = "91d3c334ca1ee894a2c6f6ad698fe8c435b76d504b13d436f0685d648d6d96f7" |
|
| 861 | 861 |
dependencies = [ |
| 862 | 862 |
"serde_derive", |
| 863 | 863 |
] |
| 864 | 864 |
|
| 865 | 865 |
[[package]] |
| 866 | 866 |
name = "serde_derive" |
| 867 |
-version = "1.0.188" |
|
| 867 |
+version = "1.0.190" |
|
| 868 | 868 |
source = "registry+https://github.com/rust-lang/crates.io-index" |
| 869 |
-checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2" |
|
| 869 |
+checksum = "67c5609f394e5c2bd7fc51efda478004ea80ef42fee983d5c67a65e34f32c0e3" |
|
| 870 | 870 |
dependencies = [ |
| 871 | 871 |
"proc-macro2", |
| 872 | 872 |
"quote", |
| 873 |
- "syn 2.0.31", |
|
| 873 |
+ "syn 2.0.38", |
|
| 874 | 874 |
] |
| 875 | 875 |
|
| 876 | 876 |
[[package]] |
| 877 | 877 |
name = "serde_json" |
| 878 |
-version = "1.0.105" |
|
| 878 |
+version = "1.0.108" |
|
| 879 | 879 |
source = "registry+https://github.com/rust-lang/crates.io-index" |
| 880 |
-checksum = "693151e1ac27563d6dbcec9dee9fbd5da8539b20fa14ad3752b2e6d363ace360" |
|
| 880 |
+checksum = "3d1c7e3eac408d115102c4c24ad393e0821bb3a5df4d506a80f85f7a742a526b" |
|
| 881 | 881 |
dependencies = [ |
| 882 | 882 |
"itoa", |
| 883 | 883 |
"ryu", |
| ... | ... |
@@ -886,9 +830,9 @@ dependencies = [ |
| 886 | 886 |
|
| 887 | 887 |
[[package]] |
| 888 | 888 |
name = "sha1" |
| 889 |
-version = "0.10.5" |
|
| 889 |
+version = "0.10.6" |
|
| 890 | 890 |
source = "registry+https://github.com/rust-lang/crates.io-index" |
| 891 |
-checksum = "f04293dc80c3993519f2d7f6f511707ee7094fe0c6d3406feb330cdb3540eba3" |
|
| 891 |
+checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" |
|
| 892 | 892 |
dependencies = [ |
| 893 | 893 |
"cfg-if", |
| 894 | 894 |
"cpufeatures", |
| ... | ... |
@@ -897,9 +841,9 @@ dependencies = [ |
| 897 | 897 |
|
| 898 | 898 |
[[package]] |
| 899 | 899 |
name = "sha2" |
| 900 |
-version = "0.10.7" |
|
| 900 |
+version = "0.10.8" |
|
| 901 | 901 |
source = "registry+https://github.com/rust-lang/crates.io-index" |
| 902 |
-checksum = "479fb9d862239e610720565ca91403019f2f00410f1864c5aa7479b950a76ed8" |
|
| 902 |
+checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" |
|
| 903 | 903 |
dependencies = [ |
| 904 | 904 |
"cfg-if", |
| 905 | 905 |
"cpufeatures", |
| ... | ... |
@@ -920,9 +864,9 @@ checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" |
| 920 | 920 |
|
| 921 | 921 |
[[package]] |
| 922 | 922 |
name = "smallvec" |
| 923 |
-version = "1.11.0" |
|
| 923 |
+version = "1.11.1" |
|
| 924 | 924 |
source = "registry+https://github.com/rust-lang/crates.io-index" |
| 925 |
-checksum = "62bb4feee49fdd9f707ef802e22365a35de4b7b299de4763d44bfea899442ff9" |
|
| 925 |
+checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" |
|
| 926 | 926 |
|
| 927 | 927 |
[[package]] |
| 928 | 928 |
name = "spin" |
| ... | ... |
@@ -952,9 +896,9 @@ dependencies = [ |
| 952 | 952 |
|
| 953 | 953 |
[[package]] |
| 954 | 954 |
name = "syn" |
| 955 |
-version = "2.0.31" |
|
| 955 |
+version = "2.0.38" |
|
| 956 | 956 |
source = "registry+https://github.com/rust-lang/crates.io-index" |
| 957 |
-checksum = "718fa2415bcb8d8bd775917a1bf12a7931b6dfa890753378538118181e0cb398" |
|
| 957 |
+checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" |
|
| 958 | 958 |
dependencies = [ |
| 959 | 959 |
"proc-macro2", |
| 960 | 960 |
"quote", |
| ... | ... |
@@ -963,9 +907,9 @@ dependencies = [ |
| 963 | 963 |
|
| 964 | 964 |
[[package]] |
| 965 | 965 |
name = "tempfile" |
| 966 |
-version = "3.8.0" |
|
| 966 |
+version = "3.8.1" |
|
| 967 | 967 |
source = "registry+https://github.com/rust-lang/crates.io-index" |
| 968 |
-checksum = "cb94d2f3cc536af71caac6b6fcebf65860b347e7ce0cc9ebe8f70d3e521054ef" |
|
| 968 |
+checksum = "7ef1adac450ad7f4b3c28589471ade84f25f731a7a0fe30d71dfa9f60fd808e5" |
|
| 969 | 969 |
dependencies = [ |
| 970 | 970 |
"cfg-if", |
| 971 | 971 |
"fastrand", |
| ... | ... |
@@ -976,22 +920,22 @@ dependencies = [ |
| 976 | 976 |
|
| 977 | 977 |
[[package]] |
| 978 | 978 |
name = "thiserror" |
| 979 |
-version = "1.0.48" |
|
| 979 |
+version = "1.0.50" |
|
| 980 | 980 |
source = "registry+https://github.com/rust-lang/crates.io-index" |
| 981 |
-checksum = "9d6d7a740b8a666a7e828dd00da9c0dc290dff53154ea77ac109281de90589b7" |
|
| 981 |
+checksum = "f9a7210f5c9a7156bb50aa36aed4c95afb51df0df00713949448cf9e97d382d2" |
|
| 982 | 982 |
dependencies = [ |
| 983 | 983 |
"thiserror-impl", |
| 984 | 984 |
] |
| 985 | 985 |
|
| 986 | 986 |
[[package]] |
| 987 | 987 |
name = "thiserror-impl" |
| 988 |
-version = "1.0.48" |
|
| 988 |
+version = "1.0.50" |
|
| 989 | 989 |
source = "registry+https://github.com/rust-lang/crates.io-index" |
| 990 |
-checksum = "49922ecae66cc8a249b77e68d1d0623c1b2c514f0060c27cdc68bd62a1219d35" |
|
| 990 |
+checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8" |
|
| 991 | 991 |
dependencies = [ |
| 992 | 992 |
"proc-macro2", |
| 993 | 993 |
"quote", |
| 994 |
- "syn 2.0.31", |
|
| 994 |
+ "syn 2.0.38", |
|
| 995 | 995 |
] |
| 996 | 996 |
|
| 997 | 997 |
[[package]] |
| ... | ... |
@@ -1026,15 +970,15 @@ dependencies = [ |
| 1026 | 1026 |
|
| 1027 | 1027 |
[[package]] |
| 1028 | 1028 |
name = "typenum" |
| 1029 |
-version = "1.16.0" |
|
| 1029 |
+version = "1.17.0" |
|
| 1030 | 1030 |
source = "registry+https://github.com/rust-lang/crates.io-index" |
| 1031 |
-checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" |
|
| 1031 |
+checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" |
|
| 1032 | 1032 |
|
| 1033 | 1033 |
[[package]] |
| 1034 | 1034 |
name = "unicode-ident" |
| 1035 |
-version = "1.0.11" |
|
| 1035 |
+version = "1.0.12" |
|
| 1036 | 1036 |
source = "registry+https://github.com/rust-lang/crates.io-index" |
| 1037 |
-checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c" |
|
| 1037 |
+checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" |
|
| 1038 | 1038 |
|
| 1039 | 1039 |
[[package]] |
| 1040 | 1040 |
name = "unicode-segmentation" |
| ... | ... |
@@ -1043,70 +987,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" |
| 1043 | 1043 |
checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36" |
| 1044 | 1044 |
|
| 1045 | 1045 |
[[package]] |
| 1046 |
-name = "version_check" |
|
| 1047 |
-version = "0.9.4" |
|
| 1048 |
-source = "registry+https://github.com/rust-lang/crates.io-index" |
|
| 1049 |
-checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" |
|
| 1050 |
- |
|
| 1051 |
-[[package]] |
|
| 1052 |
-name = "wasi" |
|
| 1053 |
-version = "0.11.0+wasi-snapshot-preview1" |
|
| 1054 |
-source = "registry+https://github.com/rust-lang/crates.io-index" |
|
| 1055 |
-checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" |
|
| 1056 |
- |
|
| 1057 |
-[[package]] |
|
| 1058 |
-name = "wasm-bindgen" |
|
| 1059 |
-version = "0.2.87" |
|
| 1046 |
+name = "uuid" |
|
| 1047 |
+version = "1.5.0" |
|
| 1060 | 1048 |
source = "registry+https://github.com/rust-lang/crates.io-index" |
| 1061 |
-checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342" |
|
| 1062 |
-dependencies = [ |
|
| 1063 |
- "cfg-if", |
|
| 1064 |
- "wasm-bindgen-macro", |
|
| 1065 |
-] |
|
| 1049 |
+checksum = "88ad59a7560b41a70d191093a945f0b87bc1deeda46fb237479708a1d6b6cdfc" |
|
| 1066 | 1050 |
|
| 1067 | 1051 |
[[package]] |
| 1068 |
-name = "wasm-bindgen-backend" |
|
| 1069 |
-version = "0.2.87" |
|
| 1070 |
-source = "registry+https://github.com/rust-lang/crates.io-index" |
|
| 1071 |
-checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd" |
|
| 1072 |
-dependencies = [ |
|
| 1073 |
- "bumpalo", |
|
| 1074 |
- "log", |
|
| 1075 |
- "once_cell", |
|
| 1076 |
- "proc-macro2", |
|
| 1077 |
- "quote", |
|
| 1078 |
- "syn 2.0.31", |
|
| 1079 |
- "wasm-bindgen-shared", |
|
| 1080 |
-] |
|
| 1081 |
- |
|
| 1082 |
-[[package]] |
|
| 1083 |
-name = "wasm-bindgen-macro" |
|
| 1084 |
-version = "0.2.87" |
|
| 1085 |
-source = "registry+https://github.com/rust-lang/crates.io-index" |
|
| 1086 |
-checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d" |
|
| 1087 |
-dependencies = [ |
|
| 1088 |
- "quote", |
|
| 1089 |
- "wasm-bindgen-macro-support", |
|
| 1090 |
-] |
|
| 1091 |
- |
|
| 1092 |
-[[package]] |
|
| 1093 |
-name = "wasm-bindgen-macro-support" |
|
| 1094 |
-version = "0.2.87" |
|
| 1095 |
-source = "registry+https://github.com/rust-lang/crates.io-index" |
|
| 1096 |
-checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" |
|
| 1097 |
-dependencies = [ |
|
| 1098 |
- "proc-macro2", |
|
| 1099 |
- "quote", |
|
| 1100 |
- "syn 2.0.31", |
|
| 1101 |
- "wasm-bindgen-backend", |
|
| 1102 |
- "wasm-bindgen-shared", |
|
| 1103 |
-] |
|
| 1104 |
- |
|
| 1105 |
-[[package]] |
|
| 1106 |
-name = "wasm-bindgen-shared" |
|
| 1107 |
-version = "0.2.87" |
|
| 1052 |
+name = "version_check" |
|
| 1053 |
+version = "0.9.4" |
|
| 1108 | 1054 |
source = "registry+https://github.com/rust-lang/crates.io-index" |
| 1109 |
-checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" |
|
| 1055 |
+checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" |
|
| 1110 | 1056 |
|
| 1111 | 1057 |
[[package]] |
| 1112 | 1058 |
name = "weezl" |
| ... | ... |
@@ -1127,6 +1017,12 @@ dependencies = [ |
| 1127 | 1127 |
] |
| 1128 | 1128 |
|
| 1129 | 1129 |
[[package]] |
| 1130 |
+name = "widestring" |
|
| 1131 |
+version = "1.0.2" |
|
| 1132 |
+source = "registry+https://github.com/rust-lang/crates.io-index" |
|
| 1133 |
+checksum = "653f141f39ec16bba3c5abe400a0c60da7468261cc2cbf36805022876bc721a8" |
|
| 1134 |
+ |
|
| 1135 |
+[[package]] |
|
| 1130 | 1136 |
name = "winapi" |
| 1131 | 1137 |
version = "0.3.9" |
| 1132 | 1138 |
source = "registry+https://github.com/rust-lang/crates.io-index" |
| ... | ... |
@@ -1291,6 +1291,13 @@ int recvloop(int *socketds, unsigned nsockets, struct cl_engine *engine, unsigne |
| 1291 | 1291 |
logg(LOGG_INFO, "HWP3 support disabled.\n"); |
| 1292 | 1292 |
} |
| 1293 | 1293 |
|
| 1294 |
+ if (optget(opts, "ScanOneNote")->enabled) {
|
|
| 1295 |
+ logg(LOGG_INFO, "OneNote support enabled.\n"); |
|
| 1296 |
+ options.parse |= CL_SCAN_PARSE_ONENOTE; |
|
| 1297 |
+ } else {
|
|
| 1298 |
+ logg(LOGG_INFO, "OneNote support disabled.\n"); |
|
| 1299 |
+ } |
|
| 1300 |
+ |
|
| 1294 | 1301 |
if (optget(opts, "PhishingScanURLs")->enabled) {
|
| 1295 | 1302 |
/* TODO: Remove deprecated option in a future feature release */ |
| 1296 | 1303 |
if ((optget(opts, "PhishingAlwaysBlockCloak")->enabled) || |
| ... | ... |
@@ -304,6 +304,7 @@ void help(void) |
| 304 | 304 |
mprintf(LOGG_INFO, " --scan-html[=yes(*)/no] Scan HTML files\n"); |
| 305 | 305 |
mprintf(LOGG_INFO, " --scan-xmldocs[=yes(*)/no] Scan xml-based document files\n"); |
| 306 | 306 |
mprintf(LOGG_INFO, " --scan-hwp3[=yes(*)/no] Scan HWP3 files\n"); |
| 307 |
+ mprintf(LOGG_INFO, " --scan-onenote[=yes(*)/no] Scan OneNote files\n"); |
|
| 307 | 308 |
mprintf(LOGG_INFO, " --scan-archive[=yes(*)/no] Scan archive files (supported by libclamav)\n"); |
| 308 | 309 |
mprintf(LOGG_INFO, " --alert-broken[=yes/no(*)] Alert on broken executable files (PE & ELF)\n"); |
| 309 | 310 |
mprintf(LOGG_INFO, " --alert-broken-media[=yes/no(*)] Alert on broken graphics files (JPEG, TIFF, PNG, GIF)\n"); |
| ... | ... |
@@ -1552,6 +1552,9 @@ int scanmanager(const struct optstruct *opts) |
| 1552 | 1552 |
if (optget(opts, "scan-hwp3")->enabled) |
| 1553 | 1553 |
options.parse |= CL_SCAN_PARSE_HWP3; |
| 1554 | 1554 |
|
| 1555 |
+ if (optget(opts, "scan-onenote")->enabled) |
|
| 1556 |
+ options.parse |= CL_SCAN_PARSE_ONENOTE; |
|
| 1557 |
+ |
|
| 1555 | 1558 |
/* TODO: Remove deprecated option in a future feature release */ |
| 1556 | 1559 |
if ((optget(opts, "algorithmic-detection")->enabled) && /* && used due to default-yes for both options */ |
| 1557 | 1560 |
(optget(opts, "heuristic-alerts")->enabled)) {
|
| ... | ... |
@@ -434,6 +434,8 @@ const struct clam_option __clam_options[] = {
|
| 434 | 434 |
|
| 435 | 435 |
{"ScanHWP3", "scan-hwp3", 0, CLOPT_TYPE_BOOL, MATCH_BOOL, 1, NULL, 0, OPT_CLAMD | OPT_CLAMSCAN, "This option enables scanning HWP3 files.\nIf you turn off this option, the original files will still be scanned, but\nwithout additional processing.", "yes"},
|
| 436 | 436 |
|
| 437 |
+ {"ScanOneNote", "scan-onenote", 0, CLOPT_TYPE_BOOL, MATCH_BOOL, 1, NULL, 0, OPT_CLAMD | OPT_CLAMSCAN, "This option enables scanning OneNote files.\nIf you turn off this option, the original files will still be scanned, but\nwithout additional processing.", "yes"},
|
|
| 438 |
+ |
|
| 437 | 439 |
{"ScanArchive", "scan-archive", 0, CLOPT_TYPE_BOOL, MATCH_BOOL, 1, NULL, 0, OPT_CLAMD | OPT_CLAMSCAN, "Scan within archives and compressed files.\nIf you turn off this option, the original files will still be scanned, but\nwithout unpacking and additional processing.", "yes"},
|
| 438 | 440 |
|
| 439 | 441 |
{"ForceToDisk", "force-to-disk", 0, CLOPT_TYPE_BOOL, MATCH_BOOL, 0, NULL, 0, OPT_CLAMD | OPT_CLAMSCAN, "This option causes memory or nested map scans to dump the content to disk.\nIf you turn on this option, more data is written to disk and is available\nwhen the leave-temps option is enabled at the cost of more disk writes.", "no"},
|
| ... | ... |
@@ -479,6 +479,13 @@ If you turn off this option, the original files will still be scanned, but witho |
| 479 | 479 |
.br |
| 480 | 480 |
Default: yes |
| 481 | 481 |
.TP |
| 482 |
+\fBScanOneNote BOOL\fR |
|
| 483 |
+This option enables scanning OneNote files. |
|
| 484 |
+.br |
|
| 485 |
+If you turn off this option, the original files will still be scanned, but without additional processing. |
|
| 486 |
+.br |
|
| 487 |
+Default: yes |
|
| 488 |
+.TP |
|
| 482 | 489 |
\fBScanArchive BOOL\fR |
| 483 | 490 |
Scan within archives and compressed files. |
| 484 | 491 |
.br |
| ... | ... |
@@ -426,6 +426,12 @@ Example |
| 426 | 426 |
# Default: yes |
| 427 | 427 |
#ScanHWP3 yes |
| 428 | 428 |
|
| 429 |
+# This option enables scanning of OneNote files. |
|
| 430 |
+# If you turn off this option, the original files will still be scanned, but |
|
| 431 |
+# without additional processing. |
|
| 432 |
+# Default: yes |
|
| 433 |
+#ScanOneNote yes |
|
| 434 |
+ |
|
| 429 | 435 |
|
| 430 | 436 |
## |
| 431 | 437 |
## Mail files |
| ... | ... |
@@ -180,6 +180,7 @@ struct cl_scan_options {
|
| 180 | 180 |
#define CL_SCAN_PARSE_OLE2 0x80 |
| 181 | 181 |
#define CL_SCAN_PARSE_HTML 0x100 |
| 182 | 182 |
#define CL_SCAN_PARSE_PE 0x200 |
| 183 |
+#define CL_SCAN_PARSE_ONENOTE 0x400 |
|
| 183 | 184 |
|
| 184 | 185 |
/* heuristic alerting options */ |
| 185 | 186 |
#define CL_SCAN_HEURISTIC_BROKEN 0x2 /* alert on broken PE and broken ELF files */ |
| ... | ... |
@@ -118,6 +118,7 @@ static struct dconf_module modules[] = {
|
| 118 | 118 |
{"DOCUMENT", "OOXML", DOC_CONF_OOXML, 1},
|
| 119 | 119 |
{"DOCUMENT", "MSPML", DOC_CONF_MSXML, 1},
|
| 120 | 120 |
{"DOCUMENT", "HWP", DOC_CONF_HWP, 1},
|
| 121 |
+ {"DOCUMENT", "ONENOTE", DOC_CONF_ONENOTE, 1},
|
|
| 121 | 122 |
|
| 122 | 123 |
{"MAIL", "MBOX", MAIL_CONF_MBOX, 1},
|
| 123 | 124 |
{"MAIL", "TNEF", MAIL_CONF_TNEF, 1},
|
| ... | ... |
@@ -138,6 +138,7 @@ static const struct ftmap_s {
|
| 138 | 138 |
{ "CL_TYPE_EGG", CL_TYPE_EGG },
|
| 139 | 139 |
{ "CL_TYPE_EGGSFX", CL_TYPE_EGGSFX },
|
| 140 | 140 |
{ "CL_TYPE_UDF", CL_TYPE_UDF },
|
| 141 |
+ { "CL_TYPE_ONENOTE", CL_TYPE_ONENOTE },
|
|
| 141 | 142 |
{ NULL, CL_TYPE_IGNORED }
|
| 142 | 143 |
}; |
| 143 | 144 |
// clang-format on |
| ... | ... |
@@ -204,5 +204,6 @@ static const char *ftypes_int[] = {
|
| 204 | 204 |
"0:0:4d4d:TIFF Big Endian:CL_TYPE_ANY:CL_TYPE_GRAPHICS:81:121", |
| 205 | 205 |
"1:*:377abcaf271c:7zip-SFX:CL_TYPE_ANY:CL_TYPE_7ZSFX:74", |
| 206 | 206 |
"1:0:3c3f786d6c2076657273696f6e3d22312e3022{0-1024}70726f6769643d22576f72642e446f63756d656e74223f3e:Microsoft Word 2003 XML Document:CL_TYPE_ANY:CL_TYPE_XML_WORD:80",
|
| 207 |
+ "0:0:e4525c7b8cd8a74daeb15378d02996d3:Microsoft OneNote Document:CL_TYPE_ANY:CL_TYPE_ONENOTE:200", |
|
| 207 | 208 |
NULL}; |
| 208 | 209 |
#endif |
| ... | ... |
@@ -191,6 +191,7 @@ typedef struct recursion_level_tag {
|
| 191 | 191 |
} recursion_level_t; |
| 192 | 192 |
|
| 193 | 193 |
typedef void *evidence_t; |
| 194 |
+typedef void *onedump_t; |
|
| 194 | 195 |
|
| 195 | 196 |
/* internal clamav context */ |
| 196 | 197 |
typedef struct cli_ctx_tag {
|
| ... | ... |
@@ -568,6 +569,7 @@ extern LIBCLAMAV_EXPORT int have_rar; |
| 568 | 568 |
#define SCAN_PARSE_OLE2 (ctx->options->parse & CL_SCAN_PARSE_OLE2) |
| 569 | 569 |
#define SCAN_PARSE_HTML (ctx->options->parse & CL_SCAN_PARSE_HTML) |
| 570 | 570 |
#define SCAN_PARSE_PE (ctx->options->parse & CL_SCAN_PARSE_PE) |
| 571 |
+#define SCAN_PARSE_ONENOTE (ctx->options->parse & CL_SCAN_PARSE_ONENOTE) |
|
| 571 | 572 |
|
| 572 | 573 |
#define SCAN_HEURISTIC_BROKEN (ctx->options->heuristic & CL_SCAN_HEURISTIC_BROKEN) |
| 573 | 574 |
#define SCAN_HEURISTIC_BROKEN_MEDIA (ctx->options->heuristic & CL_SCAN_HEURISTIC_BROKEN_MEDIA) |
| ... | ... |
@@ -4591,6 +4591,11 @@ cl_error_t cli_magic_scan(cli_ctx *ctx, cli_file_t type) |
| 4591 | 4591 |
ret = cli_scanegg(ctx); |
| 4592 | 4592 |
break; |
| 4593 | 4593 |
|
| 4594 |
+ case CL_TYPE_ONENOTE: |
|
| 4595 |
+ if (SCAN_PARSE_ONENOTE && (DCONF_ARCH & DOC_CONF_ONENOTE)) |
|
| 4596 |
+ ret = scan_onenote(ctx); |
|
| 4597 |
+ break; |
|
| 4598 |
+ |
|
| 4594 | 4599 |
case CL_TYPE_OOXML_WORD: |
| 4595 | 4600 |
case CL_TYPE_OOXML_PPT: |
| 4596 | 4601 |
case CL_TYPE_OOXML_XL: |
| ... | ... |
@@ -20,6 +20,8 @@ base64 = "0.21.0" |
| 20 | 20 |
sha1 = "0.10.5" |
| 21 | 21 |
unicode-segmentation = "1.10.1" |
| 22 | 22 |
bindgen = "0.65" |
| 23 |
+onenote_parser = { git = "https://github.com/Cisco-Talos/onenote.rs.git", branch = "CLAM-2329-new-from-slice" }
|
|
| 24 |
+hex-literal = "0.4.1" |
|
| 23 | 25 |
|
| 24 | 26 |
[lib] |
| 25 | 27 |
crate-type = ["staticlib"] |
| ... | ... |
@@ -52,6 +52,7 @@ const BINDGEN_FUNCTIONS: &[&str] = &[ |
| 52 | 52 |
"cli_versig2", |
| 53 | 53 |
"cli_getdsig", |
| 54 | 54 |
"cli_get_debug_flag", |
| 55 |
+ "cli_magic_scan_buff", |
|
| 55 | 56 |
]; |
| 56 | 57 |
|
| 57 | 58 |
// Generate bindings for these types (structs, enums): |
| ... | ... |
@@ -61,6 +62,7 @@ const BINDGEN_TYPES: &[&str] = &[ |
| 61 | 61 |
"cli_ac_result", |
| 62 | 62 |
"css_image_extractor_t", |
| 63 | 63 |
"css_image_handle_t", |
| 64 |
+ "onedump_t", |
|
| 64 | 65 |
]; |
| 65 | 66 |
|
| 66 | 67 |
// Find the required functions and types in these headers: |
| ... | ... |
@@ -70,6 +72,8 @@ const BINDGEN_HEADERS: &[&str] = &[ |
| 70 | 70 |
"../libclamav/others.h", |
| 71 | 71 |
"../libclamav/dsig.h", |
| 72 | 72 |
"../libclamav/htmlnorm.h", |
| 73 |
+ "../libclamav/fmap.h", |
|
| 74 |
+ "../libclamav/scanners.h", |
|
| 73 | 75 |
]; |
| 74 | 76 |
|
| 75 | 77 |
// Find the required headers in these directories: |
| ... | ... |
@@ -135,7 +139,7 @@ fn execute_bindgen() -> Result<(), &'static str> {
|
| 135 | 135 |
// Silence code-style warnings for generated bindings. |
| 136 | 136 |
.raw_line("#![allow(non_snake_case, non_camel_case_types, non_upper_case_globals)]")
|
| 137 | 137 |
// Make the bindings pretty. |
| 138 |
- .rustfmt_bindings(true) |
|
| 138 |
+ .formatter(bindgen::Formatter::Rustfmt) |
|
| 139 | 139 |
// Disable the layout tests. |
| 140 | 140 |
// We're committing to source control. Pointer width, integer size, etc |
| 141 | 141 |
// are probably not the same when generated as when compiled. |
| ... | ... |
@@ -36,7 +36,6 @@ use crate::validate_str_param; |
| 36 | 36 |
use flate2::{read::GzDecoder, write::GzEncoder, Compression};
|
| 37 | 37 |
use log::{debug, error, warn};
|
| 38 | 38 |
use sha2::{Digest, Sha256};
|
| 39 |
-use thiserror::Error; |
|
| 40 | 39 |
|
| 41 | 40 |
/// Size of a digital signature |
| 42 | 41 |
const SIG_SIZE: usize = 350; |
| ... | ... |
@@ -88,8 +87,8 @@ struct Context {
|
| 88 | 88 |
} |
| 89 | 89 |
|
| 90 | 90 |
/// Possible errors returned by cdiff_apply() and script2cdiff |
| 91 |
-#[derive(Debug, Error)] |
|
| 92 |
-pub enum CdiffError {
|
|
| 91 |
+#[derive(thiserror::Error, Debug)] |
|
| 92 |
+pub enum Error {
|
|
| 93 | 93 |
#[error("Error in header: {0}")]
|
| 94 | 94 |
Header(#[from] HeaderError), |
| 95 | 95 |
|
| ... | ... |
@@ -151,7 +150,7 @@ pub enum CdiffError {
|
| 151 | 151 |
|
| 152 | 152 |
/// Errors particular to input handling (i.e., syntax, or side effects from |
| 153 | 153 |
/// handling input) |
| 154 |
-#[derive(Error, Debug)] |
|
| 154 |
+#[derive(thiserror::Error, Debug)] |
|
| 155 | 155 |
pub enum InputError {
|
| 156 | 156 |
#[error("Unsupported command provided: {0}")]
|
| 157 | 157 |
UnknownCommand(String), |
| ... | ... |
@@ -199,7 +198,7 @@ pub enum InputError {
|
| 199 | 199 |
} |
| 200 | 200 |
|
| 201 | 201 |
/// Errors encountered while processing |
| 202 |
-#[derive(Debug, Error)] |
|
| 202 |
+#[derive(thiserror::Error, Debug)] |
|
| 203 | 203 |
pub enum ProcessingError {
|
| 204 | 204 |
#[error("File {0} not closed before calling action MOVE")]
|
| 205 | 205 |
NotClosedBeforeAction(String), |
| ... | ... |
@@ -238,7 +237,7 @@ pub enum ProcessingError {
|
| 238 | 238 |
IoError(#[from] std::io::Error), |
| 239 | 239 |
} |
| 240 | 240 |
|
| 241 |
-#[derive(Error, Debug)] |
|
| 241 |
+#[derive(thiserror::Error, Debug)] |
|
| 242 | 242 |
pub enum HeaderError {
|
| 243 | 243 |
#[error("invalid magic")]
|
| 244 | 244 |
BadMagic, |
| ... | ... |
@@ -253,7 +252,7 @@ pub enum HeaderError {
|
| 253 | 253 |
IoError(#[from] std::io::Error), |
| 254 | 254 |
} |
| 255 | 255 |
|
| 256 |
-#[derive(Error, Debug)] |
|
| 256 |
+#[derive(thiserror::Error, Debug)] |
|
| 257 | 257 |
pub enum SignatureError {
|
| 258 | 258 |
#[error("IO error: {0}")]
|
| 259 | 259 |
IoError(#[from] std::io::Error), |
| ... | ... |
@@ -265,7 +264,7 @@ pub enum SignatureError {
|
| 265 | 265 |
TooLarge, |
| 266 | 266 |
} |
| 267 | 267 |
|
| 268 |
-#[derive(Error, Debug)] |
|
| 268 |
+#[derive(thiserror::Error, Debug)] |
|
| 269 | 269 |
pub enum InvalidNumber {
|
| 270 | 270 |
#[error("not unicode")]
|
| 271 | 271 |
NotUnicode(#[from] std::str::Utf8Error), |
| ... | ... |
@@ -462,7 +461,7 @@ pub extern "C" fn _script2cdiff( |
| 462 | 462 |
/// signature from the sha256 of the contents written. |
| 463 | 463 |
/// |
| 464 | 464 |
/// This function will panic if any of the &str parameters contain interior NUL bytes |
| 465 |
-pub fn script2cdiff(script_file_name: &str, builder: &str, server: &str) -> Result<(), CdiffError> {
|
|
| 465 |
+pub fn script2cdiff(script_file_name: &str, builder: &str, server: &str) -> Result<(), Error> {
|
|
| 466 | 466 |
// Make a copy of the script file name to use for the cdiff file |
| 467 | 467 |
let cdiff_file_name_string = script_file_name.to_string(); |
| 468 | 468 |
let mut cdiff_file_name = cdiff_file_name_string.as_str(); |
| ... | ... |
@@ -476,18 +475,18 @@ pub fn script2cdiff(script_file_name: &str, builder: &str, server: &str) -> Resu |
| 476 | 476 |
// Get right-most hyphen index |
| 477 | 477 |
let hyphen_index = cdiff_file_name |
| 478 | 478 |
.rfind('-')
|
| 479 |
- .ok_or(CdiffError::FilenameMissingHyphen)?; |
|
| 479 |
+ .ok_or(Error::FilenameMissingHyphen)?; |
|
| 480 | 480 |
|
| 481 | 481 |
// Get the version, which should be to the right of the hyphen |
| 482 | 482 |
let version_string = cdiff_file_name |
| 483 | 483 |
.get((hyphen_index + 1)..) |
| 484 |
- .ok_or(CdiffError::FilenameMissingVersion)?; |
|
| 484 |
+ .ok_or(Error::FilenameMissingVersion)?; |
|
| 485 | 485 |
|
| 486 | 486 |
// Parse the version into usize |
| 487 | 487 |
let version = version_string |
| 488 | 488 |
.to_string() |
| 489 | 489 |
.parse::<usize>() |
| 490 |
- .map_err(CdiffError::VersionParse)?; |
|
| 490 |
+ .map_err(Error::VersionParse)?; |
|
| 491 | 491 |
|
| 492 | 492 |
// Add .cdiff suffix |
| 493 | 493 |
let cdiff_file_name = format!("{}.{}", cdiff_file_name, "cdiff");
|
| ... | ... |
@@ -495,21 +494,21 @@ pub fn script2cdiff(script_file_name: &str, builder: &str, server: &str) -> Resu |
| 495 | 495 |
|
| 496 | 496 |
// Open cdiff_file_name for writing |
| 497 | 497 |
let mut cdiff_file: File = File::create(&cdiff_file_name) |
| 498 |
- .map_err(|e| CdiffError::FileCreate(cdiff_file_name.to_owned(), e))?; |
|
| 498 |
+ .map_err(|e| Error::FileCreate(cdiff_file_name.to_owned(), e))?; |
|
| 499 | 499 |
|
| 500 | 500 |
// Open the original script file for reading |
| 501 | 501 |
let script_file: File = File::open(script_file_name) |
| 502 |
- .map_err(|e| CdiffError::FileOpen(script_file_name.to_owned(), e))?; |
|
| 502 |
+ .map_err(|e| Error::FileOpen(script_file_name.to_owned(), e))?; |
|
| 503 | 503 |
|
| 504 | 504 |
// Get file length |
| 505 | 505 |
let script_file_len = script_file |
| 506 | 506 |
.metadata() |
| 507 |
- .map_err(|e| CdiffError::FileMeta(script_file_name.to_owned(), e))? |
|
| 507 |
+ .map_err(|e| Error::FileMeta(script_file_name.to_owned(), e))? |
|
| 508 | 508 |
.len(); |
| 509 | 509 |
|
| 510 | 510 |
// Write header to cdiff file |
| 511 | 511 |
write!(cdiff_file, "ClamAV-Diff:{}:{}:", version, script_file_len)
|
| 512 |
- .map_err(|e| CdiffError::FileWrite(script_file_name.to_owned(), e))?; |
|
| 512 |
+ .map_err(|e| Error::FileWrite(script_file_name.to_owned(), e))?; |
|
| 513 | 513 |
|
| 514 | 514 |
// Set up buffered reader and gz writer |
| 515 | 515 |
let mut reader = BufReader::new(script_file); |
| ... | ... |
@@ -521,12 +520,12 @@ pub fn script2cdiff(script_file_name: &str, builder: &str, server: &str) -> Resu |
| 521 | 521 |
// Get cdiff file writer back from flate2 |
| 522 | 522 |
let mut cdiff_file = gz |
| 523 | 523 |
.finish() |
| 524 |
- .map_err(|e| CdiffError::FileWrite(cdiff_file_name.to_owned(), e))?; |
|
| 524 |
+ .map_err(|e| Error::FileWrite(cdiff_file_name.to_owned(), e))?; |
|
| 525 | 525 |
|
| 526 | 526 |
// Get the new cdiff file len |
| 527 | 527 |
let cdiff_file_len = cdiff_file |
| 528 | 528 |
.metadata() |
| 529 |
- .map_err(|e| CdiffError::FileMeta(cdiff_file_name.to_owned(), e))? |
|
| 529 |
+ .map_err(|e| Error::FileMeta(cdiff_file_name.to_owned(), e))? |
|
| 530 | 530 |
.len(); |
| 531 | 531 |
debug!( |
| 532 | 532 |
"script2cdiff() - wrote {} bytes to {}",
|
| ... | ... |
@@ -536,7 +535,7 @@ pub fn script2cdiff(script_file_name: &str, builder: &str, server: &str) -> Resu |
| 536 | 536 |
// Calculate SHA2-256 to get the sigature |
| 537 | 537 |
// TODO: Do this while the file is being written |
| 538 | 538 |
let bytes = std::fs::read(&cdiff_file_name) |
| 539 |
- .map_err(|e| CdiffError::FileRead(cdiff_file_name.to_owned(), e))?; |
|
| 539 |
+ .map_err(|e| Error::FileRead(cdiff_file_name.to_owned(), e))?; |
|
| 540 | 540 |
let sha256 = {
|
| 541 | 541 |
let mut hasher = Sha256::new(); |
| 542 | 542 |
hasher.update(&bytes); |
| ... | ... |
@@ -561,12 +560,12 @@ pub fn script2cdiff(script_file_name: &str, builder: &str, server: &str) -> Resu |
| 561 | 561 |
// Write cdiff footer delimiter |
| 562 | 562 |
cdiff_file |
| 563 | 563 |
.write_all(b":") |
| 564 |
- .map_err(|e| CdiffError::FileWrite(cdiff_file_name.to_owned(), e))?; |
|
| 564 |
+ .map_err(|e| Error::FileWrite(cdiff_file_name.to_owned(), e))?; |
|
| 565 | 565 |
|
| 566 | 566 |
// Write dsig to cdiff footer |
| 567 | 567 |
cdiff_file |
| 568 | 568 |
.write_all(dsig.to_bytes()) |
| 569 |
- .map_err(|e| CdiffError::FileWrite(cdiff_file_name, e))?; |
|
| 569 |
+ .map_err(|e| Error::FileWrite(cdiff_file_name, e))?; |
|
| 570 | 570 |
|
| 571 | 571 |
// Exit success |
| 572 | 572 |
Ok(()) |
| ... | ... |
@@ -609,7 +608,7 @@ pub extern "C" fn _cdiff_apply(fd: i32, mode: u16) -> i32 {
|
| 609 | 609 |
/// A cdiff file contains a footer that is the signed signature of the sha256 |
| 610 | 610 |
/// file contains of the header and the body. The footer begins after the first |
| 611 | 611 |
/// ':' character to the left of EOF. |
| 612 |
-pub fn cdiff_apply(file: &mut File, mode: ApplyMode) -> Result<(), CdiffError> {
|
|
| 612 |
+pub fn cdiff_apply(file: &mut File, mode: ApplyMode) -> Result<(), Error> {
|
|
| 613 | 613 |
let path = std::env::current_dir().unwrap(); |
| 614 | 614 |
debug!("cdiff_apply() - current directory is {}", path.display());
|
| 615 | 615 |
|
| ... | ... |
@@ -649,7 +648,7 @@ pub fn cdiff_apply(file: &mut File, mode: ApplyMode) -> Result<(), CdiffError> {
|
| 649 | 649 |
}; |
| 650 | 650 |
debug!("cdiff_apply() - cli_versig2() result = {}", versig_result);
|
| 651 | 651 |
if versig_result != 0 {
|
| 652 |
- return Err(CdiffError::InvalidDigitalSignature); |
|
| 652 |
+ return Err(Error::InvalidDigitalSignature); |
|
| 653 | 653 |
} |
| 654 | 654 |
|
| 655 | 655 |
// Read file length from header |
| ... | ... |
@@ -1042,7 +1041,7 @@ fn process_lines<T>( |
| 1042 | 1042 |
ctx: &mut Context, |
| 1043 | 1043 |
reader: &mut T, |
| 1044 | 1044 |
uncompressed_size: usize, |
| 1045 |
-) -> Result<(), CdiffError> |
|
| 1045 |
+) -> Result<(), Error> |
|
| 1046 | 1046 |
where |
| 1047 | 1047 |
T: BufRead, |
| 1048 | 1048 |
{
|
| ... | ... |
@@ -1059,7 +1058,7 @@ where |
| 1059 | 1059 |
match linebuf.first() {
|
| 1060 | 1060 |
// Skip comment lines |
| 1061 | 1061 |
Some(b'#') => continue, |
| 1062 |
- _ => process_line(ctx, &linebuf).map_err(|e| CdiffError::Input {
|
|
| 1062 |
+ _ => process_line(ctx, &linebuf).map_err(|e| Error::Input {
|
|
| 1063 | 1063 |
line: line_no, |
| 1064 | 1064 |
err: e, |
| 1065 | 1065 |
operation: String::from_utf8_lossy(&linebuf).to_string(), |
| ... | ... |
@@ -1150,7 +1149,7 @@ fn read_size(file: &mut File) -> Result<(u32, usize), HeaderError> {
|
| 1150 | 1150 |
} |
| 1151 | 1151 |
|
| 1152 | 1152 |
/// Calculate the sha256 of the first len bytes of a file |
| 1153 |
-fn get_hash(file: &mut File, len: usize) -> Result<[u8; 32], CdiffError> {
|
|
| 1153 |
+fn get_hash(file: &mut File, len: usize) -> Result<[u8; 32], Error> {
|
|
| 1154 | 1154 |
let mut hasher = Sha256::new(); |
| 1155 | 1155 |
|
| 1156 | 1156 |
// Seek to beginning of file |
| ... | ... |
@@ -1193,7 +1192,7 @@ mod tests {
|
| 1193 | 1193 |
use std::path::Path; |
| 1194 | 1194 |
|
| 1195 | 1195 |
/// CdiffTestError enumerates all possible errors returned by this testing library. |
| 1196 |
- #[derive(Error, Debug)] |
|
| 1196 |
+ #[derive(thiserror::Error, Debug)] |
|
| 1197 | 1197 |
pub enum CdiffTestError {
|
| 1198 | 1198 |
/// Represents all other cases of `std::io::Error`. |
| 1199 | 1199 |
#[error(transparent)] |
| ... | ... |
@@ -1545,7 +1544,7 @@ mod tests {
|
| 1545 | 1545 |
fn script2cdiff_missing_hyphen() {
|
| 1546 | 1546 |
assert!(matches!( |
| 1547 | 1547 |
script2cdiff("", "", ""),
|
| 1548 |
- Err(CdiffError::FilenameMissingHyphen) |
|
| 1548 |
+ Err(Error::FilenameMissingHyphen) |
|
| 1549 | 1549 |
)); |
| 1550 | 1550 |
} |
| 1551 | 1551 |
} |
| ... | ... |
@@ -24,14 +24,13 @@ use std::{ffi::CStr, mem::ManuallyDrop, os::raw::c_char};
|
| 24 | 24 |
|
| 25 | 25 |
use base64::{engine::general_purpose as base64_engine_standard, Engine as _};
|
| 26 | 26 |
use log::{debug, error, warn};
|
| 27 |
-use thiserror::Error; |
|
| 28 | 27 |
use unicode_segmentation::UnicodeSegmentation; |
| 29 | 28 |
|
| 30 | 29 |
use crate::sys; |
| 31 | 30 |
|
| 32 |
-/// CdiffError enumerates all possible errors returned by this library. |
|
| 33 |
-#[derive(Error, Debug)] |
|
| 34 |
-pub enum CssExtractError {
|
|
| 31 |
+/// Error enumerates all possible errors returned by this library. |
|
| 32 |
+#[derive(thiserror::Error, Debug)] |
|
| 33 |
+pub enum Error {
|
|
| 35 | 34 |
#[error("Invalid format")]
|
| 36 | 35 |
Format, |
| 37 | 36 |
|
| ... | ... |
@@ -56,7 +55,7 @@ pub struct CssImageExtractor<'a> {
|
| 56 | 56 |
} |
| 57 | 57 |
|
| 58 | 58 |
impl<'a> CssImageExtractor<'a> {
|
| 59 |
- pub fn new(css: &'a str) -> Result<Self, CssExtractError> {
|
|
| 59 |
+ pub fn new(css: &'a str) -> Result<Self, Error> {
|
|
| 60 | 60 |
Ok(Self { remaining: css })
|
| 61 | 61 |
} |
| 62 | 62 |
|
| ... | ... |
@@ -152,7 +151,7 @@ impl<'a> CssImageExtractor<'a> {
|
| 152 | 152 |
}; |
| 153 | 153 |
|
| 154 | 154 |
// Trim off " at end. |
| 155 |
- let c = url_parameter.graphemes(true).rev().next(); |
|
| 155 |
+ let c = url_parameter.graphemes(true).next_back(); |
|
| 156 | 156 |
if let Some(c) = c {
|
| 157 | 157 |
if c == "\"" {
|
| 158 | 158 |
(url_parameter, _) = url_parameter.split_at(url_parameter.len() - 1); |
| 159 | 159 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,98 @@ |
| 0 |
+/* |
|
| 1 |
+ * Rust equivalent of libclamav's scanners.c module |
|
| 2 |
+ * |
|
| 3 |
+ * Copyright (C) 2023 Cisco Systems, Inc. and/or its affiliates. All rights reserved. |
|
| 4 |
+ * |
|
| 5 |
+ * Authors: Micah Snyder |
|
| 6 |
+ * |
|
| 7 |
+ * This program is free software; you can redistribute it and/or modify |
|
| 8 |
+ * it under the terms of the GNU General Public License version 2 as |
|
| 9 |
+ * published by the Free Software Foundation. |
|
| 10 |
+ * |
|
| 11 |
+ * This program is distributed in the hope that it will be useful, |
|
| 12 |
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
| 13 |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
| 14 |
+ * GNU General Public License for more details. |
|
| 15 |
+ * |
|
| 16 |
+ * You should have received a copy of the GNU General Public License |
|
| 17 |
+ * along with this program; if not, write to the Free Software |
|
| 18 |
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, |
|
| 19 |
+ * MA 02110-1301, USA. |
|
| 20 |
+ */ |
|
| 21 |
+ |
|
| 22 |
+use std::{convert::TryInto, path::PathBuf, slice};
|
|
| 23 |
+ |
|
| 24 |
+use crate::{fmap::FMap, sys::cli_ctx, util::str_from_ptr};
|
|
| 25 |
+ |
|
| 26 |
+/// Error enumerates all possible errors returned by this library. |
|
| 27 |
+#[derive(thiserror::Error, Debug)] |
|
| 28 |
+pub enum Error {
|
|
| 29 |
+ #[error("Invalid format")]
|
|
| 30 |
+ Format, |
|
| 31 |
+ |
|
| 32 |
+ #[error("Invalid NULL pointer: {0}")]
|
|
| 33 |
+ NullPointer(&'static str), |
|
| 34 |
+ |
|
| 35 |
+ #[error("{0} parameter is NULL")]
|
|
| 36 |
+ NullParam(&'static str), |
|
| 37 |
+ |
|
| 38 |
+ #[error("No more files to extract")]
|
|
| 39 |
+ NoMoreFiles, |
|
| 40 |
+ |
|
| 41 |
+ #[error("Invalid FMap: {0}")]
|
|
| 42 |
+ BadMap(#[from] crate::fmap::Error), |
|
| 43 |
+ |
|
| 44 |
+ #[error("String not UTF8: {0}")]
|
|
| 45 |
+ Utf8(#[from] std::str::Utf8Error), |
|
| 46 |
+} |
|
| 47 |
+ |
|
| 48 |
+/// Get the ctx.sub_filepath as an Option<'str> |
|
| 49 |
+/// |
|
| 50 |
+/// # Safety |
|
| 51 |
+/// |
|
| 52 |
+/// Must be a valid ctx pointer. |
|
| 53 |
+pub unsafe fn sub_filepath(ctx: *mut cli_ctx) -> Result<Option<PathBuf>, Error> {
|
|
| 54 |
+ if ctx.is_null() {
|
|
| 55 |
+ return Err(Error::NullPointer("ctx"));
|
|
| 56 |
+ } |
|
| 57 |
+ |
|
| 58 |
+ Ok(str_from_ptr(unsafe { *ctx }.sub_filepath)
|
|
| 59 |
+ .map_err(Error::Utf8)? |
|
| 60 |
+ .map(PathBuf::from)) |
|
| 61 |
+} |
|
| 62 |
+ |
|
| 63 |
+/// Get the ctx.target_filepath as an Option<'str> |
|
| 64 |
+/// |
|
| 65 |
+/// # Safety |
|
| 66 |
+/// |
|
| 67 |
+/// Must be a valid ctx pointer. |
|
| 68 |
+pub unsafe fn target_filepath(ctx: *mut cli_ctx) -> Result<Option<PathBuf>, Error> {
|
|
| 69 |
+ if ctx.is_null() {
|
|
| 70 |
+ return Err(Error::NullPointer("ctx"));
|
|
| 71 |
+ } |
|
| 72 |
+ |
|
| 73 |
+ Ok(str_from_ptr(unsafe { *ctx }.target_filepath)
|
|
| 74 |
+ .map_err(Error::Utf8)? |
|
| 75 |
+ .map(PathBuf::from)) |
|
| 76 |
+} |
|
| 77 |
+ |
|
| 78 |
+/// Get the fmap for the current layer. |
|
| 79 |
+/// |
|
| 80 |
+/// # Safety |
|
| 81 |
+/// |
|
| 82 |
+/// Must be a valid ctx pointer. |
|
| 83 |
+pub unsafe fn current_fmap(ctx: *mut cli_ctx) -> Result<FMap, Error> {
|
|
| 84 |
+ if ctx.is_null() {
|
|
| 85 |
+ return Err(Error::NullPointer("ctx"));
|
|
| 86 |
+ } |
|
| 87 |
+ |
|
| 88 |
+ let recursion_stack_size = unsafe { *ctx }.recursion_stack_size as usize;
|
|
| 89 |
+ let recursion_level = unsafe { *ctx }.recursion_level as usize;
|
|
| 90 |
+ |
|
| 91 |
+ let recursion_stack = |
|
| 92 |
+ unsafe { slice::from_raw_parts((*ctx).recursion_stack, recursion_stack_size) };
|
|
| 93 |
+ |
|
| 94 |
+ let current_level = recursion_stack[recursion_level]; |
|
| 95 |
+ |
|
| 96 |
+ current_level.fmap.try_into().map_err(Error::BadMap) |
|
| 97 |
+} |
| ... | ... |
@@ -23,13 +23,12 @@ |
| 23 | 23 |
use std::{collections::HashMap, ffi::CStr, mem::ManuallyDrop, os::raw::c_char};
|
| 24 | 24 |
|
| 25 | 25 |
use log::{debug, error, warn};
|
| 26 |
-use thiserror::Error; |
|
| 27 | 26 |
|
| 28 | 27 |
use crate::{ffi_util::FFIError, rrf_call, sys, validate_str_param};
|
| 29 | 28 |
|
| 30 |
-/// CdiffError enumerates all possible errors returned by this library. |
|
| 31 |
-#[derive(Error, Debug)] |
|
| 32 |
-pub enum EvidenceError {
|
|
| 29 |
+/// Error enumerates all possible errors returned by this library. |
|
| 30 |
+#[derive(thiserror::Error, Debug)] |
|
| 31 |
+pub enum Error {
|
|
| 33 | 32 |
#[error("Invalid format")]
|
| 34 | 33 |
Format, |
| 35 | 34 |
|
| ... | ... |
@@ -240,21 +239,21 @@ impl Evidence {
|
| 240 | 240 |
name: &str, |
| 241 | 241 |
static_virname: *const c_char, |
| 242 | 242 |
indicator_type: IndicatorType, |
| 243 |
- ) -> Result<(), EvidenceError> {
|
|
| 243 |
+ ) -> Result<(), Error> {
|
|
| 244 | 244 |
let meta: IndicatorMeta = IndicatorMeta { static_virname };
|
| 245 | 245 |
|
| 246 | 246 |
match indicator_type {
|
| 247 | 247 |
IndicatorType::Strong => {
|
| 248 | 248 |
self.strong |
| 249 | 249 |
.entry(name.to_string()) |
| 250 |
- .or_insert_with(Vec::new) |
|
| 250 |
+ .or_default() |
|
| 251 | 251 |
.push(meta); |
| 252 | 252 |
} |
| 253 | 253 |
|
| 254 | 254 |
IndicatorType::PotentiallyUnwanted => {
|
| 255 | 255 |
self.pua |
| 256 | 256 |
.entry(name.to_string()) |
| 257 |
- .or_insert_with(Vec::new) |
|
| 257 |
+ .or_default() |
|
| 258 | 258 |
.push(meta); |
| 259 | 259 |
} |
| 260 | 260 |
|
| ... | ... |
@@ -265,7 +264,7 @@ impl Evidence {
|
| 265 | 265 |
IndicatorType::Weak => {
|
| 266 | 266 |
self.weak |
| 267 | 267 |
.entry(name.to_string()) |
| 268 |
- .or_insert_with(Vec::new) |
|
| 268 |
+ .or_default() |
|
| 269 | 269 |
.push(meta); |
| 270 | 270 |
} |
| 271 | 271 |
} |
| 272 | 272 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,105 @@ |
| 0 |
+/* |
|
| 1 |
+ * Rust interface for libclamav FMap module |
|
| 2 |
+ * |
|
| 3 |
+ * Copyright (C) 2023 Cisco Systems, Inc. and/or its affiliates. All rights reserved. |
|
| 4 |
+ * |
|
| 5 |
+ * Authors: Micah Snyder |
|
| 6 |
+ * |
|
| 7 |
+ * This program is free software; you can redistribute it and/or modify |
|
| 8 |
+ * it under the terms of the GNU General Public License version 2 as |
|
| 9 |
+ * published by the Free Software Foundation. |
|
| 10 |
+ * |
|
| 11 |
+ * This program is distributed in the hope that it will be useful, |
|
| 12 |
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
| 13 |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
| 14 |
+ * GNU General Public License for more details. |
|
| 15 |
+ * |
|
| 16 |
+ * You should have received a copy of the GNU General Public License |
|
| 17 |
+ * along with this program; if not, write to the Free Software |
|
| 18 |
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, |
|
| 19 |
+ * MA 02110-1301, USA. |
|
| 20 |
+ */ |
|
| 21 |
+ |
|
| 22 |
+use std::convert::TryFrom; |
|
| 23 |
+ |
|
| 24 |
+use log::{debug, error};
|
|
| 25 |
+ |
|
| 26 |
+use crate::{sys, util::str_from_ptr};
|
|
| 27 |
+ |
|
| 28 |
+/// Error enumerates all possible errors returned by this library. |
|
| 29 |
+#[derive(thiserror::Error, Debug)] |
|
| 30 |
+pub enum Error {
|
|
| 31 |
+ #[error("Invalid parameter: {0}")]
|
|
| 32 |
+ InvalidParameter(String), |
|
| 33 |
+ |
|
| 34 |
+ #[error("{0} parmeter is NULL")]
|
|
| 35 |
+ NullParam(&'static str), |
|
| 36 |
+ |
|
| 37 |
+ #[error("Offset {0} and length {1} not contained in FMap of size {2}")]
|
|
| 38 |
+ NotContained(usize, usize, usize), |
|
| 39 |
+ |
|
| 40 |
+ #[error("FMap pointer not initialized: {0}")]
|
|
| 41 |
+ UninitializedPtr(&'static str), |
|
| 42 |
+ |
|
| 43 |
+ #[error("Attempted to create Rust FMap interface from NULL pointer")]
|
|
| 44 |
+ Null, |
|
| 45 |
+} |
|
| 46 |
+ |
|
| 47 |
+#[derive(PartialEq, Eq, Hash, Debug)] |
|
| 48 |
+pub struct FMap {
|
|
| 49 |
+ fmap_ptr: *mut sys::cl_fmap_t, |
|
| 50 |
+} |
|
| 51 |
+ |
|
| 52 |
+impl TryFrom<*mut sys::cl_fmap_t> for FMap {
|
|
| 53 |
+ type Error = Error; |
|
| 54 |
+ |
|
| 55 |
+ fn try_from(value: *mut sys::cl_fmap_t) -> Result<Self, Self::Error> {
|
|
| 56 |
+ if value.is_null() {
|
|
| 57 |
+ return Err(Error::Null); |
|
| 58 |
+ } |
|
| 59 |
+ |
|
| 60 |
+ Ok(FMap { fmap_ptr: value })
|
|
| 61 |
+ } |
|
| 62 |
+} |
|
| 63 |
+ |
|
| 64 |
+impl<'a> FMap {
|
|
| 65 |
+ /// Simple wrapper around C FMAP module's fmap.need() method. |
|
| 66 |
+ pub fn need_off(&'a self, at: usize, len: usize) -> Result<&'a [u8], Error> {
|
|
| 67 |
+ // Get the need() method function pointer from the fmap. |
|
| 68 |
+ let need_fn = match unsafe { *self.fmap_ptr }.need {
|
|
| 69 |
+ Some(ptr) => ptr, |
|
| 70 |
+ None => return Err(Error::UninitializedPtr("need()")),
|
|
| 71 |
+ }; |
|
| 72 |
+ |
|
| 73 |
+ let ptr: *const u8 = unsafe { need_fn(self.fmap_ptr, at, len, 1) } as *const u8;
|
|
| 74 |
+ |
|
| 75 |
+ if ptr.is_null() {
|
|
| 76 |
+ let fmap_size = unsafe { *self.fmap_ptr }.len;
|
|
| 77 |
+ debug!( |
|
| 78 |
+ "need_off at {:?} len {:?} for fmap size {:?} returned NULL",
|
|
| 79 |
+ at, len, fmap_size |
|
| 80 |
+ ); |
|
| 81 |
+ return Err(Error::NotContained(at, len, fmap_size)); |
|
| 82 |
+ } |
|
| 83 |
+ |
|
| 84 |
+ let slice: &[u8] = unsafe { std::slice::from_raw_parts(ptr, len) };
|
|
| 85 |
+ |
|
| 86 |
+ Ok(slice) |
|
| 87 |
+ } |
|
| 88 |
+ |
|
| 89 |
+ pub fn len(&self) -> usize {
|
|
| 90 |
+ unsafe { (*self.fmap_ptr).len }
|
|
| 91 |
+ } |
|
| 92 |
+ |
|
| 93 |
+ pub fn is_empty(&self) -> bool {
|
|
| 94 |
+ unsafe { (*self.fmap_ptr).len == 0 }
|
|
| 95 |
+ } |
|
| 96 |
+ |
|
| 97 |
+ pub fn name(&self) -> &'static str {
|
|
| 98 |
+ unsafe {
|
|
| 99 |
+ str_from_ptr((*self.fmap_ptr).name) |
|
| 100 |
+ .unwrap_or(Some("<invalid-utf8>"))
|
|
| 101 |
+ .unwrap_or("<unnamed>")
|
|
| 102 |
+ } |
|
| 103 |
+ } |
|
| 104 |
+} |
| ... | ... |
@@ -34,14 +34,13 @@ use image::{imageops::FilterType::Lanczos3, DynamicImage, ImageBuffer, Luma, Pix
|
| 34 | 34 |
use log::{debug, error, warn};
|
| 35 | 35 |
use num_traits::{NumCast, ToPrimitive, Zero};
|
| 36 | 36 |
use rustdct::DctPlanner; |
| 37 |
-use thiserror::Error; |
|
| 38 | 37 |
use transpose::transpose; |
| 39 | 38 |
|
| 40 | 39 |
use crate::{ffi_error, ffi_util::FFIError, rrf_call, sys, validate_str_param};
|
| 41 | 40 |
|
| 42 |
-/// CdiffError enumerates all possible errors returned by this library. |
|
| 43 |
-#[derive(Error, Debug)] |
|
| 44 |
-pub enum FuzzyHashError {
|
|
| 41 |
+/// Error enumerates all possible errors returned by this library. |
|
| 42 |
+#[derive(thiserror::Error, Debug)] |
|
| 43 |
+pub enum Error {
|
|
| 45 | 44 |
#[error("Invalid format")]
|
| 46 | 45 |
Format, |
| 47 | 46 |
|
| ... | ... |
@@ -68,6 +67,9 @@ pub enum FuzzyHashError {
|
| 68 | 68 |
|
| 69 | 69 |
#[error("{0} parmeter is NULL")]
|
| 70 | 70 |
NullParam(&'static str), |
| 71 |
+ |
|
| 72 |
+ #[error("{0} hash must be {1} characters in length")]
|
|
| 73 |
+ InvalidHashLength(&'static str, usize), |
|
| 71 | 74 |
} |
| 72 | 75 |
|
| 73 | 76 |
#[derive(PartialEq, Eq, Hash, Debug)] |
| ... | ... |
@@ -81,18 +83,18 @@ pub enum FuzzyHash {
|
| 81 | 81 |
} |
| 82 | 82 |
|
| 83 | 83 |
impl TryFrom<&str> for ImageFuzzyHash {
|
| 84 |
- type Error = &'static str; |
|
| 84 |
+ type Error = Error; |
|
| 85 | 85 |
|
| 86 | 86 |
fn try_from(value: &str) -> Result<Self, Self::Error> {
|
| 87 | 87 |
if value.len() != 16 {
|
| 88 |
- return Err("Image fuzzy hash must be 16 characters in length");
|
|
| 88 |
+ return Err(Error::InvalidHashLength("ImageFuzzyHash", 16));
|
|
| 89 | 89 |
} |
| 90 | 90 |
|
| 91 | 91 |
let mut hashbytes = [0; 8]; |
| 92 | 92 |
if hex::decode_to_slice(value, &mut hashbytes).is_ok() {
|
| 93 | 93 |
Ok(ImageFuzzyHash { bytes: hashbytes })
|
| 94 | 94 |
} else {
|
| 95 |
- Err("Failed to decode image fuzzy hash bytes from hex to bytes")
|
|
| 95 |
+ Err(Error::FormatHashBytes(value.to_string())) |
|
| 96 | 96 |
} |
| 97 | 97 |
} |
| 98 | 98 |
} |
| ... | ... |
@@ -205,11 +207,11 @@ pub unsafe extern "C" fn _fuzzy_hash_calculate_image( |
| 205 | 205 |
err: *mut *mut FFIError, |
| 206 | 206 |
) -> bool {
|
| 207 | 207 |
if hash_out.is_null() {
|
| 208 |
- return ffi_error!(err = err, FuzzyHashError::NullParam("hash_out"));
|
|
| 208 |
+ return ffi_error!(err = err, Error::NullParam("hash_out"));
|
|
| 209 | 209 |
} |
| 210 | 210 |
|
| 211 | 211 |
let buffer = if file_bytes.is_null() {
|
| 212 |
- return ffi_error!(err = err, FuzzyHashError::NullParam("file_bytes"));
|
|
| 212 |
+ return ffi_error!(err = err, Error::NullParam("file_bytes"));
|
|
| 213 | 213 |
} else {
|
| 214 | 214 |
slice::from_raw_parts(file_bytes, file_size) |
| 215 | 215 |
}; |
| ... | ... |
@@ -223,7 +225,7 @@ pub unsafe extern "C" fn _fuzzy_hash_calculate_image( |
| 223 | 223 |
if hash_out_len < hash_bytes.len() {
|
| 224 | 224 |
return ffi_error!( |
| 225 | 225 |
err = err, |
| 226 |
- FuzzyHashError::InvalidParameter(format!( |
|
| 226 |
+ Error::InvalidParameter(format!( |
|
| 227 | 227 |
"hash_bytes output parameter too small to hold the hash: {} < {}",
|
| 228 | 228 |
hash_out_len, |
| 229 | 229 |
hash_bytes.len() |
| ... | ... |
@@ -257,24 +259,24 @@ impl FuzzyHashMap {
|
| 257 | 257 |
hexsig: &str, |
| 258 | 258 |
lsig_id: u32, |
| 259 | 259 |
subsig_id: u32, |
| 260 |
- ) -> Result<(), FuzzyHashError> {
|
|
| 260 |
+ ) -> Result<(), Error> {
|
|
| 261 | 261 |
let mut hexsig_split = hexsig.split('#');
|
| 262 | 262 |
|
| 263 | 263 |
let algorithm = match hexsig_split.next() {
|
| 264 | 264 |
Some(x) => x, |
| 265 |
- None => return Err(FuzzyHashError::Format), |
|
| 265 |
+ None => return Err(Error::Format), |
|
| 266 | 266 |
}; |
| 267 | 267 |
|
| 268 | 268 |
let hash = match hexsig_split.next() {
|
| 269 | 269 |
Some(x) => x, |
| 270 |
- None => return Err(FuzzyHashError::Format), |
|
| 270 |
+ None => return Err(Error::Format), |
|
| 271 | 271 |
}; |
| 272 | 272 |
|
| 273 | 273 |
let distance: u32 = match hexsig_split.next() {
|
| 274 | 274 |
Some(x) => match x.parse::<u32>() {
|
| 275 | 275 |
Ok(n) => n, |
| 276 | 276 |
Err(_) => {
|
| 277 |
- return Err(FuzzyHashError::FormatHammingDistance(x.to_string())); |
|
| 277 |
+ return Err(Error::FormatHammingDistance(x.to_string())); |
|
| 278 | 278 |
} |
| 279 | 279 |
}, |
| 280 | 280 |
None => 0, |
| ... | ... |
@@ -285,7 +287,7 @@ impl FuzzyHashMap {
|
| 285 | 285 |
error!( |
| 286 | 286 |
"Non-zero hamming distances for image fuzzy hashes are not supported in this version." |
| 287 | 287 |
); |
| 288 |
- return Err(FuzzyHashError::InvalidHammingDistance(distance)); |
|
| 288 |
+ return Err(Error::InvalidHammingDistance(distance)); |
|
| 289 | 289 |
} |
| 290 | 290 |
|
| 291 | 291 |
match algorithm {
|
| ... | ... |
@@ -293,7 +295,7 @@ impl FuzzyHashMap {
|
| 293 | 293 |
// Convert the hash string to an image fuzzy hash bytes struct |
| 294 | 294 |
let image_fuzzy_hash = hash |
| 295 | 295 |
.try_into() |
| 296 |
- .map_err(|e| FuzzyHashError::FormatHashBytes(format!("{}: {}", e, hash)))?;
|
|
| 296 |
+ .map_err(|e| Error::FormatHashBytes(format!("{}: {}", e, hash)))?;
|
|
| 297 | 297 |
|
| 298 | 298 |
let fuzzy_hash = FuzzyHash::Image(image_fuzzy_hash); |
| 299 | 299 |
|
| ... | ... |
@@ -308,14 +310,14 @@ impl FuzzyHashMap {
|
| 308 | 308 |
// Then add the current meta struct to the entry. |
| 309 | 309 |
self.hashmap |
| 310 | 310 |
.entry(fuzzy_hash) |
| 311 |
- .or_insert_with(Vec::new) |
|
| 311 |
+ .or_default() |
|
| 312 | 312 |
.push(meta); |
| 313 | 313 |
|
| 314 | 314 |
Ok(()) |
| 315 | 315 |
} |
| 316 | 316 |
_ => {
|
| 317 | 317 |
error!("Unknown fuzzy hash algorithm: {}", algorithm);
|
| 318 |
- Err(FuzzyHashError::UnknownAlgorithm(algorithm.to_string())) |
|
| 318 |
+ Err(Error::UnknownAlgorithm(algorithm.to_string())) |
|
| 319 | 319 |
} |
| 320 | 320 |
} |
| 321 | 321 |
} |
| ... | ... |
@@ -412,17 +414,17 @@ impl FuzzyHashMap {
|
| 412 | 412 |
/// |
| 413 | 413 |
/// param: hash_out is an output variable |
| 414 | 414 |
/// param: hash_out_len indicates the size of the hash_out buffer |
| 415 |
-pub fn fuzzy_hash_calculate_image(buffer: &[u8]) -> Result<Vec<u8>, FuzzyHashError> {
|
|
| 415 |
+pub fn fuzzy_hash_calculate_image(buffer: &[u8]) -> Result<Vec<u8>, Error> {
|
|
| 416 | 416 |
|
| 417 | 417 |
// Load image and attempt to catch panics in case the decoders encounter unexpected issues |
| 418 |
- let result = panic::catch_unwind(|| -> Result<DynamicImage, FuzzyHashError> {
|
|
| 419 |
- let image = image::load_from_memory(buffer).map_err(FuzzyHashError::ImageLoad)?; |
|
| 418 |
+ let result = panic::catch_unwind(|| -> Result<DynamicImage, Error> {
|
|
| 419 |
+ let image = image::load_from_memory(buffer).map_err(Error::ImageLoad)?; |
|
| 420 | 420 |
Ok(image) |
| 421 | 421 |
}); |
| 422 | 422 |
|
| 423 | 423 |
let og_image = match result {
|
| 424 | 424 |
Ok(image) => image?, |
| 425 |
- Err(_) => return Err(FuzzyHashError::ImageLoadPanic()), |
|
| 425 |
+ Err(_) => return Err(Error::ImageLoadPanic()), |
|
| 426 | 426 |
}; |
| 427 | 427 |
|
| 428 | 428 |
// Drop the alpha channel (if exists). |
| ... | ... |
@@ -24,9 +24,13 @@ |
| 24 | 24 |
pub mod sys; |
| 25 | 25 |
|
| 26 | 26 |
pub mod cdiff; |
| 27 |
+pub mod css_image_extract; |
|
| 28 |
+pub mod ctx; |
|
| 27 | 29 |
pub mod evidence; |
| 28 | 30 |
pub mod ffi_util; |
| 31 |
+pub mod fmap; |
|
| 29 | 32 |
pub mod fuzzy_hash; |
| 30 | 33 |
pub mod logging; |
| 34 |
+pub mod onenote; |
|
| 35 |
+pub mod scanners; |
|
| 31 | 36 |
pub mod util; |
| 32 |
-pub mod css_image_extract; |
| 33 | 37 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,285 @@ |
| 0 |
+/* |
|
| 1 |
+ * Onenote document parser to extract embedded files. |
|
| 2 |
+ * |
|
| 3 |
+ * Copyright (C) 2023 Cisco Systems, Inc. and/or its affiliates. All rights reserved. |
|
| 4 |
+ * |
|
| 5 |
+ * Authors: Micah Snyder |
|
| 6 |
+ * |
|
| 7 |
+ * This program is free software; you can redistribute it and/or modify |
|
| 8 |
+ * it under the terms of the GNU General Public License version 2 as |
|
| 9 |
+ * published by the Free Software Foundation. |
|
| 10 |
+ * |
|
| 11 |
+ * This program is distributed in the hope that it will be useful, |
|
| 12 |
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
| 13 |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
| 14 |
+ * GNU General Public License for more details. |
|
| 15 |
+ * |
|
| 16 |
+ * You should have received a copy of the GNU General Public License |
|
| 17 |
+ * along with this program; if not, write to the Free Software |
|
| 18 |
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, |
|
| 19 |
+ * MA 02110-1301, USA. |
|
| 20 |
+ */ |
|
| 21 |
+ |
|
| 22 |
+use std::{
|
|
| 23 |
+ convert::TryInto, |
|
| 24 |
+ mem, panic, |
|
| 25 |
+ path::{Path, PathBuf},
|
|
| 26 |
+}; |
|
| 27 |
+ |
|
| 28 |
+use hex_literal::hex; |
|
| 29 |
+use log::{debug, error};
|
|
| 30 |
+use onenote_parser; |
|
| 31 |
+ |
|
| 32 |
+/// Error enumerates all possible errors returned by this library. |
|
| 33 |
+#[derive(thiserror::Error, Debug)] |
|
| 34 |
+pub enum Error {
|
|
| 35 |
+ #[error("Invalid format")]
|
|
| 36 |
+ Format, |
|
| 37 |
+ |
|
| 38 |
+ #[error("Invalid parameter: {0}")]
|
|
| 39 |
+ InvalidParameter(String), |
|
| 40 |
+ |
|
| 41 |
+ #[error("Failed to open file: {0}, {1}")]
|
|
| 42 |
+ FailedToOpen(PathBuf, String), |
|
| 43 |
+ |
|
| 44 |
+ #[error("Failed to get size for file: {0}")]
|
|
| 45 |
+ FailedToGetFileSize(PathBuf), |
|
| 46 |
+ |
|
| 47 |
+ #[error("{0} parameter is NULL")]
|
|
| 48 |
+ NullParam(&'static str), |
|
| 49 |
+ |
|
| 50 |
+ #[error("No more files to extract")]
|
|
| 51 |
+ NoMoreFiles, |
|
| 52 |
+ |
|
| 53 |
+ #[error("Unable to parse OneNote file")]
|
|
| 54 |
+ Parse, |
|
| 55 |
+ |
|
| 56 |
+ #[error("Failed to parse OneNote file due to a panic in the onenote_parser library")]
|
|
| 57 |
+ OneNoteParserPanic, |
|
| 58 |
+} |
|
| 59 |
+ |
|
| 60 |
+fn find_bytes(haystack: &[u8], needle: &[u8]) -> Option<usize> {
|
|
| 61 |
+ haystack |
|
| 62 |
+ .windows(needle.len()) |
|
| 63 |
+ .position(|window| window == needle) |
|
| 64 |
+} |
|
| 65 |
+ |
|
| 66 |
+/// Struct representing a file extracted from a OneNote document. |
|
| 67 |
+/// This has the option of providing a file name, if one was found when extracting the file. |
|
| 68 |
+pub struct ExtractedFile {
|
|
| 69 |
+ pub name: Option<String>, |
|
| 70 |
+ pub data: Vec<u8>, |
|
| 71 |
+} |
|
| 72 |
+ |
|
| 73 |
+/// Struct used for a file handle for our OneNote parser. |
|
| 74 |
+/// This struct is used to keep track of state for our iterator to work through the document extracting each file. |
|
| 75 |
+/// There are three different ways we keep track of state depending on the file format and the way in which the file was opened. |
|
| 76 |
+#[derive(Default)] |
|
| 77 |
+pub struct OneNote<'a> {
|
|
| 78 |
+ embedded_files: Vec<ExtractedFile>, |
|
| 79 |
+ remaining_vec: Option<Vec<u8>>, |
|
| 80 |
+ remaining: Option<&'a [u8]>, |
|
| 81 |
+} |
|
| 82 |
+ |
|
| 83 |
+// https://learn.microsoft.com/en-us/openspecs/office_file_formats/ms-onestore/8806fd18-6735-4874-b111-227b83eaac26 |
|
| 84 |
+#[repr(packed)] |
|
| 85 |
+#[allow(dead_code)] |
|
| 86 |
+struct FileDataHeader {
|
|
| 87 |
+ guid_header: [u8; 16], |
|
| 88 |
+ cb_length: u64, |
|
| 89 |
+ unused: u32, |
|
| 90 |
+ reserved: u64, |
|
| 91 |
+} |
|
| 92 |
+const SIZE_OF_FILE_DATA_HEADER: usize = mem::size_of::<FileDataHeader>(); |
|
| 93 |
+ |
|
| 94 |
+// Hex sequence identifying the start of a file data store object. |
|
| 95 |
+const FILE_DATA_STORE_OBJECT: &[u8] = &hex!("e716e3bd65261145a4c48d4d0b7a9eac");
|
|
| 96 |
+ |
|
| 97 |
+// Hex sequence identifying the start of a OneNote file. |
|
| 98 |
+const ONE_MAGIC: &[u8] = &hex!("e4525c7b8cd8a74daeb15378d02996d3");
|
|
| 99 |
+ |
|
| 100 |
+impl<'a> OneNote<'a> {
|
|
| 101 |
+ /// Open a OneNote document given a slice bytes. |
|
| 102 |
+ pub fn from_bytes(data: &'a [u8], filename: &Path) -> Result<OneNote<'a>, Error> {
|
|
| 103 |
+ debug!( |
|
| 104 |
+ "Inspecting OneNote file for attachments from in-memory buffer of size {}-bytes named {}\n",
|
|
| 105 |
+ data.len(), filename.to_string_lossy() |
|
| 106 |
+ ); |
|
| 107 |
+ |
|
| 108 |
+ fn parse_section_buffer(data: &[u8], filename: &Path) -> Result<Vec<ExtractedFile>, Error> {
|
|
| 109 |
+ let mut embedded_files: Vec<ExtractedFile> = vec![]; |
|
| 110 |
+ let mut parser = onenote_parser::Parser::new(); |
|
| 111 |
+ |
|
| 112 |
+ if let Ok(section) = parser.parse_section_buffer(data, filename) {
|
|
| 113 |
+ // file appears to be OneStore 2.8 `.one` file. |
|
| 114 |
+ section.page_series().iter().for_each(|page_series| {
|
|
| 115 |
+ page_series.pages().iter().for_each(|page| {
|
|
| 116 |
+ page.contents().iter().for_each(|page_content| {
|
|
| 117 |
+ if let Some(page_outline) = page_content.outline() {
|
|
| 118 |
+ page_outline.items().iter().for_each(|outline_item| {
|
|
| 119 |
+ outline_item.element().iter().for_each(|&outline_element| {
|
|
| 120 |
+ outline_element.contents().iter().for_each(|content| {
|
|
| 121 |
+ if let Some(embedded_file) = content.embedded_file() {
|
|
| 122 |
+ let data = embedded_file.data(); |
|
| 123 |
+ let name = embedded_file.filename(); |
|
| 124 |
+ |
|
| 125 |
+ // If name is empty, set to None. |
|
| 126 |
+ let name = if name.is_empty() {
|
|
| 127 |
+ debug!("Found unnamed attached file of size {}-bytes", data.len());
|
|
| 128 |
+ None |
|
| 129 |
+ } else {
|
|
| 130 |
+ debug!("Found attached file '{}' of size {}-bytes", name, data.len());
|
|
| 131 |
+ Some(name.to_string()) |
|
| 132 |
+ }; |
|
| 133 |
+ |
|
| 134 |
+ embedded_files.push(ExtractedFile {
|
|
| 135 |
+ name, |
|
| 136 |
+ data: data.to_vec(), |
|
| 137 |
+ }); |
|
| 138 |
+ } |
|
| 139 |
+ }); |
|
| 140 |
+ }); |
|
| 141 |
+ }); |
|
| 142 |
+ } |
|
| 143 |
+ }); |
|
| 144 |
+ }); |
|
| 145 |
+ }); |
|
| 146 |
+ } else {
|
|
| 147 |
+ return Err(Error::Parse); |
|
| 148 |
+ } |
|
| 149 |
+ |
|
| 150 |
+ Ok(embedded_files) |
|
| 151 |
+ } |
|
| 152 |
+ |
|
| 153 |
+ // Try to parse the section buffer using the onenote_parser crate. |
|
| 154 |
+ // Attempt to catch panics in case the parser encounter unexpected issues. |
|
| 155 |
+ let result_result = panic::catch_unwind(|| -> Result<Vec<ExtractedFile>, Error> {
|
|
| 156 |
+ parse_section_buffer(data, filename) |
|
| 157 |
+ }); |
|
| 158 |
+ |
|
| 159 |
+ // Check if it panicked. If no panic, grab the parse result. |
|
| 160 |
+ let result = result_result.map_err(|_| Error::OneNoteParserPanic)?; |
|
| 161 |
+ |
|
| 162 |
+ if let Ok(embedded_files) = result {
|
|
| 163 |
+ // Successfully parsed the OneNote file with the onenote_parser crate. |
|
| 164 |
+ Ok(OneNote {
|
|
| 165 |
+ embedded_files, |
|
| 166 |
+ ..Default::default() |
|
| 167 |
+ }) |
|
| 168 |
+ } else {
|
|
| 169 |
+ debug!("Unable to parse OneNote file with onenote_parser crate. Trying a different method known to work with older office 2010 OneNote files to extract attachments.");
|
|
| 170 |
+ |
|
| 171 |
+ let embedded_files: Vec<ExtractedFile> = vec![]; |
|
| 172 |
+ |
|
| 173 |
+ // Verify that the OneNote document file magic is correct. |
|
| 174 |
+ // We don't check this for the onenote_parser crate because it does this for us, and may add support for newer OneNote file formats in the future. |
|
| 175 |
+ let file_magic = data.get(0..16).ok_or(Error::Format)?; |
|
| 176 |
+ if file_magic != ONE_MAGIC {
|
|
| 177 |
+ return Err(Error::Format); |
|
| 178 |
+ } |
|
| 179 |
+ |
|
| 180 |
+ Ok(OneNote {
|
|
| 181 |
+ embedded_files, |
|
| 182 |
+ remaining: Some(data), |
|
| 183 |
+ ..Default::default() |
|
| 184 |
+ }) |
|
| 185 |
+ } |
|
| 186 |
+ } |
|
| 187 |
+ |
|
| 188 |
+ /// Open a OneNote document given the document was provided as a slice of bytes. |
|
| 189 |
+ pub fn next_file(&mut self) -> Option<ExtractedFile> {
|
|
| 190 |
+ debug!("Looking to extract file from OneNote section...");
|
|
| 191 |
+ |
|
| 192 |
+ let mut file_data: Option<Vec<u8>> = None; |
|
| 193 |
+ |
|
| 194 |
+ let remaining = if let Some(remaining_in) = self.remaining {
|
|
| 195 |
+ let remaining = if let Some(pos) = find_bytes(remaining_in, FILE_DATA_STORE_OBJECT) {
|
|
| 196 |
+ let (_, remaining) = remaining_in.split_at(pos); |
|
| 197 |
+ // Found file data store object. |
|
| 198 |
+ remaining |
|
| 199 |
+ } else {
|
|
| 200 |
+ return None; |
|
| 201 |
+ }; |
|
| 202 |
+ |
|
| 203 |
+ let data_length = if let Some(x) = remaining.get(16..20) {
|
|
| 204 |
+ u32::from_le_bytes(x.try_into().unwrap()) as u64 |
|
| 205 |
+ } else {
|
|
| 206 |
+ return None; |
|
| 207 |
+ }; |
|
| 208 |
+ |
|
| 209 |
+ let data: &[u8] = remaining |
|
| 210 |
+ .get(SIZE_OF_FILE_DATA_HEADER..SIZE_OF_FILE_DATA_HEADER + data_length as usize)?; |
|
| 211 |
+ |
|
| 212 |
+ file_data = Some(data.to_vec()); |
|
| 213 |
+ |
|
| 214 |
+ Some(&remaining[SIZE_OF_FILE_DATA_HEADER + (data_length as usize)..remaining.len()]) |
|
| 215 |
+ } else {
|
|
| 216 |
+ None |
|
| 217 |
+ }; |
|
| 218 |
+ |
|
| 219 |
+ self.remaining = remaining; |
|
| 220 |
+ |
|
| 221 |
+ file_data.map(|data| ExtractedFile { data, name: None })
|
|
| 222 |
+ } |
|
| 223 |
+ |
|
| 224 |
+ /// Get the next file from the OneNote document using the method required for when we've read the file into a Vec. |
|
| 225 |
+ pub fn next_file_vec(&mut self) -> Option<ExtractedFile> {
|
|
| 226 |
+ debug!("Looking to extract file from OneNote section...");
|
|
| 227 |
+ |
|
| 228 |
+ let mut file_data: Option<Vec<u8>> = None; |
|
| 229 |
+ |
|
| 230 |
+ self.remaining_vec = if let Some(ref remaining_vec) = self.remaining_vec {
|
|
| 231 |
+ let remaining = if let Some(pos) = find_bytes(remaining_vec, FILE_DATA_STORE_OBJECT) {
|
|
| 232 |
+ let (_, remaining) = remaining_vec.split_at(pos); |
|
| 233 |
+ // Found file data store object. |
|
| 234 |
+ remaining |
|
| 235 |
+ } else {
|
|
| 236 |
+ return None; |
|
| 237 |
+ }; |
|
| 238 |
+ |
|
| 239 |
+ let data_length = if let Some(x) = remaining.get(16..20) {
|
|
| 240 |
+ u32::from_le_bytes(x.try_into().unwrap()) as u64 |
|
| 241 |
+ } else {
|
|
| 242 |
+ return None; |
|
| 243 |
+ }; |
|
| 244 |
+ |
|
| 245 |
+ let data: &[u8] = remaining |
|
| 246 |
+ .get(SIZE_OF_FILE_DATA_HEADER..SIZE_OF_FILE_DATA_HEADER + data_length as usize)?; |
|
| 247 |
+ |
|
| 248 |
+ file_data = Some(data.to_vec()); |
|
| 249 |
+ |
|
| 250 |
+ Some(Vec::from( |
|
| 251 |
+ &remaining[SIZE_OF_FILE_DATA_HEADER + (data_length as usize)..remaining.len()], |
|
| 252 |
+ )) |
|
| 253 |
+ } else {
|
|
| 254 |
+ None |
|
| 255 |
+ }; |
|
| 256 |
+ |
|
| 257 |
+ file_data.map(|data| ExtractedFile { data, name: None })
|
|
| 258 |
+ } |
|
| 259 |
+ |
|
| 260 |
+ /// Get the next file from the OneNote document using the method required for the onenote_parser crate. |
|
| 261 |
+ pub fn next_file_parser(&mut self) -> Option<ExtractedFile> {
|
|
| 262 |
+ self.embedded_files.pop() |
|
| 263 |
+ } |
|
| 264 |
+} |
|
| 265 |
+ |
|
| 266 |
+impl<'a> Iterator for OneNote<'a> {
|
|
| 267 |
+ type Item = ExtractedFile; |
|
| 268 |
+ |
|
| 269 |
+ fn next(&mut self) -> Option<ExtractedFile> {
|
|
| 270 |
+ // Find the next embedded file |
|
| 271 |
+ if self.remaining.is_some() {
|
|
| 272 |
+ // Data stored in a slice. |
|
| 273 |
+ self.next_file() |
|
| 274 |
+ } else if self.remaining_vec.is_some() {
|
|
| 275 |
+ // Data stored in a Vec. |
|
| 276 |
+ self.next_file_vec() |
|
| 277 |
+ } else if !self.embedded_files.is_empty() {
|
|
| 278 |
+ // Data stored in a Vec. |
|
| 279 |
+ self.next_file_parser() |
|
| 280 |
+ } else {
|
|
| 281 |
+ None |
|
| 282 |
+ } |
|
| 283 |
+ } |
|
| 284 |
+} |
| 0 | 285 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,129 @@ |
| 0 |
+/* |
|
| 1 |
+ * Rust equivalent of libclamav's scanners.c module |
|
| 2 |
+ * |
|
| 3 |
+ * Copyright (C) 2023 Cisco Systems, Inc. and/or its affiliates. All rights reserved. |
|
| 4 |
+ * |
|
| 5 |
+ * Authors: Micah Snyder |
|
| 6 |
+ * |
|
| 7 |
+ * This program is free software; you can redistribute it and/or modify |
|
| 8 |
+ * it under the terms of the GNU General Public License version 2 as |
|
| 9 |
+ * published by the Free Software Foundation. |
|
| 10 |
+ * |
|
| 11 |
+ * This program is distributed in the hope that it will be useful, |
|
| 12 |
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
| 13 |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
| 14 |
+ * GNU General Public License for more details. |
|
| 15 |
+ * |
|
| 16 |
+ * You should have received a copy of the GNU General Public License |
|
| 17 |
+ * along with this program; if not, write to the Free Software |
|
| 18 |
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, |
|
| 19 |
+ * MA 02110-1301, USA. |
|
| 20 |
+ */ |
|
| 21 |
+ |
|
| 22 |
+use std::{
|
|
| 23 |
+ ffi::{c_char, CString},
|
|
| 24 |
+ path::Path, |
|
| 25 |
+ ptr::null_mut, |
|
| 26 |
+}; |
|
| 27 |
+ |
|
| 28 |
+use libc::c_void; |
|
| 29 |
+use log::{debug, error, warn};
|
|
| 30 |
+ |
|
| 31 |
+use crate::{
|
|
| 32 |
+ ctx, |
|
| 33 |
+ onenote::OneNote, |
|
| 34 |
+ sys::{cl_error_t, cl_error_t_CL_ERROR, cl_error_t_CL_SUCCESS, cli_ctx, cli_magic_scan_buff},
|
|
| 35 |
+}; |
|
| 36 |
+ |
|
| 37 |
+/// Rust wrapper of libclamav's cli_magic_scan_buff() function. |
|
| 38 |
+/// Use magic sigs to identify the file type and then scan it. |
|
| 39 |
+fn magic_scan(ctx: *mut cli_ctx, buf: &[u8], name: Option<String>) -> cl_error_t {
|
|
| 40 |
+ let ptr = buf.as_ptr(); |
|
| 41 |
+ let len = buf.len(); |
|
| 42 |
+ |
|
| 43 |
+ match &name {
|
|
| 44 |
+ Some(name) => debug!("Scanning {}-byte file named {}.", len, name),
|
|
| 45 |
+ None => debug!("Scanning {}-byte unnamed file.", len),
|
|
| 46 |
+ } |
|
| 47 |
+ |
|
| 48 |
+ // Convert name to a C string. |
|
| 49 |
+ let name = match name {
|
|
| 50 |
+ Some(name) => name, |
|
| 51 |
+ None => String::from(""),
|
|
| 52 |
+ }; |
|
| 53 |
+ |
|
| 54 |
+ let name_ptr: *mut c_char = match CString::new(name) {
|
|
| 55 |
+ Ok(name_cstr) => {
|
|
| 56 |
+ // into_raw() so name_cstr doesn't get dropped and |
|
| 57 |
+ // we don't do an unsafe deref of the pointer. |
|
| 58 |
+ name_cstr.into_raw() |
|
| 59 |
+ } |
|
| 60 |
+ Err(_) => null_mut(), |
|
| 61 |
+ }; |
|
| 62 |
+ |
|
| 63 |
+ let ret = unsafe { cli_magic_scan_buff(ptr as *const c_void, len, ctx, name_ptr, 0) };
|
|
| 64 |
+ |
|
| 65 |
+ if ret != cl_error_t_CL_SUCCESS {
|
|
| 66 |
+ debug!("cli_magic_scan_buff returned error: {}", ret);
|
|
| 67 |
+ } |
|
| 68 |
+ |
|
| 69 |
+ // Okay now safe to drop the name CString. |
|
| 70 |
+ let _ = unsafe { CString::from_raw(name_ptr) };
|
|
| 71 |
+ |
|
| 72 |
+ ret |
|
| 73 |
+} |
|
| 74 |
+ |
|
| 75 |
+/// Scan a OneNote file for attachments |
|
| 76 |
+/// |
|
| 77 |
+/// # Safety |
|
| 78 |
+/// |
|
| 79 |
+/// Must be a valid ctx pointer. |
|
| 80 |
+#[no_mangle] |
|
| 81 |
+pub unsafe extern "C" fn scan_onenote(ctx: *mut cli_ctx) -> cl_error_t {
|
|
| 82 |
+ let fmap = match ctx::current_fmap(ctx) {
|
|
| 83 |
+ Ok(fmap) => fmap, |
|
| 84 |
+ Err(e) => {
|
|
| 85 |
+ warn!("Error getting FMap from ctx: {e}");
|
|
| 86 |
+ return cl_error_t_CL_ERROR; |
|
| 87 |
+ } |
|
| 88 |
+ }; |
|
| 89 |
+ |
|
| 90 |
+ let file_bytes = match fmap.need_off(0, fmap.len()) {
|
|
| 91 |
+ Ok(bytes) => bytes, |
|
| 92 |
+ Err(err) => {
|
|
| 93 |
+ error!( |
|
| 94 |
+ "Failed to get file bytes for fmap of size {}: {err}",
|
|
| 95 |
+ fmap.len() |
|
| 96 |
+ ); |
|
| 97 |
+ return cl_error_t_CL_ERROR; |
|
| 98 |
+ } |
|
| 99 |
+ }; |
|
| 100 |
+ |
|
| 101 |
+ let one = match OneNote::from_bytes(file_bytes, Path::new(fmap.name())) {
|
|
| 102 |
+ Ok(x) => x, |
|
| 103 |
+ Err(err) => {
|
|
| 104 |
+ error!("Failed to parse OneNote file: {}", err.to_string());
|
|
| 105 |
+ return cl_error_t_CL_ERROR; |
|
| 106 |
+ } |
|
| 107 |
+ }; |
|
| 108 |
+ |
|
| 109 |
+ let mut scan_result = cl_error_t_CL_SUCCESS; |
|
| 110 |
+ |
|
| 111 |
+ one.into_iter().all(|attachment| {
|
|
| 112 |
+ debug!( |
|
| 113 |
+ "Extracted {}-byte attachment with name: {:?}",
|
|
| 114 |
+ attachment.data.len(), |
|
| 115 |
+ attachment.name |
|
| 116 |
+ ); |
|
| 117 |
+ |
|
| 118 |
+ let ret = magic_scan(ctx, &attachment.data, attachment.name); |
|
| 119 |
+ if ret != cl_error_t_CL_SUCCESS {
|
|
| 120 |
+ scan_result = ret; |
|
| 121 |
+ return false; |
|
| 122 |
+ } |
|
| 123 |
+ |
|
| 124 |
+ true |
|
| 125 |
+ }); |
|
| 126 |
+ |
|
| 127 |
+ scan_result |
|
| 128 |
+} |
| ... | ... |
@@ -375,34 +375,36 @@ pub const cli_file_CL_TYPE_HWP3: cli_file = 550; |
| 375 | 375 |
pub const cli_file_CL_TYPE_OOXML_HWP: cli_file = 551; |
| 376 | 376 |
pub const cli_file_CL_TYPE_PS: cli_file = 552; |
| 377 | 377 |
pub const cli_file_CL_TYPE_EGG: cli_file = 553; |
| 378 |
-pub const cli_file_CL_TYPE_PART_ANY: cli_file = 554; |
|
| 379 |
-pub const cli_file_CL_TYPE_PART_HFSPLUS: cli_file = 555; |
|
| 380 |
-pub const cli_file_CL_TYPE_MBR: cli_file = 556; |
|
| 381 |
-pub const cli_file_CL_TYPE_HTML: cli_file = 557; |
|
| 382 |
-pub const cli_file_CL_TYPE_MAIL: cli_file = 558; |
|
| 383 |
-pub const cli_file_CL_TYPE_SFX: cli_file = 559; |
|
| 384 |
-pub const cli_file_CL_TYPE_ZIPSFX: cli_file = 560; |
|
| 385 |
-pub const cli_file_CL_TYPE_RARSFX: cli_file = 561; |
|
| 386 |
-pub const cli_file_CL_TYPE_7ZSFX: cli_file = 562; |
|
| 387 |
-pub const cli_file_CL_TYPE_CABSFX: cli_file = 563; |
|
| 388 |
-pub const cli_file_CL_TYPE_ARJSFX: cli_file = 564; |
|
| 389 |
-pub const cli_file_CL_TYPE_EGGSFX: cli_file = 565; |
|
| 390 |
-pub const cli_file_CL_TYPE_NULSFT: cli_file = 566; |
|
| 391 |
-pub const cli_file_CL_TYPE_AUTOIT: cli_file = 567; |
|
| 392 |
-pub const cli_file_CL_TYPE_ISHIELD_MSI: cli_file = 568; |
|
| 393 |
-pub const cli_file_CL_TYPE_ISO9660: cli_file = 569; |
|
| 394 |
-pub const cli_file_CL_TYPE_DMG: cli_file = 570; |
|
| 395 |
-pub const cli_file_CL_TYPE_GPT: cli_file = 571; |
|
| 396 |
-pub const cli_file_CL_TYPE_APM: cli_file = 572; |
|
| 397 |
-pub const cli_file_CL_TYPE_XDP: cli_file = 573; |
|
| 398 |
-pub const cli_file_CL_TYPE_XML_WORD: cli_file = 574; |
|
| 399 |
-pub const cli_file_CL_TYPE_XML_XL: cli_file = 575; |
|
| 400 |
-pub const cli_file_CL_TYPE_XML_HWP: cli_file = 576; |
|
| 401 |
-pub const cli_file_CL_TYPE_HWPOLE2: cli_file = 577; |
|
| 402 |
-pub const cli_file_CL_TYPE_MHTML: cli_file = 578; |
|
| 403 |
-pub const cli_file_CL_TYPE_LNK: cli_file = 579; |
|
| 404 |
-pub const cli_file_CL_TYPE_OTHER: cli_file = 580; |
|
| 405 |
-pub const cli_file_CL_TYPE_IGNORED: cli_file = 581; |
|
| 378 |
+pub const cli_file_CL_TYPE_ONENOTE: cli_file = 554; |
|
| 379 |
+pub const cli_file_CL_TYPE_PART_ANY: cli_file = 555; |
|
| 380 |
+pub const cli_file_CL_TYPE_PART_HFSPLUS: cli_file = 556; |
|
| 381 |
+pub const cli_file_CL_TYPE_MBR: cli_file = 557; |
|
| 382 |
+pub const cli_file_CL_TYPE_HTML: cli_file = 558; |
|
| 383 |
+pub const cli_file_CL_TYPE_MAIL: cli_file = 559; |
|
| 384 |
+pub const cli_file_CL_TYPE_SFX: cli_file = 560; |
|
| 385 |
+pub const cli_file_CL_TYPE_ZIPSFX: cli_file = 561; |
|
| 386 |
+pub const cli_file_CL_TYPE_RARSFX: cli_file = 562; |
|
| 387 |
+pub const cli_file_CL_TYPE_7ZSFX: cli_file = 563; |
|
| 388 |
+pub const cli_file_CL_TYPE_CABSFX: cli_file = 564; |
|
| 389 |
+pub const cli_file_CL_TYPE_ARJSFX: cli_file = 565; |
|
| 390 |
+pub const cli_file_CL_TYPE_EGGSFX: cli_file = 566; |
|
| 391 |
+pub const cli_file_CL_TYPE_NULSFT: cli_file = 567; |
|
| 392 |
+pub const cli_file_CL_TYPE_AUTOIT: cli_file = 568; |
|
| 393 |
+pub const cli_file_CL_TYPE_ISHIELD_MSI: cli_file = 569; |
|
| 394 |
+pub const cli_file_CL_TYPE_ISO9660: cli_file = 570; |
|
| 395 |
+pub const cli_file_CL_TYPE_DMG: cli_file = 571; |
|
| 396 |
+pub const cli_file_CL_TYPE_GPT: cli_file = 572; |
|
| 397 |
+pub const cli_file_CL_TYPE_APM: cli_file = 573; |
|
| 398 |
+pub const cli_file_CL_TYPE_XDP: cli_file = 574; |
|
| 399 |
+pub const cli_file_CL_TYPE_XML_WORD: cli_file = 575; |
|
| 400 |
+pub const cli_file_CL_TYPE_XML_XL: cli_file = 576; |
|
| 401 |
+pub const cli_file_CL_TYPE_XML_HWP: cli_file = 577; |
|
| 402 |
+pub const cli_file_CL_TYPE_HWPOLE2: cli_file = 578; |
|
| 403 |
+pub const cli_file_CL_TYPE_MHTML: cli_file = 579; |
|
| 404 |
+pub const cli_file_CL_TYPE_LNK: cli_file = 580; |
|
| 405 |
+pub const cli_file_CL_TYPE_UDF: cli_file = 581; |
|
| 406 |
+pub const cli_file_CL_TYPE_OTHER: cli_file = 582; |
|
| 407 |
+pub const cli_file_CL_TYPE_IGNORED: cli_file = 583; |
|
| 406 | 408 |
pub type cli_file = ::std::os::raw::c_uint; |
| 407 | 409 |
pub use self::cli_file as cli_file_t; |
| 408 | 410 |
#[repr(C)] |
| ... | ... |
@@ -612,6 +614,7 @@ pub struct recursion_level_tag {
|
| 612 | 612 |
} |
| 613 | 613 |
pub type recursion_level_t = recursion_level_tag; |
| 614 | 614 |
pub type evidence_t = *mut ::std::os::raw::c_void; |
| 615 |
+pub type onedump_t = *mut ::std::os::raw::c_void; |
|
| 615 | 616 |
#[repr(C)] |
| 616 | 617 |
#[derive(Debug, Copy, Clone)] |
| 617 | 618 |
pub struct cli_ctx_tag {
|
| ... | ... |
@@ -706,6 +709,7 @@ pub struct cl_engine {
|
| 706 | 706 |
pub tmpdir: *mut ::std::os::raw::c_char, |
| 707 | 707 |
pub keeptmp: u32, |
| 708 | 708 |
pub engine_options: u64, |
| 709 |
+ pub cache_size: u32, |
|
| 709 | 710 |
pub maxscantime: u32, |
| 710 | 711 |
pub maxscansize: u64, |
| 711 | 712 |
pub maxfilesize: u64, |
| ... | ... |
@@ -1170,6 +1174,16 @@ extern "C" {
|
| 1170 | 1170 |
} |
| 1171 | 1171 |
pub type css_image_extractor_t = *mut ::std::os::raw::c_void; |
| 1172 | 1172 |
pub type css_image_handle_t = *mut ::std::os::raw::c_void; |
| 1173 |
+extern "C" {
|
|
| 1174 |
+ #[doc = " @brief Convenience wrapper for cli_magic_scan_nested_fmap_type().\n\n Creates an fmap and calls cli_magic_scan_nested_fmap_type() for you, with type CL_TYPE_ANY.\n\n @param buffer Pointer to the buffer to be scanned.\n @param length Size in bytes of the buffer being scanned.\n @param ctx Scanning context structure.\n @param name (optional) Original name of the file (to set fmap name metadata)\n @param attributes Layer attributes of the file being scanned (is it normalized, decrypted, etc)\n @return int CL_SUCCESS, or an error code."] |
|
| 1175 |
+ pub fn cli_magic_scan_buff( |
|
| 1176 |
+ buffer: *const ::std::os::raw::c_void, |
|
| 1177 |
+ length: usize, |
|
| 1178 |
+ ctx: *mut cli_ctx, |
|
| 1179 |
+ name: *const ::std::os::raw::c_char, |
|
| 1180 |
+ attributes: u32, |
|
| 1181 |
+ ) -> cl_error_t; |
|
| 1182 |
+} |
|
| 1173 | 1183 |
#[repr(C)] |
| 1174 | 1184 |
#[derive(Debug, Copy, Clone)] |
| 1175 | 1185 |
pub struct re_guts {
|
| ... | ... |
@@ -20,7 +20,7 @@ |
| 20 | 20 |
* MA 02110-1301, USA. |
| 21 | 21 |
*/ |
| 22 | 22 |
|
| 23 |
-use std::fs::File; |
|
| 23 |
+use std::{ffi::CStr, fs::File};
|
|
| 24 | 24 |
|
| 25 | 25 |
/// Obtain a std::fs::File from an i32 in a platform-independent manner. |
| 26 | 26 |
/// |
| ... | ... |
@@ -46,3 +46,19 @@ pub fn file_from_fd_or_handle(fd: i32) -> File {
|
| 46 | 46 |
#[cfg(not(any(windows, unix)))] |
| 47 | 47 |
compile_error!("implemented only for unix and windows targets")
|
| 48 | 48 |
} |
| 49 |
+ |
|
| 50 |
+/// Get a string from a pointer |
|
| 51 |
+/// |
|
| 52 |
+/// # Safety |
|
| 53 |
+/// |
|
| 54 |
+/// The caller is responsible for making sure the lifetime of the pointer |
|
| 55 |
+/// exceeds the lifetime of the output string. |
|
| 56 |
+/// |
|
| 57 |
+/// ptr must be a valid pointer to a C string. |
|
| 58 |
+pub unsafe fn str_from_ptr(ptr: *const i8) -> Result<Option<&'static str>, std::str::Utf8Error> {
|
|
| 59 |
+ if ptr.is_null() {
|
|
| 60 |
+ return Ok(None); |
|
| 61 |
+ } |
|
| 62 |
+ |
|
| 63 |
+ Some(unsafe { CStr::from_ptr(ptr) }.to_str()).transpose()
|
|
| 64 |
+} |
| ... | ... |
@@ -82,7 +82,7 @@ class TC(testcase.TestCase): |
| 82 | 82 |
|
| 83 | 83 |
expected_stderr = [ |
| 84 | 84 |
'LibClamAV Error: Failed to load', |
| 85 |
- 'Invalid hash: Image fuzzy hash must be 16 characters in length: abcdef', |
|
| 85 |
+ 'Invalid hash: ImageFuzzyHash hash must be 16 characters in length: abcdef', |
|
| 86 | 86 |
] |
| 87 | 87 |
unexpected_stdout = [ |
| 88 | 88 |
'logo.png.bad.UNOFFICIAL FOUND', |
| ... | ... |
@@ -398,6 +398,12 @@ TCPAddr localhost |
| 398 | 398 |
# Default: yes |
| 399 | 399 |
#ScanHWP3 yes |
| 400 | 400 |
|
| 401 |
+# This option enables scanning of OneNote files. |
|
| 402 |
+# If you turn off this option, the original files will still be scanned, but |
|
| 403 |
+# without additional processing. |
|
| 404 |
+# Default: yes |
|
| 405 |
+#ScanOneNote yes |
|
| 406 |
+ |
|
| 401 | 407 |
|
| 402 | 408 |
## |
| 403 | 409 |
## Mail files |