20 Commits

Author SHA1 Message Date
kpcyrd
6669e3bf26 Release v0.3.0 2018-10-23 19:14:32 +02:00
kpcyrd
d063e8a5f1 Merge pull request #5 from kpcyrd/geoip
Add geoip code
2018-10-23 19:06:59 +02:00
kpcyrd
f865ce0059 Enforce foreign keys 2018-10-23 17:20:03 +02:00
kpcyrd
a9ab411076 Make geoip download in CI more reliable 2018-10-23 16:16:33 +02:00
kpcyrd
568f7f0f70 Add geoip downloader 2018-10-23 03:01:46 +02:00
kpcyrd
aea38f9db5 Add geoip information to database 2018-10-22 18:22:46 +02:00
kpcyrd
85fb4dc2be Expose geoip_lookup to lua 2018-10-22 16:17:29 +02:00
kpcyrd
e266d6d0cb Add geoip code 2018-10-22 13:43:10 +02:00
kpcyrd
ad862ac476 Add description to readme and index.html 2018-10-21 23:56:24 +02:00
kpcyrd
dc3875b1a9 Build docker images during CI 2018-10-21 13:29:20 +02:00
kpcyrd
ca16c87bba Merge branch 'updates' 2018-10-21 13:16:50 +02:00
kpcyrd
51caec0406 Improve db_update logging 2018-10-21 12:54:36 +02:00
kpcyrd
dbb75924d0 Introduce db_update 2018-10-18 03:51:23 +02:00
kpcyrd
6f00708c60 Merge pull request #2 from kpcyrd/travis
Add travis
2018-10-17 12:17:59 +02:00
kpcyrd
4d72b4523b Add travis 2018-10-17 11:19:53 +02:00
kpcyrd
95fc6fd0da Add scope/noscope commands 2018-10-15 10:17:27 +02:00
kpcyrd
174907c37b Add hackertarget-subdomains.lua 2018-10-13 13:39:40 +02:00
kpcyrd
f382c50ec8 Fix seccomp for alpine 2018-10-13 12:33:46 +02:00
kpcyrd
d961417282 Introduce config file 2018-10-13 03:26:05 +02:00
kpcyrd
36120d07d4 Add shell completions 2018-10-13 03:22:56 +02:00
71 changed files with 2153 additions and 357 deletions

47
.travis.yml Normal file
View File

@@ -0,0 +1,47 @@
language: rust
matrix:
include:
- os: linux
rust: stable
env:
- BUILD_MODE=test
- os: linux
rust: stable
env:
- BUILD_MODE=common
- os: linux
rust: stable
env:
- BUILD_MODE=boxxy
- os: linux
rust: stable
env:
- BUILD_MODE=docker
- os: linux
rust: stable
env:
- BUILD_MODE=docker-registry
- os: osx
rust: stable
env:
- BUILD_MODE=test
- os: osx
rust: stable
env:
- BUILD_MODE=common
- os: windows
rust: stable
env:
- BUILD_MODE="windows test"
- os: windows
rust: stable
env:
- BUILD_MODE="windows common"
before_install:
- ci/setup.sh "$TRAVIS_OS_NAME"
script:
- df -h
- ci/run.sh $BUILD_MODE
- df -h

369
Cargo.lock generated
View File

