├── .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 |
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 |
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 |
--------------------------------------------------------------------------------