├── .github └── workflows │ └── rust.yml ├── .gitignore ├── .idea ├── .gitignore ├── misc.xml └── vcs.xml ├── Cargo.lock ├── Cargo.toml ├── LICENSE ├── Makefile ├── README.md ├── doc ├── sightingdb-logo-32.png ├── sightingdb-logo-64.png ├── sightingdb-logo-large.png ├── sightingdb-logo2.png ├── sightingdb-logo2.svg ├── sightingdb-logo2_128.png ├── sightingdb-logo2_64.png ├── sightingdb-logo3.svg ├── sightingdb-logo3_128.png ├── sightingdb-logo3_256.png ├── sightingdb-logo3_64.png ├── sightingdb-spec.txt └── storage-future.txt ├── docker ├── Dockerfile ├── docker-compose.yml ├── sightingdb-entrypoint.sh ├── sightingdb.conf └── ssl-answers ├── etc ├── log4rs.yml └── sightingdb.conf ├── src ├── acl.rs ├── attribute.rs ├── db.rs ├── db_log.rs ├── main.rs ├── sighting_configure.rs ├── sighting_reader.rs └── sighting_writer.rs └── tests ├── everything.py └── test-post.py /.github/workflows/rust.yml: -------------------------------------------------------------------------------- 1 | name: Rust 2 | 3 | on: 4 | push: 5 | branches: [ master ] 6 | pull_request: 7 | branches: [ master ] 8 | 9 | jobs: 10 | build: 11 | 12 | runs-on: ubuntu-latest 13 | 14 | steps: 15 | - uses: actions/checkout@v2 16 | - name: Build 17 | run: cargo build --verbose 18 | - name: Run tests 19 | run: cargo test --verbose 20 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | log/ 3 | etc/ssl 4 | ssl -------------------------------------------------------------------------------- /.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /shelf/ 3 | /workspace.xml 4 | # Datasource local storage ignored files 5 | /dataSources/ 6 | /dataSources.local.xml 7 | # Editor-based HTTP Client requests 8 | /httpRequests/ 9 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | [[package]] 4 | name = "actix-codec" 5 | version = "0.1.2" 6 | source = "registry+https://github.com/rust-lang/crates.io-index" 7 | checksum = "9f2c11af4b06dc935d8e1b1491dad56bfb32febc49096a91e773f8535c176453" 8 | dependencies = [ 9 | "bytes", 10 | "futures", 11 | "log", 12 | "tokio-codec", 13 | "tokio-io", 14 | ] 15 | 16 | [[package]] 17 | name = "actix-connect" 18 | version = "0.2.5" 19 | source = "registry+https://github.com/rust-lang/crates.io-index" 20 | checksum = "9fade9bd4bb46bacde89f1e726c7a3dd230536092712f5d94d77ca57c087fca0" 21 | dependencies = [ 22 | "actix-codec", 23 | "actix-rt", 24 | "actix-service", 25 | "actix-utils", 26 | "derive_more", 27 | "either", 28 | "futures", 29 | "http", 30 | "log", 31 | "openssl", 32 | "tokio-current-thread", 33 | "tokio-openssl", 34 | "tokio-tcp", 35 | "trust-dns-resolver", 36 | ] 37 | 38 | [[package]] 39 | name = "actix-http" 40 | version = "0.2.11" 41 | source = "registry+https://github.com/rust-lang/crates.io-index" 42 | checksum = "fcb50f77cd28240d344fd54afd205bae8760a3b0ad448b1716a2aa31e24db139" 43 | dependencies = [ 44 | "actix-codec", 45 | "actix-connect", 46 | "actix-server-config", 47 | "actix-service", 48 | "actix-threadpool", 49 | "actix-utils", 50 | "base64 0.10.1", 51 | "bitflags", 52 | "brotli2", 53 | "bytes", 54 | "chrono", 55 | "copyless", 56 | "derive_more", 57 | "either", 58 | "encoding_rs", 59 | "failure", 60 | "flate2", 61 | "futures", 62 | "h2", 63 | "hashbrown 0.6.3", 64 | "http", 65 | "httparse", 66 | "indexmap", 67 | "language-tags", 68 | "lazy_static", 69 | "log", 70 | "mime", 71 | "openssl", 72 | "percent-encoding 2.1.0", 73 | "rand 0.7.3", 74 | "regex", 75 | "serde", 76 | "serde_json", 77 | "serde_urlencoded 0.6.1", 78 | "sha1", 79 | "slab", 80 | "time", 81 | "tokio-current-thread", 82 | "tokio-tcp", 83 | "tokio-timer", 84 | "trust-dns-resolver", 85 | ] 86 | 87 | [[package]] 88 | name = "actix-router" 89 | version = "0.1.5" 90 | source = "registry+https://github.com/rust-lang/crates.io-index" 91 | checksum = "23224bb527e204261d0291102cb9b52713084def67d94f7874923baefe04ccf7" 92 | dependencies = [ 93 | "bytes", 94 | "http", 95 | "log", 96 | "regex", 97 | "serde", 98 | "string", 99 | ] 100 | 101 | [[package]] 102 | name = "actix-rt" 103 | version = "0.2.6" 104 | source = "registry+https://github.com/rust-lang/crates.io-index" 105 | checksum = "88c9da1d06603d82ec2b6690fc5b80eb626cd2d6b573f3d9a71d5252e06d098e" 106 | dependencies = [ 107 | "actix-threadpool", 108 | "copyless", 109 | "futures", 110 | "tokio-current-thread", 111 | "tokio-executor", 112 | "tokio-reactor", 113 | "tokio-timer", 114 | ] 115 | 116 | [[package]] 117 | name = "actix-server" 118 | version = "0.6.1" 119 | source = "registry+https://github.com/rust-lang/crates.io-index" 120 | checksum = "dd626534af8d0a738e5f74901fe603af0445708f91b86a7d763d80df10d562a5" 121 | dependencies = [ 122 | "actix-rt", 123 | "actix-server-config", 124 | "actix-service", 125 | "futures", 126 | "log", 127 | "mio", 128 | "net2", 129 | "num_cpus", 130 | "openssl", 131 | "slab", 132 | "tokio-io", 133 | "tokio-openssl", 134 | "tokio-reactor", 135 | "tokio-signal", 136 | "tokio-tcp", 137 | "tokio-timer", 138 | ] 139 | 140 | [[package]] 141 | name = "actix-server-config" 142 | version = "0.1.2" 143 | source = "registry+https://github.com/rust-lang/crates.io-index" 144 | checksum = "483a34989c682d93142bacad6300375bb6ad8002d2e0bb249dbad86128b9ff30" 145 | dependencies = [ 146 | "futures", 147 | "tokio-io", 148 | "tokio-openssl", 149 | "tokio-tcp", 150 | ] 151 | 152 | [[package]] 153 | name = "actix-service" 154 | version = "0.4.2" 155 | source = "registry+https://github.com/rust-lang/crates.io-index" 156 | checksum = "bca5b48e928841ff7e7dce1fdb5b0d4582f6b1b976e08f4bac3f640643e0773f" 157 | dependencies = [ 158 | "futures", 159 | ] 160 | 161 | [[package]] 162 | name = "actix-testing" 163 | version = "0.1.0" 164 | source = "registry+https://github.com/rust-lang/crates.io-index" 165 | checksum = "af001e97ac6750994824d400a1b7087055aab14317aa012f528d0b2b363f37f1" 166 | dependencies = [ 167 | "actix-rt", 168 | "actix-server", 169 | "actix-server-config", 170 | "actix-service", 171 | "futures", 172 | "log", 173 | "net2", 174 | "tokio-reactor", 175 | "tokio-tcp", 176 | ] 177 | 178 | [[package]] 179 | name = "actix-threadpool" 180 | version = "0.1.2" 181 | source = "registry+https://github.com/rust-lang/crates.io-index" 182 | checksum = "6b5ae85d13da7e6fb86b1b7bc83185e0e3bd4cc5f421c887e1803796c034d35d" 183 | dependencies = [ 184 | "derive_more", 185 | "futures", 186 | "lazy_static", 187 | "log", 188 | "num_cpus", 189 | "parking_lot 0.9.0", 190 | "threadpool", 191 | ] 192 | 193 | [[package]] 194 | name = "actix-utils" 195 | version = "0.4.7" 196 | source = "registry+https://github.com/rust-lang/crates.io-index" 197 | checksum = "908c3109948f5c37a8b57fd343a37dcad5bb1d90bfd06300ac96b17bbe017b95" 198 | dependencies = [ 199 | "actix-codec", 200 | "actix-service", 201 | "bytes", 202 | "either", 203 | "futures", 204 | "log", 205 | "tokio-current-thread", 206 | "tokio-timer", 207 | ] 208 | 209 | [[package]] 210 | name = "actix-web" 211 | version = "1.0.9" 212 | source = "registry+https://github.com/rust-lang/crates.io-index" 213 | checksum = "af3a1b967cdbacb903c4b9ae71257a7f098d881b25eb483d0c468b7dac579b03" 214 | dependencies = [ 215 | "actix-codec", 216 | "actix-http", 217 | "actix-router", 218 | "actix-rt", 219 | "actix-server", 220 | "actix-server-config", 221 | "actix-service", 222 | "actix-testing", 223 | "actix-threadpool", 224 | "actix-utils", 225 | "actix-web-codegen", 226 | "awc", 227 | "bytes", 228 | "derive_more", 229 | "encoding_rs", 230 | "futures", 231 | "hashbrown 0.6.3", 232 | "log", 233 | "mime", 234 | "net2", 235 | "openssl", 236 | "parking_lot 0.9.0", 237 | "regex", 238 | "serde", 239 | "serde_json", 240 | "serde_urlencoded 0.6.1", 241 | "time", 242 | "url 2.2.0", 243 | ] 244 | 245 | [[package]] 246 | name = "actix-web-codegen" 247 | version = "0.1.3" 248 | source = "registry+https://github.com/rust-lang/crates.io-index" 249 | checksum = "068a33520e21c1eea89726be4d6b3ce2e6b81046904367e1677287695a043abb" 250 | dependencies = [ 251 | "proc-macro2 1.0.24", 252 | "quote 1.0.7", 253 | "syn 1.0.53", 254 | ] 255 | 256 | [[package]] 257 | name = "addr2line" 258 | version = "0.14.0" 259 | source = "registry+https://github.com/rust-lang/crates.io-index" 260 | checksum = "7c0929d69e78dd9bf5408269919fcbcaeb2e35e5d43e5815517cdc6a8e11a423" 261 | dependencies = [ 262 | "gimli", 263 | ] 264 | 265 | [[package]] 266 | name = "adler" 267 | version = "0.2.3" 268 | source = "registry+https://github.com/rust-lang/crates.io-index" 269 | checksum = "ee2a4ec343196209d6594e19543ae87a39f96d5534d7174822a3ad825dd6ed7e" 270 | 271 | [[package]] 272 | name = "ahash" 273 | version = "0.2.19" 274 | source = "registry+https://github.com/rust-lang/crates.io-index" 275 | checksum = "29661b60bec623f0586702976ff4d0c9942dcb6723161c2df0eea78455cfedfb" 276 | dependencies = [ 277 | "const-random", 278 | ] 279 | 280 | [[package]] 281 | name = "aho-corasick" 282 | version = "0.7.15" 283 | source = "registry+https://github.com/rust-lang/crates.io-index" 284 | checksum = "7404febffaa47dac81aa44dba71523c9d069b1bdc50a77db41195149e17f68e5" 285 | dependencies = [ 286 | "memchr", 287 | ] 288 | 289 | [[package]] 290 | name = "ansi_term" 291 | version = "0.9.0" 292 | source = "registry+https://github.com/rust-lang/crates.io-index" 293 | checksum = "23ac7c30002a5accbf7e8987d0632fa6de155b7c3d39d0067317a391e00a2ef6" 294 | 295 | [[package]] 296 | name = "ansi_term" 297 | version = "0.11.0" 298 | source = "registry+https://github.com/rust-lang/crates.io-index" 299 | checksum = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" 300 | dependencies = [ 301 | "winapi 0.3.9", 302 | ] 303 | 304 | [[package]] 305 | name = "anyhow" 306 | version = "1.0.34" 307 | source = "registry+https://github.com/rust-lang/crates.io-index" 308 | checksum = "bf8dcb5b4bbaa28653b647d8c77bd4ed40183b48882e130c1f1ffb73de069fd7" 309 | 310 | [[package]] 311 | name = "arc-swap" 312 | version = "0.4.7" 313 | source = "registry+https://github.com/rust-lang/crates.io-index" 314 | checksum = "4d25d88fd6b8041580a654f9d0c581a047baee2b3efee13275f2fc392fc75034" 315 | 316 | [[package]] 317 | name = "arrayref" 318 | version = "0.3.6" 319 | source = "registry+https://github.com/rust-lang/crates.io-index" 320 | checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544" 321 | 322 | [[package]] 323 | name = "arrayvec" 324 | version = "0.5.2" 325 | source = "registry+https://github.com/rust-lang/crates.io-index" 326 | checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" 327 | 328 | [[package]] 329 | name = "atomicwrites" 330 | version = "0.2.5" 331 | source = "registry+https://github.com/rust-lang/crates.io-index" 332 | checksum = "6a2baf2feb820299c53c7ad1cc4f5914a220a1cb76d7ce321d2522a94b54651f" 333 | dependencies = [ 334 | "nix", 335 | "tempdir", 336 | "winapi 0.3.9", 337 | ] 338 | 339 | [[package]] 340 | name = "atty" 341 | version = "0.2.14" 342 | source = "registry+https://github.com/rust-lang/crates.io-index" 343 | checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" 344 | dependencies = [ 345 | "hermit-abi", 346 | "libc", 347 | "winapi 0.3.9", 348 | ] 349 | 350 | [[package]] 351 | name = "autocfg" 352 | version = "0.1.7" 353 | source = "registry+https://github.com/rust-lang/crates.io-index" 354 | checksum = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2" 355 | 356 | [[package]] 357 | name = "autocfg" 358 | version = "1.0.1" 359 | source = "registry+https://github.com/rust-lang/crates.io-index" 360 | checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" 361 | 362 | [[package]] 363 | name = "awc" 364 | version = "0.2.8" 365 | source = "registry+https://github.com/rust-lang/crates.io-index" 366 | checksum = "5e995283278dd3bf0449e7534e77184adb1570c0de8b6a50bf7c9d01ad8db8c4" 367 | dependencies = [ 368 | "actix-codec", 369 | "actix-http", 370 | "actix-service", 371 | "base64 0.10.1", 372 | "bytes", 373 | "derive_more", 374 | "futures", 375 | "log", 376 | "mime", 377 | "openssl", 378 | "percent-encoding 2.1.0", 379 | "rand 0.7.3", 380 | "serde", 381 | "serde_json", 382 | "serde_urlencoded 0.6.1", 383 | "tokio-timer", 384 | ] 385 | 386 | [[package]] 387 | name = "backtrace" 388 | version = "0.3.55" 389 | source = "registry+https://github.com/rust-lang/crates.io-index" 390 | checksum = "ef5140344c85b01f9bbb4d4b7288a8aa4b3287ccef913a14bcc78a1063623598" 391 | dependencies = [ 392 | "addr2line", 393 | "cfg-if 1.0.0", 394 | "libc", 395 | "miniz_oxide", 396 | "object", 397 | "rustc-demangle", 398 | ] 399 | 400 | [[package]] 401 | name = "base64" 402 | version = "0.10.1" 403 | source = "registry+https://github.com/rust-lang/crates.io-index" 404 | checksum = "0b25d992356d2eb0ed82172f5248873db5560c4721f564b13cb5193bda5e668e" 405 | dependencies = [ 406 | "byteorder", 407 | ] 408 | 409 | [[package]] 410 | name = "base64" 411 | version = "0.13.0" 412 | source = "registry+https://github.com/rust-lang/crates.io-index" 413 | checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" 414 | 415 | [[package]] 416 | name = "bincode" 417 | version = "1.3.1" 418 | source = "registry+https://github.com/rust-lang/crates.io-index" 419 | checksum = "f30d3a39baa26f9651f17b375061f3233dde33424a8b72b0dbe93a68a0bc896d" 420 | dependencies = [ 421 | "byteorder", 422 | "serde", 423 | ] 424 | 425 | [[package]] 426 | name = "bitflags" 427 | version = "1.2.1" 428 | source = "registry+https://github.com/rust-lang/crates.io-index" 429 | checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" 430 | 431 | [[package]] 432 | name = "blake2b_simd" 433 | version = "0.5.11" 434 | source = "registry+https://github.com/rust-lang/crates.io-index" 435 | checksum = "afa748e348ad3be8263be728124b24a24f268266f6f5d58af9d75f6a40b5c587" 436 | dependencies = [ 437 | "arrayref", 438 | "arrayvec", 439 | "constant_time_eq", 440 | ] 441 | 442 | [[package]] 443 | name = "boxfnonce" 444 | version = "0.1.1" 445 | source = "registry+https://github.com/rust-lang/crates.io-index" 446 | checksum = "5988cb1d626264ac94100be357308f29ff7cbdd3b36bda27f450a4ee3f713426" 447 | 448 | [[package]] 449 | name = "brotli-sys" 450 | version = "0.3.2" 451 | source = "registry+https://github.com/rust-lang/crates.io-index" 452 | checksum = "4445dea95f4c2b41cde57cc9fee236ae4dbae88d8fcbdb4750fc1bb5d86aaecd" 453 | dependencies = [ 454 | "cc", 455 | "libc", 456 | ] 457 | 458 | [[package]] 459 | name = "brotli2" 460 | version = "0.3.2" 461 | source = "registry+https://github.com/rust-lang/crates.io-index" 462 | checksum = "0cb036c3eade309815c15ddbacec5b22c4d1f3983a774ab2eac2e3e9ea85568e" 463 | dependencies = [ 464 | "brotli-sys", 465 | "libc", 466 | ] 467 | 468 | [[package]] 469 | name = "byteorder" 470 | version = "1.3.4" 471 | source = "registry+https://github.com/rust-lang/crates.io-index" 472 | checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de" 473 | 474 | [[package]] 475 | name = "bytes" 476 | version = "0.4.12" 477 | source = "registry+https://github.com/rust-lang/crates.io-index" 478 | checksum = "206fdffcfa2df7cbe15601ef46c813fce0965eb3286db6b56c583b814b51c81c" 479 | dependencies = [ 480 | "byteorder", 481 | "either", 482 | "iovec", 483 | ] 484 | 485 | [[package]] 486 | name = "cc" 487 | version = "1.0.65" 488 | source = "registry+https://github.com/rust-lang/crates.io-index" 489 | checksum = "95752358c8f7552394baf48cd82695b345628ad3f170d607de3ca03b8dacca15" 490 | 491 | [[package]] 492 | name = "cfg-if" 493 | version = "0.1.10" 494 | source = "registry+https://github.com/rust-lang/crates.io-index" 495 | checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" 496 | 497 | [[package]] 498 | name = "cfg-if" 499 | version = "1.0.0" 500 | source = "registry+https://github.com/rust-lang/crates.io-index" 501 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 502 | 503 | [[package]] 504 | name = "chrono" 505 | version = "0.4.19" 506 | source = "registry+https://github.com/rust-lang/crates.io-index" 507 | checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73" 508 | dependencies = [ 509 | "libc", 510 | "num-integer", 511 | "num-traits", 512 | "serde", 513 | "time", 514 | "winapi 0.3.9", 515 | ] 516 | 517 | [[package]] 518 | name = "clap" 519 | version = "2.33.3" 520 | source = "registry+https://github.com/rust-lang/crates.io-index" 521 | checksum = "37e58ac78573c40708d45522f0d80fa2f01cc4f9b4e2bf749807255454312002" 522 | dependencies = [ 523 | "ansi_term 0.11.0", 524 | "atty", 525 | "bitflags", 526 | "strsim", 527 | "textwrap", 528 | "unicode-width", 529 | "vec_map", 530 | ] 531 | 532 | [[package]] 533 | name = "cloudabi" 534 | version = "0.0.3" 535 | source = "registry+https://github.com/rust-lang/crates.io-index" 536 | checksum = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" 537 | dependencies = [ 538 | "bitflags", 539 | ] 540 | 541 | [[package]] 542 | name = "cloudabi" 543 | version = "0.1.0" 544 | source = "registry+https://github.com/rust-lang/crates.io-index" 545 | checksum = "4344512281c643ae7638bbabc3af17a11307803ec8f0fcad9fae512a8bf36467" 546 | dependencies = [ 547 | "bitflags", 548 | ] 549 | 550 | [[package]] 551 | name = "const-random" 552 | version = "0.1.12" 553 | source = "registry+https://github.com/rust-lang/crates.io-index" 554 | checksum = "486d435a7351580347279f374cb8a3c16937485441db80181357b7c4d70f17ed" 555 | dependencies = [ 556 | "const-random-macro", 557 | "proc-macro-hack", 558 | ] 559 | 560 | [[package]] 561 | name = "const-random-macro" 562 | version = "0.1.12" 563 | source = "registry+https://github.com/rust-lang/crates.io-index" 564 | checksum = "49a84d8ff70e3ec52311109b019c27672b4c1929e4cf7c18bcf0cd9fb5e230be" 565 | dependencies = [ 566 | "getrandom 0.2.0", 567 | "lazy_static", 568 | "proc-macro-hack", 569 | "tiny-keccak", 570 | ] 571 | 572 | [[package]] 573 | name = "constant_time_eq" 574 | version = "0.1.5" 575 | source = "registry+https://github.com/rust-lang/crates.io-index" 576 | checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" 577 | 578 | [[package]] 579 | name = "cookie" 580 | version = "0.12.0" 581 | source = "registry+https://github.com/rust-lang/crates.io-index" 582 | checksum = "888604f00b3db336d2af898ec3c1d5d0ddf5e6d462220f2ededc33a87ac4bbd5" 583 | dependencies = [ 584 | "time", 585 | "url 1.7.2", 586 | ] 587 | 588 | [[package]] 589 | name = "cookie_store" 590 | version = "0.7.0" 591 | source = "registry+https://github.com/rust-lang/crates.io-index" 592 | checksum = "46750b3f362965f197996c4448e4a0935e791bf7d6631bfce9ee0af3d24c919c" 593 | dependencies = [ 594 | "cookie", 595 | "failure", 596 | "idna 0.1.5", 597 | "log", 598 | "publicsuffix", 599 | "serde", 600 | "serde_json", 601 | "time", 602 | "try_from", 603 | "url 1.7.2", 604 | ] 605 | 606 | [[package]] 607 | name = "copyless" 608 | version = "0.1.5" 609 | source = "registry+https://github.com/rust-lang/crates.io-index" 610 | checksum = "a2df960f5d869b2dd8532793fde43eb5427cceb126c929747a26823ab0eeb536" 611 | 612 | [[package]] 613 | name = "core-foundation" 614 | version = "0.9.1" 615 | source = "registry+https://github.com/rust-lang/crates.io-index" 616 | checksum = "0a89e2ae426ea83155dccf10c0fa6b1463ef6d5fcb44cee0b224a408fa640a62" 617 | dependencies = [ 618 | "core-foundation-sys", 619 | "libc", 620 | ] 621 | 622 | [[package]] 623 | name = "core-foundation-sys" 624 | version = "0.8.2" 625 | source = "registry+https://github.com/rust-lang/crates.io-index" 626 | checksum = "ea221b5284a47e40033bf9b66f35f984ec0ea2931eb03505246cd27a963f981b" 627 | 628 | [[package]] 629 | name = "crc32fast" 630 | version = "1.2.1" 631 | source = "registry+https://github.com/rust-lang/crates.io-index" 632 | checksum = "81156fece84ab6a9f2afdb109ce3ae577e42b1228441eded99bd77f627953b1a" 633 | dependencies = [ 634 | "cfg-if 1.0.0", 635 | ] 636 | 637 | [[package]] 638 | name = "crossbeam-deque" 639 | version = "0.7.3" 640 | source = "registry+https://github.com/rust-lang/crates.io-index" 641 | checksum = "9f02af974daeee82218205558e51ec8768b48cf524bd01d550abe5573a608285" 642 | dependencies = [ 643 | "crossbeam-epoch", 644 | "crossbeam-utils 0.7.2", 645 | "maybe-uninit", 646 | ] 647 | 648 | [[package]] 649 | name = "crossbeam-epoch" 650 | version = "0.8.2" 651 | source = "registry+https://github.com/rust-lang/crates.io-index" 652 | checksum = "058ed274caafc1f60c4997b5fc07bf7dc7cca454af7c6e81edffe5f33f70dace" 653 | dependencies = [ 654 | "autocfg 1.0.1", 655 | "cfg-if 0.1.10", 656 | "crossbeam-utils 0.7.2", 657 | "lazy_static", 658 | "maybe-uninit", 659 | "memoffset", 660 | "scopeguard", 661 | ] 662 | 663 | [[package]] 664 | name = "crossbeam-queue" 665 | version = "0.2.3" 666 | source = "registry+https://github.com/rust-lang/crates.io-index" 667 | checksum = "774ba60a54c213d409d5353bda12d49cd68d14e45036a285234c8d6f91f92570" 668 | dependencies = [ 669 | "cfg-if 0.1.10", 670 | "crossbeam-utils 0.7.2", 671 | "maybe-uninit", 672 | ] 673 | 674 | [[package]] 675 | name = "crossbeam-utils" 676 | version = "0.7.2" 677 | source = "registry+https://github.com/rust-lang/crates.io-index" 678 | checksum = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8" 679 | dependencies = [ 680 | "autocfg 1.0.1", 681 | "cfg-if 0.1.10", 682 | "lazy_static", 683 | ] 684 | 685 | [[package]] 686 | name = "crossbeam-utils" 687 | version = "0.8.1" 688 | source = "registry+https://github.com/rust-lang/crates.io-index" 689 | checksum = "02d96d1e189ef58269ebe5b97953da3274d83a93af647c2ddd6f9dab28cedb8d" 690 | dependencies = [ 691 | "autocfg 1.0.1", 692 | "cfg-if 1.0.0", 693 | "lazy_static", 694 | ] 695 | 696 | [[package]] 697 | name = "crunchy" 698 | version = "0.2.2" 699 | source = "registry+https://github.com/rust-lang/crates.io-index" 700 | checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" 701 | 702 | [[package]] 703 | name = "daemonize" 704 | version = "0.4.1" 705 | source = "registry+https://github.com/rust-lang/crates.io-index" 706 | checksum = "70c24513e34f53b640819f0ac9f705b673fcf4006d7aab8778bee72ebfc89815" 707 | dependencies = [ 708 | "boxfnonce", 709 | "libc", 710 | ] 711 | 712 | [[package]] 713 | name = "derive_more" 714 | version = "0.15.0" 715 | source = "registry+https://github.com/rust-lang/crates.io-index" 716 | checksum = "7a141330240c921ec6d074a3e188a7c7ef95668bb95e7d44fa0e5778ec2a7afe" 717 | dependencies = [ 718 | "lazy_static", 719 | "proc-macro2 0.4.30", 720 | "quote 0.6.13", 721 | "regex", 722 | "rustc_version", 723 | "syn 0.15.44", 724 | ] 725 | 726 | [[package]] 727 | name = "dirs" 728 | version = "2.0.2" 729 | source = "registry+https://github.com/rust-lang/crates.io-index" 730 | checksum = "13aea89a5c93364a98e9b37b2fa237effbb694d5cfe01c5b70941f7eb087d5e3" 731 | dependencies = [ 732 | "cfg-if 0.1.10", 733 | "dirs-sys", 734 | ] 735 | 736 | [[package]] 737 | name = "dirs-sys" 738 | version = "0.3.5" 739 | source = "registry+https://github.com/rust-lang/crates.io-index" 740 | checksum = "8e93d7f5705de3e49895a2b5e0b8855a1c27f080192ae9c32a6432d50741a57a" 741 | dependencies = [ 742 | "libc", 743 | "redox_users", 744 | "winapi 0.3.9", 745 | ] 746 | 747 | [[package]] 748 | name = "dtoa" 749 | version = "0.4.6" 750 | source = "registry+https://github.com/rust-lang/crates.io-index" 751 | checksum = "134951f4028bdadb9b84baf4232681efbf277da25144b9b0ad65df75946c422b" 752 | 753 | [[package]] 754 | name = "either" 755 | version = "1.6.1" 756 | source = "registry+https://github.com/rust-lang/crates.io-index" 757 | checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" 758 | 759 | [[package]] 760 | name = "encoding_rs" 761 | version = "0.8.26" 762 | source = "registry+https://github.com/rust-lang/crates.io-index" 763 | checksum = "801bbab217d7f79c0062f4f7205b5d4427c6d1a7bd7aafdd1475f7c59d62b283" 764 | dependencies = [ 765 | "cfg-if 1.0.0", 766 | ] 767 | 768 | [[package]] 769 | name = "enum-as-inner" 770 | version = "0.2.1" 771 | source = "registry+https://github.com/rust-lang/crates.io-index" 772 | checksum = "3d58266c97445680766be408285e798d3401c6d4c378ec5552e78737e681e37d" 773 | dependencies = [ 774 | "proc-macro2 0.4.30", 775 | "quote 0.6.13", 776 | "syn 0.15.44", 777 | ] 778 | 779 | [[package]] 780 | name = "error-chain" 781 | version = "0.12.4" 782 | source = "registry+https://github.com/rust-lang/crates.io-index" 783 | checksum = "2d2f06b9cac1506ece98fe3231e3cc9c4410ec3d5b1f24ae1c8946f0742cdefc" 784 | dependencies = [ 785 | "version_check", 786 | ] 787 | 788 | [[package]] 789 | name = "failure" 790 | version = "0.1.8" 791 | source = "registry+https://github.com/rust-lang/crates.io-index" 792 | checksum = "d32e9bd16cc02eae7db7ef620b392808b89f6a5e16bb3497d159c6b92a0f4f86" 793 | dependencies = [ 794 | "backtrace", 795 | "failure_derive", 796 | ] 797 | 798 | [[package]] 799 | name = "failure_derive" 800 | version = "0.1.8" 801 | source = "registry+https://github.com/rust-lang/crates.io-index" 802 | checksum = "aa4da3c766cd7a0db8242e326e9e4e081edd567072893ed320008189715366a4" 803 | dependencies = [ 804 | "proc-macro2 1.0.24", 805 | "quote 1.0.7", 806 | "syn 1.0.53", 807 | "synstructure", 808 | ] 809 | 810 | [[package]] 811 | name = "flate2" 812 | version = "1.0.19" 813 | source = "registry+https://github.com/rust-lang/crates.io-index" 814 | checksum = "7411863d55df97a419aa64cb4d2f167103ea9d767e2c54a1868b7ac3f6b47129" 815 | dependencies = [ 816 | "cfg-if 1.0.0", 817 | "crc32fast", 818 | "libc", 819 | "miniz-sys", 820 | "miniz_oxide", 821 | ] 822 | 823 | [[package]] 824 | name = "fnv" 825 | version = "1.0.7" 826 | source = "registry+https://github.com/rust-lang/crates.io-index" 827 | checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" 828 | 829 | [[package]] 830 | name = "foreign-types" 831 | version = "0.3.2" 832 | source = "registry+https://github.com/rust-lang/crates.io-index" 833 | checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" 834 | dependencies = [ 835 | "foreign-types-shared", 836 | ] 837 | 838 | [[package]] 839 | name = "foreign-types-shared" 840 | version = "0.1.1" 841 | source = "registry+https://github.com/rust-lang/crates.io-index" 842 | checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" 843 | 844 | [[package]] 845 | name = "form_urlencoded" 846 | version = "1.0.0" 847 | source = "registry+https://github.com/rust-lang/crates.io-index" 848 | checksum = "ece68d15c92e84fa4f19d3780f1294e5ca82a78a6d515f1efaabcc144688be00" 849 | dependencies = [ 850 | "matches", 851 | "percent-encoding 2.1.0", 852 | ] 853 | 854 | [[package]] 855 | name = "fuchsia-cprng" 856 | version = "0.1.1" 857 | source = "registry+https://github.com/rust-lang/crates.io-index" 858 | checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" 859 | 860 | [[package]] 861 | name = "fuchsia-zircon" 862 | version = "0.3.3" 863 | source = "registry+https://github.com/rust-lang/crates.io-index" 864 | checksum = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" 865 | dependencies = [ 866 | "bitflags", 867 | "fuchsia-zircon-sys", 868 | ] 869 | 870 | [[package]] 871 | name = "fuchsia-zircon-sys" 872 | version = "0.3.3" 873 | source = "registry+https://github.com/rust-lang/crates.io-index" 874 | checksum = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" 875 | 876 | [[package]] 877 | name = "futures" 878 | version = "0.1.30" 879 | source = "registry+https://github.com/rust-lang/crates.io-index" 880 | checksum = "4c7e4c2612746b0df8fed4ce0c69156021b704c9aefa360311c04e6e9e002eed" 881 | 882 | [[package]] 883 | name = "futures-cpupool" 884 | version = "0.1.8" 885 | source = "registry+https://github.com/rust-lang/crates.io-index" 886 | checksum = "ab90cde24b3319636588d0c35fe03b1333857621051837ed769faefb4c2162e4" 887 | dependencies = [ 888 | "futures", 889 | "num_cpus", 890 | ] 891 | 892 | [[package]] 893 | name = "getrandom" 894 | version = "0.1.15" 895 | source = "registry+https://github.com/rust-lang/crates.io-index" 896 | checksum = "fc587bc0ec293155d5bfa6b9891ec18a1e330c234f896ea47fbada4cadbe47e6" 897 | dependencies = [ 898 | "cfg-if 0.1.10", 899 | "libc", 900 | "wasi 0.9.0+wasi-snapshot-preview1", 901 | ] 902 | 903 | [[package]] 904 | name = "getrandom" 905 | version = "0.2.0" 906 | source = "registry+https://github.com/rust-lang/crates.io-index" 907 | checksum = "ee8025cf36f917e6a52cce185b7c7177689b838b7ec138364e50cc2277a56cf4" 908 | dependencies = [ 909 | "cfg-if 0.1.10", 910 | "libc", 911 | "wasi 0.9.0+wasi-snapshot-preview1", 912 | ] 913 | 914 | [[package]] 915 | name = "gimli" 916 | version = "0.23.0" 917 | source = "registry+https://github.com/rust-lang/crates.io-index" 918 | checksum = "f6503fe142514ca4799d4c26297c4248239fe8838d827db6bd6065c6ed29a6ce" 919 | 920 | [[package]] 921 | name = "h2" 922 | version = "0.1.26" 923 | source = "registry+https://github.com/rust-lang/crates.io-index" 924 | checksum = "a5b34c246847f938a410a03c5458c7fee2274436675e76d8b903c08efc29c462" 925 | dependencies = [ 926 | "byteorder", 927 | "bytes", 928 | "fnv", 929 | "futures", 930 | "http", 931 | "indexmap", 932 | "log", 933 | "slab", 934 | "string", 935 | "tokio-io", 936 | ] 937 | 938 | [[package]] 939 | name = "hashbrown" 940 | version = "0.6.3" 941 | source = "registry+https://github.com/rust-lang/crates.io-index" 942 | checksum = "8e6073d0ca812575946eb5f35ff68dbe519907b25c42530389ff946dc84c6ead" 943 | dependencies = [ 944 | "ahash", 945 | "autocfg 0.1.7", 946 | ] 947 | 948 | [[package]] 949 | name = "hashbrown" 950 | version = "0.9.1" 951 | source = "registry+https://github.com/rust-lang/crates.io-index" 952 | checksum = "d7afe4a420e3fe79967a00898cc1f4db7c8a49a9333a29f8a4bd76a253d5cd04" 953 | 954 | [[package]] 955 | name = "hermit-abi" 956 | version = "0.1.17" 957 | source = "registry+https://github.com/rust-lang/crates.io-index" 958 | checksum = "5aca5565f760fb5b220e499d72710ed156fdb74e631659e99377d9ebfbd13ae8" 959 | dependencies = [ 960 | "libc", 961 | ] 962 | 963 | [[package]] 964 | name = "hostname" 965 | version = "0.3.1" 966 | source = "registry+https://github.com/rust-lang/crates.io-index" 967 | checksum = "3c731c3e10504cc8ed35cfe2f1db4c9274c3d35fa486e3b31df46f068ef3e867" 968 | dependencies = [ 969 | "libc", 970 | "match_cfg", 971 | "winapi 0.3.9", 972 | ] 973 | 974 | [[package]] 975 | name = "http" 976 | version = "0.1.21" 977 | source = "registry+https://github.com/rust-lang/crates.io-index" 978 | checksum = "d6ccf5ede3a895d8856620237b2f02972c1bbc78d2965ad7fe8838d4a0ed41f0" 979 | dependencies = [ 980 | "bytes", 981 | "fnv", 982 | "itoa", 983 | ] 984 | 985 | [[package]] 986 | name = "http-body" 987 | version = "0.1.0" 988 | source = "registry+https://github.com/rust-lang/crates.io-index" 989 | checksum = "6741c859c1b2463a423a1dbce98d418e6c3c3fc720fb0d45528657320920292d" 990 | dependencies = [ 991 | "bytes", 992 | "futures", 993 | "http", 994 | "tokio-buf", 995 | ] 996 | 997 | [[package]] 998 | name = "httparse" 999 | version = "1.3.4" 1000 | source = "registry+https://github.com/rust-lang/crates.io-index" 1001 | checksum = "cd179ae861f0c2e53da70d892f5f3029f9594be0c41dc5269cd371691b1dc2f9" 1002 | 1003 | [[package]] 1004 | name = "humantime" 1005 | version = "1.3.0" 1006 | source = "registry+https://github.com/rust-lang/crates.io-index" 1007 | checksum = "df004cfca50ef23c36850aaaa59ad52cc70d0e90243c3c7737a4dd32dc7a3c4f" 1008 | dependencies = [ 1009 | "quick-error", 1010 | ] 1011 | 1012 | [[package]] 1013 | name = "hyper" 1014 | version = "0.12.35" 1015 | source = "registry+https://github.com/rust-lang/crates.io-index" 1016 | checksum = "9dbe6ed1438e1f8ad955a4701e9a944938e9519f6888d12d8558b645e247d5f6" 1017 | dependencies = [ 1018 | "bytes", 1019 | "futures", 1020 | "futures-cpupool", 1021 | "h2", 1022 | "http", 1023 | "http-body", 1024 | "httparse", 1025 | "iovec", 1026 | "itoa", 1027 | "log", 1028 | "net2", 1029 | "rustc_version", 1030 | "time", 1031 | "tokio", 1032 | "tokio-buf", 1033 | "tokio-executor", 1034 | "tokio-io", 1035 | "tokio-reactor", 1036 | "tokio-tcp", 1037 | "tokio-threadpool", 1038 | "tokio-timer", 1039 | "want", 1040 | ] 1041 | 1042 | [[package]] 1043 | name = "hyper-tls" 1044 | version = "0.3.2" 1045 | source = "registry+https://github.com/rust-lang/crates.io-index" 1046 | checksum = "3a800d6aa50af4b5850b2b0f659625ce9504df908e9733b635720483be26174f" 1047 | dependencies = [ 1048 | "bytes", 1049 | "futures", 1050 | "hyper", 1051 | "native-tls", 1052 | "tokio-io", 1053 | ] 1054 | 1055 | [[package]] 1056 | name = "idna" 1057 | version = "0.1.5" 1058 | source = "registry+https://github.com/rust-lang/crates.io-index" 1059 | checksum = "38f09e0f0b1fb55fdee1f17470ad800da77af5186a1a76c026b679358b7e844e" 1060 | dependencies = [ 1061 | "matches", 1062 | "unicode-bidi", 1063 | "unicode-normalization", 1064 | ] 1065 | 1066 | [[package]] 1067 | name = "idna" 1068 | version = "0.2.0" 1069 | source = "registry+https://github.com/rust-lang/crates.io-index" 1070 | checksum = "02e2673c30ee86b5b96a9cb52ad15718aa1f966f5ab9ad54a8b95d5ca33120a9" 1071 | dependencies = [ 1072 | "matches", 1073 | "unicode-bidi", 1074 | "unicode-normalization", 1075 | ] 1076 | 1077 | [[package]] 1078 | name = "indexmap" 1079 | version = "1.6.0" 1080 | source = "registry+https://github.com/rust-lang/crates.io-index" 1081 | checksum = "55e2e4c765aa53a0424761bf9f41aa7a6ac1efa87238f59560640e27fca028f2" 1082 | dependencies = [ 1083 | "autocfg 1.0.1", 1084 | "hashbrown 0.9.1", 1085 | ] 1086 | 1087 | [[package]] 1088 | name = "instant" 1089 | version = "0.1.9" 1090 | source = "registry+https://github.com/rust-lang/crates.io-index" 1091 | checksum = "61124eeebbd69b8190558df225adf7e4caafce0d743919e5d6b19652314ec5ec" 1092 | dependencies = [ 1093 | "cfg-if 1.0.0", 1094 | ] 1095 | 1096 | [[package]] 1097 | name = "iovec" 1098 | version = "0.1.4" 1099 | source = "registry+https://github.com/rust-lang/crates.io-index" 1100 | checksum = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e" 1101 | dependencies = [ 1102 | "libc", 1103 | ] 1104 | 1105 | [[package]] 1106 | name = "ipconfig" 1107 | version = "0.2.2" 1108 | source = "registry+https://github.com/rust-lang/crates.io-index" 1109 | checksum = "f7e2f18aece9709094573a9f24f483c4f65caa4298e2f7ae1b71cc65d853fad7" 1110 | dependencies = [ 1111 | "socket2", 1112 | "widestring", 1113 | "winapi 0.3.9", 1114 | "winreg", 1115 | ] 1116 | 1117 | [[package]] 1118 | name = "itoa" 1119 | version = "0.4.6" 1120 | source = "registry+https://github.com/rust-lang/crates.io-index" 1121 | checksum = "dc6f3ad7b9d11a0c00842ff8de1b60ee58661048eb8049ed33c73594f359d7e6" 1122 | 1123 | [[package]] 1124 | name = "kernel32-sys" 1125 | version = "0.2.2" 1126 | source = "registry+https://github.com/rust-lang/crates.io-index" 1127 | checksum = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" 1128 | dependencies = [ 1129 | "winapi 0.2.8", 1130 | "winapi-build", 1131 | ] 1132 | 1133 | [[package]] 1134 | name = "language-tags" 1135 | version = "0.2.2" 1136 | source = "registry+https://github.com/rust-lang/crates.io-index" 1137 | checksum = "a91d884b6667cd606bb5a69aa0c99ba811a115fc68915e7056ec08a46e93199a" 1138 | 1139 | [[package]] 1140 | name = "lazy_static" 1141 | version = "1.4.0" 1142 | source = "registry+https://github.com/rust-lang/crates.io-index" 1143 | checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" 1144 | 1145 | [[package]] 1146 | name = "libc" 1147 | version = "0.2.80" 1148 | source = "registry+https://github.com/rust-lang/crates.io-index" 1149 | checksum = "4d58d1b70b004888f764dfbf6a26a3b0342a1632d33968e4a179d8011c760614" 1150 | 1151 | [[package]] 1152 | name = "linked-hash-map" 1153 | version = "0.5.3" 1154 | source = "registry+https://github.com/rust-lang/crates.io-index" 1155 | checksum = "8dd5a6d5999d9907cda8ed67bbd137d3af8085216c2ac62de5be860bd41f304a" 1156 | 1157 | [[package]] 1158 | name = "lock_api" 1159 | version = "0.3.4" 1160 | source = "registry+https://github.com/rust-lang/crates.io-index" 1161 | checksum = "c4da24a77a3d8a6d4862d95f72e6fdb9c09a643ecdb402d754004a557f2bec75" 1162 | dependencies = [ 1163 | "scopeguard", 1164 | ] 1165 | 1166 | [[package]] 1167 | name = "lock_api" 1168 | version = "0.4.2" 1169 | source = "registry+https://github.com/rust-lang/crates.io-index" 1170 | checksum = "dd96ffd135b2fd7b973ac026d28085defbe8983df057ced3eb4f2130b0831312" 1171 | dependencies = [ 1172 | "scopeguard", 1173 | ] 1174 | 1175 | [[package]] 1176 | name = "log" 1177 | version = "0.4.11" 1178 | source = "registry+https://github.com/rust-lang/crates.io-index" 1179 | checksum = "4fabed175da42fed1fa0746b0ea71f412aa9d35e76e95e59b192c64b9dc2bf8b" 1180 | dependencies = [ 1181 | "cfg-if 0.1.10", 1182 | "serde", 1183 | ] 1184 | 1185 | [[package]] 1186 | name = "log-mdc" 1187 | version = "0.1.0" 1188 | source = "registry+https://github.com/rust-lang/crates.io-index" 1189 | checksum = "a94d21414c1f4a51209ad204c1776a3d0765002c76c6abcb602a6f09f1e881c7" 1190 | 1191 | [[package]] 1192 | name = "log4rs" 1193 | version = "0.13.0" 1194 | source = "registry+https://github.com/rust-lang/crates.io-index" 1195 | checksum = "e1e1ad45e4584824d760c35d71868dd7e6e5acd8f5195a9573743b369fc86cd6" 1196 | dependencies = [ 1197 | "arc-swap", 1198 | "chrono", 1199 | "flate2", 1200 | "fnv", 1201 | "humantime", 1202 | "libc", 1203 | "log", 1204 | "log-mdc", 1205 | "parking_lot 0.11.1", 1206 | "serde", 1207 | "serde-value", 1208 | "serde_derive", 1209 | "serde_json", 1210 | "serde_yaml", 1211 | "thread-id", 1212 | "typemap", 1213 | "winapi 0.3.9", 1214 | ] 1215 | 1216 | [[package]] 1217 | name = "lru-cache" 1218 | version = "0.1.2" 1219 | source = "registry+https://github.com/rust-lang/crates.io-index" 1220 | checksum = "31e24f1ad8321ca0e8a1e0ac13f23cb668e6f5466c2c57319f6a5cf1cc8e3b1c" 1221 | dependencies = [ 1222 | "linked-hash-map", 1223 | ] 1224 | 1225 | [[package]] 1226 | name = "match_cfg" 1227 | version = "0.1.0" 1228 | source = "registry+https://github.com/rust-lang/crates.io-index" 1229 | checksum = "ffbee8634e0d45d258acb448e7eaab3fce7a0a467395d4d9f228e3c1f01fb2e4" 1230 | 1231 | [[package]] 1232 | name = "matches" 1233 | version = "0.1.8" 1234 | source = "registry+https://github.com/rust-lang/crates.io-index" 1235 | checksum = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08" 1236 | 1237 | [[package]] 1238 | name = "maybe-uninit" 1239 | version = "2.0.0" 1240 | source = "registry+https://github.com/rust-lang/crates.io-index" 1241 | checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00" 1242 | 1243 | [[package]] 1244 | name = "memchr" 1245 | version = "2.3.4" 1246 | source = "registry+https://github.com/rust-lang/crates.io-index" 1247 | checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525" 1248 | 1249 | [[package]] 1250 | name = "memoffset" 1251 | version = "0.5.6" 1252 | source = "registry+https://github.com/rust-lang/crates.io-index" 1253 | checksum = "043175f069eda7b85febe4a74abbaeff828d9f8b448515d3151a14a3542811aa" 1254 | dependencies = [ 1255 | "autocfg 1.0.1", 1256 | ] 1257 | 1258 | [[package]] 1259 | name = "mime" 1260 | version = "0.3.16" 1261 | source = "registry+https://github.com/rust-lang/crates.io-index" 1262 | checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" 1263 | 1264 | [[package]] 1265 | name = "mime_guess" 1266 | version = "2.0.3" 1267 | source = "registry+https://github.com/rust-lang/crates.io-index" 1268 | checksum = "2684d4c2e97d99848d30b324b00c8fcc7e5c897b7cbb5819b09e7c90e8baf212" 1269 | dependencies = [ 1270 | "mime", 1271 | "unicase", 1272 | ] 1273 | 1274 | [[package]] 1275 | name = "miniz-sys" 1276 | version = "0.1.12" 1277 | source = "registry+https://github.com/rust-lang/crates.io-index" 1278 | checksum = "1e9e3ae51cea1576ceba0dde3d484d30e6e5b86dee0b2d412fe3a16a15c98202" 1279 | dependencies = [ 1280 | "cc", 1281 | "libc", 1282 | ] 1283 | 1284 | [[package]] 1285 | name = "miniz_oxide" 1286 | version = "0.4.3" 1287 | source = "registry+https://github.com/rust-lang/crates.io-index" 1288 | checksum = "0f2d26ec3309788e423cfbf68ad1800f061638098d76a83681af979dc4eda19d" 1289 | dependencies = [ 1290 | "adler", 1291 | "autocfg 1.0.1", 1292 | ] 1293 | 1294 | [[package]] 1295 | name = "mio" 1296 | version = "0.6.22" 1297 | source = "registry+https://github.com/rust-lang/crates.io-index" 1298 | checksum = "fce347092656428bc8eaf6201042cb551b8d67855af7374542a92a0fbfcac430" 1299 | dependencies = [ 1300 | "cfg-if 0.1.10", 1301 | "fuchsia-zircon", 1302 | "fuchsia-zircon-sys", 1303 | "iovec", 1304 | "kernel32-sys", 1305 | "libc", 1306 | "log", 1307 | "miow", 1308 | "net2", 1309 | "slab", 1310 | "winapi 0.2.8", 1311 | ] 1312 | 1313 | [[package]] 1314 | name = "mio-uds" 1315 | version = "0.6.8" 1316 | source = "registry+https://github.com/rust-lang/crates.io-index" 1317 | checksum = "afcb699eb26d4332647cc848492bbc15eafb26f08d0304550d5aa1f612e066f0" 1318 | dependencies = [ 1319 | "iovec", 1320 | "libc", 1321 | "mio", 1322 | ] 1323 | 1324 | [[package]] 1325 | name = "miow" 1326 | version = "0.2.2" 1327 | source = "registry+https://github.com/rust-lang/crates.io-index" 1328 | checksum = "ebd808424166322d4a38da87083bfddd3ac4c131334ed55856112eb06d46944d" 1329 | dependencies = [ 1330 | "kernel32-sys", 1331 | "net2", 1332 | "winapi 0.2.8", 1333 | "ws2_32-sys", 1334 | ] 1335 | 1336 | [[package]] 1337 | name = "native-tls" 1338 | version = "0.2.6" 1339 | source = "registry+https://github.com/rust-lang/crates.io-index" 1340 | checksum = "6fcc7939b5edc4e4f86b1b4a04bb1498afaaf871b1a6691838ed06fcb48d3a3f" 1341 | dependencies = [ 1342 | "lazy_static", 1343 | "libc", 1344 | "log", 1345 | "openssl", 1346 | "openssl-probe", 1347 | "openssl-sys", 1348 | "schannel", 1349 | "security-framework", 1350 | "security-framework-sys", 1351 | "tempfile", 1352 | ] 1353 | 1354 | [[package]] 1355 | name = "net2" 1356 | version = "0.2.36" 1357 | source = "registry+https://github.com/rust-lang/crates.io-index" 1358 | checksum = "d7cf75f38f16cb05ea017784dc6dbfd354f76c223dba37701734c4f5a9337d02" 1359 | dependencies = [ 1360 | "cfg-if 0.1.10", 1361 | "libc", 1362 | "winapi 0.3.9", 1363 | ] 1364 | 1365 | [[package]] 1366 | name = "nix" 1367 | version = "0.14.1" 1368 | source = "registry+https://github.com/rust-lang/crates.io-index" 1369 | checksum = "6c722bee1037d430d0f8e687bbdbf222f27cc6e4e68d5caf630857bb2b6dbdce" 1370 | dependencies = [ 1371 | "bitflags", 1372 | "cc", 1373 | "cfg-if 0.1.10", 1374 | "libc", 1375 | "void", 1376 | ] 1377 | 1378 | [[package]] 1379 | name = "num-integer" 1380 | version = "0.1.44" 1381 | source = "registry+https://github.com/rust-lang/crates.io-index" 1382 | checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db" 1383 | dependencies = [ 1384 | "autocfg 1.0.1", 1385 | "num-traits", 1386 | ] 1387 | 1388 | [[package]] 1389 | name = "num-traits" 1390 | version = "0.2.14" 1391 | source = "registry+https://github.com/rust-lang/crates.io-index" 1392 | checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" 1393 | dependencies = [ 1394 | "autocfg 1.0.1", 1395 | ] 1396 | 1397 | [[package]] 1398 | name = "num_cpus" 1399 | version = "1.13.0" 1400 | source = "registry+https://github.com/rust-lang/crates.io-index" 1401 | checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3" 1402 | dependencies = [ 1403 | "hermit-abi", 1404 | "libc", 1405 | ] 1406 | 1407 | [[package]] 1408 | name = "object" 1409 | version = "0.22.0" 1410 | source = "registry+https://github.com/rust-lang/crates.io-index" 1411 | checksum = "8d3b63360ec3cb337817c2dbd47ab4a0f170d285d8e5a2064600f3def1402397" 1412 | 1413 | [[package]] 1414 | name = "openssl" 1415 | version = "0.10.30" 1416 | source = "registry+https://github.com/rust-lang/crates.io-index" 1417 | checksum = "8d575eff3665419f9b83678ff2815858ad9d11567e082f5ac1814baba4e2bcb4" 1418 | dependencies = [ 1419 | "bitflags", 1420 | "cfg-if 0.1.10", 1421 | "foreign-types", 1422 | "lazy_static", 1423 | "libc", 1424 | "openssl-sys", 1425 | ] 1426 | 1427 | [[package]] 1428 | name = "openssl-probe" 1429 | version = "0.1.2" 1430 | source = "registry+https://github.com/rust-lang/crates.io-index" 1431 | checksum = "77af24da69f9d9341038eba93a073b1fdaaa1b788221b00a69bce9e762cb32de" 1432 | 1433 | [[package]] 1434 | name = "openssl-sys" 1435 | version = "0.9.58" 1436 | source = "registry+https://github.com/rust-lang/crates.io-index" 1437 | checksum = "a842db4709b604f0fe5d1170ae3565899be2ad3d9cbc72dedc789ac0511f78de" 1438 | dependencies = [ 1439 | "autocfg 1.0.1", 1440 | "cc", 1441 | "libc", 1442 | "pkg-config", 1443 | "vcpkg", 1444 | ] 1445 | 1446 | [[package]] 1447 | name = "ordered-float" 1448 | version = "1.1.0" 1449 | source = "registry+https://github.com/rust-lang/crates.io-index" 1450 | checksum = "3741934be594d77de1c8461ebcbbe866f585ea616a9753aa78f2bdc69f0e4579" 1451 | dependencies = [ 1452 | "num-traits", 1453 | ] 1454 | 1455 | [[package]] 1456 | name = "parking_lot" 1457 | version = "0.9.0" 1458 | source = "registry+https://github.com/rust-lang/crates.io-index" 1459 | checksum = "f842b1982eb6c2fe34036a4fbfb06dd185a3f5c8edfaacdf7d1ea10b07de6252" 1460 | dependencies = [ 1461 | "lock_api 0.3.4", 1462 | "parking_lot_core 0.6.2", 1463 | "rustc_version", 1464 | ] 1465 | 1466 | [[package]] 1467 | name = "parking_lot" 1468 | version = "0.11.1" 1469 | source = "registry+https://github.com/rust-lang/crates.io-index" 1470 | checksum = "6d7744ac029df22dca6284efe4e898991d28e3085c706c972bcd7da4a27a15eb" 1471 | dependencies = [ 1472 | "instant", 1473 | "lock_api 0.4.2", 1474 | "parking_lot_core 0.8.0", 1475 | ] 1476 | 1477 | [[package]] 1478 | name = "parking_lot_core" 1479 | version = "0.6.2" 1480 | source = "registry+https://github.com/rust-lang/crates.io-index" 1481 | checksum = "b876b1b9e7ac6e1a74a6da34d25c42e17e8862aa409cbbbdcfc8d86c6f3bc62b" 1482 | dependencies = [ 1483 | "cfg-if 0.1.10", 1484 | "cloudabi 0.0.3", 1485 | "libc", 1486 | "redox_syscall", 1487 | "rustc_version", 1488 | "smallvec 0.6.13", 1489 | "winapi 0.3.9", 1490 | ] 1491 | 1492 | [[package]] 1493 | name = "parking_lot_core" 1494 | version = "0.8.0" 1495 | source = "registry+https://github.com/rust-lang/crates.io-index" 1496 | checksum = "c361aa727dd08437f2f1447be8b59a33b0edd15e0fcee698f935613d9efbca9b" 1497 | dependencies = [ 1498 | "cfg-if 0.1.10", 1499 | "cloudabi 0.1.0", 1500 | "instant", 1501 | "libc", 1502 | "redox_syscall", 1503 | "smallvec 1.5.0", 1504 | "winapi 0.3.9", 1505 | ] 1506 | 1507 | [[package]] 1508 | name = "percent-encoding" 1509 | version = "1.0.1" 1510 | source = "registry+https://github.com/rust-lang/crates.io-index" 1511 | checksum = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831" 1512 | 1513 | [[package]] 1514 | name = "percent-encoding" 1515 | version = "2.1.0" 1516 | source = "registry+https://github.com/rust-lang/crates.io-index" 1517 | checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" 1518 | 1519 | [[package]] 1520 | name = "pkg-config" 1521 | version = "0.3.19" 1522 | source = "registry+https://github.com/rust-lang/crates.io-index" 1523 | checksum = "3831453b3449ceb48b6d9c7ad7c96d5ea673e9b470a1dc578c2ce6521230884c" 1524 | 1525 | [[package]] 1526 | name = "ppv-lite86" 1527 | version = "0.2.10" 1528 | source = "registry+https://github.com/rust-lang/crates.io-index" 1529 | checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857" 1530 | 1531 | [[package]] 1532 | name = "proc-macro-hack" 1533 | version = "0.5.19" 1534 | source = "registry+https://github.com/rust-lang/crates.io-index" 1535 | checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5" 1536 | 1537 | [[package]] 1538 | name = "proc-macro2" 1539 | version = "0.4.30" 1540 | source = "registry+https://github.com/rust-lang/crates.io-index" 1541 | checksum = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759" 1542 | dependencies = [ 1543 | "unicode-xid 0.1.0", 1544 | ] 1545 | 1546 | [[package]] 1547 | name = "proc-macro2" 1548 | version = "1.0.24" 1549 | source = "registry+https://github.com/rust-lang/crates.io-index" 1550 | checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71" 1551 | dependencies = [ 1552 | "unicode-xid 0.2.1", 1553 | ] 1554 | 1555 | [[package]] 1556 | name = "publicsuffix" 1557 | version = "1.5.4" 1558 | source = "registry+https://github.com/rust-lang/crates.io-index" 1559 | checksum = "3bbaa49075179162b49acac1c6aa45fb4dafb5f13cf6794276d77bc7fd95757b" 1560 | dependencies = [ 1561 | "error-chain", 1562 | "idna 0.2.0", 1563 | "lazy_static", 1564 | "regex", 1565 | "url 2.2.0", 1566 | ] 1567 | 1568 | [[package]] 1569 | name = "qstring" 1570 | version = "0.7.2" 1571 | source = "registry+https://github.com/rust-lang/crates.io-index" 1572 | checksum = "d464fae65fff2680baf48019211ce37aaec0c78e9264c84a3e484717f965104e" 1573 | dependencies = [ 1574 | "percent-encoding 2.1.0", 1575 | ] 1576 | 1577 | [[package]] 1578 | name = "quick-error" 1579 | version = "1.2.3" 1580 | source = "registry+https://github.com/rust-lang/crates.io-index" 1581 | checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" 1582 | 1583 | [[package]] 1584 | name = "quote" 1585 | version = "0.6.13" 1586 | source = "registry+https://github.com/rust-lang/crates.io-index" 1587 | checksum = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1" 1588 | dependencies = [ 1589 | "proc-macro2 0.4.30", 1590 | ] 1591 | 1592 | [[package]] 1593 | name = "quote" 1594 | version = "1.0.7" 1595 | source = "registry+https://github.com/rust-lang/crates.io-index" 1596 | checksum = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37" 1597 | dependencies = [ 1598 | "proc-macro2 1.0.24", 1599 | ] 1600 | 1601 | [[package]] 1602 | name = "rand" 1603 | version = "0.4.6" 1604 | source = "registry+https://github.com/rust-lang/crates.io-index" 1605 | checksum = "552840b97013b1a26992c11eac34bdd778e464601a4c2054b5f0bff7c6761293" 1606 | dependencies = [ 1607 | "fuchsia-cprng", 1608 | "libc", 1609 | "rand_core 0.3.1", 1610 | "rdrand", 1611 | "winapi 0.3.9", 1612 | ] 1613 | 1614 | [[package]] 1615 | name = "rand" 1616 | version = "0.6.5" 1617 | source = "registry+https://github.com/rust-lang/crates.io-index" 1618 | checksum = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca" 1619 | dependencies = [ 1620 | "autocfg 0.1.7", 1621 | "libc", 1622 | "rand_chacha 0.1.1", 1623 | "rand_core 0.4.2", 1624 | "rand_hc 0.1.0", 1625 | "rand_isaac", 1626 | "rand_jitter", 1627 | "rand_os", 1628 | "rand_pcg", 1629 | "rand_xorshift", 1630 | "winapi 0.3.9", 1631 | ] 1632 | 1633 | [[package]] 1634 | name = "rand" 1635 | version = "0.7.3" 1636 | source = "registry+https://github.com/rust-lang/crates.io-index" 1637 | checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" 1638 | dependencies = [ 1639 | "getrandom 0.1.15", 1640 | "libc", 1641 | "rand_chacha 0.2.2", 1642 | "rand_core 0.5.1", 1643 | "rand_hc 0.2.0", 1644 | ] 1645 | 1646 | [[package]] 1647 | name = "rand_chacha" 1648 | version = "0.1.1" 1649 | source = "registry+https://github.com/rust-lang/crates.io-index" 1650 | checksum = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef" 1651 | dependencies = [ 1652 | "autocfg 0.1.7", 1653 | "rand_core 0.3.1", 1654 | ] 1655 | 1656 | [[package]] 1657 | name = "rand_chacha" 1658 | version = "0.2.2" 1659 | source = "registry+https://github.com/rust-lang/crates.io-index" 1660 | checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" 1661 | dependencies = [ 1662 | "ppv-lite86", 1663 | "rand_core 0.5.1", 1664 | ] 1665 | 1666 | [[package]] 1667 | name = "rand_core" 1668 | version = "0.3.1" 1669 | source = "registry+https://github.com/rust-lang/crates.io-index" 1670 | checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" 1671 | dependencies = [ 1672 | "rand_core 0.4.2", 1673 | ] 1674 | 1675 | [[package]] 1676 | name = "rand_core" 1677 | version = "0.4.2" 1678 | source = "registry+https://github.com/rust-lang/crates.io-index" 1679 | checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc" 1680 | 1681 | [[package]] 1682 | name = "rand_core" 1683 | version = "0.5.1" 1684 | source = "registry+https://github.com/rust-lang/crates.io-index" 1685 | checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" 1686 | dependencies = [ 1687 | "getrandom 0.1.15", 1688 | ] 1689 | 1690 | [[package]] 1691 | name = "rand_hc" 1692 | version = "0.1.0" 1693 | source = "registry+https://github.com/rust-lang/crates.io-index" 1694 | checksum = "7b40677c7be09ae76218dc623efbf7b18e34bced3f38883af07bb75630a21bc4" 1695 | dependencies = [ 1696 | "rand_core 0.3.1", 1697 | ] 1698 | 1699 | [[package]] 1700 | name = "rand_hc" 1701 | version = "0.2.0" 1702 | source = "registry+https://github.com/rust-lang/crates.io-index" 1703 | checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" 1704 | dependencies = [ 1705 | "rand_core 0.5.1", 1706 | ] 1707 | 1708 | [[package]] 1709 | name = "rand_isaac" 1710 | version = "0.1.1" 1711 | source = "registry+https://github.com/rust-lang/crates.io-index" 1712 | checksum = "ded997c9d5f13925be2a6fd7e66bf1872597f759fd9dd93513dd7e92e5a5ee08" 1713 | dependencies = [ 1714 | "rand_core 0.3.1", 1715 | ] 1716 | 1717 | [[package]] 1718 | name = "rand_jitter" 1719 | version = "0.1.4" 1720 | source = "registry+https://github.com/rust-lang/crates.io-index" 1721 | checksum = "1166d5c91dc97b88d1decc3285bb0a99ed84b05cfd0bc2341bdf2d43fc41e39b" 1722 | dependencies = [ 1723 | "libc", 1724 | "rand_core 0.4.2", 1725 | "winapi 0.3.9", 1726 | ] 1727 | 1728 | [[package]] 1729 | name = "rand_os" 1730 | version = "0.1.3" 1731 | source = "registry+https://github.com/rust-lang/crates.io-index" 1732 | checksum = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071" 1733 | dependencies = [ 1734 | "cloudabi 0.0.3", 1735 | "fuchsia-cprng", 1736 | "libc", 1737 | "rand_core 0.4.2", 1738 | "rdrand", 1739 | "winapi 0.3.9", 1740 | ] 1741 | 1742 | [[package]] 1743 | name = "rand_pcg" 1744 | version = "0.1.2" 1745 | source = "registry+https://github.com/rust-lang/crates.io-index" 1746 | checksum = "abf9b09b01790cfe0364f52bf32995ea3c39f4d2dd011eac241d2914146d0b44" 1747 | dependencies = [ 1748 | "autocfg 0.1.7", 1749 | "rand_core 0.4.2", 1750 | ] 1751 | 1752 | [[package]] 1753 | name = "rand_xorshift" 1754 | version = "0.1.1" 1755 | source = "registry+https://github.com/rust-lang/crates.io-index" 1756 | checksum = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c" 1757 | dependencies = [ 1758 | "rand_core 0.3.1", 1759 | ] 1760 | 1761 | [[package]] 1762 | name = "rdrand" 1763 | version = "0.4.0" 1764 | source = "registry+https://github.com/rust-lang/crates.io-index" 1765 | checksum = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" 1766 | dependencies = [ 1767 | "rand_core 0.3.1", 1768 | ] 1769 | 1770 | [[package]] 1771 | name = "redox_syscall" 1772 | version = "0.1.57" 1773 | source = "registry+https://github.com/rust-lang/crates.io-index" 1774 | checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce" 1775 | 1776 | [[package]] 1777 | name = "redox_users" 1778 | version = "0.3.5" 1779 | source = "registry+https://github.com/rust-lang/crates.io-index" 1780 | checksum = "de0737333e7a9502c789a36d7c7fa6092a49895d4faa31ca5df163857ded2e9d" 1781 | dependencies = [ 1782 | "getrandom 0.1.15", 1783 | "redox_syscall", 1784 | "rust-argon2", 1785 | ] 1786 | 1787 | [[package]] 1788 | name = "regex" 1789 | version = "1.4.2" 1790 | source = "registry+https://github.com/rust-lang/crates.io-index" 1791 | checksum = "38cf2c13ed4745de91a5eb834e11c00bcc3709e773173b2ce4c56c9fbde04b9c" 1792 | dependencies = [ 1793 | "aho-corasick", 1794 | "memchr", 1795 | "regex-syntax", 1796 | "thread_local", 1797 | ] 1798 | 1799 | [[package]] 1800 | name = "regex-syntax" 1801 | version = "0.6.21" 1802 | source = "registry+https://github.com/rust-lang/crates.io-index" 1803 | checksum = "3b181ba2dcf07aaccad5448e8ead58db5b742cf85dfe035e2227f137a539a189" 1804 | 1805 | [[package]] 1806 | name = "remove_dir_all" 1807 | version = "0.5.3" 1808 | source = "registry+https://github.com/rust-lang/crates.io-index" 1809 | checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" 1810 | dependencies = [ 1811 | "winapi 0.3.9", 1812 | ] 1813 | 1814 | [[package]] 1815 | name = "reqwest" 1816 | version = "0.9.24" 1817 | source = "registry+https://github.com/rust-lang/crates.io-index" 1818 | checksum = "f88643aea3c1343c804950d7bf983bd2067f5ab59db6d613a08e05572f2714ab" 1819 | dependencies = [ 1820 | "base64 0.10.1", 1821 | "bytes", 1822 | "cookie", 1823 | "cookie_store", 1824 | "encoding_rs", 1825 | "flate2", 1826 | "futures", 1827 | "http", 1828 | "hyper", 1829 | "hyper-tls", 1830 | "log", 1831 | "mime", 1832 | "mime_guess", 1833 | "native-tls", 1834 | "serde", 1835 | "serde_json", 1836 | "serde_urlencoded 0.5.5", 1837 | "time", 1838 | "tokio", 1839 | "tokio-executor", 1840 | "tokio-io", 1841 | "tokio-threadpool", 1842 | "tokio-timer", 1843 | "url 1.7.2", 1844 | "uuid", 1845 | "winreg", 1846 | ] 1847 | 1848 | [[package]] 1849 | name = "resolv-conf" 1850 | version = "0.6.3" 1851 | source = "registry+https://github.com/rust-lang/crates.io-index" 1852 | checksum = "11834e137f3b14e309437a8276714eed3a80d1ef894869e510f2c0c0b98b9f4a" 1853 | dependencies = [ 1854 | "hostname", 1855 | "quick-error", 1856 | ] 1857 | 1858 | [[package]] 1859 | name = "rust-argon2" 1860 | version = "0.8.3" 1861 | source = "registry+https://github.com/rust-lang/crates.io-index" 1862 | checksum = "4b18820d944b33caa75a71378964ac46f58517c92b6ae5f762636247c09e78fb" 1863 | dependencies = [ 1864 | "base64 0.13.0", 1865 | "blake2b_simd", 1866 | "constant_time_eq", 1867 | "crossbeam-utils 0.8.1", 1868 | ] 1869 | 1870 | [[package]] 1871 | name = "rust-ini" 1872 | version = "0.13.0" 1873 | source = "registry+https://github.com/rust-lang/crates.io-index" 1874 | checksum = "3e52c148ef37f8c375d49d5a73aa70713125b7f19095948a923f80afdeb22ec2" 1875 | 1876 | [[package]] 1877 | name = "rustc-demangle" 1878 | version = "0.1.18" 1879 | source = "registry+https://github.com/rust-lang/crates.io-index" 1880 | checksum = "6e3bad0ee36814ca07d7968269dd4b7ec89ec2da10c4bb613928d3077083c232" 1881 | 1882 | [[package]] 1883 | name = "rustc_version" 1884 | version = "0.2.3" 1885 | source = "registry+https://github.com/rust-lang/crates.io-index" 1886 | checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" 1887 | dependencies = [ 1888 | "semver", 1889 | ] 1890 | 1891 | [[package]] 1892 | name = "rustyline" 1893 | version = "5.0.6" 1894 | source = "registry+https://github.com/rust-lang/crates.io-index" 1895 | checksum = "a23cb19702a8d6afb6edb3c842386e680d4883760e0df74e6848e23c2a87a635" 1896 | dependencies = [ 1897 | "cfg-if 0.1.10", 1898 | "dirs", 1899 | "libc", 1900 | "log", 1901 | "memchr", 1902 | "nix", 1903 | "unicode-segmentation", 1904 | "unicode-width", 1905 | "utf8parse", 1906 | "winapi 0.3.9", 1907 | ] 1908 | 1909 | [[package]] 1910 | name = "ryu" 1911 | version = "1.0.5" 1912 | source = "registry+https://github.com/rust-lang/crates.io-index" 1913 | checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" 1914 | 1915 | [[package]] 1916 | name = "schannel" 1917 | version = "0.1.19" 1918 | source = "registry+https://github.com/rust-lang/crates.io-index" 1919 | checksum = "8f05ba609c234e60bee0d547fe94a4c7e9da733d1c962cf6e59efa4cd9c8bc75" 1920 | dependencies = [ 1921 | "lazy_static", 1922 | "winapi 0.3.9", 1923 | ] 1924 | 1925 | [[package]] 1926 | name = "scopeguard" 1927 | version = "1.1.0" 1928 | source = "registry+https://github.com/rust-lang/crates.io-index" 1929 | checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" 1930 | 1931 | [[package]] 1932 | name = "security-framework" 1933 | version = "2.0.0" 1934 | source = "registry+https://github.com/rust-lang/crates.io-index" 1935 | checksum = "c1759c2e3c8580017a484a7ac56d3abc5a6c1feadf88db2f3633f12ae4268c69" 1936 | dependencies = [ 1937 | "bitflags", 1938 | "core-foundation", 1939 | "core-foundation-sys", 1940 | "libc", 1941 | "security-framework-sys", 1942 | ] 1943 | 1944 | [[package]] 1945 | name = "security-framework-sys" 1946 | version = "2.0.0" 1947 | source = "registry+https://github.com/rust-lang/crates.io-index" 1948 | checksum = "f99b9d5e26d2a71633cc4f2ebae7cc9f874044e0c351a27e17892d76dce5678b" 1949 | dependencies = [ 1950 | "core-foundation-sys", 1951 | "libc", 1952 | ] 1953 | 1954 | [[package]] 1955 | name = "semver" 1956 | version = "0.9.0" 1957 | source = "registry+https://github.com/rust-lang/crates.io-index" 1958 | checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" 1959 | dependencies = [ 1960 | "semver-parser", 1961 | ] 1962 | 1963 | [[package]] 1964 | name = "semver-parser" 1965 | version = "0.7.0" 1966 | source = "registry+https://github.com/rust-lang/crates.io-index" 1967 | checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" 1968 | 1969 | [[package]] 1970 | name = "serde" 1971 | version = "1.0.117" 1972 | source = "registry+https://github.com/rust-lang/crates.io-index" 1973 | checksum = "b88fa983de7720629c9387e9f517353ed404164b1e482c970a90c1a4aaf7dc1a" 1974 | dependencies = [ 1975 | "serde_derive", 1976 | ] 1977 | 1978 | [[package]] 1979 | name = "serde-value" 1980 | version = "0.6.0" 1981 | source = "registry+https://github.com/rust-lang/crates.io-index" 1982 | checksum = "5a65a7291a8a568adcae4c10a677ebcedbc6c9cec91c054dee2ce40b0e3290eb" 1983 | dependencies = [ 1984 | "ordered-float", 1985 | "serde", 1986 | ] 1987 | 1988 | [[package]] 1989 | name = "serde_derive" 1990 | version = "1.0.117" 1991 | source = "registry+https://github.com/rust-lang/crates.io-index" 1992 | checksum = "cbd1ae72adb44aab48f325a02444a5fc079349a8d804c1fc922aed3f7454c74e" 1993 | dependencies = [ 1994 | "proc-macro2 1.0.24", 1995 | "quote 1.0.7", 1996 | "syn 1.0.53", 1997 | ] 1998 | 1999 | [[package]] 2000 | name = "serde_json" 2001 | version = "1.0.59" 2002 | source = "registry+https://github.com/rust-lang/crates.io-index" 2003 | checksum = "dcac07dbffa1c65e7f816ab9eba78eb142c6d44410f4eeba1e26e4f5dfa56b95" 2004 | dependencies = [ 2005 | "itoa", 2006 | "ryu", 2007 | "serde", 2008 | ] 2009 | 2010 | [[package]] 2011 | name = "serde_urlencoded" 2012 | version = "0.5.5" 2013 | source = "registry+https://github.com/rust-lang/crates.io-index" 2014 | checksum = "642dd69105886af2efd227f75a520ec9b44a820d65bc133a9131f7d229fd165a" 2015 | dependencies = [ 2016 | "dtoa", 2017 | "itoa", 2018 | "serde", 2019 | "url 1.7.2", 2020 | ] 2021 | 2022 | [[package]] 2023 | name = "serde_urlencoded" 2024 | version = "0.6.1" 2025 | source = "registry+https://github.com/rust-lang/crates.io-index" 2026 | checksum = "9ec5d77e2d4c73717816afac02670d5c4f534ea95ed430442cad02e7a6e32c97" 2027 | dependencies = [ 2028 | "dtoa", 2029 | "itoa", 2030 | "serde", 2031 | "url 2.2.0", 2032 | ] 2033 | 2034 | [[package]] 2035 | name = "serde_yaml" 2036 | version = "0.8.14" 2037 | source = "registry+https://github.com/rust-lang/crates.io-index" 2038 | checksum = "f7baae0a99f1a324984bcdc5f0718384c1f69775f1c7eec8b859b71b443e3fd7" 2039 | dependencies = [ 2040 | "dtoa", 2041 | "linked-hash-map", 2042 | "serde", 2043 | "yaml-rust", 2044 | ] 2045 | 2046 | [[package]] 2047 | name = "sha1" 2048 | version = "0.6.0" 2049 | source = "registry+https://github.com/rust-lang/crates.io-index" 2050 | checksum = "2579985fda508104f7587689507983eadd6a6e84dd35d6d115361f530916fa0d" 2051 | 2052 | [[package]] 2053 | name = "sightingdb" 2054 | version = "0.0.4" 2055 | dependencies = [ 2056 | "actix-web", 2057 | "ansi_term 0.9.0", 2058 | "anyhow", 2059 | "atomicwrites", 2060 | "base64 0.10.1", 2061 | "bincode", 2062 | "chrono", 2063 | "clap", 2064 | "daemonize", 2065 | "dirs", 2066 | "flate2", 2067 | "log", 2068 | "log4rs", 2069 | "openssl", 2070 | "qstring", 2071 | "reqwest", 2072 | "rust-ini", 2073 | "rustyline", 2074 | "serde", 2075 | "serde_json", 2076 | ] 2077 | 2078 | [[package]] 2079 | name = "signal-hook-registry" 2080 | version = "1.2.2" 2081 | source = "registry+https://github.com/rust-lang/crates.io-index" 2082 | checksum = "ce32ea0c6c56d5eacaeb814fbed9960547021d3edd010ded1425f180536b20ab" 2083 | dependencies = [ 2084 | "libc", 2085 | ] 2086 | 2087 | [[package]] 2088 | name = "slab" 2089 | version = "0.4.2" 2090 | source = "registry+https://github.com/rust-lang/crates.io-index" 2091 | checksum = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8" 2092 | 2093 | [[package]] 2094 | name = "smallvec" 2095 | version = "0.6.13" 2096 | source = "registry+https://github.com/rust-lang/crates.io-index" 2097 | checksum = "f7b0758c52e15a8b5e3691eae6cc559f08eee9406e548a4477ba4e67770a82b6" 2098 | dependencies = [ 2099 | "maybe-uninit", 2100 | ] 2101 | 2102 | [[package]] 2103 | name = "smallvec" 2104 | version = "1.5.0" 2105 | source = "registry+https://github.com/rust-lang/crates.io-index" 2106 | checksum = "7acad6f34eb9e8a259d3283d1e8c1d34d7415943d4895f65cc73813c7396fc85" 2107 | 2108 | [[package]] 2109 | name = "socket2" 2110 | version = "0.3.17" 2111 | source = "registry+https://github.com/rust-lang/crates.io-index" 2112 | checksum = "2c29947abdee2a218277abeca306f25789c938e500ea5a9d4b12a5a504466902" 2113 | dependencies = [ 2114 | "cfg-if 1.0.0", 2115 | "libc", 2116 | "redox_syscall", 2117 | "winapi 0.3.9", 2118 | ] 2119 | 2120 | [[package]] 2121 | name = "string" 2122 | version = "0.2.1" 2123 | source = "registry+https://github.com/rust-lang/crates.io-index" 2124 | checksum = "d24114bfcceb867ca7f71a0d3fe45d45619ec47a6fbfa98cb14e14250bfa5d6d" 2125 | dependencies = [ 2126 | "bytes", 2127 | ] 2128 | 2129 | [[package]] 2130 | name = "strsim" 2131 | version = "0.8.0" 2132 | source = "registry+https://github.com/rust-lang/crates.io-index" 2133 | checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" 2134 | 2135 | [[package]] 2136 | name = "syn" 2137 | version = "0.15.44" 2138 | source = "registry+https://github.com/rust-lang/crates.io-index" 2139 | checksum = "9ca4b3b69a77cbe1ffc9e198781b7acb0c7365a883670e8f1c1bc66fba79a5c5" 2140 | dependencies = [ 2141 | "proc-macro2 0.4.30", 2142 | "quote 0.6.13", 2143 | "unicode-xid 0.1.0", 2144 | ] 2145 | 2146 | [[package]] 2147 | name = "syn" 2148 | version = "1.0.53" 2149 | source = "registry+https://github.com/rust-lang/crates.io-index" 2150 | checksum = "8833e20724c24de12bbaba5ad230ea61c3eafb05b881c7c9d3cfe8638b187e68" 2151 | dependencies = [ 2152 | "proc-macro2 1.0.24", 2153 | "quote 1.0.7", 2154 | "unicode-xid 0.2.1", 2155 | ] 2156 | 2157 | [[package]] 2158 | name = "synstructure" 2159 | version = "0.12.4" 2160 | source = "registry+https://github.com/rust-lang/crates.io-index" 2161 | checksum = "b834f2d66f734cb897113e34aaff2f1ab4719ca946f9a7358dba8f8064148701" 2162 | dependencies = [ 2163 | "proc-macro2 1.0.24", 2164 | "quote 1.0.7", 2165 | "syn 1.0.53", 2166 | "unicode-xid 0.2.1", 2167 | ] 2168 | 2169 | [[package]] 2170 | name = "tempdir" 2171 | version = "0.3.7" 2172 | source = "registry+https://github.com/rust-lang/crates.io-index" 2173 | checksum = "15f2b5fb00ccdf689e0149d1b1b3c03fead81c2b37735d812fa8bddbbf41b6d8" 2174 | dependencies = [ 2175 | "rand 0.4.6", 2176 | "remove_dir_all", 2177 | ] 2178 | 2179 | [[package]] 2180 | name = "tempfile" 2181 | version = "3.1.0" 2182 | source = "registry+https://github.com/rust-lang/crates.io-index" 2183 | checksum = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9" 2184 | dependencies = [ 2185 | "cfg-if 0.1.10", 2186 | "libc", 2187 | "rand 0.7.3", 2188 | "redox_syscall", 2189 | "remove_dir_all", 2190 | "winapi 0.3.9", 2191 | ] 2192 | 2193 | [[package]] 2194 | name = "textwrap" 2195 | version = "0.11.0" 2196 | source = "registry+https://github.com/rust-lang/crates.io-index" 2197 | checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" 2198 | dependencies = [ 2199 | "unicode-width", 2200 | ] 2201 | 2202 | [[package]] 2203 | name = "thread-id" 2204 | version = "3.3.0" 2205 | source = "registry+https://github.com/rust-lang/crates.io-index" 2206 | checksum = "c7fbf4c9d56b320106cd64fd024dadfa0be7cb4706725fc44a7d7ce952d820c1" 2207 | dependencies = [ 2208 | "libc", 2209 | "redox_syscall", 2210 | "winapi 0.3.9", 2211 | ] 2212 | 2213 | [[package]] 2214 | name = "thread_local" 2215 | version = "1.0.1" 2216 | source = "registry+https://github.com/rust-lang/crates.io-index" 2217 | checksum = "d40c6d1b69745a6ec6fb1ca717914848da4b44ae29d9b3080cbee91d72a69b14" 2218 | dependencies = [ 2219 | "lazy_static", 2220 | ] 2221 | 2222 | [[package]] 2223 | name = "threadpool" 2224 | version = "1.8.1" 2225 | source = "registry+https://github.com/rust-lang/crates.io-index" 2226 | checksum = "d050e60b33d41c19108b32cea32164033a9013fe3b46cbd4457559bfbf77afaa" 2227 | dependencies = [ 2228 | "num_cpus", 2229 | ] 2230 | 2231 | [[package]] 2232 | name = "time" 2233 | version = "0.1.44" 2234 | source = "registry+https://github.com/rust-lang/crates.io-index" 2235 | checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255" 2236 | dependencies = [ 2237 | "libc", 2238 | "wasi 0.10.0+wasi-snapshot-preview1", 2239 | "winapi 0.3.9", 2240 | ] 2241 | 2242 | [[package]] 2243 | name = "tiny-keccak" 2244 | version = "2.0.2" 2245 | source = "registry+https://github.com/rust-lang/crates.io-index" 2246 | checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237" 2247 | dependencies = [ 2248 | "crunchy", 2249 | ] 2250 | 2251 | [[package]] 2252 | name = "tinyvec" 2253 | version = "1.1.0" 2254 | source = "registry+https://github.com/rust-lang/crates.io-index" 2255 | checksum = "ccf8dbc19eb42fba10e8feaaec282fb50e2c14b2726d6301dbfeed0f73306a6f" 2256 | dependencies = [ 2257 | "tinyvec_macros", 2258 | ] 2259 | 2260 | [[package]] 2261 | name = "tinyvec_macros" 2262 | version = "0.1.0" 2263 | source = "registry+https://github.com/rust-lang/crates.io-index" 2264 | checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" 2265 | 2266 | [[package]] 2267 | name = "tokio" 2268 | version = "0.1.22" 2269 | source = "registry+https://github.com/rust-lang/crates.io-index" 2270 | checksum = "5a09c0b5bb588872ab2f09afa13ee6e9dac11e10a0ec9e8e3ba39a5a5d530af6" 2271 | dependencies = [ 2272 | "bytes", 2273 | "futures", 2274 | "mio", 2275 | "num_cpus", 2276 | "tokio-current-thread", 2277 | "tokio-executor", 2278 | "tokio-io", 2279 | "tokio-reactor", 2280 | "tokio-tcp", 2281 | "tokio-threadpool", 2282 | "tokio-timer", 2283 | ] 2284 | 2285 | [[package]] 2286 | name = "tokio-buf" 2287 | version = "0.1.1" 2288 | source = "registry+https://github.com/rust-lang/crates.io-index" 2289 | checksum = "8fb220f46c53859a4b7ec083e41dec9778ff0b1851c0942b211edb89e0ccdc46" 2290 | dependencies = [ 2291 | "bytes", 2292 | "either", 2293 | "futures", 2294 | ] 2295 | 2296 | [[package]] 2297 | name = "tokio-codec" 2298 | version = "0.1.2" 2299 | source = "registry+https://github.com/rust-lang/crates.io-index" 2300 | checksum = "25b2998660ba0e70d18684de5d06b70b70a3a747469af9dea7618cc59e75976b" 2301 | dependencies = [ 2302 | "bytes", 2303 | "futures", 2304 | "tokio-io", 2305 | ] 2306 | 2307 | [[package]] 2308 | name = "tokio-current-thread" 2309 | version = "0.1.7" 2310 | source = "registry+https://github.com/rust-lang/crates.io-index" 2311 | checksum = "b1de0e32a83f131e002238d7ccde18211c0a5397f60cbfffcb112868c2e0e20e" 2312 | dependencies = [ 2313 | "futures", 2314 | "tokio-executor", 2315 | ] 2316 | 2317 | [[package]] 2318 | name = "tokio-executor" 2319 | version = "0.1.10" 2320 | source = "registry+https://github.com/rust-lang/crates.io-index" 2321 | checksum = "fb2d1b8f4548dbf5e1f7818512e9c406860678f29c300cdf0ebac72d1a3a1671" 2322 | dependencies = [ 2323 | "crossbeam-utils 0.7.2", 2324 | "futures", 2325 | ] 2326 | 2327 | [[package]] 2328 | name = "tokio-io" 2329 | version = "0.1.13" 2330 | source = "registry+https://github.com/rust-lang/crates.io-index" 2331 | checksum = "57fc868aae093479e3131e3d165c93b1c7474109d13c90ec0dda2a1bbfff0674" 2332 | dependencies = [ 2333 | "bytes", 2334 | "futures", 2335 | "log", 2336 | ] 2337 | 2338 | [[package]] 2339 | name = "tokio-openssl" 2340 | version = "0.3.0" 2341 | source = "registry+https://github.com/rust-lang/crates.io-index" 2342 | checksum = "771d6246b170ae108d67d9963c23f31a579016c016d73bd4bd7d6ef0252afda7" 2343 | dependencies = [ 2344 | "futures", 2345 | "openssl", 2346 | "tokio-io", 2347 | ] 2348 | 2349 | [[package]] 2350 | name = "tokio-reactor" 2351 | version = "0.1.12" 2352 | source = "registry+https://github.com/rust-lang/crates.io-index" 2353 | checksum = "09bc590ec4ba8ba87652da2068d150dcada2cfa2e07faae270a5e0409aa51351" 2354 | dependencies = [ 2355 | "crossbeam-utils 0.7.2", 2356 | "futures", 2357 | "lazy_static", 2358 | "log", 2359 | "mio", 2360 | "num_cpus", 2361 | "parking_lot 0.9.0", 2362 | "slab", 2363 | "tokio-executor", 2364 | "tokio-io", 2365 | "tokio-sync", 2366 | ] 2367 | 2368 | [[package]] 2369 | name = "tokio-signal" 2370 | version = "0.2.9" 2371 | source = "registry+https://github.com/rust-lang/crates.io-index" 2372 | checksum = "d0c34c6e548f101053321cba3da7cbb87a610b85555884c41b07da2eb91aff12" 2373 | dependencies = [ 2374 | "futures", 2375 | "libc", 2376 | "mio", 2377 | "mio-uds", 2378 | "signal-hook-registry", 2379 | "tokio-executor", 2380 | "tokio-io", 2381 | "tokio-reactor", 2382 | "winapi 0.3.9", 2383 | ] 2384 | 2385 | [[package]] 2386 | name = "tokio-sync" 2387 | version = "0.1.8" 2388 | source = "registry+https://github.com/rust-lang/crates.io-index" 2389 | checksum = "edfe50152bc8164fcc456dab7891fa9bf8beaf01c5ee7e1dd43a397c3cf87dee" 2390 | dependencies = [ 2391 | "fnv", 2392 | "futures", 2393 | ] 2394 | 2395 | [[package]] 2396 | name = "tokio-tcp" 2397 | version = "0.1.4" 2398 | source = "registry+https://github.com/rust-lang/crates.io-index" 2399 | checksum = "98df18ed66e3b72e742f185882a9e201892407957e45fbff8da17ae7a7c51f72" 2400 | dependencies = [ 2401 | "bytes", 2402 | "futures", 2403 | "iovec", 2404 | "mio", 2405 | "tokio-io", 2406 | "tokio-reactor", 2407 | ] 2408 | 2409 | [[package]] 2410 | name = "tokio-threadpool" 2411 | version = "0.1.18" 2412 | source = "registry+https://github.com/rust-lang/crates.io-index" 2413 | checksum = "df720b6581784c118f0eb4310796b12b1d242a7eb95f716a8367855325c25f89" 2414 | dependencies = [ 2415 | "crossbeam-deque", 2416 | "crossbeam-queue", 2417 | "crossbeam-utils 0.7.2", 2418 | "futures", 2419 | "lazy_static", 2420 | "log", 2421 | "num_cpus", 2422 | "slab", 2423 | "tokio-executor", 2424 | ] 2425 | 2426 | [[package]] 2427 | name = "tokio-timer" 2428 | version = "0.2.13" 2429 | source = "registry+https://github.com/rust-lang/crates.io-index" 2430 | checksum = "93044f2d313c95ff1cb7809ce9a7a05735b012288a888b62d4434fd58c94f296" 2431 | dependencies = [ 2432 | "crossbeam-utils 0.7.2", 2433 | "futures", 2434 | "slab", 2435 | "tokio-executor", 2436 | ] 2437 | 2438 | [[package]] 2439 | name = "tokio-udp" 2440 | version = "0.1.6" 2441 | source = "registry+https://github.com/rust-lang/crates.io-index" 2442 | checksum = "e2a0b10e610b39c38b031a2fcab08e4b82f16ece36504988dcbd81dbba650d82" 2443 | dependencies = [ 2444 | "bytes", 2445 | "futures", 2446 | "log", 2447 | "mio", 2448 | "tokio-codec", 2449 | "tokio-io", 2450 | "tokio-reactor", 2451 | ] 2452 | 2453 | [[package]] 2454 | name = "traitobject" 2455 | version = "0.1.0" 2456 | source = "registry+https://github.com/rust-lang/crates.io-index" 2457 | checksum = "efd1f82c56340fdf16f2a953d7bda4f8fdffba13d93b00844c25572110b26079" 2458 | 2459 | [[package]] 2460 | name = "trust-dns-proto" 2461 | version = "0.7.4" 2462 | source = "registry+https://github.com/rust-lang/crates.io-index" 2463 | checksum = "5559ebdf6c2368ddd11e20b11d6bbaf9e46deb803acd7815e93f5a7b4a6d2901" 2464 | dependencies = [ 2465 | "byteorder", 2466 | "enum-as-inner", 2467 | "failure", 2468 | "futures", 2469 | "idna 0.1.5", 2470 | "lazy_static", 2471 | "log", 2472 | "rand 0.6.5", 2473 | "smallvec 0.6.13", 2474 | "socket2", 2475 | "tokio-executor", 2476 | "tokio-io", 2477 | "tokio-reactor", 2478 | "tokio-tcp", 2479 | "tokio-timer", 2480 | "tokio-udp", 2481 | "url 1.7.2", 2482 | ] 2483 | 2484 | [[package]] 2485 | name = "trust-dns-resolver" 2486 | version = "0.11.1" 2487 | source = "registry+https://github.com/rust-lang/crates.io-index" 2488 | checksum = "6c9992e58dba365798803c0b91018ff6c8d3fc77e06977c4539af2a6bfe0a039" 2489 | dependencies = [ 2490 | "cfg-if 0.1.10", 2491 | "failure", 2492 | "futures", 2493 | "ipconfig", 2494 | "lazy_static", 2495 | "log", 2496 | "lru-cache", 2497 | "resolv-conf", 2498 | "smallvec 0.6.13", 2499 | "tokio-executor", 2500 | "trust-dns-proto", 2501 | ] 2502 | 2503 | [[package]] 2504 | name = "try-lock" 2505 | version = "0.2.3" 2506 | source = "registry+https://github.com/rust-lang/crates.io-index" 2507 | checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642" 2508 | 2509 | [[package]] 2510 | name = "try_from" 2511 | version = "0.3.2" 2512 | source = "registry+https://github.com/rust-lang/crates.io-index" 2513 | checksum = "283d3b89e1368717881a9d51dad843cc435380d8109c9e47d38780a324698d8b" 2514 | dependencies = [ 2515 | "cfg-if 0.1.10", 2516 | ] 2517 | 2518 | [[package]] 2519 | name = "typemap" 2520 | version = "0.3.3" 2521 | source = "registry+https://github.com/rust-lang/crates.io-index" 2522 | checksum = "653be63c80a3296da5551e1bfd2cca35227e13cdd08c6668903ae2f4f77aa1f6" 2523 | dependencies = [ 2524 | "unsafe-any", 2525 | ] 2526 | 2527 | [[package]] 2528 | name = "unicase" 2529 | version = "2.6.0" 2530 | source = "registry+https://github.com/rust-lang/crates.io-index" 2531 | checksum = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6" 2532 | dependencies = [ 2533 | "version_check", 2534 | ] 2535 | 2536 | [[package]] 2537 | name = "unicode-bidi" 2538 | version = "0.3.4" 2539 | source = "registry+https://github.com/rust-lang/crates.io-index" 2540 | checksum = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5" 2541 | dependencies = [ 2542 | "matches", 2543 | ] 2544 | 2545 | [[package]] 2546 | name = "unicode-normalization" 2547 | version = "0.1.16" 2548 | source = "registry+https://github.com/rust-lang/crates.io-index" 2549 | checksum = "a13e63ab62dbe32aeee58d1c5408d35c36c392bba5d9d3142287219721afe606" 2550 | dependencies = [ 2551 | "tinyvec", 2552 | ] 2553 | 2554 | [[package]] 2555 | name = "unicode-segmentation" 2556 | version = "1.7.1" 2557 | source = "registry+https://github.com/rust-lang/crates.io-index" 2558 | checksum = "bb0d2e7be6ae3a5fa87eed5fb451aff96f2573d2694942e40543ae0bbe19c796" 2559 | 2560 | [[package]] 2561 | name = "unicode-width" 2562 | version = "0.1.8" 2563 | source = "registry+https://github.com/rust-lang/crates.io-index" 2564 | checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3" 2565 | 2566 | [[package]] 2567 | name = "unicode-xid" 2568 | version = "0.1.0" 2569 | source = "registry+https://github.com/rust-lang/crates.io-index" 2570 | checksum = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" 2571 | 2572 | [[package]] 2573 | name = "unicode-xid" 2574 | version = "0.2.1" 2575 | source = "registry+https://github.com/rust-lang/crates.io-index" 2576 | checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" 2577 | 2578 | [[package]] 2579 | name = "unsafe-any" 2580 | version = "0.4.2" 2581 | source = "registry+https://github.com/rust-lang/crates.io-index" 2582 | checksum = "f30360d7979f5e9c6e6cea48af192ea8fab4afb3cf72597154b8f08935bc9c7f" 2583 | dependencies = [ 2584 | "traitobject", 2585 | ] 2586 | 2587 | [[package]] 2588 | name = "url" 2589 | version = "1.7.2" 2590 | source = "registry+https://github.com/rust-lang/crates.io-index" 2591 | checksum = "dd4e7c0d531266369519a4aa4f399d748bd37043b00bde1e4ff1f60a120b355a" 2592 | dependencies = [ 2593 | "idna 0.1.5", 2594 | "matches", 2595 | "percent-encoding 1.0.1", 2596 | ] 2597 | 2598 | [[package]] 2599 | name = "url" 2600 | version = "2.2.0" 2601 | source = "registry+https://github.com/rust-lang/crates.io-index" 2602 | checksum = "5909f2b0817350449ed73e8bcd81c8c3c8d9a7a5d8acba4b27db277f1868976e" 2603 | dependencies = [ 2604 | "form_urlencoded", 2605 | "idna 0.2.0", 2606 | "matches", 2607 | "percent-encoding 2.1.0", 2608 | ] 2609 | 2610 | [[package]] 2611 | name = "utf8parse" 2612 | version = "0.1.1" 2613 | source = "registry+https://github.com/rust-lang/crates.io-index" 2614 | checksum = "8772a4ccbb4e89959023bc5b7cb8623a795caa7092d99f3aa9501b9484d4557d" 2615 | 2616 | [[package]] 2617 | name = "uuid" 2618 | version = "0.7.4" 2619 | source = "registry+https://github.com/rust-lang/crates.io-index" 2620 | checksum = "90dbc611eb48397705a6b0f6e917da23ae517e4d127123d2cf7674206627d32a" 2621 | dependencies = [ 2622 | "rand 0.6.5", 2623 | ] 2624 | 2625 | [[package]] 2626 | name = "vcpkg" 2627 | version = "0.2.10" 2628 | source = "registry+https://github.com/rust-lang/crates.io-index" 2629 | checksum = "6454029bf181f092ad1b853286f23e2c507d8e8194d01d92da4a55c274a5508c" 2630 | 2631 | [[package]] 2632 | name = "vec_map" 2633 | version = "0.8.2" 2634 | source = "registry+https://github.com/rust-lang/crates.io-index" 2635 | checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" 2636 | 2637 | [[package]] 2638 | name = "version_check" 2639 | version = "0.9.2" 2640 | source = "registry+https://github.com/rust-lang/crates.io-index" 2641 | checksum = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed" 2642 | 2643 | [[package]] 2644 | name = "void" 2645 | version = "1.0.2" 2646 | source = "registry+https://github.com/rust-lang/crates.io-index" 2647 | checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" 2648 | 2649 | [[package]] 2650 | name = "want" 2651 | version = "0.2.0" 2652 | source = "registry+https://github.com/rust-lang/crates.io-index" 2653 | checksum = "b6395efa4784b027708f7451087e647ec73cc74f5d9bc2e418404248d679a230" 2654 | dependencies = [ 2655 | "futures", 2656 | "log", 2657 | "try-lock", 2658 | ] 2659 | 2660 | [[package]] 2661 | name = "wasi" 2662 | version = "0.9.0+wasi-snapshot-preview1" 2663 | source = "registry+https://github.com/rust-lang/crates.io-index" 2664 | checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" 2665 | 2666 | [[package]] 2667 | name = "wasi" 2668 | version = "0.10.0+wasi-snapshot-preview1" 2669 | source = "registry+https://github.com/rust-lang/crates.io-index" 2670 | checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" 2671 | 2672 | [[package]] 2673 | name = "widestring" 2674 | version = "0.4.3" 2675 | source = "registry+https://github.com/rust-lang/crates.io-index" 2676 | checksum = "c168940144dd21fd8046987c16a46a33d5fc84eec29ef9dcddc2ac9e31526b7c" 2677 | 2678 | [[package]] 2679 | name = "winapi" 2680 | version = "0.2.8" 2681 | source = "registry+https://github.com/rust-lang/crates.io-index" 2682 | checksum = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" 2683 | 2684 | [[package]] 2685 | name = "winapi" 2686 | version = "0.3.9" 2687 | source = "registry+https://github.com/rust-lang/crates.io-index" 2688 | checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" 2689 | dependencies = [ 2690 | "winapi-i686-pc-windows-gnu", 2691 | "winapi-x86_64-pc-windows-gnu", 2692 | ] 2693 | 2694 | [[package]] 2695 | name = "winapi-build" 2696 | version = "0.1.1" 2697 | source = "registry+https://github.com/rust-lang/crates.io-index" 2698 | checksum = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" 2699 | 2700 | [[package]] 2701 | name = "winapi-i686-pc-windows-gnu" 2702 | version = "0.4.0" 2703 | source = "registry+https://github.com/rust-lang/crates.io-index" 2704 | checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 2705 | 2706 | [[package]] 2707 | name = "winapi-x86_64-pc-windows-gnu" 2708 | version = "0.4.0" 2709 | source = "registry+https://github.com/rust-lang/crates.io-index" 2710 | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 2711 | 2712 | [[package]] 2713 | name = "winreg" 2714 | version = "0.6.2" 2715 | source = "registry+https://github.com/rust-lang/crates.io-index" 2716 | checksum = "b2986deb581c4fe11b621998a5e53361efe6b48a151178d0cd9eeffa4dc6acc9" 2717 | dependencies = [ 2718 | "winapi 0.3.9", 2719 | ] 2720 | 2721 | [[package]] 2722 | name = "ws2_32-sys" 2723 | version = "0.2.1" 2724 | source = "registry+https://github.com/rust-lang/crates.io-index" 2725 | checksum = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e" 2726 | dependencies = [ 2727 | "winapi 0.2.8", 2728 | "winapi-build", 2729 | ] 2730 | 2731 | [[package]] 2732 | name = "yaml-rust" 2733 | version = "0.4.4" 2734 | source = "registry+https://github.com/rust-lang/crates.io-index" 2735 | checksum = "39f0c922f1a334134dc2f7a8b67dc5d25f0735263feec974345ff706bcf20b0d" 2736 | dependencies = [ 2737 | "linked-hash-map", 2738 | ] 2739 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "sightingdb" 3 | version = "0.0.4" 4 | authors = ["Sebastien Tricaud "] 5 | edition = "2018" 6 | 7 | [[bin]] 8 | name = "sightingdb" 9 | path = "src/main.rs" 10 | 11 | [dependencies] 12 | dirs = "2.0.2" 13 | rustyline = "5.0.0" 14 | 15 | reqwest = "0.9.18" 16 | daemonize = "0.4.1" 17 | 18 | serde = "1.0.94" 19 | serde_json = { version = "1.0.39", features = ["arbitrary_precision"] } 20 | 21 | ansi_term = "0.9" 22 | atomicwrites = "0.2.3" 23 | #protobuf = "2.6.2" 24 | 25 | rust-ini = "0.13.0" 26 | log4rs = "0.13.0" 27 | log = "0.4.11" 28 | openssl = "0.10.23" 29 | base64 = "0.10.1" 30 | #memory-balloon = "0.1.0" 31 | clap = "2.33.0" 32 | qstring = "0.7.0" 33 | anyhow = "1.0.34" 34 | 35 | bincode = "*" 36 | flate2 = "*" 37 | 38 | [dependencies.chrono] 39 | version = "0.4.7" 40 | features = ["serde"] 41 | 42 | [dependencies.actix-web] 43 | version = "1.0.0" 44 | features = ["ssl"] 45 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (C) 2019 Devo, Inc. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | all: sightingdb 2 | 3 | sightingdb: src/main.rs src/main.rs 4 | cargo build 5 | 6 | release: src/main.rs src/main.rs 7 | cargo build --release 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | 3 | SightingDB is a database designed for Sightings, a technique to count items. This is helpful for Threat Intelligence as Sightings allow 4 | to enrich indicators or attributes with Observations, rather than Reputation. 5 | 6 | Simply speaking, by pushing data to SightingDB, you will get the first time it was observed, the last time, its count. 7 | 8 | However, it will also provide the following features: 9 | * Keep track of how many times something was searched 10 | * Keep track of the hourly statistics per item 11 | * Get the consensus for each item (how many times the same value exists in another namespace) 12 | 13 | SightingDB is designed to scale writing and reading. 14 | 15 | Building 16 | ======== 17 | 18 | 1) Make sure you have Rust and Cargo installed 19 | 2) Run ''make'' 20 | 21 | Running 22 | ======= 23 | 24 | To run from the source directory: 25 | 26 | 1. Generate a certificate: `cd etc; mkdir ssl; cd ssl; openssl req -new -newkey rsa:2048 -days 365 -nodes -x509 -keyout key.pem -out cert.pem; cd ../..` 27 | 2. `ln -s etc/ssl ssl` 28 | 3. `ln -s etc/sighting-daemon.ini sighting-daemon.ini` 29 | 4. Start the Sighting DB: ./target/debug/sighting-daemon 30 | 31 | Client Demo 32 | =========== 33 | 34 | Writing 35 | ------- 36 | $ curl -k https://localhost:9999/w/my/namespace/?val=127.0.0.1 37 | {"message":"ok"} 38 | $ curl -k https://localhost:9999/w/another/namespace/?val=127.0.0.1 39 | {"message":"ok"} 40 | $ curl -k https://localhost:9999/w/another/namespace/?val=127.0.0.1 41 | {"message":"ok"} 42 | 43 | Reading 44 | ------- 45 | $ curl -k https://localhost:9999/r/my/namespace/?val=$(b64 127.0.0.1) 46 | {"value":"127.0.0.1","first_seen":1566624658,"last_seen":1566624658,"count":1,"tag":"","ttl":0,"consensus":2} 47 | 48 | $ curl -k https://localhost:9999/r/another/namespace/?val=127.0.0.1 49 | {"value":"127.0.0.1","first_seen":1566624686,"last_seen":1566624689,"count":2,"tag":"","ttl":0,"consensus":2} 50 | 51 | $ curl -k https://localhost:9999/rs/my/namespace/?val=127.0.0.1 52 | {"value":"127.0.0.1","first_seen":1593719022,"last_seen":1593721509,"count":10,"tags":"","ttl":0,"stats":{"1593716400":2,"1593720000":8},"consensus":1} 53 | 54 | Authentication 55 | -------------- 56 | $ curl -H 'Authorization: changeme' -k https://localhost:9999/w/my/namespace/?val=127.0.0.1 57 | {"message":"ok"} 58 | 59 | REST Endpoints 60 | ============== 61 | /w: write (GET) 62 | /wb: write in bulk mode (POST) 63 | /r: read (GET) 64 | /rs: read with statistics (GET) 65 | /rb: read in bulk mode (POST) 66 | /rbs: read with statistics in bulk mode (POST) 67 | /d: delete (GET) 68 | /c: configure (GET) 69 | /i: info (GET) -------------------------------------------------------------------------------- /doc/sightingdb-logo-32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stricaud/sightingdb/242c492f8d0bb64a77ffcbe6efea3cb596b9140a/doc/sightingdb-logo-32.png -------------------------------------------------------------------------------- /doc/sightingdb-logo-64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stricaud/sightingdb/242c492f8d0bb64a77ffcbe6efea3cb596b9140a/doc/sightingdb-logo-64.png -------------------------------------------------------------------------------- /doc/sightingdb-logo-large.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stricaud/sightingdb/242c492f8d0bb64a77ffcbe6efea3cb596b9140a/doc/sightingdb-logo-large.png -------------------------------------------------------------------------------- /doc/sightingdb-logo2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stricaud/sightingdb/242c492f8d0bb64a77ffcbe6efea3cb596b9140a/doc/sightingdb-logo2.png -------------------------------------------------------------------------------- /doc/sightingdb-logo2.svg: -------------------------------------------------------------------------------- 1 | 2 | 17 | 19 | 28 | 37 | 40 | 49 | 50 | 53 | 62 | 63 | 66 | 74 | 75 | 76 | 96 | 98 | 99 | 101 | image/svg+xml 102 | 104 | 105 | 106 | 107 | 108 | 112 | 116 | 125 | 133 | 134 | 149 | 164 | 179 | 194 | 210 | 225 | 240 | 255 | 271 | 287 | 303 | 319 | 335 | 351 | 367 | 368 | 369 | -------------------------------------------------------------------------------- /doc/sightingdb-logo2_128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stricaud/sightingdb/242c492f8d0bb64a77ffcbe6efea3cb596b9140a/doc/sightingdb-logo2_128.png -------------------------------------------------------------------------------- /doc/sightingdb-logo2_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stricaud/sightingdb/242c492f8d0bb64a77ffcbe6efea3cb596b9140a/doc/sightingdb-logo2_64.png -------------------------------------------------------------------------------- /doc/sightingdb-logo3.svg: -------------------------------------------------------------------------------- 1 | 2 | 17 | 19 | 28 | 37 | 40 | 49 | 50 | 53 | 62 | 63 | 66 | 74 | 75 | 76 | 96 | 98 | 99 | 101 | image/svg+xml 102 | 104 | 105 | 106 | 107 | 108 | 112 | 128 | 143 | 158 | 173 | 189 | 204 | 219 | 234 | 250 | 266 | 282 | 298 | 314 | 330 | 346 | 361 | 376 | 391 | 406 | 421 | 437 | 453 | 469 | 485 | 501 | 516 | 531 | 546 | 561 | 576 | 592 | 608 | 624 | 640 | 656 | 671 | 686 | 701 | 716 | 731 | 747 | 763 | 779 | 795 | 811 | 826 | 841 | 856 | 872 | 873 | 874 | -------------------------------------------------------------------------------- /doc/sightingdb-logo3_128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stricaud/sightingdb/242c492f8d0bb64a77ffcbe6efea3cb596b9140a/doc/sightingdb-logo3_128.png -------------------------------------------------------------------------------- /doc/sightingdb-logo3_256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stricaud/sightingdb/242c492f8d0bb64a77ffcbe6efea3cb596b9140a/doc/sightingdb-logo3_256.png -------------------------------------------------------------------------------- /doc/sightingdb-logo3_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stricaud/sightingdb/242c492f8d0bb64a77ffcbe6efea3cb596b9140a/doc/sightingdb-logo3_64.png -------------------------------------------------------------------------------- /doc/sightingdb-spec.txt: -------------------------------------------------------------------------------- 1 | Sighting DB Specification 2 | ========================= 3 | 4 | The goal of Sighting is to give automated context to a given Attribute. 5 | 6 | An Attribute, commonly known as an indicator in the Threat Intelligence Landscape can be anything, but usually falls 7 | into one of those categories: 8 | 9 | * IP Address 10 | * URL 11 | * Host 12 | * Hash 13 | * String in memory 14 | * ... 15 | 16 | Attribute Storage 17 | ----------------- 18 | 19 | An Attribute is stored with the following information, some being mandatory and others being optional. 20 | 21 | Mandatory 22 | +++++++++ 23 | 24 | * **Path**: A Path is the container which is greatly flexible, to be tailored to the user needs. It is a simple string separated with the slash character '/' such as, for an IPv4 storage "/demo/ipv4". The last part of the path should contain the object type for the sake of clarity. 25 | 26 | * **Value**: The Value must be encoded in Base64 URL with no padding. The tool b64 which encodes such a string is provided so it can be called from the shell, such as $(b64 10.0.0.1) to produce the string "MTAuMC4wLjE". 27 | 28 | 29 | Optional 30 | ++++++++ 31 | 32 | * **Source** (string): Provide information about the source. 33 | * **Tags** (string): Adding tags, for anything that has not been thought in the first place. If tags start being widely used, they are likely to become a standard 34 | * **TTL** (integer): Expiration time in seconds 35 | 36 | Optional fields for a given Attribute can be set after the object creation. 37 | 38 | Tags 39 | ++++ 40 | 41 | Tags follow the MISP Taxonomy, which can be found there: https://github.com/MISP/misp-taxonomies 42 | 43 | If there is any improvement that should be made, please use this page to open issues or pull requests. 44 | 45 | Tags are separated with the ';' character. 46 | 47 | Expiration 48 | ++++++++++ 49 | 50 | Expiration is done by the TTL, however when an attribute is expired, it is moved to the internal path: /_internal/expirations/ where values are expanded from first_seen/last_seen and count is added if another one expires after. 51 | An attribute expiration check is only done ONLY at reading, there is no scheduler that tracks the time, only when being read. 52 | 53 | -------------------------------------------------------------------------------- /doc/storage-future.txt: -------------------------------------------------------------------------------- 1 | Storage 2 | ======= 3 | 4 | Default storage is a simple tree which contains the path + value. The path is usually the type of value, such as a host, an IP address, a hash etc. 5 | 6 | Read and Write on Multiple instances 7 | ==================================== 8 | 9 | We do a XOR on the available machines with the first four bytes of our value in order to avoid using a consensus to read and write our data. This 10 | allow a blazingly fast access to our values. 11 | 12 | Adding a new Node 13 | ================= 14 | 15 | This is a slow operation which requires to re-XOR our values in order to move the appropriate ones to the new node. We take only one thread for this 16 | so the DB is still fast, new writes go directly to the new node, while read is first fetch to the new node and then looked on the original node handling 17 | them if the data has not been moved. 18 | 19 | -------------------------------------------------------------------------------- /docker/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM rust:latest 2 | MAINTAINER Sebastien Tricaud 3 | RUN apt update -q 4 | RUN apt -qy --no-install-recommends install git apt-transport-https ca-certificates pkg-config openssl libssl-dev jed 5 | RUN update-ca-certificates 6 | WORKDIR /opt/ 7 | RUN git clone https://github.com/stricaud/sightingdb.git /opt/sightingdb 8 | WORKDIR /opt/sightingdb 9 | RUN cargo build --release 10 | COPY sightingdb.conf /etc/sightingdb/ 11 | RUN mkdir /etc/sightingdb/ssl 12 | WORKDIR /etc/sightingdb/ssl 13 | COPY ssl-answers /etc/sightingdb/ssl/ 14 | RUN openssl req -new -newkey rsa:2048 -days 365 -nodes -x509 -keyout key.pem -out cert.pem < /etc/sightingdb/ssl/ssl-answers 15 | WORKDIR /opt/sightingdb/ 16 | RUN mkdir /var/log/sightingdb/ 17 | 18 | EXPOSE 9999 19 | COPY sightingdb-entrypoint.sh /usr/local/bin/ 20 | ENTRYPOINT ["/usr/local/bin/sightingdb-entrypoint.sh"] 21 | 22 | -------------------------------------------------------------------------------- /docker/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | services: 3 | sightingdb: 4 | build: . 5 | environment: 6 | - SIGHTINGDB_APIKEY=changeme 7 | ports: 8 | - "9999:9999" 9 | -------------------------------------------------------------------------------- /docker/sightingdb-entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [ -z $SIGHTINGDB_APIKEY ] 4 | then 5 | echo "The environment variable SIGHTINGDB_API is not set, so we leave the default to 'changeme'." 6 | /opt/sightingdb/target/release/sightingdb 7 | else 8 | /opt/sightingdb/target/release/sightingdb -k $SIGHTINGDB_APIKEY 9 | fi 10 | -------------------------------------------------------------------------------- /docker/sightingdb.conf: -------------------------------------------------------------------------------- 1 | [daemon] 2 | listen_ip=0.0.0.0 3 | listen_port=9999 4 | authenticate=true 5 | daemonize=false 6 | dbdir=/var/lib/sightingdb 7 | log_level=debug 8 | ssl=true 9 | ssl_cert=ssl/cert.pem 10 | ssl_key=ssl/key.pem 11 | post_limit=2500000000 12 | log_out=/var/log/sightingdb/sightingdb.log 13 | log_err=/var/log/sightingdb/sightingdb.error.log 14 | -------------------------------------------------------------------------------- /docker/ssl-answers: -------------------------------------------------------------------------------- 1 | US 2 | California 3 | San Francisco 4 | 5 | 6 | 7 | root@localhost 8 | -------------------------------------------------------------------------------- /etc/log4rs.yml: -------------------------------------------------------------------------------- 1 | refresh_rate: 30 seconds 2 | 3 | appenders: 4 | stdout: 5 | kind: console 6 | 7 | file: 8 | kind: rolling_file 9 | path: log/sightingdb.log 10 | append: true 11 | encoder: 12 | kind: pattern 13 | policy: 14 | kind: compound 15 | trigger: 16 | kind: size 17 | limit: 10mb 18 | roller: 19 | kind: delete 20 | 21 | db_log: 22 | kind: rolling_file 23 | path: log/db.log 24 | encoder: 25 | kind: pattern 26 | policy: 27 | kind: compound 28 | trigger: 29 | kind: size 30 | limit: 10mb 31 | roller: 32 | kind: delete 33 | 34 | root: 35 | level: info 36 | appenders: 37 | - stdout 38 | 39 | loggers: 40 | sightingdb::db_log: 41 | level: info 42 | appenders: 43 | - db_log 44 | additive: false 45 | 46 | 47 | -------------------------------------------------------------------------------- /etc/sightingdb.conf: -------------------------------------------------------------------------------- 1 | [daemon] 2 | listen_ip=0.0.0.0 3 | listen_port=9999 4 | authenticate=false 5 | daemonize=false 6 | dbdir=/var/lib/sighting 7 | log_level=debug 8 | ssl=true 9 | ssl_cert=ssl/cert.pem 10 | ssl_key=ssl/key.pem 11 | post_limit=2500000000 12 | log_out=/var/log/sightingdb/sightingdb.log 13 | log_err=/var/log/sightingdb/sightingdb.error.log 14 | -------------------------------------------------------------------------------- /src/acl.rs: -------------------------------------------------------------------------------- 1 | use crate::db::Database; 2 | 3 | pub fn can_read(db: &mut Database, authkey: &str, _namespace: &str) -> bool { 4 | let mut apikey_namespace = String::from("_config/acl/apikeys/"); 5 | apikey_namespace.push_str(authkey); 6 | db.namespace_exists(&apikey_namespace) 7 | } 8 | 9 | pub fn can_write(db: &mut Database, authkey: &str, _namespace: &str) -> bool { 10 | let mut apikey_namespace = String::from("_config/acl/apikeys/"); 11 | apikey_namespace.push_str(authkey); 12 | db.namespace_exists(&apikey_namespace) 13 | } 14 | -------------------------------------------------------------------------------- /src/attribute.rs: -------------------------------------------------------------------------------- 1 | use chrono::{DateTime, NaiveDateTime, Utc}; 2 | use serde::{Deserialize, Serialize, Serializer}; 3 | use std::fmt; 4 | use anyhow::Result; 5 | 6 | use chrono::serde::ts_seconds; 7 | use std::collections::BTreeMap; 8 | use serde::ser::SerializeStruct; 9 | 10 | #[derive(Deserialize, Clone, PartialEq)] 11 | pub struct Attribute { 12 | pub value: String, 13 | #[serde(with = "ts_seconds")] 14 | pub first_seen: DateTime, 15 | #[serde(with = "ts_seconds")] 16 | pub last_seen: DateTime, 17 | pub count: u128, 18 | pub tags: String, 19 | pub ttl: u128, 20 | pub stats: BTreeMap, 21 | // i64 because DateTime.timestamp() returns i64 :'(; We track count by time. 22 | pub consensus: u128, 23 | } 24 | 25 | //"stats":{"1586548800":1}, 26 | 27 | impl Attribute { 28 | pub fn new(value: &str) -> Attribute { 29 | Attribute { 30 | value: String::from(value), // FIXME: change to Vec 31 | first_seen: DateTime::::from_utc(NaiveDateTime::from_timestamp(0, 0), Utc), 32 | last_seen: DateTime::::from_utc(NaiveDateTime::from_timestamp(0, 0), Utc), 33 | count: 0, 34 | tags: String::from(""), 35 | ttl: 0, 36 | stats: BTreeMap::new(), 37 | consensus: 0, 38 | } 39 | } 40 | 41 | pub fn make_stats(&mut self, time: DateTime) { 42 | let rounded_time = time.timestamp() - time.timestamp() % 3600; 43 | self.stats 44 | .entry(rounded_time) 45 | .and_modify(|e| *e += 1) 46 | .or_insert(1); 47 | } 48 | 49 | pub fn make_stats_from_timestamp(&mut self, timestamp: i64) { 50 | let rounded_time = timestamp - timestamp % 3600; 51 | self.stats 52 | .entry(rounded_time) 53 | .and_modify(|e| *e += 1) 54 | .or_insert(1); 55 | } 56 | 57 | pub fn count(&mut self) -> u128 { 58 | self.count 59 | } 60 | 61 | pub fn incr(&mut self) { 62 | if self.first_seen.timestamp() == 0 { 63 | self.first_seen = Utc::now(); 64 | } 65 | self.last_seen = Utc::now(); 66 | 67 | self.make_stats(self.last_seen); 68 | 69 | self.count += 1; 70 | } 71 | 72 | pub fn set_consensus(&mut self, consensus_count: u128) { 73 | self.consensus = consensus_count; 74 | } 75 | 76 | pub fn incr_from_timestamp(&mut self, timestamp: i64) { 77 | if self.first_seen.timestamp() == 0 { 78 | self.first_seen = 79 | DateTime::::from_utc(NaiveDateTime::from_timestamp(timestamp, 0), Utc); 80 | } 81 | if timestamp < self.first_seen.timestamp() { 82 | self.first_seen = 83 | DateTime::::from_utc(NaiveDateTime::from_timestamp(timestamp, 0), Utc); 84 | } 85 | if timestamp > self.last_seen.timestamp() { 86 | self.last_seen = 87 | DateTime::::from_utc(NaiveDateTime::from_timestamp(timestamp, 0), Utc); 88 | } 89 | self.make_stats_from_timestamp(timestamp); 90 | self.count += 1; 91 | } 92 | 93 | pub fn increment(&mut self, timestamp: i64) { 94 | if timestamp.is_negative() { 95 | self.incr() 96 | } else { 97 | self.incr_from_timestamp(timestamp) 98 | } 99 | } 100 | 101 | pub fn serialize_with_stats(&self) -> Result { 102 | let mut json_value = serde_json::to_value(&self)?; 103 | json_value["stats"] = serde_json::to_value(&self.stats)?; 104 | serde_json::to_string(&json_value).map_err(|e| e.into()) 105 | } 106 | } 107 | 108 | impl fmt::Debug for Attribute { 109 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 110 | write!(f, "Attribute {{ value: {}, first_seen: {:?}, last_seen: {:?}, count: {}, tags: {:?}, ttl: {:?}}}", 111 | self.value, self.first_seen, self.last_seen, self.count, self.tags, self.ttl) 112 | } 113 | } 114 | 115 | impl Serialize for Attribute { 116 | fn serialize(&self, serializer: S) -> Result 117 | where 118 | S: Serializer , 119 | { 120 | 121 | let mut state = serializer.serialize_struct("Attribute", 7)?; 122 | state.serialize_field("value", &self.value)?; 123 | // Following code from Serialize impl in to_seconds 124 | state.serialize_field("first_seen", &self.first_seen.timestamp())?; 125 | state.serialize_field("last_seen", &self.last_seen.timestamp())?; 126 | state.serialize_field("count", &self.count)?; 127 | state.serialize_field("tags", &self.tags)?; 128 | state.serialize_field("ttl", &self.ttl)?; 129 | state.serialize_field("consensus", &self.consensus)?; 130 | state.end() 131 | } 132 | } 133 | 134 | #[cfg(test)] 135 | mod tests { 136 | use super::*; 137 | 138 | #[test] 139 | fn test_serialize_with_stats() -> Result<()> { 140 | let mut stats: BTreeMap = BTreeMap::new(); 141 | for i in 0..5 { 142 | stats.insert(i, i as u128); 143 | } 144 | let mut attr = Attribute::new("test"); 145 | attr.stats = stats; 146 | let serialized = &attr.serialize_with_stats()?; 147 | let deserialized: Attribute = serde_json::from_str(&serialized)?; 148 | assert_eq!(deserialized, attr); 149 | Ok(()) 150 | } 151 | } -------------------------------------------------------------------------------- /src/db.rs: -------------------------------------------------------------------------------- 1 | use serde::Serialize; 2 | use std::collections::HashMap; 3 | 4 | use crate::attribute::Attribute; 5 | use crate::db_log::log_attribute; 6 | 7 | pub struct Database { 8 | db_path: String, 9 | // Where are DB is stored on disk 10 | hashtable: HashMap> 11 | } 12 | 13 | #[derive(Serialize)] 14 | pub struct DbError { 15 | error: String, 16 | namespace: String, 17 | value: String, 18 | } 19 | 20 | impl Database { 21 | pub fn new() -> Database { 22 | let mut db = Database { 23 | db_path: String::from(""), 24 | hashtable: HashMap::new(), 25 | }; 26 | // We initialize the default apikey: 'changeme' 27 | let attr = Attribute::new(""); 28 | let mut tmphash = HashMap::new(); 29 | tmphash.insert("".to_string(), attr); 30 | db.hashtable 31 | .insert("_config/acl/apikeys/changeme".to_string(), tmphash); 32 | db 33 | } 34 | pub fn set_db_path(&mut self, path: String) { 35 | self.db_path = path; 36 | } 37 | // Return the count of the written value 38 | pub fn write( 39 | &mut self, 40 | path: &str, 41 | value: &str, 42 | timestamp: i64, 43 | write_consensus: bool, 44 | ) -> u128 { 45 | let (attr, new_value_to_path) = match self.hashtable.get_mut(path) { 46 | Some(valuestable) => { 47 | match valuestable.get_mut(value) { 48 | // New attribute in a path that exists 49 | None => { 50 | let mut attr = Attribute::new(value); 51 | attr.increment(timestamp); 52 | valuestable.insert(value.to_string(), attr.clone()); 53 | (attr, false) 54 | } 55 | // Update to an existing attribute 56 | Some(attr) => { 57 | attr.increment(timestamp); 58 | (attr.clone(), true) 59 | } 60 | } 61 | } 62 | None => { 63 | // New value to a path that does not exist 64 | let mut newvaluestable = HashMap::new(); 65 | let mut attr = Attribute::new(value); 66 | attr.increment(timestamp); 67 | newvaluestable.insert(value.to_string(), attr.clone()); 68 | self.hashtable.insert(path.to_string(), newvaluestable); 69 | (attr, true) 70 | } 71 | }; 72 | 73 | 74 | if new_value_to_path && write_consensus { 75 | // Check for consensus 76 | // Do we have the value in _all? If not then 77 | // we add it and consensus is the count of the 78 | // value from _all. 79 | self.write(&"_all".to_string(), value, 0, false); 80 | } 81 | log_attribute(path, &attr); 82 | attr.count 83 | } 84 | 85 | pub fn new_consensus(&mut self, path: &str, value: &str, consensus_count: u128) -> u128 { 86 | let valuestable = self.hashtable.get_mut(&path.to_string()).unwrap(); 87 | let attr = valuestable.get_mut(&value.to_string()); 88 | match attr { 89 | Some(_attr) => { 90 | let iattr = valuestable.get_mut(&value.to_string()).unwrap(); 91 | iattr.set_consensus(consensus_count); 92 | iattr.consensus 93 | } 94 | None => 0, 95 | } 96 | } 97 | pub fn get_count(&mut self, path: &str, value: &str) -> u128 { 98 | let valuestable = self.hashtable.get_mut(&path.to_string()); 99 | match valuestable { 100 | Some(valuestable) => { 101 | let attr = valuestable.get_mut(&value.to_string()); 102 | match attr { 103 | Some(attr) => attr.count(), 104 | None => 0, 105 | } 106 | } 107 | None => 0, 108 | } 109 | } 110 | pub fn namespace_exists(&mut self, namespace: &str) -> bool { 111 | let valuestable = self.hashtable.get_mut(&namespace.to_string()); 112 | valuestable.is_some() 113 | } 114 | 115 | pub fn get_namespace_attrs(&mut self, namespace: &str) -> String { 116 | let valuestable = self.hashtable.get_mut(&namespace.to_string()); 117 | 118 | match valuestable { 119 | Some(valuestable) => { 120 | let mut response: HashMap<&str, Vec<&Attribute>> = HashMap::new(); 121 | response.insert("attributes", valuestable.iter().map(|(_, attr)| attr).collect::>()); 122 | serde_json::to_string(&response).unwrap() 123 | } 124 | None => { 125 | let err = serde_json::to_string(&DbError { 126 | error: String::from("Namespace not found"), 127 | namespace: namespace.to_string(), 128 | value: "".to_string(), 129 | }); 130 | err.unwrap() 131 | } 132 | } 133 | } 134 | 135 | pub fn get_attr( 136 | &mut self, 137 | path: &str, 138 | value: &str, 139 | with_stats: bool, 140 | consensus_count: u128, 141 | ) -> String { 142 | let valuestable = self.hashtable.get_mut(&path.to_string()); 143 | 144 | match valuestable { 145 | Some(valuestable) => { 146 | let attr = valuestable.get_mut(&value.to_string()); 147 | match attr { 148 | Some(attr) => { 149 | if attr.ttl > 0 { 150 | println!("FIXME, IMPLEMENT TTL. {:?}", attr); 151 | } 152 | attr.consensus = consensus_count; 153 | 154 | if with_stats { 155 | attr.serialize_with_stats().unwrap() 156 | } else { 157 | serde_json::to_string(attr).unwrap() 158 | } 159 | } 160 | None => { 161 | let err = serde_json::to_string(&DbError { 162 | error: String::from("Value not found"), 163 | namespace: path.to_string(), 164 | value: value.to_string(), 165 | }); 166 | err.unwrap() 167 | } 168 | } 169 | } 170 | None => { 171 | let err = serde_json::to_string(&DbError { 172 | error: String::from("Path not found"), 173 | namespace: path.to_string(), 174 | value: value.to_string(), 175 | }); 176 | err.unwrap() 177 | } 178 | } 179 | // return String::from(""); // unreachable statement, however I want to make it clear this is our default 180 | } 181 | 182 | pub fn delete(&mut self, namespace: &str) -> bool { 183 | let res = self.hashtable.remove(&namespace.to_string()); 184 | res.is_some() 185 | } 186 | } 187 | 188 | impl Default for Database { 189 | fn default() -> Self { 190 | Self::new() 191 | } 192 | } 193 | -------------------------------------------------------------------------------- /src/db_log.rs: -------------------------------------------------------------------------------- 1 | use crate::attribute::Attribute; 2 | 3 | pub fn log_attribute(path: &str, attribute: &Attribute) { 4 | log::info!("{} | {}", path, serde_json::to_string(attribute).unwrap()) 5 | } 6 | -------------------------------------------------------------------------------- /src/main.rs: -------------------------------------------------------------------------------- 1 | extern crate ansi_term; 2 | extern crate clap; 3 | extern crate daemonize; 4 | extern crate dirs; 5 | extern crate qstring; 6 | 7 | mod acl; 8 | mod attribute; 9 | mod db; 10 | mod sighting_configure; 11 | mod sighting_reader; 12 | mod sighting_writer; 13 | mod db_log; 14 | 15 | use clap::Arg; 16 | use std::sync::Arc; 17 | use std::sync::Mutex; 18 | 19 | use ansi_term::Color::Red; 20 | use daemonize::Daemonize; 21 | use ini::Ini; 22 | 23 | use actix_web::{web, App, HttpRequest, HttpResponse, HttpServer, Responder}; 24 | use openssl::ssl::{SslAcceptor, SslFiletype, SslMethod}; 25 | 26 | use qstring::QString; 27 | 28 | use serde::{Deserialize, Serialize}; 29 | 30 | use std::fs; 31 | use std::fs::File; 32 | use std::path::{Path, PathBuf}; 33 | 34 | pub struct SharedState { 35 | pub db: db::Database, 36 | pub authenticate: bool, 37 | } 38 | 39 | impl SharedState { 40 | pub fn new() -> Self { 41 | Self { 42 | db: db::Database::new(), 43 | authenticate: true, 44 | } 45 | } 46 | } 47 | 48 | impl Default for SharedState { 49 | fn default() -> Self { 50 | Self::new() 51 | } 52 | } 53 | 54 | #[derive(Serialize)] 55 | pub struct Message { 56 | message: String, 57 | } 58 | 59 | #[derive(Serialize)] 60 | pub struct InfoData { 61 | implementation: String, 62 | version: String, 63 | vendor: String, 64 | author: String, 65 | } 66 | 67 | fn help(_req: HttpRequest) -> impl Responder { 68 | "Sighting Daemon, written by Sebastien Tricaud, (C) Devo Inc. 2019 69 | REST Endpoints: 70 | \t/w: write (GET) 71 | \t/wb: write in bulk mode (POST) 72 | \t/r: read (GET) 73 | \t/rs: read with statistics (GET) 74 | \t/rb: read in bulk mode (POST) 75 | \t/rbs: read with statistics in bulk mode (POST) 76 | \t/d: delete (GET) 77 | \t/c: configure (GET) 78 | \t/i: info (GET) 79 | " 80 | } 81 | 82 | fn read_with_stats(data: web::Data>>, _req: HttpRequest) -> impl Responder { 83 | let sharedstate = &mut *data.lock().unwrap(); 84 | 85 | let (_, path) = _req.path().split_at(4); 86 | if sharedstate.authenticate { 87 | let http_header_auth = _req.head().headers.get("Authorization"); 88 | match http_header_auth { 89 | Some(apikey) => { 90 | let can_read = acl::can_read(&mut sharedstate.db, apikey.to_str().unwrap(), path); 91 | if !can_read { 92 | return HttpResponse::Ok().json(Message { 93 | message: String::from("API key not found."), 94 | }); 95 | } 96 | } 97 | None => { 98 | return HttpResponse::Ok().json(Message { 99 | message: String::from("Please add the API key in the Authorization headers."), 100 | }); 101 | } 102 | } 103 | } 104 | let query_string = QString::from(_req.query_string()); 105 | 106 | let val = query_string.get("noshadow"); 107 | let mut with_shadow = true; 108 | match val { 109 | Some(_v) => { 110 | with_shadow = false; 111 | } 112 | None => {} 113 | } 114 | 115 | let val = query_string.get("val"); 116 | match val { 117 | Some(v) => { 118 | let ans = sighting_reader::read(&mut sharedstate.db, path, v, true, with_shadow); 119 | HttpResponse::Ok().body(ans) 120 | } 121 | None => HttpResponse::Ok().json(Message { 122 | message: String::from("Error: val= not found!"), 123 | }), 124 | } 125 | } 126 | 127 | fn read(data: web::Data>>, _req: HttpRequest) -> impl Responder { 128 | let sharedstate = &mut *data.lock().unwrap(); 129 | 130 | let (_, path) = _req.path().split_at(3); 131 | if sharedstate.authenticate { 132 | let http_header_auth = _req.head().headers.get("Authorization"); 133 | match http_header_auth { 134 | Some(apikey) => { 135 | let can_read = acl::can_read(&mut sharedstate.db, apikey.to_str().unwrap(), path); 136 | if !can_read { 137 | return HttpResponse::Ok().json(Message { 138 | message: String::from("API key not found."), 139 | }); 140 | } 141 | } 142 | None => { 143 | return HttpResponse::Ok().json(Message { 144 | message: String::from("Please add the API key in the Authorization headers."), 145 | }); 146 | } 147 | } 148 | } 149 | 150 | let query_string = QString::from(_req.query_string()); 151 | 152 | let val = query_string.get("noshadow"); 153 | let mut with_shadow = true; 154 | match val { 155 | Some(_v) => { 156 | with_shadow = false; 157 | } 158 | None => {} 159 | } 160 | 161 | 162 | let val = query_string.get("val"); 163 | match val { 164 | Some(v) => { 165 | let ans = sighting_reader::read(&mut sharedstate.db, path, v, false, with_shadow); 166 | HttpResponse::Ok().body(ans) 167 | } 168 | // None => HttpResponse::Ok().json(Message { 169 | // message: String::from("Error: val= not found!"), 170 | // }), 171 | None => { 172 | let ans = sighting_reader::read_namespace(&mut sharedstate.db, path); 173 | HttpResponse::Ok().body(ans) 174 | } 175 | } 176 | } 177 | 178 | // fn write(db: web::Data>, _req: HttpRequest) -> impl Responder { 179 | fn write(data: web::Data>>, _req: HttpRequest) -> HttpResponse { 180 | let sharedstate = &mut *data.lock().unwrap(); 181 | 182 | // println!("{:?}", _req.path()); 183 | let (_, path) = _req.path().split_at(3); // We remove '/w/' 184 | 185 | if sharedstate.authenticate { 186 | let http_header_auth = _req.head().headers.get("Authorization"); 187 | match http_header_auth { 188 | Some(apikey) => { 189 | let can_write = acl::can_write(&mut sharedstate.db, apikey.to_str().unwrap(), path); 190 | if !can_write { 191 | let mut error_msg = String::from("Cannot write to namespace: /"); 192 | error_msg.push_str(path); 193 | return HttpResponse::Ok().json(Message { message: error_msg }); 194 | } 195 | } 196 | None => { 197 | return HttpResponse::Ok().json(Message { 198 | message: String::from("Please add the API key in the Authorization headers."), 199 | }); 200 | } 201 | } 202 | } 203 | 204 | let query_string = QString::from(_req.query_string()); 205 | 206 | let val = query_string.get("val"); 207 | match val { 208 | Some(v) => { 209 | let timestamp = query_string.get("timestamp").unwrap_or("0"); 210 | let timestamp_i = timestamp.parse::().unwrap_or(0); 211 | let could_write = sighting_writer::write(&mut sharedstate.db, path, v, timestamp_i); 212 | if could_write { 213 | HttpResponse::Ok().json(Message { 214 | message: String::from("ok"), 215 | }) 216 | } else { 217 | HttpResponse::Ok().json(Message { 218 | message: String::from("Could not write request!"), 219 | }) 220 | } 221 | } 222 | None => HttpResponse::BadRequest().json(Message { 223 | message: String::from("Did not received a val= argument in the query string."), 224 | }), 225 | } 226 | } 227 | 228 | fn configure(_req: HttpRequest) -> impl Responder { 229 | "configure" 230 | } 231 | 232 | #[derive(Serialize, Deserialize)] 233 | pub struct PostData { 234 | items: Vec, 235 | } 236 | 237 | #[derive(Serialize, Deserialize)] 238 | pub struct BulkSighting { 239 | namespace: String, 240 | value: String, 241 | timestamp: Option, 242 | noshadow: bool, 243 | } 244 | 245 | fn read_bulk( 246 | data: web::Data>>, 247 | postdata: web::Json, 248 | _req: HttpRequest, 249 | ) -> impl Responder { 250 | let sharedstate = &mut *data.lock().unwrap(); 251 | 252 | let mut json_response = String::from("{\n\t\"items\": [\n"); 253 | 254 | for v in &postdata.items { 255 | if sharedstate.authenticate { 256 | let http_header_auth = _req.head().headers.get("Authorization"); 257 | match http_header_auth { 258 | Some(apikey) => { 259 | let can_read = acl::can_read( 260 | &mut sharedstate.db, 261 | apikey.to_str().unwrap(), 262 | v.namespace.as_str(), 263 | ); 264 | if !can_read { 265 | return HttpResponse::Ok().json(Message { 266 | message: String::from("API key not found."), 267 | }); 268 | } 269 | } 270 | None => { 271 | return HttpResponse::Ok().json(Message { 272 | message: String::from( 273 | "Please add the API key in the Authorization headers.", 274 | ), 275 | }); 276 | } 277 | } 278 | } 279 | 280 | let ans = sighting_reader::read( 281 | &mut sharedstate.db, 282 | v.namespace.as_str(), 283 | v.value.as_str(), 284 | false, // no stats 285 | !v.noshadow, 286 | ); 287 | 288 | json_response.push_str("\t\t"); 289 | json_response.push_str(&ans); 290 | json_response.push_str(",\n"); 291 | } 292 | json_response.pop(); 293 | json_response.pop(); // We don't need the last , 294 | json_response.push_str("\n"); // however we need the line return :) 295 | 296 | json_response.push_str("\t]\n}\n"); 297 | HttpResponse::Ok().body(json_response) 298 | } 299 | 300 | fn read_bulk_with_stats( 301 | data: web::Data>>, 302 | postdata: web::Json, 303 | _req: HttpRequest, 304 | ) -> impl Responder { 305 | let sharedstate = &mut *data.lock().unwrap(); 306 | 307 | let mut json_response = String::from("{\n\t\"items\": [\n"); 308 | 309 | for v in &postdata.items { 310 | if sharedstate.authenticate { 311 | let http_header_auth = _req.head().headers.get("Authorization"); 312 | match http_header_auth { 313 | Some(apikey) => { 314 | let can_read = acl::can_read( 315 | &mut sharedstate.db, 316 | apikey.to_str().unwrap(), 317 | v.namespace.as_str(), 318 | ); 319 | if !can_read { 320 | return HttpResponse::Ok().json(Message { 321 | message: String::from("API key not found."), 322 | }); 323 | } 324 | } 325 | None => { 326 | return HttpResponse::Ok().json(Message { 327 | message: String::from( 328 | "Please add the API key in the Authorization headers.", 329 | ), 330 | }); 331 | } 332 | } 333 | } 334 | 335 | let ans = sighting_reader::read( 336 | &mut sharedstate.db, 337 | v.namespace.as_str(), 338 | v.value.as_str(), 339 | true, 340 | !v.noshadow, 341 | ); 342 | 343 | json_response.push_str("\t\t"); 344 | json_response.push_str(&ans); 345 | json_response.push_str(",\n"); 346 | } 347 | json_response.pop(); 348 | json_response.pop(); // We don't need the last , 349 | json_response.push_str("\n"); // however we need the line return :) 350 | 351 | json_response.push_str("\t]\n}\n"); 352 | HttpResponse::Ok().body(json_response) 353 | } 354 | 355 | fn write_bulk( 356 | data: web::Data>>, 357 | postdata: web::Json, 358 | _req: HttpRequest, 359 | ) -> impl Responder { 360 | let sharedstate = &mut *data.lock().unwrap(); 361 | let mut could_write = false; 362 | 363 | for v in &postdata.items { 364 | if !v.value.is_empty() { 365 | // There is no need to write a value that does not exists 366 | let http_header_auth = _req.head().headers.get("Authorization"); 367 | match http_header_auth { 368 | Some(apikey) => { 369 | let can_write = acl::can_write( 370 | &mut sharedstate.db, 371 | apikey.to_str().unwrap(), 372 | v.namespace.as_str(), 373 | ); 374 | if !can_write { 375 | return HttpResponse::Ok().json(Message { 376 | message: String::from("API key not found."), 377 | }); 378 | } 379 | } 380 | None => { 381 | return HttpResponse::Ok().json(Message { 382 | message: String::from( 383 | "Please add the API key in the Authorization headers.", 384 | ), 385 | }); 386 | } 387 | } 388 | 389 | let timestamp = v.timestamp.unwrap_or(0); 390 | could_write = sighting_writer::write( 391 | &mut sharedstate.db, 392 | v.namespace.as_str(), 393 | v.value.as_str(), 394 | timestamp, 395 | ); 396 | } 397 | } 398 | 399 | if could_write { 400 | return HttpResponse::Ok().json(Message { 401 | message: String::from("ok"), 402 | }); 403 | } 404 | HttpResponse::Ok().json(Message { 405 | message: String::from("Invalid base64 encoding (base64 url with non padding) value"), 406 | }) 407 | } 408 | 409 | fn delete(data: web::Data>>, _req: HttpRequest) -> HttpResponse { 410 | let sharedstate = &mut *data.lock().unwrap(); 411 | 412 | let (_, path) = _req.path().split_at(3); // We remove '/w/' 413 | let http_header_auth = _req.head().headers.get("Authorization"); 414 | match http_header_auth { 415 | Some(apikey) => { 416 | let can_write = acl::can_write(&mut sharedstate.db, apikey.to_str().unwrap(), path); 417 | if !can_write { 418 | let mut error_msg = String::from("Cannot write to namespace: /"); 419 | error_msg.push_str(path); 420 | return HttpResponse::Ok().json(Message { message: error_msg }); 421 | } 422 | } 423 | None => { 424 | return HttpResponse::Ok().json(Message { 425 | message: String::from("Please add the API key in the Authorization headers."), 426 | }); 427 | } 428 | } 429 | 430 | let deleted = sharedstate.db.delete(path); 431 | if !deleted { 432 | return HttpResponse::Ok().json(Message { 433 | message: String::from("Namespace not found, nothing was deleted."), 434 | }); 435 | } 436 | 437 | HttpResponse::Ok().json(Message { 438 | message: String::from("ok"), 439 | }) 440 | } 441 | 442 | fn create_home_config() { 443 | let mut home_config = dirs::home_dir().unwrap(); 444 | home_config.push(".sightingdb"); 445 | match fs::create_dir_all(home_config) { 446 | Ok(_) => {} 447 | Err(e) => { 448 | log::error!("Error creating home configuration: {}", e); 449 | } 450 | } 451 | } 452 | 453 | fn sightingdb_get_config() -> Result { 454 | let ini_file = PathBuf::from("/etc/sightingdb/sightingdb.conf"); 455 | let mut home_ini_file = dirs::home_dir().unwrap(); 456 | 457 | let can_open = Path::new(&ini_file).exists(); 458 | if can_open { 459 | return Ok(String::from(ini_file.to_str().unwrap())); 460 | } 461 | 462 | home_ini_file.push(".sightingdb"); 463 | home_ini_file.push("sightingdb.conf"); 464 | 465 | let can_open = Path::new(&home_ini_file).exists(); 466 | if can_open { 467 | return Ok(String::from(home_ini_file.to_str().unwrap())); 468 | } 469 | 470 | Err("Cannot locate sightingdb.conf in neither from the -c flag, /etc/sightingdb or ~/.sightingdb/") 471 | } 472 | 473 | fn sightingdb_get_pid() -> String { 474 | let can_create_file = File::create("/var/run/sightingdb.pid"); 475 | match can_create_file { 476 | Ok(_) => String::from("/var/run/sightingdb.pid"), 477 | Err(..) => { 478 | let mut home_pid = dirs::home_dir().unwrap(); 479 | home_pid.push(".sightingdb"); 480 | home_pid.push("sighting-daemon.pid"); 481 | let pid_file = home_pid.to_str().unwrap(); 482 | let can_create_home_pid_file = File::create(pid_file); 483 | match can_create_home_pid_file { 484 | Ok(_) => String::from(pid_file), 485 | Err(..) => { 486 | log::error!("Cannot write pid to /var/run not ~/.sightingdb/, using current dir: sightingdb.pid"); 487 | String::from("./sightingdb.pid") 488 | } 489 | } 490 | } 491 | } 492 | // return String::from("./sightingdb.pid"); This is the default, but since the compiler gives a warning, I comment this out 493 | } 494 | 495 | fn main() { 496 | create_home_config(); 497 | 498 | let sharedstate = Arc::new(Mutex::new(SharedState::new())); 499 | 500 | let matches = clap::App::new("SightingDB") 501 | .version("0.4") 502 | .author("Sebastien Tricaud ") 503 | .about("Sightings Database") 504 | .arg( 505 | Arg::with_name("config") 506 | .short("c") 507 | .long("config") 508 | .value_name("FILE") 509 | .help("Sets a custom config file") 510 | .takes_value(true), 511 | ) 512 | .arg( 513 | Arg::with_name("logging-config") 514 | .short("l") 515 | .long("logging-config") 516 | .value_name("LOGGING_CONFIG") 517 | .takes_value(true) 518 | ) 519 | .arg( 520 | Arg::with_name("v") 521 | .short("v") 522 | .multiple(true) 523 | .help("Sets the level of verbosity"), 524 | ) 525 | .arg( 526 | Arg::with_name("apikey") 527 | .short("k") 528 | .long("apikey") 529 | .value_name("APIKEY") 530 | .help("Set the default API KEY") 531 | .takes_value(true) 532 | ) 533 | .get_matches(); 534 | 535 | log4rs::init_file(matches.value_of("logging_config").unwrap_or("etc/log4rs.yml"), Default::default()).unwrap(); 536 | 537 | // match matches.occurrences_of("v") { 538 | // 0 => println!("No verbose info"), 539 | // 1 => println!("Some verbose info"), 540 | // 2 => println!("Tons of verbose info"), 541 | // 3 | _ => println!("Don't be crazy"), 542 | // } 543 | 544 | let configarg = matches.value_of("config"); 545 | let configstr; 546 | match configarg { 547 | Some(_configstr) => { 548 | configstr = _configstr.to_string(); 549 | } 550 | None => { 551 | let sightingdb_ini_file = sightingdb_get_config().unwrap(); 552 | configstr = sightingdb_ini_file; 553 | } 554 | } 555 | 556 | let apikeyarg = matches.value_of("apikey"); 557 | match apikeyarg { 558 | Some(apikey) => { 559 | sharedstate.lock().unwrap().db.delete("_config/acl/apikeys/changeme"); 560 | let mut namespace_withkey = String::from("_config/acl/apikeys/"); 561 | namespace_withkey.push_str(apikey); 562 | sharedstate.lock().unwrap().db.write(&namespace_withkey, "", 0, false); 563 | } 564 | None => {} 565 | } 566 | 567 | 568 | log::info!("Using configuration file: {}", configstr); 569 | let configpath = Path::new(&configstr); 570 | let config = Ini::load_from_file(&configstr).unwrap(); 571 | log::info!("Config path:{}", configpath.parent().unwrap().display()); 572 | 573 | let daemon_config = config.section(Some("daemon")).unwrap(); 574 | 575 | let listen_ip = daemon_config.get("listen_ip").unwrap(); 576 | let listen_port = daemon_config.get("listen_port").unwrap(); 577 | 578 | let server_address = format!("{}:{}", listen_ip, listen_port); 579 | 580 | let welcome_string = Red.paint("Starting Sighting Daemon").to_string(); 581 | log::info!("{}", welcome_string); 582 | 583 | let use_ssl; 584 | match daemon_config.get("ssl").unwrap().as_ref() { 585 | "false" => use_ssl = false, 586 | _ => use_ssl = true, // no mistake, only false can start the unsecure server. 587 | } 588 | match daemon_config.get("authenticate").unwrap().as_ref() { 589 | "false" => { 590 | sharedstate.lock().unwrap().authenticate = false; 591 | } 592 | _ => sharedstate.lock().unwrap().authenticate = true, // no mistake, only false can start the unsecure server. 593 | } 594 | if !sharedstate.lock().unwrap().authenticate { 595 | let auth_string = Red 596 | .paint("No authentication used for the database.") 597 | .to_string(); 598 | log::info!("{}", auth_string); 599 | } 600 | 601 | let mut ssl_cert: PathBuf; 602 | let ssl_cert_config = daemon_config.get("ssl_cert").unwrap(); 603 | if ssl_cert_config.starts_with('/') { 604 | ssl_cert = PathBuf::from(ssl_cert_config); 605 | } else { 606 | ssl_cert = PathBuf::from(configpath.parent().unwrap()); 607 | ssl_cert.push(&ssl_cert_config); 608 | } 609 | 610 | let mut ssl_key: PathBuf; 611 | let ssl_key_config = daemon_config.get("ssl_key").unwrap(); 612 | if ssl_key_config.starts_with('/') { 613 | ssl_key = PathBuf::from(ssl_key_config); 614 | } else { 615 | ssl_key = PathBuf::from(configpath.parent().unwrap()); 616 | ssl_key.push(&ssl_key_config); 617 | } 618 | 619 | match daemon_config.get("daemonize").unwrap().as_ref() { 620 | "true" => { 621 | let stdout = File::create(daemon_config.get("log_out").unwrap()).unwrap(); 622 | let stderr = File::create(daemon_config.get("log_err").unwrap()).unwrap(); 623 | 624 | let pid_file = sightingdb_get_pid(); 625 | match Daemonize::new().pid_file(pid_file).stdout(stdout).stderr(stderr).start() { 626 | Ok(_) => {} 627 | Err(e) => log::error!("Error starting daemon: {}", e), 628 | } 629 | } 630 | "false" => log::warn!("This daemon is not daemonized. To run in background, set 'daemonize = true' in sigthing-daemon.ini"), 631 | _ => log::info!("Unknown daemon setting. Starting in foreground."), 632 | } 633 | 634 | if use_ssl { 635 | let mut builder = SslAcceptor::mozilla_intermediate(SslMethod::tls()).unwrap(); 636 | builder 637 | .set_private_key_file(ssl_key, SslFiletype::PEM) 638 | .unwrap(); 639 | builder 640 | .set_certificate_chain_file(ssl_cert.to_str().unwrap()) 641 | .unwrap(); 642 | 643 | // routes: 644 | // w -> write 645 | // r -> read 646 | // c -> config (push all to disk, alway in memory, both) 647 | // i -> info 648 | // untyped -> things that have an incorrect type match 649 | 650 | let post_limit: usize = daemon_config 651 | .get("post_limit") 652 | .unwrap() 653 | .parse() 654 | .unwrap_or(2_500_000_000); 655 | 656 | HttpServer::new(move || { 657 | App::new() 658 | .data(sharedstate.clone()) 659 | .route("/r/*", web::get().to(read)) 660 | .route("/rb", web::post().to(read_bulk)) 661 | .route("/rs/*", web::get().to(read_with_stats)) 662 | .route("/rbs", web::post().to(read_bulk_with_stats)) 663 | .route("/w/*", web::get().to(write)) 664 | .route("/wb", web::post().to(write_bulk)) 665 | .route("/c/*", web::get().to(configure)) 666 | .route("/i", web::get().to(info)) 667 | .route("/d/*", web::get().to(delete)) 668 | .default_service(web::to(help)) 669 | .data(web::JsonConfig::default().limit(post_limit)) 670 | }) 671 | .bind_ssl(server_address, builder) 672 | .unwrap() 673 | .run() 674 | .unwrap(); 675 | } 676 | } 677 | 678 | fn info(_req: HttpRequest) -> impl Responder { 679 | let info_data = InfoData { 680 | implementation: String::from("SightingDB"), 681 | version: String::from("0.0.4"), 682 | vendor: String::from("Devo"), 683 | author: String::from("Sebastien Tricaud"), 684 | }; 685 | HttpResponse::Ok().json(&info_data) 686 | } 687 | -------------------------------------------------------------------------------- /src/sighting_configure.rs: -------------------------------------------------------------------------------- 1 | // use std::collections::HashMap; 2 | 3 | // #[derive(PartialEq, Eq)] 4 | // pub enum ConfigStorage { 5 | // IN_MEMORY, 6 | // ON_DISK, 7 | // } 8 | 9 | // pub struct Configuration { 10 | // storage: HashMap, 11 | // } 12 | 13 | // impl Configuration { 14 | // pub fn new() -> Configuration { 15 | // Configuration { 16 | // storage: HashMap::new(), 17 | // } 18 | // } 19 | // pub fn set_storage(&mut self, storage: ConfigStorage, path: String) { 20 | // self.storage.insert(path, storage); 21 | // } 22 | // pub fn get_storage(&mut self, path: String) -> String { 23 | // let storageopt = self.storage.get_mut(&path); 24 | // match storageopt { 25 | // Some(storageopt) => { 26 | // match storageopt { 27 | // ConfigStorage::IN_MEMORY => { return String::from("IN_MEMORY"); }, 28 | // ConfigStorage::ON_DISK => { return String::from("ON_DISK"); }, 29 | // } 30 | // }, 31 | // None => { 32 | // return String::from("IN_MEMORY"); 33 | // } 34 | // } 35 | // } 36 | 37 | // } 38 | 39 | // pub fn set(path: &str, value: &str) { 40 | // println!("Configuring path {}", path); 41 | // } 42 | 43 | // pub fn get(path: &str, value: &str) { 44 | // println!("Get configuration"); 45 | // } 46 | -------------------------------------------------------------------------------- /src/sighting_reader.rs: -------------------------------------------------------------------------------- 1 | use crate::db::Database; 2 | use serde::Serialize; 3 | 4 | #[derive(Serialize)] 5 | pub struct Message { 6 | message: String, 7 | } 8 | 9 | // #[derive(Deserialize)] 10 | // struct NotFound { 11 | // error: String, 12 | // path: String, 13 | // value: String 14 | // } 15 | 16 | pub fn read(db: &mut Database, path: &str, value: &str, with_stats: bool, with_shadow: bool) -> String { 17 | if path.starts_with("_config/") { 18 | let err = serde_json::to_string(&Message { 19 | message: String::from("No access to _config namespace from outside!"), 20 | }) 21 | .unwrap(); 22 | return err; 23 | } 24 | 25 | let consensus = db.get_count(&"_all".to_string(), value); 26 | let attr = db.get_attr(path, value, with_stats, consensus); 27 | 28 | // Shadow Sightings 29 | if with_shadow { 30 | let mut shadow_path: String = "_shadow/".to_owned(); 31 | shadow_path.push_str(path); 32 | // _shadow does not write the consensus 33 | db.write(&shadow_path, value, 0, false); 34 | } 35 | 36 | attr 37 | } 38 | 39 | pub fn read_namespace(db: &mut Database, namespace: &str) -> String { 40 | if namespace.starts_with("_config/") { 41 | let err = serde_json::to_string(&Message { 42 | message: String::from("No access to _config namespace from outside!"), 43 | }) 44 | .unwrap(); 45 | return err; 46 | } 47 | 48 | let namespace_with_values = db.get_namespace_attrs(namespace); 49 | 50 | namespace_with_values 51 | } 52 | 53 | // Our internal reading does not trigger shadow sightings. 54 | // USELESS FOR NOW, but will need to reactivate once we have the possibility to skip shadow if we want to 55 | // pub fn read_internal(db: &mut Database, path: &str, value: &str, with_stats: bool) -> String { 56 | // let consensus = db.get_count(&"_all".to_string(), value); 57 | // let attr = db.get_attr(path, value, with_stats, consensus); 58 | 59 | // return attr; 60 | // } 61 | -------------------------------------------------------------------------------- /src/sighting_writer.rs: -------------------------------------------------------------------------------- 1 | // extern crate base64; 2 | // use base64::{decode_config, encode_config, URL_SAFE_NO_PAD}; 3 | 4 | use crate::db::Database; 5 | 6 | pub fn write(db: &mut Database, path: &str, value: &str, timestamp: i64) -> bool { 7 | db.write(path, value, timestamp, true); 8 | true 9 | } 10 | -------------------------------------------------------------------------------- /tests/everything.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import sightingdb 3 | import sys 4 | import json 5 | 6 | print(sightingdb.__file__) 7 | 8 | con = sightingdb.connection(host="localhost", apikey="changeme") 9 | con.disable_ssl_warnings() 10 | 11 | deleter = sightingdb.delete(con) 12 | deleter.delete("/_tests/namespace") 13 | deleter.delete("/other/namespace") 14 | deleter.delete("/your/namespace") 15 | 16 | writer = sightingdb.writer(con) 17 | writer.add("/namespace", "127.0.0.1", timestamp=5555) 18 | writer.add("/other/namespace", "127.0.0.1", timestamp=1587364370) 19 | writer.add("/other/namespace", "127.0.0.1") 20 | writer.add("/your/namespace", "172.16.0.23") 21 | try: 22 | writer.commit() 23 | except: 24 | print("SightingDB is not listening to localhost:9999. Please start it so we can run our tests") 25 | sys.exit(1) 26 | 27 | 28 | def test_one_read(reader, namespace=None, value=None, first_seen=None, consensus=None): 29 | got_one_false = False 30 | out = reader.read_one(namespace, value) 31 | print(str(out)+": ", end="") 32 | try: 33 | if value: 34 | if out["value"] != value: 35 | got_one_false = True 36 | if first_seen: 37 | if out["first_seen"] != first_seen: 38 | got_one_false = True 39 | if consensus: 40 | if out["consensus"] != consensus: 41 | got_one_false = True 42 | except: 43 | got_one_false = True 44 | 45 | if got_one_false: 46 | print("\033[91mERROR\033[0m") 47 | else: 48 | print("\033[92mOK\033[0m") 49 | 50 | con = sightingdb.connection(host="localhost", apikey="changeme") 51 | reader = sightingdb.reader(con) 52 | 53 | test_one_read(reader, namespace="/namespace", value="127.0.0.1", first_seen=5555, consensus=2) 54 | test_one_read(reader, namespace="/other/namespace", value="127.0.0.1", consensus=2) 55 | test_one_read(reader, namespace="/other/namespace", value="127.0.0.1", consensus=2) 56 | test_one_read(reader, namespace="/your/namespace", value="172.16.0.23", consensus=1) 57 | 58 | 59 | -------------------------------------------------------------------------------- /tests/test-post.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | import json 3 | import requests 4 | 5 | jdata = json.dumps({"items": [{"namespace": "foo/bar/ip", "value":"127.0.0.1"}, {"namespace": "foo/bar/ip", "value":"192.168.0.12", "timestamp": 5555}, {"namespace": "foo/bar/ip", "value":"192.168.0.12"}]}) 6 | #print(str(jdata)) 7 | jheaders={"content-type": "application/json"} 8 | 9 | #print(str(data)) 10 | 11 | print("We write") 12 | r = requests.post("https://127.0.0.1:9999/wb", headers=jheaders, data=jdata, verify=False) 13 | print(r.status_code) 14 | print(r.text) 15 | 16 | print("We read") 17 | r = requests.post("https://127.0.0.1:9999/rb", headers=jheaders, data=jdata, verify=False) 18 | print(r.status_code) 19 | print(r.text) 20 | --------------------------------------------------------------------------------