@@ -57,7 +57,7 @@ version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"backtrace-sys 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)",
"cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-demangle 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -95,6 +95,17 @@ name = "bitflags"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "blake2"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"byte-tools 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"crypto-mac 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"digest 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
"opaque-debug 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "blake2-rfc"
version = "0.2.18"
@@ -112,13 +123,13 @@ dependencies = [
"base64 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)",
"bufstream 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
"caps 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)",
"errno 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
"error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
"futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)",
"http 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper 0.12.11 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper 0.12.12 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper-rustls 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -143,6 +154,11 @@ name = "build_const"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "byte-tools"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "byteorder"
version = "1.2.6"
@@ -174,7 +190,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "cfg-if"
version = "0.1.5"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@@ -184,17 +200,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bytes 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)",
"ct-logs 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"failure 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"failure 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)",
"http 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper 0.12.11 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper 0.12.12 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper-rustls 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
"rustls 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
"trust-dns-proto 0.5.0-alpha.3 (registry+https://github.com/rust-lang/crates.io-index)",
"trust-dns-proto 0.5.0-alpha.5 (registry+https://github.com/rust-lang/crates.io-index)",
"trust-dns-resolver 0.10.0-alpha.3 (registry+https://github.com/rust-lang/crates.io-index)",
"webpki-roots 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -306,7 +322,7 @@ version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
"cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -320,7 +336,7 @@ version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
"cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"crossbeam-utils 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -333,7 +349,7 @@ version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
"cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"crossbeam-utils 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -345,7 +361,7 @@ name = "crossbeam-utils"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -353,6 +369,15 @@ name = "crossbeam-utils"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "crypto-mac"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"generic-array 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
"subtle 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "cssparser"
version = "0.24.1"
@@ -408,7 +433,7 @@ dependencies = [
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
"openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"openssl-sys 0.9.36 (registry+https://github.com/rust-lang/crates.io-index)",
"openssl-sys 0.9.39 (registry+https://github.com/rust-lang/crates.io-index)",
"schannel 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)",
"socket2 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -422,7 +447,7 @@ dependencies = [
"cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
"libz-sys 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)",
"openssl-sys 0.9.36 (registry+https://github.com/rust-lang/crates.io-index)",
"openssl-sys 0.9.39 (registry+https://github.com/rust-lang/crates.io-index)",
"pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
"vcpkg 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -468,6 +493,14 @@ dependencies = [
"migrations_macros 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "digest"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"generic-array 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "dirs"
version = "1.0.4"
@@ -483,7 +516,7 @@ name = "dotenv"
version = "0.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"failure 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"failure 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -506,7 +539,7 @@ name = "encoding_rs"
version = "0.8.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -558,22 +591,32 @@ dependencies = [
[[package]]
name = "failure"
version = "0.1.2"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"backtrace 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
"failure_derive 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"failure_derive 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "failure_derive"
version = "0.1.2"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)",
"synstructure 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 0.15.13 (registry+https://github.com/rust-lang/crates.io-index)",
"synstructure 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "filetime"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -644,6 +687,14 @@ name = "gcc"
version = "0.3.55"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "generic-array"
version = "0.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "glob"
version = "0.2.11"
@@ -651,7 +702,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "h2"
version = "0.1.12"
version = "0.1.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"byteorder 1.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -659,7 +710,7 @@ dependencies = [
"fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
"futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)",
"http 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)",
"indexmap 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"indexmap 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
"slab 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
"string 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -676,17 +727,22 @@ dependencies = [
"pest 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "hex"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "hlua-badtouch"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
"lua52-sys 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"lua52-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -705,7 +761,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
"mac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"markup5ever 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
"markup5ever 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro2 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 0.13.11 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -754,13 +810,13 @@ dependencies = [
[[package]]
name = "hyper"
version = "0.12.11"
version = "0.12.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bytes 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)",
"futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)",
"futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
"h2 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
"h2 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)",
"http 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)",
"httparse 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -785,7 +841,7 @@ dependencies = [
"ct-logs 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)",
"http 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper 0.12.11 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper 0.12.12 (registry+https://github.com/rust-lang/crates.io-index)",
"rustls 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-io 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -802,8 +858,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bytes 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)",
"futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper 0.12.11 (registry+https://github.com/rust-lang/crates.io-index)",
"native-tls 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper 0.12.12 (registry+https://github.com/rust-lang/crates.io-index)",
"native-tls 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-io 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -819,7 +875,7 @@ dependencies = [
[[package]]
name = "indexmap"
version = "1.0.1"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@@ -848,7 +904,7 @@ name = "isatty"
version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -964,7 +1020,7 @@ name = "log"
version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -977,10 +1033,10 @@ dependencies = [
[[package]]
name = "lua52-sys"
version = "0.1.1"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"gcc 0.3.55 (registry+https://github.com/rust-lang/crates.io-index)",
"cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
"pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -997,16 +1053,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "markup5ever"
version = "0.7.2"
version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"phf 0.7.23 (registry+https://github.com/rust-lang/crates.io-index)",
"phf_codegen 0.7.23 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)",
"string_cache 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)",
"string_cache_codegen 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
"string_cache_codegen 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
"tendril 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -1015,12 +1071,22 @@ name = "matches"
version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "maxminddb"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "memchr"
version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
"version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -1058,7 +1124,7 @@ dependencies = [
[[package]]
name = "mime"
version = "0.3.9"
version = "0.3.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"unicase 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1069,7 +1135,7 @@ name = "mime_guess"
version = "2.0.0-alpha.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"mime 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
"mime 0.3.12 (registry+https://github.com/rust-lang/crates.io-index)",
"phf 0.7.23 (registry+https://github.com/rust-lang/crates.io-index)",
"phf_codegen 0.7.23 (registry+https://github.com/rust-lang/crates.io-index)",
"unicase 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1116,14 +1182,15 @@ dependencies = [
[[package]]
name = "native-tls"
version = "0.2.1"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
"openssl 0.10.12 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
"openssl 0.10.15 (registry+https://github.com/rust-lang/crates.io-index)",
"openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"openssl-sys 0.9.36 (registry+https://github.com/rust-lang/crates.io-index)",
"openssl-sys 0.9.39 (registry+https://github.com/rust-lang/crates.io-index)",
"schannel 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)",
"security-framework 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"security-framework-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1135,7 +1202,7 @@ name = "net2"
version = "0.2.33"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -1155,7 +1222,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
"cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
"cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
"void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -1167,7 +1234,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "nom"
version = "4.1.0"
version = "4.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"memchr 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1188,35 +1255,40 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"base64 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)",
"curl 0.4.18 (registry+https://github.com/rust-lang/crates.io-index)",
"failure 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"failure 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)",
"url 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "opaque-debug"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "opener"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"failure 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"failure_derive 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"failure 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"failure_derive 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "openssl"
version = "0.10.12"
version = "0.10.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
"cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
"openssl-sys 0.9.36 (registry+https://github.com/rust-lang/crates.io-index)",
"openssl-sys 0.9.39 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -1226,7 +1298,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "openssl-sys"
version = "0.9.36"
version = "0.9.39"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1506,7 +1578,7 @@ version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"argon2rs 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
"failure 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"failure 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -1561,7 +1633,7 @@ dependencies = [
[[package]]
name = "reqwest"
version = "0.9.2"
version = "0.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"base64 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1569,14 +1641,14 @@ dependencies = [
"encoding_rs 0.8.10 (registry+https://github.com/rust-lang/crates.io-index)",
"futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)",
"http 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper 0.12.11 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper 0.12.12 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper-tls 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"libflate 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
"mime 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
"mime 0.3.12 (registry+https://github.com/rust-lang/crates.io-index)",
"mime_guess 2.0.0-alpha.6 (registry+https://github.com/rust-lang/crates.io-index)",
"native-tls 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
"native-tls 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_urlencoded 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1661,7 +1733,7 @@ dependencies = [
"handlebars 0.28.3 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
"rocket 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -1846,17 +1918,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "serde"
version = "1.0.79"
version = "1.0.80"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "serde_derive"
version = "1.0.79"
version = "1.0.80"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 0.15.9 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 0.15.13 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -1866,7 +1938,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"itoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
"ryu 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -1876,7 +1948,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"dtoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
"itoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
"url 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -1915,7 +1987,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"base64 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
"failure 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"failure 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -1929,7 +2001,7 @@ dependencies = [
[[package]]
name = "sn0int"
version = "0.2.0"
version = "0.3.0"
dependencies = [
"base64 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)",
"boxxy 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1942,12 +2014,14 @@ dependencies = [
"diesel_migrations 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"dirs 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
"env_logger 0.5.13 (registry+https://github.com/rust-lang/crates.io-index)",
"failure 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"failure 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"hlua-badtouch 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
"kuchiki 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libflate 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
"maplit 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"maxminddb 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
"nix 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
"opener 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"publicsuffix 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1955,8 +2029,8 @@ dependencies = [
"regex 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
"rustyline 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"separator 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_urlencoded 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
"shellwords 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1964,7 +2038,9 @@ dependencies = [
"sn0int-common 0.2.0",
"structopt 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)",
"syscallz 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"trust-dns-proto 0.5.0-alpha.3 (registry+https://github.com/rust-lang/crates.io-index)",
"tar 0.4.17 (registry+https://github.com/rust-lang/crates.io-index)",
"toml 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"trust-dns-proto 0.5.0-alpha.5 (registry+https://github.com/rust-lang/crates.io-index)",
"url 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -1972,30 +2048,35 @@ dependencies = [
name = "sn0int-common"
version = "0.2.0"
dependencies = [
"failure 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"nom 4.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
"failure 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"nom 4.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "sn0int-registry"
version = "0.2.0"
version = "0.3.0"
dependencies = [
"blake2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
"diesel 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"diesel_full_text_search 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"diesel_migrations 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"dotenv 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)",
"failure 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"failure 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
"maplit 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"oauth2 2.0.0-alpha.2 (registry+https://github.com/rust-lang/crates.io-index)",
"reqwest 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)",
"reqwest 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)",
"rocket 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)",
"rocket_codegen 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)",
"rocket_contrib 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)",
"semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)",
"sn0int-common 0.2.0",
"url 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -2005,7 +2086,7 @@ name = "socket2"
version = "0.3.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2035,20 +2116,20 @@ dependencies = [
"new_debug_unreachable 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"phf_shared 0.7.23 (registry+https://github.com/rust-lang/crates.io-index)",
"precomputed-hash 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
"string_cache_codegen 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
"string_cache_codegen 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
"string_cache_shared 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "string_cache_codegen"
version = "0.4.1"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"phf_generator 0.7.23 (registry+https://github.com/rust-lang/crates.io-index)",
"phf_shared 0.7.23 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro2 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)",
"string_cache_shared 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -2078,9 +2159,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 0.15.9 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 0.15.13 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "subtle"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "syn"
version = "0.11.11"
@@ -2113,7 +2199,7 @@ dependencies = [
[[package]]
name = "syn"
version = "0.15.9"
version = "0.15.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2131,12 +2217,12 @@ dependencies = [
[[package]]
name = "synstructure"
version = "0.9.0"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 0.15.13 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -2150,12 +2236,23 @@ dependencies = [
"seccomp-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "tar"
version = "0.4.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"filetime 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
"xattr 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "tempfile"
version = "3.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2408,7 +2505,7 @@ name = "toml"
version = "0.4.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -2418,11 +2515,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "trust-dns-proto"
version = "0.5.0-alpha.3"
version = "0.5.0-alpha.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"byteorder 1.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
"failure 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"failure 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)",
"idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2444,8 +2541,8 @@ name = "trust-dns-resolver"
version = "0.10.0-alpha.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"failure 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"failure 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)",
"ipconfig 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2454,7 +2551,7 @@ dependencies = [
"resolv-conf 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
"smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
"trust-dns-proto 0.5.0-alpha.3 (registry+https://github.com/rust-lang/crates.io-index)",
"trust-dns-proto 0.5.0-alpha.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -2467,6 +2564,11 @@ name = "typeable"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "typenum"
version = "1.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "ucd-util"
version = "0.1.1"
@@ -2696,6 +2798,14 @@ dependencies = [
"winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "xattr"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "yansi"
version = "0.4.0"
@@ -2714,15 +2824,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum base64 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "96434f987501f0ed4eb336a411e0631ecd1afa11574fe148587adc4ff96143c9"
"checksum base64 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)" = "489d6c0ed21b11d038c31b6ceccca973e65d73ba3bd8ecb9a2babf5546164643"
"checksum bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "228047a76f468627ca71776ecdebd732a3423081fcf5125585bcd7c49886ce12"
"checksum blake2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "91721a6330935673395a0607df4d49a9cb90ae12d259f1b3e0a3f6e1d486872e"
"checksum blake2-rfc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)" = "5d6d530bdd2d52966a6d03b7a964add7ae1a288d25214066fd4b600f0f796400"
"checksum boxxy 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "10581466a188276917624eea8c2f8939ebf17faa5ee46361ac14d408c3114253"
"checksum bufstream 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "40e38929add23cdf8a366df9b0e088953150724bcbe5fc330b0d8eb3b328eec8"
"checksum build_const 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "39092a32794787acd8525ee150305ff051b0aa6cc2abaf193924f5ab05425f39"
"checksum byte-tools 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "980479e6fde23246dfb54d47580d66b4e99202e7579c5eaa9fe10ecb5ebd2182"
"checksum byteorder 1.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "90492c5858dd7d2e78691cfb89f90d273a2800fc11d98f60786e5d87e2f83781"
"checksum bytes 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "0ce55bd354b095246fc34caf4e9e242f5297a7fd938b090cadfea6eee614aa62"
"checksum caps 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9c71a98c48851ab3763bf766c4a5129e66a9b355f7ff1e93a68e725bbcd05221"
"checksum cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)" = "f159dfd43363c4d08055a07703eb7a3406b0dac4d0584d96965a3262db3c9d16"
"checksum cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "0c4e7bb64a8ebb0d856483e1e682ea3422f883c5f5615a90d51a2c82fe87fdd3"
"checksum cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "082bb9b28e00d3c9d39cc03e64ce4cea0f1bb9b3fde493f0cbc008472d22bdf4"
"checksum chrootable-https 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "03e57ee232e2ba201e717737f5b04e7470bb057b989df25e7d44c92bc8b1bbe8"
"checksum clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b957d88f4b6a63b9d70d5f454ac8011819c6efa7727858f458ab71c756ce2d3e"
"checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f"
@@ -2740,6 +2852,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum crossbeam-epoch 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9c90f1474584f38e270b5b613e898c8c328aa4f3dea85e0a27ac2e642f009416"
"checksum crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2760899e32a1d58d5abb31129f8fae5de75220bc2176e77ff7c627ae45c918d9"
"checksum crossbeam-utils 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "677d453a17e8bd2b913fa38e8b9cf04bcdbb5be790aa294f2389661d72036015"
"checksum crypto-mac 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4434400df11d95d556bac068ddfedd482915eb18fe8bea89bc80b6e4b1c179e5"
"checksum cssparser 0.24.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b200a7193703a615c8d2751fed1ede39b9c4b3905e09d1ec7064a24688c190fc"
"checksum cssparser-macros 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "72b64d0d64184a082f38028396875c08c8ee083481f6f16e6e0cf52c338bd785"
"checksum ct-logs 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "95a4bf5107667e12bf6ce31a3a5066d67acc88942b6742117a41198734aaccaa"
@@ -2750,6 +2863,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum diesel_derives 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "03bcaf77491f53e400d5ee3bdd57142ea4e1c47fe9217b3361ff9a76ca0e3d37"
"checksum diesel_full_text_search 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7ad3168d9d2008c58b8c9fabb79ddc38d1f9d511fa15e0dcbd6b987912b05783"
"checksum diesel_migrations 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "17b42c35d1ce9e8d57a3e7001b4127f2bc1b073a89708bb7019f5be27c991c28"
"checksum digest 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "05f47366984d3ad862010e22c7ce81a7dbcaebbdfb37241a620f8b6596ee135c"
"checksum dirs 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "88972de891f6118092b643d85a0b28e0678e0f948d7f879aa32f2d5aafe97d2a"
"checksum dotenv 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c0d0a1279c96732bc6800ce6337b6a614697b0e74ae058dc03c62ebeb78b4d86"
"checksum dtoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6d301140eb411af13d3115f9a562c85cc6b541ade9dfa314132244aaee7489dd"
@@ -2760,8 +2874,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum errno-dragonfly 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "14ca354e36190500e1e1fb267c647932382b54053c50b14970856c0b00a35067"
"checksum error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "07e791d3be96241c77c43846b665ef1384606da2cd2a48730abe606a12906e02"
"checksum error-chain 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6930e04918388a9a2e41d518c25cf679ccafe26733fb4127dbf21993f2575d46"
"checksum failure 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7efb22686e4a466b1ec1a15c2898f91fa9cb340452496dca654032de20ff95b9"
"checksum failure_derive 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "946d0e98a50d9831f5d589038d2ca7f8f455b1c21028c0db0e84116a12696426"
"checksum failure 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6dd377bcc1b1b7ce911967e3ec24fa19c3224394ec05b54aa7b083d498341ac7"
"checksum failure_derive 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "64c2d913fe8ed3b6c6518eedf4538255b989945c14c2a7d5cbff62a5e2120596"
"checksum filetime 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "da4b9849e77b13195302c174324b5ba73eec9b236b24c221a61000daefb95c5f"
"checksum fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2fad85553e09a6f881f739c29f0b00b0f01357c743266d478b68951ce23285f3"
"checksum foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1"
"checksum foreign-types-shared 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
@@ -2772,9 +2887,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "ab90cde24b3319636588d0c35fe03b1333857621051837ed769faefb4c2162e4"
"checksum fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c"
"checksum gcc 0.3.55 (registry+https://github.com/rust-lang/crates.io-index)" = "8f5f3913fa0bfe7ee1fd8248b6b9f42a5af4b9d65ec2dd2c3c26132b950ecfc2"
"checksum generic-array 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3c0f28c2f5bfb5960175af447a2da7c18900693738343dc896ffbcabd9839592"
"checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb"
"checksum h2 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "a27e7ed946e8335bdf9a191bc1b9b14a03ba822d013d2f58437f4fabcbd7fc2c"
"checksum h2 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "7dd33bafe2e6370e6c8eb0cf1b8c5f93390b90acde7e9b03723f166b28b648ed"
"checksum handlebars 0.28.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1bed53dfb11098ec893ed54aa8b9828ffb98d28acbe56a49419935e5a8688ca9"
"checksum hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "805026a5d0141ffc30abb3be3173848ad46a1b1664fe632428479619a3644d77"
"checksum hlua-badtouch 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d7508a0706ab5bdb0382bb080eb2041d6289d371f59799fd5953d4143fbd5977"
"checksum hostname 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "21ceb46a83a85e824ef93669c8b390009623863b5c195d1ba747292c0c72f94e"
"checksum html5ever 0.22.3 (registry+https://github.com/rust-lang/crates.io-index)" = "b04478cf718862650a0bf66acaf8f2f8c906fbc703f35c916c1f4211b069a364"
@@ -2782,11 +2899,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum httparse 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e8734b0cfd3bc3e101ec59100e101c2eecd19282202e87808b3037b442777a83"
"checksum humantime 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0484fda3e7007f2a4a0d9c3a703ca38c71c54c55602ce4660c419fd32e188c9e"
"checksum hyper 0.10.13 (registry+https://github.com/rust-lang/crates.io-index)" = "368cb56b2740ebf4230520e2b90ebb0461e69034d85d1945febd9b3971426db2"
"checksum hyper 0.12.11 (registry+https://github.com/rust-lang/crates.io-index)" = "78d50abbd1790e0f4c74cb1d4a2211b439bac661d54107ad5564c55e77906762"
"checksum hyper 0.12.12 (registry+https://github.com/rust-lang/crates.io-index)" = "4aca412c241a2dd53af261efc7adf7736fdebd67dc0d1cc1ffdbcb9407e0e810"
"checksum hyper-rustls 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)" = "68f2aa6b1681795bf4da8063f718cd23145aa0c9a5143d9787b345aa60d38ee4"
"checksum hyper-tls 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "32cd73f14ad370d3b4d4b7dce08f69b81536c82e39fcc89731930fe5788cd661"
"checksum idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "38f09e0f0b1fb55fdee1f17470ad800da77af5186a1a76c026b679358b7e844e"
"checksum indexmap 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "08173ba1e906efb6538785a8844dd496f5d34f0a2d88038e95195172fc667220"
"checksum indexmap 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7e81a7c05f79578dbc15793d8b619db9ba32b4577003ef3af1a91c416798c58d"
"checksum iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dbe6e417e7d0975db6512b90796e8ce223145ac4e33c377e4a42882a0e88bb08"
"checksum ipconfig 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "fccb81dd962b29a25de46c4f46e497b75117aa816468b6fff7a63a598a192394"
"checksum isatty 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e31a8281fc93ec9693494da65fbf28c0c2aa60a2eaec25dc58e2f31952e95edc"
@@ -2806,33 +2923,35 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b"
"checksum log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d4fcce5fa49cc693c312001daf1d13411c4a5283796bac1084299ea3e567113f"
"checksum lru-cache 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4d06ff7ff06f729ce5f4e227876cb88d10bc59cd4ae1e09fbb2bde15c850dc21"
"checksum lua52-sys 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "39c2835cc62c821132f91bb28fa41ae178f56b056ab9577c6f7ed81a908b1187"
"checksum lua52-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d451db153c94e455dc817d388f9674f6232425c28db3509e90251c55b8df2f94"
"checksum mac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4"
"checksum maplit 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "08cbb6b4fef96b6d77bfc40ec491b1690c779e77b05cd9f07f787ed376fd4c43"
"checksum markup5ever 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bfedc97d5a503e96816d10fedcd5b42f760b2e525ce2f7ec71f6a41780548475"
"checksum markup5ever 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a87c4100d614080c8ab43334fb028ebe387f273fb61ed4ff0eae9189b94b6be8"
"checksum matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08"
"checksum maxminddb 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7f1511a09d61db34ee71f3639421300acc5fb7787431d879473acd096b6c5990"
"checksum memchr 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4b3629fe9fdbff6daa6c33b90f7c08355c1aca05a3d01fa8063b822fcf185f3b"
"checksum memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0f9dc261e2b62d7a622bf416ea3c5245cdd5d9a7fcc428c0d06804dfce1775b3"
"checksum migrations_internals 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8cf7c8c4f83fa9f47440c0b4af99973502de55e6e7b875f693bd263e03f93e7e"
"checksum migrations_macros 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "79f12499ef7353bdeca2d081bc61edd8351dac09a33af845952009b5a3d68c1a"
"checksum mime 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "ba626b8a6de5da682e1caa06bdb42a335aee5a84db8e5046a3e8ab17ba0a3ae0"
"checksum mime 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "4b082692d3f6cf41b453af73839ce3dfc212c4411cbb2441dff80a716e38bd79"
"checksum mime 0.3.12 (registry+https://github.com/rust-lang/crates.io-index)" = "0a907b83e7b9e987032439a387e187119cddafc92d5c2aaeb1d92580a793f630"
"checksum mime_guess 2.0.0-alpha.6 (registry+https://github.com/rust-lang/crates.io-index)" = "30de2e4613efcba1ec63d8133f344076952090c122992a903359be5a4f99c3ed"
"checksum mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)" = "71646331f2619b1026cc302f87a2b8b648d5c6dd6937846a16cc8ce0f347f432"
"checksum mio-uds 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)" = "966257a94e196b11bb43aca423754d87429960a768de9414f3691d6957abf125"
"checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919"
"checksum native-tls 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8b0a7bd714e83db15676d31caf968ad7318e9cc35f93c85a90231c8f22867549"
"checksum native-tls 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ff8e08de0070bbf4c31f452ea2a70db092f36f6f2e4d897adf5674477d488fb2"
"checksum net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "42550d9fb7b6684a6d404d9fa7250c2eb2646df731d1c06afc06dcee9e1bcf88"
"checksum new_debug_unreachable 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0cdc457076c78ab54d5e0d6fa7c47981757f1e34dc39ff92787f217dede586c4"
"checksum nix 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d37e713a259ff641624b6cb20e3b12b2952313ba36b6823c0f16e6cfd9e5de17"
"checksum nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "9a2228dca57108069a5262f2ed8bd2e82496d2e074a06d1ccc7ce1687b6ae0a2"
"checksum nom 4.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "50b5469365a145d6c39ca7eff1a3048465206268c3f46617bb40c7752397be07"
"checksum nom 4.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9c349f68f25f596b9f44cf0e7c69752a5c633b0550c3ff849518bfba0233774a"
"checksum num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c51a3322e4bca9d212ad9a158a02abc6934d005490c054a2778df73a70aa0a30"
"checksum oauth2 2.0.0-alpha.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0b03cbda9babb980e485e84c7230812f99568b23c68b04008dd0b22f4179a57a"
"checksum opaque-debug 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "51ecbcb821e1bd256d456fe858aaa7f380b63863eab2eb86eee1bd9f33dd6682"
"checksum opener 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "176cd8eadff5ef9fa5c6d19452535662c02c6bf29b3d594a3fc01f749bb24c94"
"checksum openssl 0.10.12 (registry+https://github.com/rust-lang/crates.io-index)" = "5e2e79eede055813a3ac52fb3915caf8e1c9da2dec1587871aec9f6f7b48508d"
"checksum openssl 0.10.15 (registry+https://github.com/rust-lang/crates.io-index)" = "5e1309181cdcbdb51bc3b6bedb33dfac2a83b3d585033d3f6d9e22e8c1928613"
"checksum openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "77af24da69f9d9341038eba93a073b1fdaaa1b788221b00a69bce9e762cb32de"
"checksum openssl-sys 0.9.36 (registry+https://github.com/rust-lang/crates.io-index)" = "409d77eeb492a1aebd6eb322b2ee72ff7c7496b4434d98b3bf8be038755de65e"
"checksum openssl-sys 0.9.39 (registry+https://github.com/rust-lang/crates.io-index)" = "278c1ad40a89aa1e741a1eed089a2f60b18fab8089c3139b542140fc7d674106"
"checksum ordermap 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)" = "b81cf3b8cb96aa0e73bbedfcdc9708d09fec2854ba8d474be4e6f666d7379e8b"
"checksum owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cdf84f41639e037b484f93433aa3897863b561ed65c6e59c7073d7c561710f37"
"checksum parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "f0802bff09003b291ba756dc7e79313e51cc31667e94afbe847def490424cde5"
@@ -2873,7 +2992,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum regex-syntax 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7d707a4fa2637f2dca2ef9fd02225ec7661fe01a53623c1e6515b6916511f7a7"
"checksum regex-syntax 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "747ba3b235651f6e2f67dfa8bcdcd073ddb7c243cb21c442fc12395dfcac212d"
"checksum remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3488ba1b9a2084d38645c4c08276a1752dcbf2c7130d74f1569681ad5d2799c5"
"checksum reqwest 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1d68c7bf0b1dc3860b80c6d31d05808bf54cdc1bfc70a4680893791becd083ae"
"checksum reqwest 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)" = "aa238ac676ec77e62be3e70656828ca4f596fccd33c6fab92942701bc8c8b4fe"
"checksum resolv-conf 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c62bd95a41841efdf7fca2ae9951e64a8d8eae7e5da196d8ce489a2241491a92"
"checksum ring 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1f2a6dc7fc06a05e6de183c5b97058582e9da2de0c136eafe49609769c507724"
"checksum ring 0.13.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dbe642b9dd1ba0038d78c4a3999d1ee56178b4d415c1e1fbaba83b06dce012f0"
@@ -2902,8 +3021,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
"checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
"checksum separator 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7acc4d818f952ed02e7911df5da8098c8b00a3c5ba2832e035a750b56e8fc32b"
"checksum serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)" = "84257ccd054dc351472528c8587b4de2dbf0dc0fe2e634030c1a90bfdacebaa9"
"checksum serde_derive 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)" = "31569d901045afbff7a9479f793177fe9259819aff10ab4f89ef69bbc5f567fe"
"checksum serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)" = "15c141fc7027dd265a47c090bf864cf62b42c4d228bbcf4e51a0c9e2b0d3f7ef"
"checksum serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)" = "225de307c6302bec3898c51ca302fc94a7a1697ef0845fcee6448f33c032249c"
"checksum serde_json 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)" = "43344e7ce05d0d8280c5940cabb4964bea626aa58b1ec0e8c73fa2a8512a38ce"
"checksum serde_urlencoded 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "aaed41d9fb1e2f587201b863356590c90c1157495d811430a0c0325fe8169650"
"checksum servo_arc 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d98238b800e0d1576d8b6e3de32827c2d74bee68bb97748dcf5071fb53965432"
@@ -2917,18 +3036,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum state 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7345c971d1ef21ffdbd103a75990a15eb03604fc8b8852ca8cb418ee1a099028"
"checksum string 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "00caf261d6f90f588f8450b8e1230fa0d5be49ee6140fdfbcb55335aff350970"
"checksum string_cache 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "25d70109977172b127fe834e5449e5ab1740b9ba49fa18a2020f509174f25423"
"checksum string_cache_codegen 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "35293b05cf1494e8ddd042a7df6756bf18d07f42d234f32e71dce8a7aabb0191"
"checksum string_cache_codegen 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1eea1eee654ef80933142157fdad9dd8bc43cf7c74e999e369263496f04ff4da"
"checksum string_cache_shared 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b1884d1bc09741d466d9b14e6d37ac89d6909cbcac41dd9ae982d4d063bbedfc"
"checksum strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb4f380125926a99e52bc279241539c018323fab05ad6368b56f93d9369ff550"
"checksum structopt 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)" = "d77af7242f18c40fd19cb270985930f239ee1646cfb482050bbae9da1d18743b"
"checksum structopt-derive 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)" = "17ff01fe96de9d16e7372ae5f19dd7ece2c703b51043c3db9ea27f9e393ea311"
"checksum subtle 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2d67a5a62ba6e01cb2192ff309324cb4875d0c451d55fe2319433abe7a05a8ee"
"checksum syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad"
"checksum syn 0.13.11 (registry+https://github.com/rust-lang/crates.io-index)" = "14f9bf6292f3a61d2c716723fdb789a41bbe104168e6f496dc6497e531ea1b9b"
"checksum syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)" = "261ae9ecaa397c42b960649561949d69311f08eeaea86a65696e6e46517cf741"
"checksum syn 0.15.9 (registry+https://github.com/rust-lang/crates.io-index)" = "b10ee269228fb723234fce98e9aac0eaed2bd5f1ad2f6930e8d5b93f04445a1a"
"checksum syn 0.15.13 (registry+https://github.com/rust-lang/crates.io-index)" = "7b4439ee8325b4e4b57e59309c3724c9a4478eaeb4eb094b6f3fac180a3b2876"
"checksum synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6"
"checksum synstructure 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "85bb9b7550d063ea184027c9b8c20ac167cd36d3e06b3a40bceb9d746dc1a7b7"
"checksum synstructure 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ec37f4fab4bafaf6b5621c1d54e6aa5d4d059a8f84929e87abfdd7f9f04c6db2"
"checksum syscallz 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e7ba6c26a802c1b51eb4a9c88a37000c6b7e443994d6b53dfcdf85b69dbec045"
"checksum tar 0.4.17 (registry+https://github.com/rust-lang/crates.io-index)" = "83b0d14b53dbfd62681933fadd651e815f99e6084b649e049ab99296e05ab3de"
"checksum tempfile 3.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "55c1195ef8513f3273d55ff59fe5da6940287a0d7a98331254397f464833675b"
"checksum tendril 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9de21546595a0873061940d994bbbc5c35f024ae4fd61ec5c5b159115684f508"
"checksum termcolor 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "4096add70612622289f2fdcdbd5086dc81c1e2675e6ae58d6c4f62a16c6d7f2f"
@@ -2953,10 +3074,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum tokio-uds 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "22e3aa6d1fcc19e635418dc0a30ab5bd65d347973d6f43f1a37bf8d9d1335fc9"
"checksum toml 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "4a2ecc31b0351ea18b3fe11274b8db6e4d82bce861bbb22e6dbed40417902c65"
"checksum traitobject 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "efd1f82c56340fdf16f2a953d7bda4f8fdffba13d93b00844c25572110b26079"
"checksum trust-dns-proto 0.5.0-alpha.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3fabc184ed90d027afee46386e6418b9c953b7be527f62cc37724a1720e07d68"
"checksum trust-dns-proto 0.5.0-alpha.5 (registry+https://github.com/rust-lang/crates.io-index)" = "3daf083dfce3c3554e82b768078331864df1ab220e6c3c1dbb4c847173d33ff6"
"checksum trust-dns-resolver 0.10.0-alpha.3 (registry+https://github.com/rust-lang/crates.io-index)" = "476d293db1c1027727a1683b681550a24207277e96bb1fb763053e1164621971"
"checksum try-lock 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e604eb7b43c06650e854be16a2a03155743d3752dd1c943f6829e26b7a36e382"
"checksum typeable 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1410f6f91f21d1612654e7cc69193b0334f909dcf2c790c4826254fbb86f8887"
"checksum typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "612d636f949607bdf9b123b4a6f6d966dedf3ff669f7f045890d3a4a73948169"
"checksum ucd-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fd2be2d6639d0f8fe6cdda291ad456e23629558d466e2789d2c3e9892bda285d"
"checksum unicase 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7f4765f83163b74f957c797ad9253caf97f103fb064d3999aea9568d09fc8a33"
"checksum unicase 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9d3218ea14b4edcaccfa0df0a64a3792a2c32cc706f1b336e48867f9d3147f90"
@@ -2992,4 +3114,5 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum winreg 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a27a759395c1195c4cc5cda607ef6f8f6498f64e78f7900f5de0a127a424704a"
"checksum winutil 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7daf138b6b14196e3830a588acf1e86966c694d3e8fb026fb105b8b5dca07e6e"
"checksum ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e"
"checksum xattr 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "244c3741f4240ef46274860397c7c74e50eb23624996930e484c16679633a54c"
"checksum yansi 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d60c3b48c9cdec42fb06b3b84b5b087405e1fa1c644a1af3930e4dfafe93de48"

View File

@@ -1,6 +1,6 @@
[package]
name = "sn0int"
version = "0.2.0"
version = "0.3.0"
description = "OSINT framework and package manager"
authors = ["kpcyrd <git@rxv.cc>"]
license = "GPL-3.0"
@@ -8,6 +8,9 @@ repository = "https://github.com/kpcyrd/sn0int"
categories = ["command-line-utilities"]
readme = "README.md"
[badges]
travis-ci = { repository = "kpcyrd/sn0int" }
[workspace]
members = ["sn0int-registry/sn0int-common",
"sn0int-registry"]
@@ -30,8 +33,6 @@ diesel_migrations = { version = "1.3.0", features = ["sqlite"] }
dirs = "1.0"
url = "1.7"
nix = "0.11"
caps = "0.3"
syscallz = "0.7"
chrootable-https = "0.3.3"
trust-dns-proto = "0.5.0-alpha.1"
base64 = "0.9"
@@ -47,6 +48,14 @@ separator = "0.3.1"
maplit = "1.0.1"
sloppy-rfc4880 = "0.1.2"
regex = "1.0"
toml = "0.4"
maxminddb = "0.10.0"
tar = "0.4.17"
libflate = "0.1.14"
[target.'cfg(target_os="linux")'.dependencies]
caps = "0.3"
syscallz = "0.7"
[dev-dependencies]
boxxy = "0.8"

View File

@@ -1,6 +1,29 @@
# sn0int
# sn0int [![Build Status][travis-img]][travis] [![Crates.io][crates-img]][crates]
work in progress
[travis-img]: https://travis-ci.org/kpcyrd/sn0int.svg?branch=master
[travis]: https://travis-ci.org/kpcyrd/sn0int
[crates-img]: https://img.shields.io/crates/v/sn0int.svg
[crates]: https://crates.io/crates/sn0int
sn0int is an OSINT framework and package manager. It's purpose is
semi-automatically processing public information to enumerate attack surface.
sn0int itself is only providing an engine that can be extended with scripts.
sn0int is heavily inspired by recon-ng, but takes a few different design
approaches. We've tried to correct some limitations in the database design and
also addressed the modularity problem:
Instead of downloading and reviewing python scripts that have full access to
your system, sn0int is executing modules in a lua sandbox. Modules can be
published to the sn0int registry and then installed by users. This means that
you don't have to send pull requests to sn0int to add a module and updates can
be shipped much faster.
## Installation
- Archlinux: `yaourt -S sn0int`
- Alpine: `apk add --no-cache sqlite-dev libseccomp-dev cargo` + build from source
- Debian: `apt install libsqlite3-dev libseccomp-dev` + build from source
## License

3
ci/boxxy_stage1.txt Normal file
View File

@@ -0,0 +1,3 @@
stage1
ls
echo sandbox fail

39
ci/run.sh Executable file
View File

@@ -0,0 +1,39 @@
#!/bin/sh
set -exu
case "$1" in
build)
cargo build --verbose
cargo build --verbose --examples
;;
test)
ci/run.sh build
wget https://geolite.maxmind.com/download/geoip/database/GeoLite2-City.tar.gz
cargo run --example geoip-download -- -e GeoLite2-City.tar.gz GeoLite2-City.mmdb GeoLite2-City.mmdb
cargo test --verbose
cargo test --verbose -- --ignored
;;
common)
cd sn0int-registry/sn0int-common
cargo test --verbose
;;
windows)
export SQLITE3_LIB_DIR="$TRAVIS_BUILD_DIR"
ci/run.sh "$2"
;;
boxxy)
cargo build --verbose --examples
if cat ci/boxxy_stage1.txt | RUST_LOG=boxxy cargo run --example boxxy; then
echo "SANDOX ERROR: should've crashed"
exit 1
fi
;;
docker)
docker build -t sn0int .
docker images
docker run --rm sn0int --help
;;
docker-registry)
docker build -t sn0int-registry sn0int-registry/
docker images
;;
esac

16
ci/setup.sh Executable file
View File

@@ -0,0 +1,16 @@
#!/bin/sh
set -exu
case "$1" in
linux)
sudo apt update
sudo apt install libsqlite3-dev libseccomp-dev
;;
osx)
brew install sqlite3
;;
windows)
curl -fsS --retry 3 --retry-connrefused -o sqlite3.zip https://sqlite.org/2017/sqlite-dll-win64-x64-3160200.zip
7z e sqlite3.zip -y
"C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\VC\\bin\\lib.exe" /def:sqlite3.def /OUT:sqlite3.lib /machine:x64
;;
esac

View File

@@ -0,0 +1,44 @@
extern crate sn0int;
extern crate env_logger;
extern crate chrootable_https;
#[macro_use] extern crate log;
#[macro_use] extern crate structopt;
use sn0int::errors::*;
use sn0int::paths;
use std::fs;
use structopt::StructOpt;
#[derive(Debug, StructOpt)]
pub struct Args {
url: String,
filter: String,
target: String,
#[structopt(short="e", long="extract-only")]
extract_only: bool,
}
fn run() -> Result<()> {
let args = Args::from_args();
debug!("{:?}", args);
let path = paths::cache_dir()?.join(&args.target);
if args.extract_only {
let body = fs::read(&args.url)?;
sn0int::archive::extract(&mut &body[..], &args.filter, path)?;
} else {
sn0int::geoip::GeoIP::download(path, &args.filter, &args.url)?;
}
Ok(())
}
fn main() {
env_logger::init();
if let Err(err) = run() {
eprintln!("Error: {}", err);
for cause in err.iter_chain().skip(1) {
eprintln!("Because: {}", cause);
}
std::process::exit(1);
}
}

30
examples/geoip.rs Normal file
View File

@@ -0,0 +1,30 @@
extern crate sn0int;
extern crate env_logger;
use std::env;
use sn0int::errors::*;
fn run() -> Result<()> {
let geoip = sn0int::geoip::GeoIP::open_or_download()?;
for arg in env::args().skip(1) {
let ip = arg.parse()?;
let lookup = geoip.lookup(ip)?;
println!("{:#?}", lookup);
}
Ok(())
}
fn main() {
env_logger::init();
if let Err(err) = run() {
eprintln!("Error: {}", err);
for cause in err.iter_chain().skip(1) {
eprintln!("Because: {}", cause);
}
std::process::exit(1);
}
}

View File

@@ -24,7 +24,7 @@ CREATE TABLE subdomain_ipaddrs (
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
subdomain_id INTEGER NOT NULL,
ip_addr_id INTEGER NOT NULL,
FOREIGN KEY(subdomain_id) REFERENCES domains(id),
FOREIGN KEY(subdomain_id) REFERENCES subdomains(id),
FOREIGN KEY(ip_addr_id) REFERENCES ipaddrs(id),
CONSTRAINT subdomain_ipaddr_unique UNIQUE (subdomain_id, ip_addr_id)
);
@@ -35,6 +35,6 @@ CREATE TABLE urls (
value VARCHAR NOT NULL,
status INTEGER,
body BLOB,
FOREIGN KEY(subdomain_id) REFERENCES domains(id),
FOREIGN KEY(subdomain_id) REFERENCES subdomains(id),
CONSTRAINT url_unique UNIQUE (value)
);

View File

@@ -1,5 +1,5 @@
CREATE TABLE emails (
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
value VARCHAR NOT NULL,
CONSTRAINT domain_unique UNIQUE (value)
CONSTRAINT email_unique UNIQUE (value)
);

View File

@@ -0,0 +1,90 @@
PRAGMA foreign_keys=off;
-- domains
ALTER TABLE domains RENAME TO _domains_old;
CREATE TABLE domains (
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
value VARCHAR NOT NULL,
CONSTRAINT domain_unique UNIQUE (value)
);
INSERT INTO domains (id, value)
SELECT id, value
FROM _domains_old;
DROP TABLE _domains_old;
-- subdomains
ALTER TABLE subdomains RENAME TO _subdomains_old;
CREATE TABLE subdomains (
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
domain_id INTEGER NOT NULL,
value VARCHAR NOT NULL,
FOREIGN KEY(domain_id) REFERENCES domains(id),
CONSTRAINT subdomain_unique UNIQUE (value)
);
INSERT INTO subdomains (id, domain_id, value)
SELECT id, domain_id, value
FROM _subdomains_old;
DROP TABLE _subdomains_old;
-- ipaddrs
ALTER TABLE ipaddrs RENAME TO _ipaddrs_old;
CREATE TABLE ipaddrs (
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
family VARCHAR NOT NULL,
value VARCHAR NOT NULL,
CONSTRAINT ipaddr_unique UNIQUE (value)
);
INSERT INTO ipaddrs (id, family, value)
SELECT id, family, value
FROM _ipaddrs_old;
DROP TABLE _ipaddrs_old;
-- urls
ALTER TABLE urls RENAME TO _urls_old;
CREATE TABLE urls (
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
subdomain_id INTEGER NOT NULL,
value VARCHAR NOT NULL,
status INTEGER,
body BLOB,
FOREIGN KEY(subdomain_id) REFERENCES subdomains(id),
CONSTRAINT url_unique UNIQUE (value)
);
INSERT INTO urls (id, subdomain_id, value, status, body)
SELECT id, subdomain_id, value, status, body
FROM _urls_old;
DROP TABLE _urls_old;
-- emails
ALTER TABLE emails RENAME TO _emails_old;
CREATE TABLE emails (
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
value VARCHAR NOT NULL,
CONSTRAINT domain_unique UNIQUE (value)
);
INSERT INTO emails (id, value)
SELECT id, value
FROM _emails_old;
DROP TABLE _emails_old;
PRAGMA foreign_keys=on;

View File

@@ -0,0 +1,5 @@
ALTER TABLE domains ADD COLUMN unscoped BOOLEAN DEFAULT 0 NOT NULL;
ALTER TABLE subdomains ADD COLUMN unscoped BOOLEAN DEFAULT 0 NOT NULL;
ALTER TABLE ipaddrs ADD COLUMN unscoped BOOLEAN DEFAULT 0 NOT NULL;
ALTER TABLE urls ADD COLUMN unscoped BOOLEAN DEFAULT 0 NOT NULL;
ALTER TABLE emails ADD COLUMN unscoped BOOLEAN DEFAULT 0 NOT NULL;

View File

@@ -0,0 +1,60 @@
PRAGMA foreign_keys=off;
-- subdomains
ALTER TABLE subdomains RENAME TO _subdomains_old;
CREATE TABLE subdomains (
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
domain_id INTEGER NOT NULL,
value VARCHAR NOT NULL,
unscoped BOOLEAN DEFAULT 0 NOT NULL,
FOREIGN KEY(domain_id) REFERENCES domains(id),
CONSTRAINT subdomain_unique UNIQUE (value)
);
INSERT INTO subdomains (id, domain_id, value, unscoped)
SELECT id, domain_id, value, unscoped
FROM _subdomains_old;
DROP TABLE _subdomains_old;
-- emails
ALTER TABLE emails RENAME TO _emails_old;
CREATE TABLE emails (
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
value VARCHAR NOT NULL,
unscoped BOOLEAN DEFAULT 0 NOT NULL,
CONSTRAINT emails_unique UNIQUE (value)
);
INSERT INTO emails (id, value, unscoped)
SELECT id, value, unscoped
FROM _emails_old;
DROP TABLE _emails_old;
-- urls
ALTER TABLE urls RENAME TO _urls_old;
CREATE TABLE urls (
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
subdomain_id INTEGER NOT NULL,
value VARCHAR NOT NULL,
status INTEGER,
body BLOB,
unscoped BOOLEAN DEFAULT 0 NOT NULL,
FOREIGN KEY(subdomain_id) REFERENCES subdomains(id),
CONSTRAINT url_unique UNIQUE (value)
);
INSERT INTO urls (id, subdomain_id, value, status, body, unscoped)
SELECT id, subdomain_id, value, status, body, unscoped
FROM _urls_old;
DROP TABLE _urls_old;
PRAGMA foreign_keys=on;

View File

@@ -0,0 +1,3 @@
ALTER TABLE subdomains ADD COLUMN resolvable BOOLEAN;
ALTER TABLE emails ADD COLUMN valid BOOLEAN;
ALTER TABLE urls ADD COLUMN online BOOLEAN;

View File

@@ -0,0 +1,21 @@
PRAGMA foreign_keys=off;
-- ipaddrs
ALTER TABLE ipaddrs RENAME TO _ipaddrs_old;
CREATE TABLE ipaddrs (
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
family VARCHAR NOT NULL,
value VARCHAR NOT NULL,
unscoped BOOLEAN DEFAULT 0 NOT NULL,
CONSTRAINT ipaddr_unique UNIQUE (value)
);
INSERT INTO ipaddrs (id, family, value, unscoped)
SELECT id, family, value, unscoped
FROM _ipaddrs_old;
DROP TABLE _ipaddrs_old;
PRAGMA foreign_keys=on;

View File

@@ -0,0 +1,7 @@
ALTER TABLE ipaddrs ADD COLUMN continent VARCHAR;
ALTER TABLE ipaddrs ADD COLUMN continent_code VARCHAR;
ALTER TABLE ipaddrs ADD COLUMN country VARCHAR;
ALTER TABLE ipaddrs ADD COLUMN country_code VARCHAR;
ALTER TABLE ipaddrs ADD COLUMN city VARCHAR;
ALTER TABLE ipaddrs ADD COLUMN latitude FLOAT;
ALTER TABLE ipaddrs ADD COLUMN longitude FLOAT;

View File

@@ -7,8 +7,16 @@ function run(arg)
records = dns(arg['value'], 'A')
if last_err() then return end
if records['success'] == nil then
-- TODO: consider marking the subdomain is inaccessible
-- update subdomain
resolvable = records['success'] ~= nil
if arg['resolvable'] ~= resolvable then
-- TODO: pass arg to function as well
db_update('subdomain', arg, {
resolvable=resolvable
})
end
if not resolvable then
return
end

38
modules/dev/geoip.lua Normal file
View File

@@ -0,0 +1,38 @@
-- Description: Query certificate transparency logs to discover subdomains
-- Version: 0.1.0
-- Source: ipaddrs
-- License: GPL-3.0
function run(arg)
lookup = geoip_lookup(arg['value'])
if last_err() then return end
fields = {
'continent',
'continent_code',
'country',
'country_code',
'city',
'latitude',
'longitude',
}
update = {}
updated = false
i = 1
while i <= #fields do
f = fields[i]
if lookup[f] ~= arg[f] then
update[f] = lookup[f]
updated = true
end
i = i+1
end
if updated then
db_update('ipaddr', arg, update)
end
end

View File

@@ -0,0 +1,30 @@
-- Description: Query hackertarget for subdomains of a domain
-- Version: 0.1.0
-- Source: domains
-- License: GPL-3.0
function run(arg)
session = http_mksession()
req = http_request(session, 'GET', 'https://api.hackertarget.com/hostsearch/', {
query={
q=arg['value']
}
})
resp = http_send(req)
if last_err() then return end
if resp['status'] ~= 200 then return 'http error: ' .. resp['status'] end
m = regex_find_all("([^,]+),.+\\n?", resp['text'])
i = 1
while i <= #m do
db_add('subdomain', {
domain_id=arg['id'],
value=m[i][2]
})
i = i+1
end
end

View File

@@ -1,6 +1,6 @@
[package]
name = "sn0int-registry"
version = "0.2.0"
version = "0.3.0"
description = "sn0int registry"
authors = ["kpcyrd <git@rxv.cc>"]
license = "GPL-3.0"
@@ -22,8 +22,13 @@ failure = "0.1"
url = "1.0"
log = "0.4"
semver = "0.9.0"
lazy_static = "1.1"
blake2 = "0.8.0"
hex = "0.3.1"
maplit = "1.0.1"
serde = "1.0"
serde_derive = "1.0"
serde_json = "1.0"
dotenv = "0.13"

View File

@@ -19,3 +19,12 @@ h1 a {
text-decoration: none;
color: #00aa00;
}
a {
color: #00aa00;
}
.code {
background-color: #222;
padding: 10px;
}

View File

@@ -135,9 +135,7 @@ named!(metaline<&str, (EntryType, &str)>, do_parse!(
tag!(": ") >>
value: take_until!("\n") >>
tag!("\n") >>
(
(name, value)
)
(name, value)
));
named!(metalines<&str, Vec<(EntryType, &str)>>, do_parse!(

View File

@@ -0,0 +1,13 @@
use blake2::{Blake2b, Digest};
pub static FAVICON: &[u8] = include_bytes!("../assets/favicon.ico");
pub static STYLE_SHEET: &str = include_str!("../assets/style.css");
lazy_static! {
pub static ref ASSET_REV: String = {
let mut h = Blake2b::new();
h.input(STYLE_SHEET.as_bytes());
hex::encode(&h.result()[0..8])
};
}

View File

@@ -8,9 +8,12 @@ extern crate sn0int_common;
extern crate rocket;
#[macro_use] extern crate rocket_contrib;
extern crate dotenv;
// extern crate serde;
extern crate blake2;
extern crate serde_json;
#[macro_use] extern crate serde_derive;
#[macro_use] extern crate log;
#[macro_use] extern crate maplit;
#[macro_use] extern crate lazy_static;
#[macro_use] extern crate failure;
#[macro_use] extern crate diesel;
#[macro_use] extern crate diesel_migrations;
@@ -20,13 +23,13 @@ extern crate url;
extern crate reqwest;
extern crate semver;
use rocket::response::content;
use rocket_contrib::{Json, Value, Template};
use dotenv::dotenv;
use std::env;
use errors::*;
pub mod assets;
pub mod auth;
pub mod auth2;
pub mod db;
@@ -38,21 +41,6 @@ pub mod routes;
pub mod schema;
#[get("/")]
fn index() -> Template {
Template::render("index", ())
}
#[get("/favicon.ico")]
fn favicon() -> Vec<u8> {
include_bytes!("../assets/favicon.ico").to_vec()
}
#[get("/assets/style.css")]
fn style() -> content::Css<&'static str> {
content::Css(include_str!("../assets/style.css"))
}
#[catch(400)]
fn bad_request() -> Json<Value> {
Json(json!({
@@ -100,9 +88,9 @@ fn run() -> Result<()> {
routes::auth::login,
])
.mount("/", routes![
index,
favicon,
style
routes::assets::index,
routes::assets::favicon,
routes::assets::style,
])
.catch(catchers![
bad_request,

View File

@@ -0,0 +1,26 @@
use rocket::http::Status;
use rocket::response::content;
use rocket_contrib::Template;
use assets::{ASSET_REV, FAVICON, STYLE_SHEET};
#[get("/")]
fn index() -> Template {
Template::render("index", hashmap!{
"ASSET_REV" => ASSET_REV.as_str(),
})
}
#[get("/favicon.ico")]
fn favicon() -> Vec<u8> {
FAVICON.to_vec()
}
#[get("/assets/<rev>/style.css")]
fn style(rev: String) -> Result<content::Css<&'static str>, Status> {
if rev == *ASSET_REV {
Ok(content::Css(STYLE_SHEET))
} else {
Err(Status::NotFound)
}
}

View File

@@ -4,10 +4,16 @@ use db;
use rocket::request::Form;
use rocket::response::Redirect;
use rocket_contrib::Template;
use assets::ASSET_REV;
use serde_json::{self, Value};
#[get("/?<auth>")]
pub fn get(auth: OAuth) -> Template {
let mut auth = serde_json::to_value(&auth).expect("OAuth serialization failed");
if let Value::Object(ref mut map) = auth {
map.insert("ASSET_REV".to_string(), Value::String(ASSET_REV.to_string()));
}
Template::render("auth-confirm", auth)
}
@@ -17,7 +23,9 @@ pub fn post(auth: Form<OAuth>, connection: db::Connection) -> ApiResult<Template
let client = Authenticator::from_env()?;
client.store_code(code, state, &connection)?;
Ok(Template::render("auth-done", vec![1]))
Ok(Template::render("auth-done", hashmap!{
"ASSET_REV" => ASSET_REV.as_str(),
}))
}
#[get("/<session>")]

View File

@@ -1,2 +1,3 @@
pub mod api;
pub mod assets;
pub mod auth;

View File

@@ -3,7 +3,7 @@
<head>
<meta charset="utf-8">
<title>sn0int registry</title>
<link rel="stylesheet" href="/assets/style.css">
<link rel="stylesheet" href="/assets/{{ASSET_REV}}/style.css">
</head>
<body>
<h1><a href="/">sn0int</a></h1>

View File

@@ -1,6 +1,49 @@
{{#*inline "page"}}
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
This is the registry server of sn0int, an OSINT framework and package
manager. It's purpose is semi-automatically processing public
information to enumerate attack surface. sn0int itself is only
providing an engine that can be extended with scripts.
</p>
<p>
The registry server allows uploading modules that can be installed by
users afterwards. This is done using sn0int which needs to be
<a href="https://github.com/kpcyrd/sn0int#installation" target="_blank"
rel="noopener">installed</a>.
</p>
<p>
You can search for modules with sn0int using:
</p>
<p class="code"><code>
sn0int search ctlogs
</code></p>
<p>
To install the module afterwards run:
</p>
<p class="code"><code>
sn0int install kpcyrd/ctlogs
</code></p>
<p>
If you want to publish your own module, you need to login with github first:
</p>
<p class="code"><code>
sn0int login
</code></p>
<p>
Afterwards you can upload your module to the registry (this is going to
publish your module as yourgithubuser/example):
</p>
<p class="code"><code>
sn0int publish ./path/to/example.lua
</code></p>
<p>
For more information, visit <a href="https://github.com/kpcyrd/sn0int"
target="_blank" rel="noopener">sn0int on github</a>.
</p>
{{/inline}}
{{~> base }}

View File

@@ -1,5 +1,6 @@
use errors::*;
use std::fmt;
use config::Config;
use chrootable_https::{self, HttpClient, Body, Request, Uri};
use chrootable_https::http::request::Builder as RequestBuilder;
use chrootable_https::header::CONTENT_TYPE;
@@ -12,8 +13,6 @@ use sn0int_common::api::*;
use sn0int_common::ModuleID;
use web;
pub const API_URL: &str = "http://[::1]:8000";
pub struct Client {
server: String,
@@ -22,10 +21,10 @@ pub struct Client {
}
impl Client {
pub fn new<I: Into<String>>(server: I) -> Result<Client> {
pub fn new(config: &Config) -> Result<Client> {
let client = chrootable_https::Client::with_system_resolver()?;
Ok(Client {
server: server.into(),
server: config.core.registry.clone(),
client,
session: None,
})
@@ -98,7 +97,7 @@ impl Client {
pub fn publish_module(&self, name: &str, body: String) -> Result<PublishResponse> {
let url = format!("{}/api/v0/publish/{}", self.server, name);
let reply = self.post::<PublishResponse, _>(&url, &PublishRequest {
code: body.into(),
code: body,
})?;
Ok(reply)
}

40
src/archive.rs Normal file
View File

@@ -0,0 +1,40 @@
use errors::*;
use tar;
use libflate::gzip;
use std::io;
use std::fs::File;
use std::path::Path;
pub fn extract<R: io::Read, P: AsRef<Path>>(read: &mut R, filter: &str, target: P) -> Result<()> {
let file = gzip::Decoder::new(read)?;
let mut ar = tar::Archive::new(file);
for entry in ar.entries()? {
let mut entry = entry?;
let file_name = {
let path = entry.path()?;
path.file_name()
.ok_or(format_err!("Invalid path in archive"))?
.to_str()
.ok_or(format_err!("Filename is invalid utf8"))?
.to_owned()
};
debug!("Found in archive: {:?}", file_name);
if filter == file_name {
debug!("Extracting to {:?}", target.as_ref());
let mut target = File::create(target)?;
let n = io::copy(&mut entry, &mut target)?;
debug!("Wrote {:?} bytes", n);
return Ok(());
}
debug!("Skipping file");
}
bail!("Nothing in archive matched filter")
}

View File

@@ -1,4 +1,4 @@
use structopt::clap::AppSettings;
use structopt::clap::{AppSettings, Shell};
use sn0int_common::ModuleID;
@@ -43,6 +43,9 @@ pub enum SubCommand {
#[structopt(author="", name="search")]
/// Search in the registry
Search(Search),
#[structopt(author="", name="completions")]
/// Generate shell completions
Completions(Completions),
}
#[derive(Debug, StructOpt)]
@@ -81,3 +84,9 @@ pub struct Search {
/// The search query
pub query: String,
}
#[derive(Debug, StructOpt)]
pub struct Completions {
#[structopt(raw(possible_values="&Shell::variants()"))]
pub shell: Shell,
}

View File

@@ -3,7 +3,8 @@ use opener;
use std::fs;
use std::thread;
use std::time::Duration;
use api::{API_URL, Client};
use api::Client;
use config::Config;
use paths;
use term;
@@ -22,8 +23,8 @@ pub fn save_token(session: &str) -> Result<()> {
Ok(())
}
pub fn run_login() -> Result<()> {
let mut client = Client::new(API_URL)?;
pub fn run_login(config: &Config) -> Result<()> {
let mut client = Client::new(config)?;
if let Ok(session) = load_token() {
client.authenticate(session);
@@ -35,7 +36,7 @@ pub fn run_login() -> Result<()> {
let session = Client::random_session();
client.authenticate(session.clone());
let url = format!("{}/auth/{}", API_URL, session);
let url = format!("{}/auth/{}", config.core.registry, session);
term::success(&format!("Opening url: {}", url));
opener::open(url)?;

View File

@@ -4,3 +4,5 @@ pub mod run_cmd;
pub mod use_cmd;
pub mod select_cmd;
pub mod mod_cmd;
pub mod noscope_cmd;
pub mod scope_cmd;

View File

@@ -39,6 +39,7 @@ pub struct Reload {
pub fn run(rl: &mut Readline, args: &[String]) -> Result<()> {
let args = Args::from_iter_safe(args)?;
let config = rl.config().clone();
match args.subcommand {
SubCommand::List(_) => {
@@ -49,11 +50,11 @@ pub fn run(rl: &mut Readline, args: &[String]) -> Result<()> {
}
},
SubCommand::Install(install) => {
registry::run_install(&install)?;
registry::run_install(&install, &config)?;
// trigger reload
run(rl, &[String::from("mod"), String::from("reload")])?;
},
SubCommand::Search(search) => registry::run_search(&search)?,
SubCommand::Search(search) => registry::run_search(&search, &config)?,
SubCommand::Reload(_) => {
let current = rl.take_module()
.map(|m| m.canonical());

50
src/cmd/noscope_cmd.rs Normal file
View File

@@ -0,0 +1,50 @@
use errors::*;
use db;
use shell::Readline;
use structopt::StructOpt;
use models::*;
use term;
#[derive(Debug, StructOpt)]
pub enum Args {
#[structopt(name="domains")]
Domains(Filter),
#[structopt(name="subdomains")]
Subdomains(Filter),
#[structopt(name="ipaddrs")]
IpAddrs(Filter),
#[structopt(name="urls")]
Urls(Filter),
#[structopt(name="emails")]
Emails(Filter),
}
#[derive(Debug, StructOpt)]
pub struct Filter {
args: Vec<String>,
}
impl Filter {
pub fn parse(&self) -> Result<db::Filter> {
db::Filter::parse(&self.args)
}
}
pub fn run(rl: &mut Readline, args: &[String]) -> Result<()> {
let args = Args::from_iter_safe(args)?;
let rows = match args {
Args::Domains(filter) => noscope::<Domain>(rl, &filter),
Args::Subdomains(filter) => noscope::<Subdomain>(rl, &filter),
Args::IpAddrs(filter) => noscope::<IpAddr>(rl, &filter),
Args::Urls(filter) => noscope::<Url>(rl, &filter),
Args::Emails(filter) => noscope::<Email>(rl, &filter),
}?;
term::info(&format!("Updated {} rows", rows));
Ok(())
}
fn noscope<T: Model + Detailed>(rl: &mut Readline, filter: &Filter) -> Result<usize> {
rl.db().noscope::<T>(&filter.parse()?)
}

View File

@@ -22,9 +22,10 @@ fn prepare_arg<T: Serialize + fmt::Display>(x: T) -> Result<(serde_json::Value,
Ok((arg, Some(pretty)))
}
fn prepare_args<T: Model + Serialize + fmt::Display>(db: &Database) -> Result<Vec<(serde_json::Value, Option<String>)>> {
fn prepare_args<T: Scopable + Serialize + fmt::Display>(db: &Database) -> Result<Vec<(serde_json::Value, Option<String>)>> {
db.list::<T>()?
.into_iter()
.filter(|x| x.scoped())
.map(prepare_arg)
.collect()
}

50
src/cmd/scope_cmd.rs Normal file
View File

@@ -0,0 +1,50 @@
use errors::*;
use db;
use shell::Readline;
use structopt::StructOpt;
use models::*;
use term;
#[derive(Debug, StructOpt)]
pub enum Args {
#[structopt(name="domains")]
Domains(Filter),
#[structopt(name="subdomains")]
Subdomains(Filter),
#[structopt(name="ipaddrs")]
IpAddrs(Filter),
#[structopt(name="urls")]
Urls(Filter),
#[structopt(name="emails")]
Emails(Filter),
}
#[derive(Debug, StructOpt)]
pub struct Filter {
args: Vec<String>,
}
impl Filter {
pub fn parse(&self) -> Result<db::Filter> {
db::Filter::parse(&self.args)
}
}
pub fn run(rl: &mut Readline, args: &[String]) -> Result<()> {
let args = Args::from_iter_safe(args)?;
let rows = match args {
Args::Domains(filter) => scope::<Domain>(rl, &filter),
Args::Subdomains(filter) => scope::<Subdomain>(rl, &filter),
Args::IpAddrs(filter) => scope::<IpAddr>(rl, &filter),
Args::Urls(filter) => scope::<Url>(rl, &filter),
Args::Emails(filter) => scope::<Email>(rl, &filter),
}?;
term::info(&format!("Updated {} rows", rows));
Ok(())
}
fn scope<T: Model + Detailed>(rl: &mut Readline, filter: &Filter) -> Result<usize> {
rl.db().scope::<T>(&filter.parse()?)
}

View File

@@ -27,7 +27,7 @@ pub struct Filter {
impl Filter {
pub fn parse(&self) -> Result<db::Filter> {
db::Filter::parse(&self.args)
db::Filter::parse_optional(&self.args)
}
}

View File

@@ -1,3 +1,5 @@
use args::{Args, Completions};
use errors::*;
use rustyline;
use rustyline::completion::Completer;
use rustyline::highlight::Highlighter;
@@ -5,6 +7,8 @@ use rustyline::hint::Hinter;
use shellwords;
use std::borrow::Cow::{self, Borrowed, Owned};
use std::str::FromStr;
use std::io::stdout;
use structopt::StructOpt;
use shell::Command;
@@ -14,6 +18,26 @@ pub struct CmdCompleter {
}
impl CmdCompleter {
pub fn filter(&self, cmd: &str, args: &[String]) -> rustyline::Result<(usize, Vec<String>)> {
// we can only complete the 2nd argument
if args.len() != 2 {
Ok((0, vec![]))
} else {
let arg = &args[1];
let options = &["domains",
"subdomains",
"ipaddrs",
"urls",
"emails"];
let results: Vec<String> = options.iter()
.filter(|x| x.starts_with(arg))
.map(|x| format!("{} {} ", cmd, x))
.collect();
Ok((0, results))
}
}
}
impl Completer for CmdCompleter {
@@ -90,6 +114,7 @@ impl Completer for CmdCompleter {
}
},
Command::Noscope => self.filter("noscope", &cmd),
Command::Use => {
// we can only complete the 2nd argument
if args != 2 {
@@ -104,26 +129,8 @@ impl Completer for CmdCompleter {
Ok((0, results))
}
},
Command::Select => {
// we can only complete the 2nd argument
if args != 2 {
Ok((0, vec![]))
} else {
let arg = &cmd[1];
let options = &["domains",
"subdomains",
"ipaddrs",
"urls",
"emails"];
let results: Vec<String> = options.iter()
.filter(|x| x.starts_with(arg))
.map(|x| format!("select {} ", x))
.collect();
Ok((0, results))
}
},
Command::Scope => self.filter("scope", &cmd),
Command::Select => self.filter("select", &cmd),
_ => Ok((0, vec![])),
}
}
@@ -161,3 +168,8 @@ impl Highlighter for CmdCompleter {
}
impl rustyline::Helper for CmdCompleter {}
pub fn run_generate(args: &Completions) -> Result<()> {
Args::clap().gen_completions_to("sn0int", args.shell, &mut stdout());
Ok(())
}

62
src/config.rs Normal file
View File

@@ -0,0 +1,62 @@
use dirs;
use errors::*;
use std::fs;
use std::path::{Path, PathBuf};
use toml;
#[derive(Debug, Default, Clone, Serialize, Deserialize)]
pub struct Config {
pub core: CoreConfig,
}
impl Config {
pub fn load() -> Result<Config> {
let path = Config::path()?;
Config::load_from(&path)
}
pub fn path() -> Result<PathBuf> {
let path = dirs::config_dir()
.ok_or_else(|| format_err!("Failed to find config directory"))?;
let path = path.join("sn0int.toml");
Ok(path)
}
pub fn load_or_default() -> Result<Config> {
let path = Config::path()?;
if path.exists() {
Config::load_from(&path)
} else {
Ok(Config::default())
}
}
pub fn load_from<P: AsRef<Path>>(path: P) -> Result<Config> {
let config = fs::read(&path)
.context("Failed to read config file")?;
let config = toml::from_slice(&config)?;
Ok(config)
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CoreConfig {
#[serde(default="default_registry")]
pub registry: String,
}
impl Default for CoreConfig {
fn default() -> CoreConfig {
CoreConfig {
registry: default_registry(),
}
}
}
#[inline]
fn default_registry() -> String {
String::from("http://[::1]:8000")
}

View File

@@ -31,6 +31,8 @@ impl Database {
.context("Failed to connect to database")?;
migrations::run(&db)
.context("Failed to run migrations")?;
db.execute("PRAGMA foreign_keys = ON")
.context("Failed to enforce foreign keys")?;
Ok(db)
}, false)?;
@@ -49,30 +51,37 @@ impl Database {
}
/// Returns true if we didn't have this value yet
pub fn insert_generic(&self, object: &Object) -> Result<(bool, i32)> {
pub fn insert_generic(&self, object: &Insert) -> Result<(bool, i32)> {
match object {
Object::Domain(object) => self.insert_domain_struct(&NewDomain {
Insert::Domain(object) => self.insert_domain_struct(&NewDomain {
value: &object.value,
}),
Object::Subdomain(object) => self.insert_subdomain_struct(&NewSubdomain {
Insert::Subdomain(object) => self.insert_subdomain_struct(&NewSubdomain {
domain_id: object.domain_id,
value: &object.value,
}),
Object::IpAddr(object) => self.insert_ipaddr_struct(&NewIpAddr {
Insert::IpAddr(object) => self.insert_ipaddr_struct(&NewIpAddr {
family: &object.family,
value: &object.value,
continent: object.continent.as_ref(),
continent_code: object.continent_code.as_ref(),
country: object.country.as_ref(),
country_code: object.country_code.as_ref(),
city: object.city.as_ref(),
longitude: object.longitude,
latitude: object.latitude,
}),
Object::SubdomainIpAddr(object) => self.insert_subdomain_ipaddr_struct(&NewSubdomainIpAddr {
Insert::SubdomainIpAddr(object) => self.insert_subdomain_ipaddr_struct(&NewSubdomainIpAddr {
subdomain_id: object.subdomain_id,
ip_addr_id: object.ip_addr_id,
}),
Object::Url(object) => self.insert_url_struct(&NewUrl {
Insert::Url(object) => self.insert_url_struct(&NewUrl {
subdomain_id: object.subdomain_id,
value: &object.value,
status: object.status,
body: object.body.as_ref().map(|x| x.as_ref()),
}),
Object::Email(object) => self.insert_email_struct(&NewEmail {
Insert::Email(object) => self.insert_email_struct(&NewEmail {
value: &object.value,
}),
}
@@ -144,6 +153,13 @@ impl Database {
let new_ipaddr = NewIpAddr {
family: &family,
value: &ipaddr,
continent: None,
continent_code: None,
country: None,
country_code: None,
city: None,
longitude: None,
latitude: None,
};
self.insert_ipaddr_struct(&new_ipaddr)
@@ -224,6 +240,49 @@ impl Database {
//
pub fn update_generic(&self, object: &Update) -> Result<i32> {
match object {
Update::Subdomain(object) => self.update_subdomain(object),
Update::IpAddr(object) => self.update_ipaddr(object),
Update::Url(object) => self.update_url(object),
Update::Email(object) => self.update_email(object),
}
}
pub fn update_subdomain(&self, subdomain: &SubdomainUpdate) -> Result<i32> {
use schema::subdomains::columns::*;
diesel::update(subdomains::table.filter(id.eq(subdomain.id)))
.set(subdomain)
.execute(&self.db)?;
Ok(subdomain.id)
}
pub fn update_ipaddr(&self, ipaddr: &IpAddrUpdate) -> Result<i32> {
use schema::ipaddrs::columns::*;
diesel::update(ipaddrs::table.filter(id.eq(ipaddr.id)))
.set(ipaddr)
.execute(&self.db)?;
Ok(ipaddr.id)
}
pub fn update_url(&self, url: &UrlUpdate) -> Result<i32> {
use schema::urls::columns::*;
diesel::update(urls::table.filter(id.eq(url.id)))
.set(url)
.execute(&self.db)?;
Ok(url.id)
}
pub fn update_email(&self, email: &EmailUpdate) -> Result<i32> {
use schema::emails::columns::*;
diesel::update(emails::table.filter(id.eq(email.id)))
.set(email)
.execute(&self.db)?;
Ok(email.id)
}
//
pub fn list<T: Model>(&self) -> Result<Vec<T>> {
T::list(self)
}
@@ -231,6 +290,14 @@ impl Database {
pub fn filter<T: Model>(&self, filter: &Filter) -> Result<Vec<T>> {
T::filter(self, filter)
}
pub fn scope<T: Scopable>(&self, filter: &Filter) -> Result<usize> {
T::scope(self, filter)
}
pub fn noscope<T: Scopable>(&self, filter: &Filter) -> Result<usize> {
T::noscope(self, filter)
}
}
#[derive(Debug, PartialEq)]
@@ -249,7 +316,7 @@ impl Filter {
debug!("Parsing query: {:?}", args);
if args.is_empty() {
return Ok(Filter::new("1"));
bail!("Filter condition is required");
}
if args[0].to_lowercase() == "where" {
@@ -263,7 +330,7 @@ impl Filter {
let mut expect_value = false;
for arg in args {
if let Some(idx) = arg.find("=") {
if let Some(idx) = arg.find('=') {
if idx != 0 {
let (key, value) = arg.split_at(idx);
query += &format!(" {} = {:?}", key, &value[1..]);
@@ -287,6 +354,17 @@ impl Filter {
Ok(Filter::new(query))
}
pub fn parse_optional(args: &[String]) -> Result<Filter> {
debug!("Parsing optional query: {:?}", args);
if args.is_empty() {
debug!("Using filter with no condition");
return Ok(Filter::new("1"));
}
Self::parse(args)
}
pub fn query(&self) -> &str {
&self.query
}

View File

@@ -1,8 +1,9 @@
use errors::*;
use engine::Reporter;
use geoip::GeoIP;
use hlua::{self, AnyLuaValue};
use models::Object;
use models::{Insert, Update};
use psl::Psl;
use runtime;
use serde_json;
@@ -39,18 +40,28 @@ pub trait State {
self.send(&Event::Status(msg))
}
fn db_insert(&self, object: Object) -> Result<i32> {
self.send(&Event::Object(object));
fn db_insert(&self, object: Insert) -> Result<i32> {
self.send(&Event::Insert(object));
let reply = self.recv()?;
let reply: result::Result<i32, String> = serde_json::from_value(reply)?;
reply.map_err(|err| format_err!("Failed to add to database: {:?}", err))
}
fn db_update(&self, object: String, update: Update) -> Result<i32> {
self.send(&Event::Update((object, update)));
let reply = self.recv()?;
let reply: result::Result<i32, String> = serde_json::from_value(reply)?;
reply.map_err(|err| format_err!("Failed to update database: {:?}", err))
}
fn dns_config(&self) -> Arc<DnsConfig>;
fn psl(&self) -> Arc<Psl>;
fn geoip(&self) -> Arc<GeoIP>;
fn http_mksession(&self) -> String;
fn http_request(&self, session_id: &str, method: String, url: String, options: RequestOptions) -> HttpRequest;
@@ -65,6 +76,7 @@ pub struct LuaState {
http_sessions: Arc<Mutex<HashMap<String, HttpSession>>>,
dns_config: Arc<DnsConfig>,
psl: Arc<Psl>,
geoip: Arc<GeoIP>,
}
impl State for LuaState {
@@ -116,6 +128,10 @@ impl State for LuaState {
self.psl.clone()
}
fn geoip(&self) -> Arc<GeoIP> {
self.geoip.clone()
}
fn http_mksession(&self) -> String {
let mut mtx = self.http_sessions.lock().unwrap();
let (id, session) = HttpSession::new();
@@ -143,7 +159,7 @@ pub struct Script {
code: String,
}
fn ctx<'a>(dns_config: DnsConfig, psl: Psl) -> (hlua::Lua<'a>, Arc<LuaState>) {
fn ctx<'a>(dns_config: DnsConfig, psl: Psl, geoip: GeoIP) -> (hlua::Lua<'a>, Arc<LuaState>) {
debug!("Creating lua context");
let mut lua = hlua::Lua::new();
lua.open_string();
@@ -154,12 +170,15 @@ fn ctx<'a>(dns_config: DnsConfig, psl: Psl) -> (hlua::Lua<'a>, Arc<LuaState>) {
dns_config: Arc::new(dns_config),
psl: Arc::new(psl),
geoip: Arc::new(geoip),
});
runtime::clear_err(&mut lua, state.clone());
runtime::db_add(&mut lua, state.clone());
runtime::db_update(&mut lua, state.clone());
runtime::dns(&mut lua, state.clone());
runtime::error(&mut lua, state.clone());
runtime::geoip_lookup(&mut lua, state.clone());
runtime::html_select(&mut lua, state.clone());
runtime::html_select_list(&mut lua, state.clone());
runtime::http_mksession(&mut lua, state.clone());
@@ -206,8 +225,13 @@ impl Script {
})
}
pub fn run(&self, dns_config: DnsConfig, psl: Psl, tx: Arc<Mutex<Box<Reporter>>>, arg: AnyLuaValue) -> Result<()> {
let (mut lua, state) = ctx(dns_config, psl);
pub fn run(&self, dns_config: DnsConfig,
psl: Psl,
geoip: GeoIP,
tx: Arc<Mutex<Box<Reporter>>>,
arg: AnyLuaValue
) -> Result<()> {
let (mut lua, state) = ctx(dns_config, psl, geoip);
debug!("Initializing lua module");
lua.execute::<()>(&self.code)?;
@@ -244,6 +268,7 @@ impl Script {
com
// ===END ICANN DOMAINS===
"#)?;
self.run(dns_config, psl, DummyReporter::new(), AnyLuaValue::LuaNil)
let geoip = GeoIP::open_or_download()?;
self.run(dns_config, psl, geoip, DummyReporter::new(), AnyLuaValue::LuaNil)
}
}

View File

@@ -2,6 +2,7 @@ use errors::*;
use channel;
use chrootable_https::dns::DnsConfig;
use engine::{Module, Event, Reporter};
use geoip::GeoIP;
use psl::Psl;
use serde_json;
@@ -65,12 +66,12 @@ impl Supervisor {
pub fn send_start(&mut self, dns_config: DnsConfig, psl: String, module: Module, arg: serde_json::Value) -> Result<()> {
let start = serde_json::to_value(StartCommand::new(dns_config, psl, module, arg))?;
self.send(start)?;
self.send(&start)?;
Ok(())
}
pub fn send(&mut self, value: serde_json::Value) -> Result<()> {
let mut value = serde_json::to_string(&value)?;
pub fn send(&mut self, value: &serde_json::Value) -> Result<()> {
let mut value = serde_json::to_string(value)?;
value.push('\n');
self.stdin.write_all(value.as_bytes())?;
debug!("Supervisor sent: {:?}", value);
@@ -156,13 +157,23 @@ pub fn spawn_module(module: Module, tx: channel::Sender<(Event, Option<mpsc::Sen
tx.send((Event::Fatal(err), None));
break;
},
Event::Object(object) => {
Event::Insert(object) => {
let (tx2, rx2) = mpsc::channel();
tx.send((Event::Object(object), Some(tx2)));
tx.send((Event::Insert(object), Some(tx2)));
let reply = rx2.recv().unwrap();
let value = serde_json::to_value(reply).expect("Failed to serialize reply");
if let Err(_) = supervisor.send(value) {
if let Err(_) = supervisor.send(&value) {
tx.send((Event::Error("Failed to send to child".into()), None));
}
},
Event::Update(object) => {
let (tx2, rx2) = mpsc::channel();
tx.send((Event::Update(object), Some(tx2)));
let reply = rx2.recv().unwrap();
let value = serde_json::to_value(reply).expect("Failed to serialize reply");
if let Err(_) = supervisor.send(&value) {
tx.send((Event::Error("Failed to send to child".into()), None));
}
},
@@ -175,13 +186,14 @@ pub fn spawn_module(module: Module, tx: channel::Sender<(Event, Option<mpsc::Sen
Ok(())
}
pub fn run_worker() -> Result<()> {
pub fn run_worker(geoip: GeoIP) -> Result<()> {
let mut reporter = StdioReporter::setup();
let start = reporter.recv_start()?;
let mtx: Arc<Mutex<Box<Reporter>>> = Arc::new(Mutex::new(Box::new(reporter)));
let result = start.module.run(start.dns_config,
start.psl,
&start.psl,
geoip,
mtx.clone(),
start.arg.into());
let mut reporter = Arc::try_unwrap(mtx).expect("Failed to consume Arc")

View File

@@ -1,5 +1,6 @@
use errors::*;
use geoip::GeoIP;
use json::LuaJsonValue;
use serde_json;
use std::fs;
@@ -169,11 +170,11 @@ impl Module {
&self.source
}
pub fn run(&self, dns_config: DnsConfig, psl: String, reporter: Arc<Mutex<Box<Reporter>>>, arg: LuaJsonValue) -> Result<()> {
pub fn run(&self, dns_config: DnsConfig, psl: &str, geoip: GeoIP, reporter: Arc<Mutex<Box<Reporter>>>, arg: LuaJsonValue) -> Result<()> {
debug!("Loading public suffix list");
let psl = Psl::from_str(&psl)?;
debug!("Executing lua script {}", self.canonical());
self.script.run(dns_config, psl, reporter, arg.into())
self.script.run(dns_config, psl, geoip, reporter, arg.into())
}
fn cmp_canonical(&self, other: &Module) -> Ordering {

View File

@@ -1,6 +1,17 @@
use errors::*;
use hlua::{AnyHashableLuaValue, AnyLuaValue};
use std::collections::{self, HashMap};
use json::LuaJsonValue;
use serde;
use serde_json;
pub fn from_lua<T>(x: LuaJsonValue) -> Result<T>
where for<'de> T: serde::Deserialize<'de>
{
serde_json::from_value(x.into())
.map_err(Error::from)
}
#[derive(Debug, Default)]
pub struct LuaMap(HashMap<AnyHashableLuaValue, AnyLuaValue>);

218
src/geoip.rs Normal file
View File

@@ -0,0 +1,218 @@
use errors::*;
use archive;
use chrootable_https::Client;
use maxminddb::{self, geoip2};
use std::fmt;
use std::fs::File;
use std::net::IpAddr;
use std::collections::BTreeMap;
use std::path::Path;
use paths;
use worker;
pub static GEOIP_CITY_URL: &str = "https://geolite.maxmind.com/download/geoip/database/GeoLite2-City.tar.gz";
fn from_geoip_model_names(names: Option<BTreeMap<String, String>>) -> Option<String> {
let names = match names {
Some(names) => names,
_ => return None,
};
names.get("en")
.map(|x| x.to_owned())
}
#[derive(Debug, Serialize)]
pub struct Lookup {
continent: Option<String>,
continent_code: Option<String>,
country: Option<String>,
country_code: Option<String>,
city: Option<String>,
latitude: Option<f64>,
longitude: Option<f64>,
}
impl From<geoip2::City> for Lookup {
fn from(lookup: geoip2::City) -> Lookup {
// parse maxminddb lookup
let continent = match lookup.continent {
Some(continent) => Continent::from_maxmind(continent),
_ => None,
};
let country = match lookup.country {
Some(country) => Country::from_maxmind(country),
_ => None,
};
let city = match lookup.city {
Some(city) => from_geoip_model_names(city.names),
_ => None,
};
let location = match lookup.location {
Some(location) => Location::from_maxmind(location),
_ => None,
};
// flatten datastructure
let (continent, continent_code) = match continent {
Some(x) => (Some(x.name), Some(x.code)),
_ => (None, None),
};
let (country, country_code) = match country {
Some(x) => (Some(x.name), Some(x.code)),
_ => (None, None),
};
let (latitude, longitude) = match location {
Some(x) => (Some(x.latitude), Some(x.longitude)),
_ => (None, None),
};
// return result
Lookup {
continent,
continent_code,
country,
country_code,
city,
latitude,
longitude,
}
}
}
#[derive(Debug, Serialize)]
pub struct Continent {
code: String,
name: String,
}
impl Continent {
fn from_maxmind(continent: geoip2::model::Continent) -> Option<Self> {
let code = match continent.code {
Some(code) => code,
_ => return None,
};
let name = match from_geoip_model_names(continent.names) {
Some(name) => name,
_ => return None,
};
Some(Continent {
code,
name,
})
}
}
#[derive(Debug, Serialize)]
pub struct Country {
code: String,
name: String,
}
impl Country {
fn from_maxmind(country: geoip2::model::Country) -> Option<Self> {
let code = match country.iso_code {
Some(code) => code,
_ => return None,
};
let name = match from_geoip_model_names(country.names) {
Some(name) => name,
_ => return None,
};
Some(Country {
code,
name,
})
}
}
#[derive(Debug, Serialize)]
pub struct Location {
latitude: f64,
longitude: f64,
}
impl Location {
fn from_maxmind(location: geoip2::model::Location) -> Option<Self> {
let latitude = match location.latitude {
Some(latitude) => latitude,
_ => return None,
};
let longitude = match location.longitude {
Some(longitude) => longitude,
_ => return None,
};
Some(Location {
latitude,
longitude,
})
}
}
pub struct GeoIP {
reader: maxminddb::Reader,
}
impl fmt::Debug for GeoIP {
fn fmt(&self, w: &mut fmt::Formatter) -> fmt::Result {
write!(w, "GeoIP {{ ... }}")
}
}
impl GeoIP {
pub fn open(path: &str) -> Result<GeoIP> {
let reader = maxminddb::Reader::open(path)
.context("Failed to open geoip database")?;
Ok(GeoIP {
reader,
})
}
pub fn open_or_download() -> Result<GeoIP> {
let path = paths::cache_dir()?.join("GeoLite2-City.mmdb");
if File::open(&path).is_err() {
worker::spawn_fn("Downloading GeoIP city database", || {
GeoIP::download(&path, "GeoLite2-City.mmdb", GEOIP_CITY_URL)
}, false)?;
};
let path = path.to_str().ok_or(format_err!("Failed to decode path"))?;
GeoIP::open(&path)
}
pub fn download<P: AsRef<Path>>(path: P, filter: &str, url: &str) -> Result<()> {
debug!("Downloading {:?}...", url);
let client = Client::with_system_resolver()?;
let resp = client.get(url)?;
debug!("Downloaded {} bytes", resp.body.len());
archive::extract(&mut &resp.body[..], filter, path)?;
Ok(())
}
pub fn lookup(&self, ip: IpAddr) -> Result<Lookup> {
let city: geoip2::City = self.reader.lookup(ip)?;
debug!("GeoIP result: {:?}", city);
Ok(Lookup::from(city))
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_geoip_lookup() {
let ip = "1.1.1.1".parse().unwrap();
let geoip = GeoIP::open_or_download().expect("Failed to load geoip");
let lookup = geoip.lookup(ip).expect("GeoIP lookup failed");
println!("{:#?}", lookup);
assert_eq!(lookup.city, None);
}
}

View File

@@ -13,7 +13,9 @@ extern crate chrootable_https;
extern crate trust_dns_proto;
extern crate url;
extern crate nix;
#[cfg(target_os = "linux")]
extern crate caps;
#[cfg(target_os = "linux")]
extern crate syscallz;
extern crate hlua_badtouch as hlua;
extern crate base64;
@@ -23,6 +25,10 @@ extern crate opener;
extern crate separator;
extern crate sloppy_rfc4880;
extern crate regex;
extern crate toml;
extern crate maxminddb;
extern crate tar;
extern crate libflate;
extern crate serde;
extern crate serde_json;
extern crate serde_urlencoded;
@@ -35,13 +41,16 @@ extern crate serde_urlencoded;
#[macro_use] extern crate crossbeam_channel as channel;
pub mod api;
pub mod archive;
pub mod args;
pub mod auth;
pub mod cmd;
pub mod complete;
pub mod config;
pub mod db;
pub mod errors;
pub mod engine;
pub mod geoip;
pub mod html;
pub mod json;
pub mod migrations;

View File

@@ -7,8 +7,12 @@ extern crate structopt;
use sn0int::args::{self, Args, SubCommand};
use sn0int::auth;
use sn0int::cmd;
use sn0int::complete;
use sn0int::config::Config;
use sn0int::errors::*;
use sn0int::engine::{self, Module};
use sn0int::geoip::GeoIP;
use sn0int::paths;
use sn0int::registry;
use sn0int::sandbox;
use sn0int::shell;
@@ -16,8 +20,8 @@ use structopt::StructOpt;
use std::path::Path;
fn run_run(gargs: &Args, args: &args::Run) -> Result<()> {
let mut rl = shell::init(gargs)?;
fn run_run(gargs: &Args, args: &args::Run, config: Config) -> Result<()> {
let mut rl = shell::init(gargs, config)?;
if let Some(module) = &args.module {
let module = rl.engine().get(&module)?.clone();
@@ -41,9 +45,16 @@ fn run_run(gargs: &Args, args: &args::Run) -> Result<()> {
}
fn run_sandbox() -> Result<()> {
// TODO: this file should be processed after the sandbox is up
let geoip_path = paths::cache_dir()?
.join("GeoLite2-City.mmdb");
let geoip_path = geoip_path.to_str()
.ok_or(format_err!("Failed to decode geoip city path"))?;
let geoip = GeoIP::open(&geoip_path)?;
sandbox::init()
.context("Failed to init sandbox")?;
engine::isolation::run_worker()
engine::isolation::run_worker(geoip)
}
fn run() -> Result<()> {
@@ -53,14 +64,18 @@ fn run() -> Result<()> {
sandbox::fasten_seatbelt()?;
}
let config = Config::load_or_default()
.context("Failed to load config")?;
match args.subcommand {
Some(SubCommand::Run(ref run)) => run_run(&args, run),
Some(SubCommand::Run(ref run)) => run_run(&args, run, config),
Some(SubCommand::Sandbox(_)) => run_sandbox(),
Some(SubCommand::Login(_)) => auth::run_login(),
Some(SubCommand::Publish(ref publish)) => registry::run_publish(&args, publish),
Some(SubCommand::Install(ref install)) => registry::run_install(install),
Some(SubCommand::Search(ref search)) => registry::run_search(search),
None => shell::run(&args),
Some(SubCommand::Login(_)) => auth::run_login(&config),
Some(SubCommand::Publish(ref publish)) => registry::run_publish(&args, publish, &config),
Some(SubCommand::Install(ref install)) => registry::run_install(install, &config),
Some(SubCommand::Search(ref search)) => registry::run_search(search, &config),
Some(SubCommand::Completions(ref completions)) => complete::run_generate(completions),
None => shell::run(&args, config),
}
}

View File

@@ -1,15 +1,15 @@
use errors::*;
use diesel;
use diesel::prelude::*;
use json::LuaJsonValue;
use models::*;
use serde_json;
#[derive(Identifiable, Queryable, Serialize, PartialEq, Debug)]
#[derive(Identifiable, Queryable, Serialize, Deserialize, PartialEq, Debug)]
#[table_name="domains"]
pub struct Domain {
pub id: i32,
pub value: String,
pub unscoped: bool,
}
impl fmt::Display for Domain {
@@ -69,6 +69,30 @@ impl Model for Domain {
}
}
impl Scopable for Domain {
fn scoped(&self) -> bool {
!self.unscoped
}
fn scope(db: &Database, filter: &Filter) -> Result<usize> {
use schema::domains::dsl::*;
diesel::update(domains.filter(filter.sql()))
.set(unscoped.eq(false))
.execute(db.db())
.map_err(Error::from)
}
fn noscope(db: &Database, filter: &Filter) -> Result<usize> {
use schema::domains::dsl::*;
diesel::update(domains.filter(filter.sql()))
.set(unscoped.eq(true))
.execute(db.db())
.map_err(Error::from)
}
}
pub struct PrintableDomain {
value: String,
}
@@ -90,11 +114,16 @@ impl Printable<PrintableDomain> for Domain {
pub struct DetailedDomain {
id: i32,
value: String,
unscoped: bool,
}
impl fmt::Display for DetailedDomain {
fn fmt(&self, w: &mut fmt::Formatter) -> fmt::Result {
write!(w, "\x1b[32m#{}\x1b[0m, \x1b[32m{:?}\x1b[0m", self.id, self.value)
if !self.unscoped {
write!(w, "\x1b[32m#{}\x1b[0m, \x1b[32m{:?}\x1b[0m", self.id, self.value)
} else {
write!(w, "\x1b[90m#{}, {:?}\x1b[0m", self.id, self.value)
}
}
}
@@ -105,6 +134,7 @@ impl Detailed for Domain {
Ok(DetailedDomain {
id: self.id,
value: self.value.to_string(),
unscoped: self.unscoped,
})
}
}
@@ -121,13 +151,6 @@ pub struct NewDomainOwned {
pub value: String,
}
impl NewDomainOwned {
pub fn from_lua(x: LuaJsonValue) -> Result<NewDomainOwned> {
let x = serde_json::from_value(x.into())?;
Ok(x)
}
}
impl Printable<PrintableDomain> for NewDomainOwned {
fn printable(&self, _db: &Database) -> Result<PrintableDomain> {
Ok(PrintableDomain {

View File

@@ -1,15 +1,16 @@
use errors::*;
use diesel;
use diesel::prelude::*;
use json::LuaJsonValue;
use models::*;
use serde_json;
#[derive(Identifiable, Queryable, Serialize, PartialEq, Debug)]
#[derive(Identifiable, Queryable, Serialize, Deserialize, PartialEq, Debug)]
#[table_name="emails"]
pub struct Email {
pub id: i32,
pub value: String,
pub unscoped: bool,
pub valid: Option<bool>,
}
impl fmt::Display for Email {
@@ -69,6 +70,46 @@ impl Model for Email {
}
}
impl Scopable for Email {
fn scoped(&self) -> bool {
!self.unscoped
}
fn scope(db: &Database, filter: &Filter) -> Result<usize> {
use schema::emails::dsl::*;
diesel::update(emails.filter(filter.sql()))
.set(unscoped.eq(false))
.execute(db.db())
.map_err(Error::from)
}
fn noscope(db: &Database, filter: &Filter) -> Result<usize> {
use schema::emails::dsl::*;
diesel::update(emails.filter(filter.sql()))
.set(unscoped.eq(true))
.execute(db.db())
.map_err(Error::from)
}
}
#[derive(Identifiable, AsChangeset, Serialize, Deserialize, Debug)]
#[table_name="emails"]
pub struct EmailUpdate {
pub id: i32,
pub valid: Option<bool>,
}
impl fmt::Display for EmailUpdate {
fn fmt(&self, w: &mut fmt::Formatter) -> fmt::Result {
if let Some(valid) = self.valid {
write!(w, "valid => {:?}", valid)?;
}
Ok(())
}
}
pub struct PrintableEmail {
value: String,
}
@@ -90,11 +131,16 @@ impl Printable<PrintableEmail> for Email {
pub struct DetailedEmail {
id: i32,
value: String,
unscoped: bool,
}
impl fmt::Display for DetailedEmail {
fn fmt(&self, w: &mut fmt::Formatter) -> fmt::Result {
write!(w, "\x1b[32m#{}\x1b[0m, \x1b[32m{:?}\x1b[0m", self.id, self.value)
if !self.unscoped {
write!(w, "\x1b[32m#{}\x1b[0m, \x1b[32m{:?}\x1b[0m", self.id, self.value)
} else {
write!(w, "\x1b[90m#{}, {:?}\x1b[0m", self.id, self.value)
}
}
}
@@ -105,6 +151,7 @@ impl Detailed for Email {
Ok(DetailedEmail {
id: self.id,
value: self.value.to_string(),
unscoped: self.unscoped,
})
}
}
@@ -121,13 +168,6 @@ pub struct NewEmailOwned {
pub value: String,
}
impl NewEmailOwned {
pub fn from_lua(x: LuaJsonValue) -> Result<NewEmailOwned> {
let x = serde_json::from_value(x.into())?;
Ok(x)
}
}
impl Printable<PrintableEmail> for NewEmailOwned {
fn printable(&self, _db: &Database) -> Result<PrintableEmail> {
Ok(PrintableEmail {

View File

@@ -1,18 +1,25 @@
use errors::*;
use diesel;
use diesel::prelude::*;
use json::LuaJsonValue;
use models::*;
use serde_json;
use std::net;
use std::result;
#[derive(Identifiable, Queryable, Associations, Serialize, PartialEq, Debug)]
#[derive(Identifiable, Queryable, Associations, Serialize, Deserialize, PartialEq, Debug)]
#[table_name="ipaddrs"]
pub struct IpAddr {
pub id: i32,
pub family: String,
pub value: String,
pub unscoped: bool,
pub continent: Option<String>,
pub continent_code: Option<String>,
pub country: Option<String>,
pub country_code: Option<String>,
pub city: Option<String>,
pub latitude: Option<f32>,
pub longitude: Option<f32>,
}
impl fmt::Display for IpAddr {
@@ -72,6 +79,30 @@ impl Model for IpAddr {
}
}
impl Scopable for IpAddr {
fn scoped(&self) -> bool {
!self.unscoped
}
fn scope(db: &Database, filter: &Filter) -> Result<usize> {
use schema::ipaddrs::dsl::*;
diesel::update(ipaddrs.filter(filter.sql()))
.set(unscoped.eq(false))
.execute(db.db())
.map_err(Error::from)
}
fn noscope(db: &Database, filter: &Filter) -> Result<usize> {
use schema::ipaddrs::dsl::*;
diesel::update(ipaddrs.filter(filter.sql()))
.set(unscoped.eq(true))
.execute(db.db())
.map_err(Error::from)
}
}
impl IpAddr {
fn subdomains(&self, db: &Database) -> Result<Vec<Subdomain>> {
let subdomain_ids = SubdomainIpAddr::belonging_to(self)
@@ -110,14 +141,55 @@ pub struct DetailedIpAddr {
id: i32,
value: net::IpAddr,
subdomains: Vec<PrintableSubdomain>,
unscoped: bool,
continent: Option<String>,
country: Option<String>,
city: Option<String>,
}
impl fmt::Display for DetailedIpAddr {
fn fmt(&self, w: &mut fmt::Formatter) -> fmt::Result {
write!(w, "\x1b[32m#{}\x1b[0m, \x1b[32m{}\x1b[0m", self.id, self.value)?;
if !self.unscoped {
write!(w, "\x1b[32m#{}\x1b[0m, \x1b[32m{}\x1b[0m", self.id, self.value)?;
for subdomain in &self.subdomains {
write!(w, "\n\t\x1b[33m{}\x1b[0m", subdomain)?;
if let Some(ref continent) = self.continent {
write!(w, " [{}", continent)?;
if let Some(ref country) = self.country {
write!(w, " / {}", country)?;
}
if let Some(ref city) = self.city {
write!(w, " / {}", city)?;
}
write!(w, "]")?;
}
for subdomain in &self.subdomains {
write!(w, "\n\t\x1b[33m{}\x1b[0m", subdomain)?;
}
} else {
write!(w, "\x1b[90m#{}, {}", self.id, self.value)?;
if let Some(ref continent) = self.continent {
write!(w, " [{}", continent)?;
if let Some(ref country) = self.country {
write!(w, " / {}", country)?;
}
if let Some(ref city) = self.city {
write!(w, " / {}", city)?;
}
write!(w, "]")?;
}
write!(w, "\x1b[0m");
for subdomain in &self.subdomains {
write!(w, "\n\t\x1b[90m{}\x1b[0m", subdomain)?;
}
}
Ok(())
@@ -136,6 +208,10 @@ impl Detailed for IpAddr {
id: self.id,
value: self.value.parse()?,
subdomains,
unscoped: self.unscoped,
continent: self.continent.clone(),
country: self.country.clone(),
city: self.city.clone(),
})
}
}
@@ -145,6 +221,13 @@ impl Detailed for IpAddr {
pub struct NewIpAddr<'a> {
pub family: &'a str,
pub value: &'a str,
pub continent: Option<&'a String>,
pub continent_code: Option<&'a String>,
pub country: Option<&'a String>,
pub country_code: Option<&'a String>,
pub city: Option<&'a String>,
pub latitude: Option<f32>,
pub longitude: Option<f32>,
}
#[derive(Debug, Insertable, Serialize, Deserialize)]
@@ -152,12 +235,55 @@ pub struct NewIpAddr<'a> {
pub struct NewIpAddrOwned {
pub family: String,
pub value: String,
pub continent: Option<String>,
pub continent_code: Option<String>,
pub country: Option<String>,
pub country_code: Option<String>,
pub city: Option<String>,
pub latitude: Option<f32>,
pub longitude: Option<f32>,
}
impl NewIpAddrOwned {
pub fn from_lua(x: LuaJsonValue) -> Result<NewIpAddrOwned> {
let x = serde_json::from_value(x.into())?;
Ok(x)
#[derive(Identifiable, AsChangeset, Serialize, Deserialize, Debug)]
#[table_name="ipaddrs"]
pub struct IpAddrUpdate {
pub id: i32,
pub continent: Option<String>,
pub continent_code: Option<String>,
pub country: Option<String>,
pub country_code: Option<String>,
pub city: Option<String>,
pub latitude: Option<f32>,
pub longitude: Option<f32>,
}
impl fmt::Display for IpAddrUpdate {
fn fmt(&self, w: &mut fmt::Formatter) -> fmt::Result {
let mut updates = Vec::new();
if let Some(ref continent) = self.continent {
updates.push(format!("continent => {:?}", continent));
}
if let Some(ref continent_code) = self.continent_code {
updates.push(format!("continent_code => {:?}", continent_code));
}
if let Some(ref country) = self.country {
updates.push(format!("country => {:?}", country));
}
if let Some(ref country_code) = self.country_code {
updates.push(format!("country_code => {:?}", country_code));
}
if let Some(ref city) = self.city {
updates.push(format!("city => {:?}", city));
}
if let Some(ref latitude) = self.latitude {
updates.push(format!("latitude => {:?}", latitude));
}
if let Some(ref longitude) = self.longitude {
updates.push(format!("longitude => {:?}", longitude));
}
write!(w, "{}", updates.join(", "))
}
}

View File

@@ -5,7 +5,7 @@ use schema::*;
#[derive(Debug, Serialize, Deserialize)]
pub enum Object {
pub enum Insert {
Domain(NewDomainOwned),
Subdomain(NewSubdomainOwned),
IpAddr(NewIpAddrOwned),
@@ -14,19 +14,38 @@ pub enum Object {
Email(NewEmailOwned),
}
impl Object {
impl Insert {
pub fn printable(&self, db: &Database) -> Result<String> {
Ok(match self {
Object::Domain(x) => format!("Domain: {}", x.printable(db)?),
Object::Subdomain(x) => format!("Subdomain: {}", x.printable(db)?),
Object::IpAddr(x) => format!("IpAddr: {}", x.printable(db)?),
Object::SubdomainIpAddr(x) => x.printable(db)?.to_string(),
Object::Url(x) => format!("Url: {}", x.printable(db)?),
Object::Email(x) => format!("Email: {}", x.printable(db)?),
Insert::Domain(x) => format!("Domain: {}", x.printable(db)?),
Insert::Subdomain(x) => format!("Subdomain: {}", x.printable(db)?),
Insert::IpAddr(x) => format!("IpAddr: {}", x.printable(db)?),
Insert::SubdomainIpAddr(x) => x.printable(db)?.to_string(),
Insert::Url(x) => format!("Url: {}", x.printable(db)?),
Insert::Email(x) => format!("Email: {}", x.printable(db)?),
})
}
}
#[derive(Debug, Serialize, Deserialize)]
pub enum Update {
Subdomain(SubdomainUpdate),
IpAddr(IpAddrUpdate),
Url(UrlUpdate),
Email(EmailUpdate),
}
impl fmt::Display for Update {
fn fmt(&self, w: &mut fmt::Formatter) -> fmt::Result {
match self {
Update::Subdomain(update) => write!(w, "{}", update),
Update::IpAddr(update) => write!(w, "{}", update),
Update::Url(update) => write!(w, "{}", update),
Update::Email(update) => write!(w, "{}", update),
}
}
}
pub trait Model: Sized {
type ID: ?Sized;
@@ -41,11 +60,19 @@ pub trait Model: Sized {
fn id_opt(db: &Database, query: &Self::ID) -> Result<Option<i32>>;
}
pub trait Scopable: Model {
fn scoped(&self) -> bool;
fn scope(db: &Database, filter: &Filter) -> Result<usize>;
fn noscope(db: &Database, filter: &Filter) -> Result<usize>;
}
pub trait Printable<T: Sized> {
fn printable(&self, db: &Database) -> Result<T>;
}
pub trait Detailed {
pub trait Detailed: Scopable {
type T: fmt::Display;
fn detailed(&self, db: &Database) -> Result<Self::T>;

View File

@@ -1,8 +1,7 @@
use errors::*;
use diesel;
use diesel::prelude::*;
use json::LuaJsonValue;
use models::*;
use serde_json;
use std::result;
@@ -13,6 +12,8 @@ pub struct Subdomain {
pub id: i32,
pub domain_id: i32,
pub value: String,
pub unscoped: bool,
pub resolvable: Option<bool>,
}
impl fmt::Display for Subdomain {
@@ -72,6 +73,30 @@ impl Model for Subdomain {
}
}
impl Scopable for Subdomain {
fn scoped(&self) -> bool {
!self.unscoped
}
fn scope(db: &Database, filter: &Filter) -> Result<usize> {
use schema::subdomains::dsl::*;
diesel::update(subdomains.filter(filter.sql()))
.set(unscoped.eq(false))
.execute(db.db())
.map_err(Error::from)
}
fn noscope(db: &Database, filter: &Filter) -> Result<usize> {
use schema::subdomains::dsl::*;
diesel::update(subdomains.filter(filter.sql()))
.set(unscoped.eq(true))
.execute(db.db())
.map_err(Error::from)
}
}
impl Subdomain {
fn ip_addrs(&self, db: &Database) -> Result<Vec<IpAddr>> {
let ipaddr_ids = SubdomainIpAddr::belonging_to(self)
@@ -88,6 +113,22 @@ impl Subdomain {
}
}
#[derive(Identifiable, AsChangeset, Serialize, Deserialize, Debug)]
#[table_name="subdomains"]
pub struct SubdomainUpdate {
pub id: i32,
pub resolvable: Option<bool>,
}
impl fmt::Display for SubdomainUpdate {
fn fmt(&self, w: &mut fmt::Formatter) -> fmt::Result {
if let Some(resolvable) = self.resolvable {
write!(w, "resolvable => {:?}", resolvable)?;
}
Ok(())
}
}
pub struct PrintableSubdomain {
value: String,
}
@@ -110,15 +151,24 @@ pub struct DetailedSubdomain {
id: i32,
value: String,
ipaddrs: Vec<PrintableIpAddr>,
unscoped: bool,
}
// TODO: maybe print urls as well
impl fmt::Display for DetailedSubdomain {
fn fmt(&self, w: &mut fmt::Formatter) -> fmt::Result {
write!(w, "\x1b[32m#{}\x1b[0m, \x1b[32m{:?}\x1b[0m", self.id, self.value)?;
if !self.unscoped {
write!(w, "\x1b[32m#{}\x1b[0m, \x1b[32m{:?}\x1b[0m", self.id, self.value)?;
for ipaddr in &self.ipaddrs {
write!(w, "\n\t\x1b[33m{}\x1b[0m", ipaddr)?;
for ipaddr in &self.ipaddrs {
write!(w, "\n\t\x1b[33m{}\x1b[0m", ipaddr)?;
}
} else {
write!(w, "\x1b[90m#{}, {:?}\x1b[0m", self.id, self.value)?;
for ipaddr in &self.ipaddrs {
write!(w, "\n\t\x1b[90m{}\x1b[0m", ipaddr)?;
}
}
Ok(())
@@ -137,6 +187,7 @@ impl Detailed for Subdomain {
id: self.id,
value: self.value.to_string(),
ipaddrs,
unscoped: self.unscoped,
})
}
}
@@ -155,13 +206,6 @@ pub struct NewSubdomainOwned {
pub value: String,
}
impl NewSubdomainOwned {
pub fn from_lua(x: LuaJsonValue) -> Result<NewSubdomainOwned> {
let x = serde_json::from_value(x.into())?;
Ok(x)
}
}
impl Printable<PrintableSubdomain> for NewSubdomainOwned {
fn printable(&self, _db: &Database) -> Result<PrintableSubdomain> {
Ok(PrintableSubdomain {

View File

@@ -1,8 +1,6 @@
use errors::*;
use diesel::prelude::*;
use json::LuaJsonValue;
use models::*;
use serde_json;
use std::net;
@@ -100,13 +98,6 @@ pub struct NewSubdomainIpAddr {
pub ip_addr_id: i32,
}
impl NewSubdomainIpAddr {
pub fn from_lua(x: LuaJsonValue) -> Result<NewSubdomainIpAddr> {
let x = serde_json::from_value(x.into())?;
Ok(x)
}
}
impl Printable<PrintableSubdomainIpAddr> for NewSubdomainIpAddr {
fn printable(&self, db: &Database) -> Result<PrintableSubdomainIpAddr> {
let subdomain = Subdomain::by_id(db, self.subdomain_id)?;

View File

@@ -1,12 +1,11 @@
use errors::*;
use diesel;
use diesel::prelude::*;
use json::LuaJsonValue;
use models::*;
use ser;
use serde_json;
#[derive(Identifiable, Queryable, Associations, Serialize, PartialEq, Debug)]
#[derive(Identifiable, Queryable, Associations, Serialize, Deserialize, PartialEq, Debug)]
#[belongs_to(Subdomain)]
#[table_name="urls"]
pub struct Url {
@@ -15,6 +14,14 @@ pub struct Url {
pub value: String,
pub status: Option<i32>,
pub body: Option<Vec<u8>>,
pub unscoped: bool,
pub online: Option<bool>,
}
impl fmt::Display for Url {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.value)
}
}
impl Model for Url {
@@ -68,6 +75,57 @@ impl Model for Url {
}
}
impl Scopable for Url {
fn scoped(&self) -> bool {
!self.unscoped
}
fn scope(db: &Database, filter: &Filter) -> Result<usize> {
use schema::urls::dsl::*;
diesel::update(urls.filter(filter.sql()))
.set(unscoped.eq(false))
.execute(db.db())
.map_err(Error::from)
}
fn noscope(db: &Database, filter: &Filter) -> Result<usize> {
use schema::urls::dsl::*;
diesel::update(urls.filter(filter.sql()))
.set(unscoped.eq(true))
.execute(db.db())
.map_err(Error::from)
}
}
#[derive(Identifiable, AsChangeset, Serialize, Deserialize, Debug)]
#[table_name="urls"]
pub struct UrlUpdate {
pub id: i32,
pub status: Option<i32>,
pub body: Option<Vec<u8>>,
pub online: Option<bool>,
}
impl fmt::Display for UrlUpdate {
fn fmt(&self, w: &mut fmt::Formatter) -> fmt::Result {
let mut updates = Vec::new();
if let Some(online) = self.online {
updates.push(format!("online => {:?}", online));
}
if let Some(status) = self.status {
updates.push(format!("status => {:?}", status));
}
if let Some(ref body) = self.body {
updates.push(format!("body => [{} bytes]", body.len()));
}
write!(w, "{}", updates.join(", "))
}
}
pub struct PrintableUrl {
value: String,
status: Option<u16>,
@@ -98,14 +156,23 @@ pub struct DetailedUrl {
id: i32,
value: String,
status: Option<u16>,
unscoped: bool,
}
impl fmt::Display for DetailedUrl {
fn fmt(&self, w: &mut fmt::Formatter) -> fmt::Result {
write!(w, "\x1b[32m#{}\x1b[0m, \x1b[32m{:?}\x1b[0m", self.id, self.value)?;
if !self.unscoped {
write!(w, "\x1b[32m#{}\x1b[0m, \x1b[32m{:?}\x1b[0m", self.id, self.value)?;
if let Some(status) = self.status {
write!(w, " (\x1b[33m{}\x1b[0m)", status)?;
if let Some(status) = self.status {
write!(w, " (\x1b[33m{}\x1b[0m)", status)?;
}
} else {
write!(w, "\x1b[90m#{}, {:?}\x1b[0m", self.id, self.value)?;
if let Some(status) = self.status {
write!(w, "\x1b[90m ({})\x1b[0m", status)?;
}
}
Ok(())
@@ -120,6 +187,7 @@ impl Detailed for Url {
id: self.id,
value: self.value.to_string(),
status: self.status.map(|x| x as u16),
unscoped: self.unscoped,
})
}
}
@@ -143,13 +211,6 @@ pub struct NewUrlOwned {
pub body: Option<Vec<u8>>,
}
impl NewUrlOwned {
pub fn from_lua(x: LuaJsonValue) -> Result<NewUrlOwned> {
let x = serde_json::from_value(x.into())?;
Ok(x)
}
}
impl Printable<PrintableUrl> for NewUrlOwned {
fn printable(&self, _db: &Database) -> Result<PrintableUrl> {
Ok(PrintableUrl {

View File

@@ -1,7 +1,8 @@
use errors::*;
use args::{Args, Publish, Install, Search};
use api::{API_URL, Client};
use api::Client;
use auth;
use config::Config;
use colored::Colorize;
use separator::Separatable;
use sn0int_common::metadata::Metadata;
@@ -12,16 +13,16 @@ use term;
use worker;
pub fn run_publish(_args: &Args, publish: &Publish) -> Result<()> {
pub fn run_publish(_args: &Args, publish: &Publish, config: &Config) -> Result<()> {
let session = auth::load_token()
.context("Failed to load auth token")?;
let mut client = Client::new(API_URL)?;
let mut client = Client::new(&config)?;
client.authenticate(session);
let path = Path::new(&publish.path);
let name = path.file_stem().ok_or(format_err!("Couldn't get file name"))?;
let ext = path.extension().ok_or(format_err!("Couldn't get file extension"))?;
let name = path.file_stem().ok_or_else(|| format_err!("Couldn't get file name"))?;
let ext = path.extension().ok_or_else(|| format_err!("Couldn't get file extension"))?;
if ext != "lua" {
bail!("File extension has to be .lua");
@@ -46,8 +47,8 @@ pub fn run_publish(_args: &Args, publish: &Publish) -> Result<()> {
Ok(())
}
pub fn run_install(install: &Install) -> Result<()> {
let client = Client::new(API_URL)?;
pub fn run_install(install: &Install, config: &Config) -> Result<()> {
let client = Client::new(&config)?;
let label = format!("Installing {}", install.module);
worker::spawn_fn(&label, || {
@@ -56,7 +57,7 @@ pub fn run_install(install: &Install) -> Result<()> {
None => client.query_module(&install.module)
.context("Failed to query module infos")?
.latest
.ok_or(format_err!("Module doesn't have a latest version"))?,
.ok_or_else(|| format_err!("Module doesn't have a latest version"))?,
};
let module = client.download_module(&install.module, &version)
@@ -76,8 +77,8 @@ pub fn run_install(install: &Install) -> Result<()> {
}, false)
}
pub fn run_search(search: &Search) -> Result<()> {
let client = Client::new(API_URL)?;
pub fn run_search(search: &Search, config: &Config) -> Result<()> {
let client = Client::new(&config)?;
let label = format!("Searching {:?}", search.query);
let modules = worker::spawn_fn(&label, || {

View File

@@ -1,47 +1,121 @@
use errors::*;
use engine::ctx::State;
use engine::structs;
use hlua::{self, AnyLuaValue};
use std::str::FromStr;
use std::sync::Arc;
use models::*;
// use hlua::AnyHashableLuaValue;
// use std::collections::HashMap;
use json::LuaJsonValue;
#[derive(Debug)]
pub enum Family {
Domain,
Subdomain,
IpAddr,
SubdomainIpAddr,
Url,
Email,
}
impl FromStr for Family {
type Err = Error;
fn from_str(s: &str) -> Result<Family> {
Ok(match s {
"domain" => Family::Domain,
"subdomain" => Family::Subdomain,
"ipaddr" => Family::IpAddr,
"subdomain-ipaddr" => Family::SubdomainIpAddr,
"url" => Family::Url,
"email" => Family::Email,
_ => bail!("Unknown object family"),
})
}
}
pub fn db_add(lua: &mut hlua::Lua, state: Arc<State>) {
lua.set("db_add", hlua::function2(move |family: String, object: AnyLuaValue| -> Result<i32> {
let family = Family::from_str(&family)
.map_err(|e| state.set_error(e))?;
let object = LuaJsonValue::from(object);
let object = match family.as_str() {
"domain" => {
Object::Domain(NewDomainOwned::from_lua(object)
let object = match family {
Family::Domain => {
Insert::Domain(structs::from_lua::<NewDomainOwned>(object)
.map_err(|e| state.set_error(e))?)
},
"subdomain" => {
Object::Subdomain(NewSubdomainOwned::from_lua(object)
Family::Subdomain => {
Insert::Subdomain(structs::from_lua::<NewSubdomainOwned>(object)
.map_err(|e| state.set_error(e))?)
},
"ipaddr" => {
Object::IpAddr(NewIpAddrOwned::from_lua(object)
Family::IpAddr => {
Insert::IpAddr(structs::from_lua::<NewIpAddrOwned>(object)
.map_err(|e| state.set_error(e))?)
},
"subdomain-ipaddr" => {
Object::SubdomainIpAddr(NewSubdomainIpAddr::from_lua(object)
Family::SubdomainIpAddr => {
Insert::SubdomainIpAddr(structs::from_lua::<NewSubdomainIpAddr>(object)
.map_err(|e| state.set_error(e))?)
},
"url" => {
Object::Url(NewUrlOwned::from_lua(object)
Family::Url => {
Insert::Url(structs::from_lua::<NewUrlOwned>(object)
.map_err(|e| state.set_error(e))?)
},
"email" => {
Object::Email(NewEmailOwned::from_lua(object)
Family::Email => {
Insert::Email(structs::from_lua::<NewEmailOwned>(object)
.map_err(|e| state.set_error(e))?)
},
_ => return Err(state.set_error(format_err!("Unknown object family"))),
};
state.db_insert(object)
.map_err(|e| state.set_error(e))
}))
}
pub fn db_update(lua: &mut hlua::Lua, state: Arc<State>) {
lua.set("db_update", hlua::function3(move |family: String, object: AnyLuaValue, update: AnyLuaValue| -> Result<i32> {
let family = Family::from_str(&family)
.map_err(|e| state.set_error(e))?;
let object = LuaJsonValue::from(object);
let mut update = LuaJsonValue::from(update);
let (id, object) = match family {
Family::Domain => bail!("Domain doesn't have mutable fields"),
Family::Subdomain => structs::from_lua::<Domain>(object)
.map(|x| (x.id, x.to_string()))
.map_err(|e| state.set_error(e)),
Family::IpAddr => structs::from_lua::<IpAddr>(object)
.map(|x| (x.id, x.to_string()))
.map_err(|e| state.set_error(e)),
Family::SubdomainIpAddr => bail!("Unsupported operation"),
Family::Url => structs::from_lua::<Url>(object)
.map(|x| (x.id, x.to_string()))
.map_err(|e| state.set_error(e)),
Family::Email => structs::from_lua::<Email>(object)
.map(|x| (x.id, x.to_string()))
.map_err(|e| state.set_error(e)),
}?;
// copy the id over to the update struct so we can identify the row
if let LuaJsonValue::Object(ref mut update) = update {
update.insert("id".into(), LuaJsonValue::Number(id.into()));
}
let update = match family {
Family::Domain => bail!("Domain doesn't have mutable fields"),
Family::Subdomain => Update::Subdomain(structs::from_lua::<SubdomainUpdate>(update)
.map_err(|e| state.set_error(e))?),
Family::IpAddr => Update::IpAddr(structs::from_lua::<IpAddrUpdate>(update)
.map_err(|e| state.set_error(e))?),
Family::SubdomainIpAddr => bail!("Unsupported operation"),
Family::Url => Update::Url(structs::from_lua::<UrlUpdate>(update)
.map_err(|e| state.set_error(e))?),
Family::Email => Update::Email(structs::from_lua::<EmailUpdate>(update)
.map_err(|e| state.set_error(e))?),
};
state.db_update(object, update)
.map_err(|e| state.set_error(e))
}))
}

View File

@@ -121,4 +121,17 @@ mod tests {
"#).expect("Failed to load script");
script.test().expect("Script failed");
}
#[test]
#[ignore]
fn verify_nx_record() {
let script = Script::load_unchecked(r#"
function run()
x = dns('doesntexist.example.com', 'A')
print(x)
return x['success'] == nil
end
"#).expect("Failed to load script");
script.test().expect("Script failed");
}
}

42
src/runtime/geoip.rs Normal file
View File

@@ -0,0 +1,42 @@
use errors::*;
use engine::ctx::State;
use json::LuaJsonValue;
use hlua::{self, AnyLuaValue};
use serde_json;
use std::sync::Arc;
use std::net::IpAddr;
pub fn geoip_lookup(lua: &mut hlua::Lua, state: Arc<State>) {
lua.set("geoip_lookup", hlua::function1(move |ip: String| -> Result<AnyLuaValue> {
let ip = ip.parse::<IpAddr>()
.context("Failed to parse IP")
.map_err(|err| state.set_error(err.into()))?;
let lookup = state.geoip().lookup(ip)
.map_err(|err| state.set_error(err))?;
let lookup = serde_json::to_value(lookup)
.map_err(|e| state.set_error(e.into()))?;
Ok(LuaJsonValue::from(lookup).into())
}))
}
#[cfg(test)]
mod tests {
use engine::ctx::Script;
#[test]
fn verify_geoip() {
let script = Script::load_unchecked(r#"
function run()
x = geoip_lookup('1.1.1.1')
print(x)
end
"#).expect("Failed to load script");
script.test().expect("Script failed");
}
}

View File

@@ -8,6 +8,7 @@ macro_rules! import_fns {
import_fns!(db);
import_fns!(dns);
import_fns!(error);
import_fns!(geoip);
import_fns!(http);
import_fns!(html);
import_fns!(json);

View File

@@ -8,10 +8,10 @@ use std::sync::Arc;
use std::io::BufReader;
fn pgp_pubkey_lua(pubkey: Vec<u8>) -> Result<AnyLuaValue> {
fn pgp_pubkey_lua(pubkey: &[u8]) -> Result<AnyLuaValue> {
let mut uids = LuaList::new();
for (tag, body) in sloppy_rfc4880::Parser::new(pubkey.as_slice()) {
for (tag, body) in sloppy_rfc4880::Parser::new(pubkey) {
match tag {
Tag::UserID => {
let body = String::from_utf8(body)?;
@@ -32,7 +32,7 @@ pub fn pgp_pubkey(lua: &mut hlua::Lua, state: Arc<State>) {
lua.set("pgp_pubkey", hlua::function1(move |pubkey: AnyLuaValue| -> Result<AnyLuaValue> {
let pubkey = byte_array(pubkey)
.map_err(|err| state.set_error(err))?;
pgp_pubkey_lua(pubkey)
pgp_pubkey_lua(&pubkey)
.map_err(|err| state.set_error(err))
}))
}
@@ -43,7 +43,7 @@ pub fn pgp_pubkey_armored(lua: &mut hlua::Lua, state: Arc<State>) {
let pubkey = sloppy_rfc4880::armor::read_armored(&mut r)
.map_err(|err| state.set_error(err))?;
pgp_pubkey_lua(pubkey)
pgp_pubkey_lua(&pubkey)
.map_err(|err| state.set_error(err))
}))
}

View File

@@ -6,7 +6,7 @@ use std::sync::Arc;
pub fn psl_domain_from_dns_name(lua: &mut hlua::Lua, state: Arc<State>) {
lua.set("psl_domain_from_dns_name", hlua::function1(move |dns_name: String| -> Result<String> {
let dns_name = state.psl().parse_dns_name(&dns_name)
.map_err(|err| state.set_error(Error::from(err)))?;
.map_err(|err| state.set_error(err))?;
let domain = dns_name.domain()
.ok_or_else(|| format_err!("Failed to get domain from {:?}", dns_name))

View File

@@ -7,7 +7,7 @@ use regex::{Regex, Captures};
use std::sync::Arc;
fn capture_to_lua(caps: Captures) -> AnyLuaValue {
fn capture_to_lua(caps: &Captures) -> AnyLuaValue {
let mut i = 0;
let mut list = LuaList::new();
while let Some(cap) = caps.get(i) {
@@ -23,7 +23,7 @@ pub fn regex_find(lua: &mut hlua::Lua, state: Arc<State>) {
.map_err(|err| state.set_error(Error::from(err)))?;
match re.captures(&data) {
Some(caps) => Ok(capture_to_lua(caps)),
Some(caps) => Ok(capture_to_lua(&caps)),
None => Ok(AnyLuaValue::LuaNil),
}
}))
@@ -35,7 +35,7 @@ pub fn regex_find_all(lua: &mut hlua::Lua, state: Arc<State>) {
.map_err(|err| state.set_error(Error::from(err)))?;
let list = re.captures_iter(&data)
.map(capture_to_lua)
.map(|x| capture_to_lua(&x))
.collect();
Ok(list)

View File

@@ -1,12 +1,15 @@
use errors::*;
#[cfg(target_os = "linux")]
use caps::{self, CapSet};
use nix;
#[cfg(target_os = "linux")]
pub mod seccomp;
static CHROOT: &str = "/var/empty";
#[cfg(target_os = "linux")]
/// Drop all privileges that are only needed to setup the sandbox
pub fn fasten_seatbelt() -> Result<()> {
info!("Dropping all capabilities");
@@ -17,17 +20,30 @@ pub fn fasten_seatbelt() -> Result<()> {
Ok(())
}
#[cfg(not(target_os = "linux"))]
pub fn fasten_seatbelt() -> Result<()> {
Ok(())
}
#[cfg(target_os = "linux")]
pub fn init() -> Result<()> {
if let Err(_) = nix::unistd::chroot(CHROOT) {
if let Err(err) = nix::unistd::chroot(CHROOT) {
// TODO: add setting to make this a hard fail
warn!("Failed to chroot");
warn!("Failed to chroot: {:?}", err);
} else {
nix::unistd::chdir("/")?;
info!("Successful chroot to {:?}", CHROOT);
}
fasten_seatbelt()?;
#[cfg(target_os = "linux")]
seccomp::init()?;
Ok(())
}
#[cfg(not(target_os = "linux"))]
pub fn init() -> Result<()> {
Ok(())
}

View File

@@ -11,6 +11,7 @@ pub fn init() -> Result<()> {
ctx.allow_syscall(Syscall::sigaltstack)?;
ctx.allow_syscall(Syscall::munmap)?;
ctx.allow_syscall(Syscall::openat)?;
ctx.allow_syscall(Syscall::open)?;
ctx.allow_syscall(Syscall::fcntl)?;
ctx.allow_syscall(Syscall::uname)?;
ctx.allow_syscall(Syscall::close)?;
@@ -21,6 +22,7 @@ pub fn init() -> Result<()> {
ctx.allow_syscall(Syscall::socket)?;
ctx.allow_syscall(Syscall::connect)?;
ctx.allow_syscall(Syscall::epoll_wait)?;
ctx.allow_syscall(Syscall::epoll_pwait)?;
ctx.allow_syscall(Syscall::getrandom)?;
ctx.allow_syscall(Syscall::bind)?;
ctx.allow_syscall(Syscall::ioctl)?;
@@ -38,6 +40,8 @@ pub fn init() -> Result<()> {
ctx.allow_syscall(Syscall::nanosleep)?;
ctx.allow_syscall(Syscall::exit)?;
ctx.allow_syscall(Syscall::exit_group)?;
ctx.allow_syscall(Syscall::brk)?;
ctx.allow_syscall(Syscall::rt_sigprocmask)?;
ctx.load()?;

View File

@@ -2,6 +2,7 @@ table! {
domains (id) {
id -> Integer,
value -> Text,
unscoped -> Bool,
}
}
@@ -9,6 +10,8 @@ table! {
emails (id) {
id -> Integer,
value -> Text,
unscoped -> Bool,
valid -> Nullable<Bool>,
}
}
@@ -17,6 +20,14 @@ table! {
id -> Integer,
family -> Text,
value -> Text,
unscoped -> Bool,
continent -> Nullable<Text>,
continent_code -> Nullable<Text>,
country -> Nullable<Text>,
country_code -> Nullable<Text>,
city -> Nullable<Text>,
latitude -> Nullable<Float>,
longitude -> Nullable<Float>,
}
}
@@ -33,6 +44,8 @@ table! {
id -> Integer,
domain_id -> Integer,
value -> Text,
unscoped -> Bool,
resolvable -> Nullable<Bool>,
}
}
@@ -43,13 +56,15 @@ table! {
value -> Text,
status -> Nullable<Integer>,
body -> Nullable<Binary>,
unscoped -> Bool,
online -> Nullable<Bool>,
}
}
joinable!(subdomain_ipaddrs -> domains (subdomain_id));
joinable!(subdomain_ipaddrs -> ipaddrs (ip_addr_id));
joinable!(subdomain_ipaddrs -> subdomains (subdomain_id));
joinable!(subdomains -> domains (domain_id));
joinable!(urls -> domains (subdomain_id));
joinable!(urls -> subdomains (subdomain_id));
allow_tables_to_appear_in_same_query!(
domains,

View File

@@ -3,12 +3,14 @@ use errors::*;
use args::Args;
use cmd::*;
use complete::CmdCompleter;
use config::Config;
use colored::Colorize;
use ctrlc;
use db::Database;
use engine::{Engine, Module};
use geoip::GeoIP;
use rustyline::error::ReadlineError;
use rustyline::{CompletionType, Config, EditMode, Editor};
use rustyline::{self, CompletionType, EditMode, Editor};
use shellwords;
use std::str::FromStr;
use std::sync::Arc;
@@ -25,7 +27,9 @@ pub enum Command {
Add,
Back,
Mod,
Noscope,
Run,
Scope,
Set,
Select,
SwitchDb,
@@ -41,7 +45,9 @@ impl Command {
Command::Add => "add",
Command::Back => "back",
Command::Mod => "mod",
Command::Noscope => "noscope",
Command::Run => "run",
Command::Scope => "scope",
Command::Set => "set",
Command::Select => "select",
Command::SwitchDb => "switch_db",
@@ -57,7 +63,9 @@ impl Command {
Command::Add.as_str(),
Command::Back.as_str(),
Command::Mod.as_str(),
Command::Noscope.as_str(),
Command::Run.as_str(),
Command::Scope.as_str(),
Command::Set.as_str(),
Command::Select.as_str(),
Command::SwitchDb.as_str(),
@@ -78,7 +86,9 @@ impl FromStr for Command {
"add" => Ok(Command::Add),
"back" => Ok(Command::Back),
"mod" => Ok(Command::Mod),
"noscope" => Ok(Command::Noscope),
"run" => Ok(Command::Run),
"scope" => Ok(Command::Scope),
"set" => Ok(Command::Set),
"select" => Ok(Command::Select),
"switch_db" => Ok(Command::SwitchDb),
@@ -94,17 +104,18 @@ pub struct Readline {
prompt: Prompt,
db: Database,
psl: Psl,
config: Config,
engine: Engine,
signal_register: Arc<AtomicUsize>,
}
impl Readline {
pub fn new(db: Database, psl: Psl, engine: Engine) -> Readline {
let config = Config::builder()
pub fn new(config: Config, db: Database, psl: Psl, engine: Engine) -> Readline {
let rl_config = rustyline::Config::builder()
.completion_type(CompletionType::List)
.edit_mode(EditMode::Emacs)
.build();
let mut rl: Editor<CmdCompleter> = Editor::with_config(config);
let mut rl: Editor<CmdCompleter> = Editor::with_config(rl_config);
let h = CmdCompleter::default();
rl.set_helper(Some(h));
@@ -116,6 +127,7 @@ impl Readline {
prompt,
db,
psl,
config,
engine,
signal_register: Arc::new(AtomicUsize::new(1)),
};
@@ -150,6 +162,10 @@ impl Readline {
&self.psl
}
pub fn config(&self) -> &Config {
&self.config
}
pub fn engine(&self) -> &Engine {
&self.engine
}
@@ -271,7 +287,9 @@ pub fn run_once(rl: &mut Readline) -> Result<bool> {
return Ok(true);
},
Some((Command::Mod, args)) => mod_cmd::run(rl, &args)?,
Some((Command::Noscope, args)) => noscope_cmd::run(rl, &args)?,
Some((Command::Run, args)) => run_cmd::run(rl, &args)?,
Some((Command::Scope, args)) => scope_cmd::run(rl, &args)?,
// TODO: show global settings
// TODO: if module is some, show module settings
// TODO: set jobs 25
@@ -291,7 +309,7 @@ pub fn run_once(rl: &mut Readline) -> Result<bool> {
Ok(false)
}
pub fn init(args: &Args) -> Result<Readline> {
pub fn init(args: &Args, config: Config) -> Result<Readline> {
// TODO: enforce valid characters for workspace name
let workspace = match args.workspace {
Some(ref workspace) => workspace.as_str(),
@@ -300,16 +318,17 @@ pub fn init(args: &Args) -> Result<Readline> {
let db = Database::establish(workspace)?;
let psl = Psl::open_or_download()?;
let _geoip = GeoIP::open_or_download()?;
let engine = Engine::new()?;
let rl = Readline::new(db, psl, engine);
let rl = Readline::new(config, db, psl, engine);
Ok(rl)
}
pub fn run(args: &Args) -> Result<()> {
pub fn run(args: &Args, config: Config) -> Result<()> {
print_banner();
let mut rl = init(args)?;
let mut rl = init(args, config)?;
rl.load_history().ok();
rl.set_signal_handler()

View File

@@ -91,7 +91,7 @@ impl HttpRequest {
let cookies = session.cookies.clone();
let user_agent = options.user_agent.or_else(|| Some("sn0int".to_string())); // TODO
let timeout = options.timeout.map(|x| Duration::from_millis(x));
let timeout = options.timeout.map(Duration::from_millis);
let mut request = HttpRequest {
session: session.id.clone(),
@@ -103,7 +103,7 @@ impl HttpRequest {
basic_auth: options.basic_auth,
user_agent,
body: None,
timeout: timeout,
timeout,
};
if let Some(json) = options.json {

View File

@@ -2,7 +2,7 @@ use errors::*;
use channel;
use engine::{self, Module};
use models::Object;
use models::{Insert, Update};
use serde_json;
use shell::Readline;
use std::time::Duration;
@@ -17,7 +17,8 @@ pub enum Event {
Error(String),
Fatal(String),
Status(String),
Object(Object),
Insert(Insert),
Update((String, Update)),
Done,
}
@@ -48,13 +49,13 @@ pub fn spawn(rl: &mut Readline, module: Module, arg: serde_json::Value, pretty_a
break;
},
Some((Event::Status(status), _)) => spinner.status(status),
Some((Event::Object(object), tx)) => {
Some((Event::Insert(object), tx)) => {
let result = rl.db().insert_generic(&object);
debug!("{:?} => {:?}", object, result);
let result = match result {
Ok((true, id)) => {
if let Ok(obj) = object.printable(rl.db()) {
spinner.log(&format!("{}", obj));
spinner.log(&obj.to_string());
} else {
spinner.error(&format!("Failed to query necessary fields for {:?}", object));
}
@@ -71,6 +72,20 @@ pub fn spawn(rl: &mut Readline, module: Module, arg: serde_json::Value, pretty_a
tx.expect("Failed to get db result channel")
.send(result).expect("Failed to send db result to channel");
},
Some((Event::Update((object, update)), tx)) => {
let result = rl.db().update_generic(&update);
debug!("{:?}: {:?} => {:?}", object, update, result);
let result = result.map_err(|e| e.to_string());
if let Err(ref err) = result {
spinner.error(&err);
} else {
spinner.log(&format!("Updating {:?} ({})", object, update));
}
tx.expect("Failed to get db result channel")
.send(result).expect("Failed to send db result to channel");
},
Some((Event::Done, _)) => break,
None => break, // channel closed
},
@@ -105,7 +120,8 @@ pub fn spawn_fn<F, T>(label: &str, f: F, clear: bool) -> Result<T>
Some(Event::Error(error)) => spinner.error(&error),
Some(Event::Fatal(error)) => spinner.error(&error),
Some(Event::Status(status)) => spinner.status(status),
Some(Event::Object(_)) => (),
Some(Event::Insert(_)) => (),
Some(Event::Update(_)) => (),
Some(Event::Done) => break,
None => break, // channel closed
},