update to sequoia-0.20

This commit is contained in:
Vincent Breitmoser 2020-11-04 22:21:00 +01:00
parent 2131bb1753
commit 860bd6e552
29 changed files with 516 additions and 287 deletions

190
Cargo.lock generated
View File

@ -79,6 +79,11 @@ dependencies = [
"winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "anyhow"
version = "1.0.34"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "arrayref" name = "arrayref"
version = "0.3.6" version = "0.3.6"
@ -172,6 +177,11 @@ name = "base64"
version = "0.12.3" version = "0.12.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "base64"
version = "0.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "bindgen" name = "bindgen"
version = "0.51.1" version = "0.51.1"
@ -262,6 +272,14 @@ dependencies = [
"libc 0.2.80 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.80 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "buffered-reader"
version = "0.20.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.80 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "bumpalo" name = "bumpalo"
version = "3.4.0" version = "3.4.0"
@ -484,6 +502,11 @@ dependencies = [
"strsim 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)", "strsim 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "dyn-clone"
version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "either" name = "either"
version = "1.6.1" version = "1.6.1"
@ -511,6 +534,14 @@ dependencies = [
"log 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "ena"
version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"log 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "encode_unicode" name = "encode_unicode"
version = "0.3.6" version = "0.3.6"
@ -622,6 +653,11 @@ name = "fixedbitset"
version = "0.1.9" version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "fixedbitset"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "fnv" name = "fnv"
version = "1.0.7" version = "1.0.7"
@ -735,9 +771,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
name = "hagrid" name = "hagrid"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"anyhow 1.0.34 (registry+https://github.com/rust-lang/crates.io-index)",
"base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", "base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
"chrono 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)", "chrono 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)",
"failure 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
"gettext 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "gettext 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"gettext-macros 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", "gettext-macros 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
"glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -756,7 +792,7 @@ dependencies = [
"rocket_i18n 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "rocket_i18n 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rocket_prometheus 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "rocket_prometheus 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"runtime-fmt 0.4.1 (git+https://github.com/Valodim/runtime-fmt?rev=44c15d832cb327ef33f95548a9a964d98c006fe4)", "runtime-fmt 0.4.1 (git+https://github.com/Valodim/runtime-fmt?rev=44c15d832cb327ef33f95548a9a964d98c006fe4)",
"sequoia-openpgp 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)", "sequoia-openpgp 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.117 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.117 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.117 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.117 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.59 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.59 (registry+https://github.com/rust-lang/crates.io-index)",
@ -772,18 +808,17 @@ dependencies = [
name = "hagrid-database" name = "hagrid-database"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"anyhow 1.0.34 (registry+https://github.com/rust-lang/crates.io-index)",
"base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", "base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
"chrono 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)", "chrono 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)",
"failure 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
"fs2 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "fs2 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
"hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"idna 0.1.5 (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.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)",
"multipart 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)", "multipart 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)",
"pathdiff 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "pathdiff 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
"sequoia-openpgp 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)", "sequoia-openpgp 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.117 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.117 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.117 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.117 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.59 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.59 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1002,6 +1037,14 @@ dependencies = [
"either 1.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "either 1.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "itertools"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"either 1.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "itoa" name = "itoa"
version = "0.4.6" version = "0.4.6"
@ -1040,11 +1083,40 @@ dependencies = [
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "lalrpop"
version = "0.19.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"ascii-canvas 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
"bit-set 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
"diff 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
"docopt 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"ena 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)",
"itertools 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
"lalrpop-util 0.19.1 (registry+https://github.com/rust-lang/crates.io-index)",
"petgraph 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
"regex-syntax 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.117 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.117 (registry+https://github.com/rust-lang/crates.io-index)",
"sha2 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
"string_cache 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
"term 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-xid 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "lalrpop-util" name = "lalrpop-util"
version = "0.17.2" version = "0.17.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "lalrpop-util"
version = "0.19.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "language-tags" name = "language-tags"
version = "0.2.2" version = "0.2.2"
@ -1150,6 +1222,11 @@ dependencies = [
"winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "memsec"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "mime" name = "mime"
version = "0.2.6" version = "0.2.6"
@ -1288,6 +1365,17 @@ dependencies = [
"nettle-sys 2.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "nettle-sys 2.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "nettle"
version = "7.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"getrandom 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.80 (registry+https://github.com/rust-lang/crates.io-index)",
"nettle-sys 2.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
"thiserror 1.0.22 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "nettle-sys" name = "nettle-sys"
version = "2.0.4" version = "2.0.4"
@ -1509,6 +1597,15 @@ dependencies = [
"ordermap 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", "ordermap 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "petgraph"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"fixedbitset 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"indexmap 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "phf" name = "phf"
version = "0.7.24" version = "0.7.24"
@ -1544,6 +1641,14 @@ dependencies = [
"unicase 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "unicase 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "phf_shared"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"siphasher 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "pkg-config" name = "pkg-config"
version = "0.3.19" version = "0.3.19"
@ -2028,6 +2133,28 @@ dependencies = [
"unicode-normalization 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-normalization 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "sequoia-openpgp"
version = "0.20.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"anyhow 1.0.34 (registry+https://github.com/rust-lang/crates.io-index)",
"backtrace 0.3.54 (registry+https://github.com/rust-lang/crates.io-index)",
"base64 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)",
"buffered-reader 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)",
"dyn-clone 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
"idna 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"lalrpop 0.19.1 (registry+https://github.com/rust-lang/crates.io-index)",
"lalrpop-util 0.19.1 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.80 (registry+https://github.com/rust-lang/crates.io-index)",
"memsec 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
"nettle 7.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
"thiserror 1.0.22 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-normalization 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "serde" name = "serde"
version = "1.0.117" version = "1.0.117"
@ -2093,6 +2220,11 @@ name = "siphasher"
version = "0.2.3" version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "siphasher"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "slab" name = "slab"
version = "0.4.2" version = "0.4.2"
@ -2188,6 +2320,18 @@ dependencies = [
"string_cache_shared 0.3.0 (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"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"new_debug_unreachable 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
"phf_shared 0.8.0 (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.117 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "string_cache_codegen" name = "string_cache_codegen"
version = "0.4.4" version = "0.4.4"
@ -2316,6 +2460,24 @@ dependencies = [
"unicode-width 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-width 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "thiserror"
version = "1.0.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"thiserror-impl 1.0.22 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "thiserror-impl"
version = "1.0.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 1.0.48 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "thread_local" name = "thread_local"
version = "1.0.1" version = "1.0.1"
@ -2697,6 +2859,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum aesni 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2f70a6b5f971e473091ab7cfb5ffac6cde81666c4556751d8d5620ead8abf100" "checksum aesni 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2f70a6b5f971e473091ab7cfb5ffac6cde81666c4556751d8d5620ead8abf100"
"checksum aho-corasick 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7404febffaa47dac81aa44dba71523c9d069b1bdc50a77db41195149e17f68e5" "checksum aho-corasick 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7404febffaa47dac81aa44dba71523c9d069b1bdc50a77db41195149e17f68e5"
"checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" "checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b"
"checksum anyhow 1.0.34 (registry+https://github.com/rust-lang/crates.io-index)" = "bf8dcb5b4bbaa28653b647d8c77bd4ed40183b48882e130c1f1ffb73de069fd7"
"checksum arrayref 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544" "checksum arrayref 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544"
"checksum arrayvec 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" "checksum arrayvec 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b"
"checksum ascii 0.8.7 (registry+https://github.com/rust-lang/crates.io-index)" = "97be891acc47ca214468e09425d02cef3af2c94d0d82081cd02061f996802f14" "checksum ascii 0.8.7 (registry+https://github.com/rust-lang/crates.io-index)" = "97be891acc47ca214468e09425d02cef3af2c94d0d82081cd02061f996802f14"
@ -2710,6 +2873,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0b25d992356d2eb0ed82172f5248873db5560c4721f564b13cb5193bda5e668e" "checksum base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0b25d992356d2eb0ed82172f5248873db5560c4721f564b13cb5193bda5e668e"
"checksum base64 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b41b7ea54a0c9d92199de89e20e58d49f02f8e699814ef3fdf266f6f748d15c7" "checksum base64 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b41b7ea54a0c9d92199de89e20e58d49f02f8e699814ef3fdf266f6f748d15c7"
"checksum base64 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3441f0f7b02788e948e47f457ca01f1d7e6d92c693bc132c22b087d3141c03ff" "checksum base64 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3441f0f7b02788e948e47f457ca01f1d7e6d92c693bc132c22b087d3141c03ff"
"checksum base64 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)" = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd"
"checksum base64 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)" = "489d6c0ed21b11d038c31b6ceccca973e65d73ba3bd8ecb9a2babf5546164643" "checksum base64 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)" = "489d6c0ed21b11d038c31b6ceccca973e65d73ba3bd8ecb9a2babf5546164643"
"checksum bindgen 0.51.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ebd71393f1ec0509b553aa012b9b58e81dadbdff7130bd3b8cba576e69b32f75" "checksum bindgen 0.51.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ebd71393f1ec0509b553aa012b9b58e81dadbdff7130bd3b8cba576e69b32f75"
"checksum bit-set 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6e11e16035ea35e4e5997b393eacbf6f63983188f7a2ad25bfb13465f5ad59de" "checksum bit-set 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6e11e16035ea35e4e5997b393eacbf6f63983188f7a2ad25bfb13465f5ad59de"
@ -2721,6 +2885,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum block-padding 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "fa79dedbb091f449f1f39e53edf88d5dbe95f895dae6135a8d7b881fb5af73f5" "checksum block-padding 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "fa79dedbb091f449f1f39e53edf88d5dbe95f895dae6135a8d7b881fb5af73f5"
"checksum buf_redux 0.8.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b953a6887648bb07a535631f2bc00fbdb2a2216f135552cb3f534ed136b9c07f" "checksum buf_redux 0.8.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b953a6887648bb07a535631f2bc00fbdb2a2216f135552cb3f534ed136b9c07f"
"checksum buffered-reader 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c1e5d50ee739fd77dff227ed8343145e1143aa97fa450890cc22a20f41b857af" "checksum buffered-reader 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c1e5d50ee739fd77dff227ed8343145e1143aa97fa450890cc22a20f41b857af"
"checksum buffered-reader 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fd574044e0e73feb49cdf47728cb4f5299a32eb4743766cc3fb2e202525bfac5"
"checksum bumpalo 3.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2e8c087f005730276d1096a652e92a8bacee2e2472bcc9715a74d2bec38b5820" "checksum bumpalo 3.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2e8c087f005730276d1096a652e92a8bacee2e2472bcc9715a74d2bec38b5820"
"checksum byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7" "checksum byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7"
"checksum byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de" "checksum byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de"
@ -2748,9 +2913,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum dirs 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "3fd78930633bd1c6e35c4b42b1df7b0cbc6bc191146e512bb3bedf243fcc3901" "checksum dirs 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "3fd78930633bd1c6e35c4b42b1df7b0cbc6bc191146e512bb3bedf243fcc3901"
"checksum discard 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "212d0f5754cb6769937f4501cc0e67f4f4483c8d2c3e1e922ee9edbe4ab4c7c0" "checksum discard 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "212d0f5754cb6769937f4501cc0e67f4f4483c8d2c3e1e922ee9edbe4ab4c7c0"
"checksum docopt 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7f525a586d310c87df72ebcd98009e57f1cc030c8c268305287a476beb653969" "checksum docopt 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7f525a586d310c87df72ebcd98009e57f1cc030c8c268305287a476beb653969"
"checksum dyn-clone 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d55796afa1b20c2945ca8eabfc421839f2b766619209f1ede813cf2484f31804"
"checksum either 1.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" "checksum either 1.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457"
"checksum email 0.0.20 (registry+https://github.com/rust-lang/crates.io-index)" = "91549a51bb0241165f13d57fc4c72cef063b4088fb078b019ecbf464a45f22e4" "checksum email 0.0.20 (registry+https://github.com/rust-lang/crates.io-index)" = "91549a51bb0241165f13d57fc4c72cef063b4088fb078b019ecbf464a45f22e4"
"checksum ena 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8944dc8fa28ce4a38f778bd46bf7d923fe73eed5a439398507246c8e017e6f36" "checksum ena 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8944dc8fa28ce4a38f778bd46bf7d923fe73eed5a439398507246c8e017e6f36"
"checksum ena 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d7402b94a93c24e742487327a7cd839dc9d36fec9de9fb25b09f2dae459f36c3"
"checksum encode_unicode 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" "checksum encode_unicode 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f"
"checksum encoding 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "6b0d943856b990d12d3b55b359144ff341533e516d94098b1d3fc1ac666d36ec" "checksum encoding 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "6b0d943856b990d12d3b55b359144ff341533e516d94098b1d3fc1ac666d36ec"
"checksum encoding-index-japanese 1.20141219.5 (registry+https://github.com/rust-lang/crates.io-index)" = "04e8b2ff42e9a05335dbf8b5c6f7567e5591d0d916ccef4e0b1710d32a0d0c91" "checksum encoding-index-japanese 1.20141219.5 (registry+https://github.com/rust-lang/crates.io-index)" = "04e8b2ff42e9a05335dbf8b5c6f7567e5591d0d916ccef4e0b1710d32a0d0c91"
@ -2765,6 +2932,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum fast_chemail 0.9.6 (registry+https://github.com/rust-lang/crates.io-index)" = "495a39d30d624c2caabe6312bfead73e7717692b44e0b32df168c275a2e8e9e4" "checksum fast_chemail 0.9.6 (registry+https://github.com/rust-lang/crates.io-index)" = "495a39d30d624c2caabe6312bfead73e7717692b44e0b32df168c275a2e8e9e4"
"checksum filetime 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)" = "3ed85775dcc68644b5c950ac06a2b23768d3bc9390464151aaf27136998dcf9e" "checksum filetime 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)" = "3ed85775dcc68644b5c950ac06a2b23768d3bc9390464151aaf27136998dcf9e"
"checksum fixedbitset 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "86d4de0081402f5e88cdac65c8dcdcc73118c1a7a465e2a05f0da05843a8ea33" "checksum fixedbitset 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "86d4de0081402f5e88cdac65c8dcdcc73118c1a7a465e2a05f0da05843a8ea33"
"checksum fixedbitset 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "37ab347416e802de484e4d03c7316c48f1ecb56574dfd4a46a80f173ce1de04d"
"checksum fnv 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" "checksum fnv 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
"checksum fs2 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "9564fc758e15025b46aa6643b1b77d047d1a56a1aea6e01002ac0c7026876213" "checksum fs2 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "9564fc758e15025b46aa6643b1b77d047d1a56a1aea6e01002ac0c7026876213"
"checksum fsevent 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5ab7d1bd1bd33cc98b0889831b72da23c0aa4df9cec7e0702f46ecea04b35db6" "checksum fsevent 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5ab7d1bd1bd33cc98b0889831b72da23c0aa4df9cec7e0702f46ecea04b35db6"
@ -2799,10 +2967,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e" "checksum iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e"
"checksum iron 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c6d308ca2d884650a8bf9ed2ff4cb13fbb2207b71f64cda11dc9b892067295e8" "checksum iron 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c6d308ca2d884650a8bf9ed2ff4cb13fbb2207b71f64cda11dc9b892067295e8"
"checksum itertools 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f56a2d0bc861f9165be4eb3442afd3c236d8a98afd426f65d92324ae1091a484" "checksum itertools 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f56a2d0bc861f9165be4eb3442afd3c236d8a98afd426f65d92324ae1091a484"
"checksum itertools 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "284f18f85651fe11e8a991b2adb42cb078325c996ed026d994719efcfca1d54b"
"checksum itoa 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "dc6f3ad7b9d11a0c00842ff8de1b60ee58661048eb8049ed33c73594f359d7e6" "checksum itoa 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "dc6f3ad7b9d11a0c00842ff8de1b60ee58661048eb8049ed33c73594f359d7e6"
"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
"checksum lalrpop 0.17.2 (registry+https://github.com/rust-lang/crates.io-index)" = "64dc3698e75d452867d9bd86f4a723f452ce9d01fe1d55990b79f0c790aa67db" "checksum lalrpop 0.17.2 (registry+https://github.com/rust-lang/crates.io-index)" = "64dc3698e75d452867d9bd86f4a723f452ce9d01fe1d55990b79f0c790aa67db"
"checksum lalrpop 0.19.1 (registry+https://github.com/rust-lang/crates.io-index)" = "60fb56191fb8ed5311597e5750debe6779c9fdb487dbaa5ff302592897d7a2c8"
"checksum lalrpop-util 0.17.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c277d18683b36349ab5cd030158b54856fca6bb2d5dc5263b06288f486958b7c" "checksum lalrpop-util 0.17.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c277d18683b36349ab5cd030158b54856fca6bb2d5dc5263b06288f486958b7c"
"checksum lalrpop-util 0.19.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6771161eff561647fad8bb7e745e002c304864fb8f436b52b30acda51fca4408"
"checksum language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a91d884b6667cd606bb5a69aa0c99ba811a115fc68915e7056ec08a46e93199a" "checksum language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a91d884b6667cd606bb5a69aa0c99ba811a115fc68915e7056ec08a46e93199a"
"checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" "checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
"checksum lazycell 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" "checksum lazycell 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
@ -2818,6 +2989,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum maybe-uninit 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00" "checksum maybe-uninit 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00"
"checksum memchr 2.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525" "checksum memchr 2.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525"
"checksum memsec 0.5.7 (registry+https://github.com/rust-lang/crates.io-index)" = "0cb9280f8c37546661083aa45eb0318d8469253d31e87649faed25522428398e" "checksum memsec 0.5.7 (registry+https://github.com/rust-lang/crates.io-index)" = "0cb9280f8c37546661083aa45eb0318d8469253d31e87649faed25522428398e"
"checksum memsec 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2af4f95d8737f4ffafbd1fb3c703cdc898868a244a59786793cba0520ebdcbdd"
"checksum mime 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "ba626b8a6de5da682e1caa06bdb42a335aee5a84db8e5046a3e8ab17ba0a3ae0" "checksum mime 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "ba626b8a6de5da682e1caa06bdb42a335aee5a84db8e5046a3e8ab17ba0a3ae0"
"checksum mime 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)" = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" "checksum mime 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)" = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d"
"checksum mime_guess 1.8.8 (registry+https://github.com/rust-lang/crates.io-index)" = "216929a5ee4dd316b1702eedf5e74548c123d370f47841ceaac38ca154690ca3" "checksum mime_guess 1.8.8 (registry+https://github.com/rust-lang/crates.io-index)" = "216929a5ee4dd316b1702eedf5e74548c123d370f47841ceaac38ca154690ca3"
@ -2831,6 +3003,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum mustache 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "51956ef1c5d20a1384524d91e616fb44dfc7d8f249bf696d49c97dd3289ecab5" "checksum mustache 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "51956ef1c5d20a1384524d91e616fb44dfc7d8f249bf696d49c97dd3289ecab5"
"checksum net2 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)" = "3ebc3ec692ed7c9a255596c67808dee269f64655d8baf7b4f0638e51ba1d6853" "checksum net2 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)" = "3ebc3ec692ed7c9a255596c67808dee269f64655d8baf7b4f0638e51ba1d6853"
"checksum nettle 5.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c40aad15a496df1ae843b5ca10cef328e64d04854404464f464fd5e11aa6d77d" "checksum nettle 5.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c40aad15a496df1ae843b5ca10cef328e64d04854404464f464fd5e11aa6d77d"
"checksum nettle 7.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b1afae85450b829ad720f2827e3b07d78e06b5521cfe5ed72808a9f593e7cdd8"
"checksum nettle-sys 2.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b8629333ff5f3b74d251dae253e383cda9242410fac4244a4fe855469be101fb" "checksum nettle-sys 2.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b8629333ff5f3b74d251dae253e383cda9242410fac4244a4fe855469be101fb"
"checksum new_debug_unreachable 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "e4a24736216ec316047a1fc4252e27dabb04218aa4a3f37c6e7ddbf1f9782b54" "checksum new_debug_unreachable 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "e4a24736216ec316047a1fc4252e27dabb04218aa4a3f37c6e7ddbf1f9782b54"
"checksum nickel 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e5061a832728db2dacb61cefe0ce303b58f85764ec680e71d9138229640a46d9" "checksum nickel 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e5061a832728db2dacb61cefe0ce303b58f85764ec680e71d9138229640a46d9"
@ -2856,10 +3029,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum pest_generator 2.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "99b8db626e31e5b81787b9783425769681b347011cc59471e33ea46d2ea0cf55" "checksum pest_generator 2.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "99b8db626e31e5b81787b9783425769681b347011cc59471e33ea46d2ea0cf55"
"checksum pest_meta 2.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "54be6e404f5317079812fc8f9f5279de376d8856929e21c184ecf6bbd692a11d" "checksum pest_meta 2.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "54be6e404f5317079812fc8f9f5279de376d8856929e21c184ecf6bbd692a11d"
"checksum petgraph 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)" = "9c3659d1ee90221741f65dd128d9998311b0e40c5d3c23a62445938214abce4f" "checksum petgraph 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)" = "9c3659d1ee90221741f65dd128d9998311b0e40c5d3c23a62445938214abce4f"
"checksum petgraph 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "467d164a6de56270bd7c4d070df81d07beace25012d5103ced4e9ff08d6afdb7"
"checksum phf 0.7.24 (registry+https://github.com/rust-lang/crates.io-index)" = "b3da44b85f8e8dfaec21adae67f95d93244b2ecf6ad2a692320598dcc8e6dd18" "checksum phf 0.7.24 (registry+https://github.com/rust-lang/crates.io-index)" = "b3da44b85f8e8dfaec21adae67f95d93244b2ecf6ad2a692320598dcc8e6dd18"
"checksum phf_codegen 0.7.24 (registry+https://github.com/rust-lang/crates.io-index)" = "b03e85129e324ad4166b06b2c7491ae27fe3ec353af72e72cd1654c7225d517e" "checksum phf_codegen 0.7.24 (registry+https://github.com/rust-lang/crates.io-index)" = "b03e85129e324ad4166b06b2c7491ae27fe3ec353af72e72cd1654c7225d517e"
"checksum phf_generator 0.7.24 (registry+https://github.com/rust-lang/crates.io-index)" = "09364cc93c159b8b06b1f4dd8a4398984503483891b0c26b867cf431fb132662" "checksum phf_generator 0.7.24 (registry+https://github.com/rust-lang/crates.io-index)" = "09364cc93c159b8b06b1f4dd8a4398984503483891b0c26b867cf431fb132662"
"checksum phf_shared 0.7.24 (registry+https://github.com/rust-lang/crates.io-index)" = "234f71a15de2288bcb7e3b6515828d22af7ec8598ee6d24c3b526fa0a80b67a0" "checksum phf_shared 0.7.24 (registry+https://github.com/rust-lang/crates.io-index)" = "234f71a15de2288bcb7e3b6515828d22af7ec8598ee6d24c3b526fa0a80b67a0"
"checksum phf_shared 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c00cf8b9eafe68dde5e9eaa2cef8ee84a9336a47d566ec55ca16589633b65af7"
"checksum pkg-config 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)" = "3831453b3449ceb48b6d9c7ad7c96d5ea673e9b470a1dc578c2ce6521230884c" "checksum pkg-config 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)" = "3831453b3449ceb48b6d9c7ad7c96d5ea673e9b470a1dc578c2ce6521230884c"
"checksum plugin 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "1a6a0dc3910bc8db877ffed8e457763b317cf880df4ae19109b9f77d277cf6e0" "checksum plugin 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "1a6a0dc3910bc8db877ffed8e457763b317cf880df4ae19109b9f77d277cf6e0"
"checksum polyval 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7ec3341498978de3bfd12d1b22f1af1de22818f5473a11e8a6ef997989e3a212" "checksum polyval 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7ec3341498978de3bfd12d1b22f1af1de22818f5473a11e8a6ef997989e3a212"
@ -2915,6 +3090,7 @@ 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 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 semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
"checksum sequoia-openpgp 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a21df36cb0b83413e1f1e5ad15a295aaedcd1e464fd0f575115abef9b4b852ca" "checksum sequoia-openpgp 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a21df36cb0b83413e1f1e5ad15a295aaedcd1e464fd0f575115abef9b4b852ca"
"checksum sequoia-openpgp 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5e2245b0c1109e00608a6f553d6786b7f8add457c7909d5c6241504f677d68a2"
"checksum serde 1.0.117 (registry+https://github.com/rust-lang/crates.io-index)" = "b88fa983de7720629c9387e9f517353ed404164b1e482c970a90c1a4aaf7dc1a" "checksum serde 1.0.117 (registry+https://github.com/rust-lang/crates.io-index)" = "b88fa983de7720629c9387e9f517353ed404164b1e482c970a90c1a4aaf7dc1a"
"checksum serde_derive 1.0.117 (registry+https://github.com/rust-lang/crates.io-index)" = "cbd1ae72adb44aab48f325a02444a5fc079349a8d804c1fc922aed3f7454c74e" "checksum serde_derive 1.0.117 (registry+https://github.com/rust-lang/crates.io-index)" = "cbd1ae72adb44aab48f325a02444a5fc079349a8d804c1fc922aed3f7454c74e"
"checksum serde_json 1.0.59 (registry+https://github.com/rust-lang/crates.io-index)" = "dcac07dbffa1c65e7f816ab9eba78eb142c6d44410f4eeba1e26e4f5dfa56b95" "checksum serde_json 1.0.59 (registry+https://github.com/rust-lang/crates.io-index)" = "dcac07dbffa1c65e7f816ab9eba78eb142c6d44410f4eeba1e26e4f5dfa56b95"
@ -2923,6 +3099,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum sha2 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a256f46ea78a0c0d9ff00077504903ac881a1dafdc20da66545699e7776b3e69" "checksum sha2 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a256f46ea78a0c0d9ff00077504903ac881a1dafdc20da66545699e7776b3e69"
"checksum shlex 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7fdf1b9db47230893d76faad238fd6097fd6d6a9245cd7a4d90dbd639536bbd2" "checksum shlex 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7fdf1b9db47230893d76faad238fd6097fd6d6a9245cd7a4d90dbd639536bbd2"
"checksum siphasher 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0b8de496cf83d4ed58b6be86c3a275b8602f6ffe98d3024a869e124147a9a3ac" "checksum siphasher 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0b8de496cf83d4ed58b6be86c3a275b8602f6ffe98d3024a869e124147a9a3ac"
"checksum siphasher 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "fa8f3741c7372e75519bd9346068370c9cdaabcc1f9599cbcf2a2719352286b7"
"checksum slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8" "checksum slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8"
"checksum smallvec 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "f7b0758c52e15a8b5e3691eae6cc559f08eee9406e548a4477ba4e67770a82b6" "checksum smallvec 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "f7b0758c52e15a8b5e3691eae6cc559f08eee9406e548a4477ba4e67770a82b6"
"checksum smallvec 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "fbee7696b84bbf3d89a1c2eccff0850e3047ed46bfcd2e92c29a2d074d57e252" "checksum smallvec 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "fbee7696b84bbf3d89a1c2eccff0850e3047ed46bfcd2e92c29a2d074d57e252"
@ -2934,6 +3111,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum stdweb-internal-macros 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)" = "58fa5ff6ad0d98d1ffa8cb115892b6e69d67799f6763e162a1c9db421dc22e11" "checksum stdweb-internal-macros 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)" = "58fa5ff6ad0d98d1ffa8cb115892b6e69d67799f6763e162a1c9db421dc22e11"
"checksum stdweb-internal-runtime 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "213701ba3370744dcd1a12960caa4843b3d68b4d1c0a5d575e0d65b2ee9d16c0" "checksum stdweb-internal-runtime 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "213701ba3370744dcd1a12960caa4843b3d68b4d1c0a5d575e0d65b2ee9d16c0"
"checksum string_cache 0.7.5 (registry+https://github.com/rust-lang/crates.io-index)" = "89c058a82f9fd69b1becf8c274f412281038877c553182f1d02eb027045a2d67" "checksum string_cache 0.7.5 (registry+https://github.com/rust-lang/crates.io-index)" = "89c058a82f9fd69b1becf8c274f412281038877c553182f1d02eb027045a2d67"
"checksum string_cache 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2940c75beb4e3bf3a494cef919a747a2cb81e52571e212bfbd185074add7208a"
"checksum string_cache_codegen 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "f0f45ed1b65bf9a4bf2f7b7dc59212d1926e9eaf00fa998988e420fd124467c6" "checksum string_cache_codegen 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "f0f45ed1b65bf9a4bf2f7b7dc59212d1926e9eaf00fa998988e420fd124467c6"
"checksum string_cache_shared 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b1884d1bc09741d466d9b14e6d37ac89d6909cbcac41dd9ae982d4d063bbedfc" "checksum string_cache_shared 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b1884d1bc09741d466d9b14e6d37ac89d6909cbcac41dd9ae982d4d063bbedfc"
"checksum strsim 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" "checksum strsim 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
@ -2949,6 +3127,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum term 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "edd106a334b7657c10b7c540a0106114feadeb4dc314513e97df481d5d966f42" "checksum term 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "edd106a334b7657c10b7c540a0106114feadeb4dc314513e97df481d5d966f42"
"checksum terminal_size 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "9a14cd9f8c72704232f0bfc8455c0e861f0ad4eb60cc9ec8a170e231414c1e13" "checksum terminal_size 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "9a14cd9f8c72704232f0bfc8455c0e861f0ad4eb60cc9ec8a170e231414c1e13"
"checksum textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" "checksum textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
"checksum thiserror 1.0.22 (registry+https://github.com/rust-lang/crates.io-index)" = "0e9ae34b84616eedaaf1e9dd6026dbe00dcafa92aa0c8077cb69df1fcfe5e53e"
"checksum thiserror-impl 1.0.22 (registry+https://github.com/rust-lang/crates.io-index)" = "9ba20f23e85b10754cd195504aebf6a27e2e6cbe28c17778a0c930724628dd56"
"checksum thread_local 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d40c6d1b69745a6ec6fb1ca717914848da4b44ae29d9b3080cbee91d72a69b14" "checksum thread_local 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d40c6d1b69745a6ec6fb1ca717914848da4b44ae29d9b3080cbee91d72a69b14"
"checksum time 0.1.44 (registry+https://github.com/rust-lang/crates.io-index)" = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255" "checksum time 0.1.44 (registry+https://github.com/rust-lang/crates.io-index)" = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255"
"checksum time 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)" = "55b7151c9065e80917fbf285d9a5d1432f60db41d170ccafc749a136b41a93af" "checksum time 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)" = "55b7151c9065e80917fbf285d9a5d1432f60db41d170ccafc749a136b41a93af"

View File

@ -15,10 +15,10 @@ members = [
[dependencies] [dependencies]
hagrid-database = { path = "database" } hagrid-database = { path = "database" }
chrono = "0.4.10" chrono = "0.4.10"
failure = "0.1.5" anyhow = "1"
rocket = "0" rocket = "0"
rocket_codegen = "0" rocket_codegen = "0"
sequoia-openpgp = { version = "0.14", default-features = false } sequoia-openpgp = { version = "0.20", default-features = false, features = ["crypto-nettle"] }
multipart = "0" multipart = "0"
serde = "1.0" serde = "1.0"
serde_derive = "1.0" serde_derive = "1.0"

View File

@ -4,8 +4,8 @@ version = "0.1.0"
authors = ["Kai Michaelis <kai@sequoia-pgp.org>"] authors = ["Kai Michaelis <kai@sequoia-pgp.org>"]
[dependencies] [dependencies]
failure = "0.1.5" anyhow = "1"
sequoia-openpgp = { version = "0.14", default-features = false } sequoia-openpgp = { version = "0.20", default-features = false, features = ["crypto-nettle"] }
multipart = "0" multipart = "0"
log = "0" log = "0"
rand = "0.6" rand = "0.6"
@ -23,7 +23,6 @@ fs2 = "0.4"
walkdir = "2.2" walkdir = "2.2"
chrono = "0.4" chrono = "0.4"
zbase32 = "0.1.2" zbase32 = "0.1.2"
lazy_static = "1.4"
[lib] [lib]
name = "hagrid_database" name = "hagrid_database"

View File

@ -308,7 +308,6 @@ impl Filesystem {
) -> Result<()> { ) -> Result<()> {
use walkdir::WalkDir; use walkdir::WalkDir;
use std::fs; use std::fs;
use failure::format_err;
for entry in WalkDir::new(checks_dir) { for entry in WalkDir::new(checks_dir) {
let entry = entry?; let entry = entry?;
@ -460,7 +459,7 @@ impl Database for Filesystem {
if !link_fpr_target.ends_with(&path_published) { if !link_fpr_target.ends_with(&path_published) {
info!("Fingerprint points to different key for {} (expected {:?} to be suffix of {:?})", info!("Fingerprint points to different key for {} (expected {:?} to be suffix of {:?})",
fpr, &path_published, &link_fpr_target); fpr, &path_published, &link_fpr_target);
Err(failure::err_msg(format!("Fingerprint collision for key {}", fpr)))?; Err(anyhow!(format!("Fingerprint collision for key {}", fpr)))?;
} }
} }
@ -468,7 +467,7 @@ impl Database for Filesystem {
if !link_keyid_target.ends_with(&path_published) { if !link_keyid_target.ends_with(&path_published) {
info!("KeyID points to different key for {} (expected {:?} to be suffix of {:?})", info!("KeyID points to different key for {} (expected {:?} to be suffix of {:?})",
fpr, &path_published, &link_keyid_target); fpr, &path_published, &link_keyid_target);
Err(failure::err_msg(format!("KeyID collision for key {}", fpr)))?; Err(anyhow!(format!("KeyID collision for key {}", fpr)))?;
} }
} }
@ -606,8 +605,6 @@ impl Database for Filesystem {
/// Note that this operation may take a long time, and is /// Note that this operation may take a long time, and is
/// generally only useful for testing. /// generally only useful for testing.
fn check_consistency(&self) -> Result<()> { fn check_consistency(&self) -> Result<()> {
use failure::format_err;
// A cache of all Certs, for quick lookups. // A cache of all Certs, for quick lookups.
let mut tpks = HashMap::new(); let mut tpks = HashMap::new();
@ -646,9 +643,10 @@ impl Database for Filesystem {
// check that all subkeys are linked // check that all subkeys are linked
self.perform_checks(&self.keys_dir_published, &mut tpks, self.perform_checks(&self.keys_dir_published, &mut tpks,
|_, tpk, primary_fp| { |_, tpk, primary_fp| {
let policy = &POLICY;
let fingerprints = tpk let fingerprints = tpk
.keys() .keys()
.with_policy(&*POLICY, None) .with_policy(policy, None)
.for_certification() .for_certification()
.for_signing() .for_signing()
.map(|amalgamation| amalgamation.key().fingerprint()) .map(|amalgamation| amalgamation.key().fingerprint())

View File

@ -9,15 +9,13 @@ use openpgp::serialize::SerializeInto;
use chrono::prelude::Utc; use chrono::prelude::Utc;
extern crate failure; #[macro_use]
use failure::Error; extern crate anyhow;
use failure::Fallible as Result; use anyhow::Result;
extern crate fs2; extern crate fs2;
extern crate idna; extern crate idna;
#[macro_use] #[macro_use]
extern crate log; extern crate log;
#[macro_use]
extern crate lazy_static;
extern crate pathdiff; extern crate pathdiff;
extern crate rand; extern crate rand;
extern crate serde; extern crate serde;
@ -67,7 +65,7 @@ pub enum Query {
} }
impl FromStr for Query { impl FromStr for Query {
type Err = failure::Error; type Err = anyhow::Error;
fn from_str(term: &str) -> Result<Self> { fn from_str(term: &str) -> Result<Self> {
use self::Query::*; use self::Query::*;
@ -75,8 +73,7 @@ impl FromStr for Query {
let looks_like_short_key_id = !term.contains('@') && let looks_like_short_key_id = !term.contains('@') &&
(term.starts_with("0x") && term.len() < 16 || term.len() == 8); (term.starts_with("0x") && term.len() < 16 || term.len() == 8);
if looks_like_short_key_id { if looks_like_short_key_id {
return Err(failure::err_msg( return Err(anyhow!("Search by Short Key ID is not supported, sorry!"));
"Search by Short Key ID is not supported, sorry!"));
} }
if let Ok(fp) = Fingerprint::from_str(term) { if let Ok(fp) = Fingerprint::from_str(term) {
Ok(ByFingerprint(fp)) Ok(ByFingerprint(fp))
@ -85,7 +82,7 @@ impl FromStr for Query {
} else if let Ok(email) = Email::from_str(term) { } else if let Ok(email) = Email::from_str(term) {
Ok(ByEmail(email)) Ok(ByEmail(email))
} else { } else {
Err(failure::err_msg("Invalid search query!")) Err(anyhow!("Invalid search query!"))
} }
} }
} }
@ -217,14 +214,14 @@ pub trait Database: Sync + Send {
(new_tpk, false) (new_tpk, false)
}; };
let is_revoked = is_status_revoked(full_tpk_new.revoked(&*POLICY, None)); let is_revoked = is_status_revoked(full_tpk_new.revocation_status(&POLICY, None));
let is_ok = is_revoked || let is_ok = is_revoked ||
full_tpk_new.keys().subkeys().next().is_some() || full_tpk_new.keys().subkeys().next().is_some() ||
full_tpk_new.userids().next().is_some(); full_tpk_new.userids().next().is_some();
if !is_ok { if !is_ok {
self.write_to_quarantine(&fpr_primary, &tpk_to_string(&full_tpk_new)?)?; self.write_to_quarantine(&fpr_primary, &tpk_to_string(&full_tpk_new)?)?;
return Err(failure::err_msg("Not a well-formed key!")); return Err(anyhow!("Not a well-formed key!"));
} }
let published_tpk_old = self let published_tpk_old = self
@ -240,7 +237,6 @@ pub trait Database: Sync + Send {
let mut email_status: Vec<_> = full_tpk_new let mut email_status: Vec<_> = full_tpk_new
.userids() .userids()
.bundles()
.map(|binding| { .map(|binding| {
if let Ok(email) = Email::try_from(binding.userid()) { if let Ok(email) = Email::try_from(binding.userid()) {
Some((binding, email)) Some((binding, email))
@ -251,7 +247,7 @@ pub trait Database: Sync + Send {
.flatten() .flatten()
.filter(|(binding, email)| known_uids.contains(binding.userid()) || published_emails.contains(email)) .filter(|(binding, email)| known_uids.contains(binding.userid()) || published_emails.contains(email))
.flat_map(|(binding, email)| { .flat_map(|(binding, email)| {
if is_status_revoked(binding.revoked(&*POLICY, None)) { if is_status_revoked(binding.revocation_status(&POLICY, None)) {
Some((email, EmailAddressStatus::Revoked)) Some((email, EmailAddressStatus::Revoked))
} else if !is_revoked && published_emails.contains(&email) { } else if !is_revoked && published_emails.contains(&email) {
Some((email, EmailAddressStatus::Published)) Some((email, EmailAddressStatus::Published))
@ -281,8 +277,7 @@ pub trait Database: Sync + Send {
.filter(|email| { .filter(|email| {
let has_unrevoked_userid = published_tpk_new let has_unrevoked_userid = published_tpk_new
.userids() .userids()
.bundles() .filter(|binding| !is_status_revoked(binding.revocation_status(&POLICY, None)))
.filter(|binding| !is_status_revoked(binding.revoked(&*POLICY, None)))
.map(|binding| binding.userid()) .map(|binding| binding.userid())
.map(|uid| Email::try_from(uid).ok()) .map(|uid| Email::try_from(uid).ok())
.flatten() .flatten()
@ -358,10 +353,10 @@ pub trait Database: Sync + Send {
fn get_tpk_status(&self, fpr_primary: &Fingerprint, known_addresses: &[Email]) -> Result<TpkStatus> { fn get_tpk_status(&self, fpr_primary: &Fingerprint, known_addresses: &[Email]) -> Result<TpkStatus> {
let tpk_full = self.by_fpr_full(&fpr_primary) let tpk_full = self.by_fpr_full(&fpr_primary)
.ok_or_else(|| failure::err_msg("Key not in database!")) .ok_or_else(|| anyhow!("Key not in database!"))
.and_then(|bytes| Cert::from_bytes(bytes.as_bytes()))?; .and_then(|bytes| Cert::from_bytes(bytes.as_bytes()))?;
let is_revoked = is_status_revoked(tpk_full.revoked(&*POLICY, None)); let is_revoked = is_status_revoked(tpk_full.revocation_status(&POLICY, None));
let unparsed_uids = tpk_full let unparsed_uids = tpk_full
.userids() .userids()
@ -379,13 +374,12 @@ pub trait Database: Sync + Send {
let mut email_status: Vec<_> = tpk_full let mut email_status: Vec<_> = tpk_full
.userids() .userids()
.bundles()
.flat_map(|binding| { .flat_map(|binding| {
let uid = binding.userid(); let uid = binding.userid();
if let Ok(email) = Email::try_from(uid) { if let Ok(email) = Email::try_from(uid) {
if !known_addresses.contains(&email) { if !known_addresses.contains(&email) {
None None
} else if is_status_revoked(binding.revoked(&*POLICY, None)) { } else if is_status_revoked(binding.revocation_status(&POLICY, None)) {
Some((email, EmailAddressStatus::Revoked)) Some((email, EmailAddressStatus::Revoked))
} else if published_uids.contains(uid) { } else if published_uids.contains(uid) {
Some((email, EmailAddressStatus::Published)) Some((email, EmailAddressStatus::Published))
@ -424,7 +418,7 @@ pub trait Database: Sync + Send {
self.nolock_unlink_email_if_other(fpr_primary, email_new)?; self.nolock_unlink_email_if_other(fpr_primary, email_new)?;
let full_tpk = self.by_fpr_full(&fpr_primary) let full_tpk = self.by_fpr_full(&fpr_primary)
.ok_or_else(|| failure::err_msg("Key not in database!")) .ok_or_else(|| anyhow!("Key not in database!"))
.and_then(|bytes| Cert::from_bytes(bytes.as_bytes()))?; .and_then(|bytes| Cert::from_bytes(bytes.as_bytes()))?;
let published_uids_old: Vec<UserID> = self let published_uids_old: Vec<UserID> = self
@ -455,7 +449,7 @@ pub trait Database: Sync + Send {
.map(|binding| Email::try_from(binding.userid())) .map(|binding| Email::try_from(binding.userid()))
.flatten() .flatten()
.any(|email| email == *email_new) { .any(|email| email == *email_new) {
return Err(failure::err_msg("Requested UserID not found!")); return Err(anyhow!("Requested UserID not found!"));
} }
let published_tpk_clean = tpk_clean(&published_tpk_new)?; let published_tpk_clean = tpk_clean(&published_tpk_new)?;
@ -519,7 +513,7 @@ pub trait Database: Sync + Send {
email_remove: impl Fn(&UserID) -> bool, email_remove: impl Fn(&UserID) -> bool,
) -> Result<()> { ) -> Result<()> {
let published_tpk_old = self.by_fpr(&fpr_primary) let published_tpk_old = self.by_fpr(&fpr_primary)
.ok_or_else(|| failure::err_msg("Key not in database!")) .ok_or_else(|| anyhow!("Key not in database!"))
.and_then(|bytes| Cert::from_bytes(bytes.as_bytes()))?; .and_then(|bytes| Cert::from_bytes(bytes.as_bytes()))?;
let published_emails_old: Vec<Email> = published_tpk_old let published_emails_old: Vec<Email> = published_tpk_old
@ -584,7 +578,7 @@ pub trait Database: Sync + Send {
) -> Result<RegenerateResult> { ) -> Result<RegenerateResult> {
let tpk = self.by_primary_fpr(&fpr_primary) let tpk = self.by_primary_fpr(&fpr_primary)
.and_then(|bytes| Cert::from_bytes(bytes.as_bytes()).ok()) .and_then(|bytes| Cert::from_bytes(bytes.as_bytes()).ok())
.ok_or_else(|| failure::err_msg("Key not in database!"))?; .ok_or_else(|| anyhow!("Key not in database!"))?;
let published_emails: Vec<Email> = tpk let published_emails: Vec<Email> = tpk
.userids() .userids()
@ -665,16 +659,15 @@ fn tpk_get_emails(cert: &Cert) -> Vec<Email> {
pub fn tpk_get_linkable_fprs(tpk: &Cert) -> Vec<Fingerprint> { pub fn tpk_get_linkable_fprs(tpk: &Cert) -> Vec<Fingerprint> {
let ref signing_capable = KeyFlags::empty() let ref signing_capable = KeyFlags::empty()
.set_signing(true) .set_signing()
.set_certification(true); .set_certification();
let ref fpr_primary = Fingerprint::try_from(tpk.fingerprint()).unwrap(); let ref fpr_primary = Fingerprint::try_from(tpk.fingerprint()).unwrap();
tpk tpk
.keys() .keys()
.bundles()
.into_iter() .into_iter()
.flat_map(|bundle| { .flat_map(|bundle| {
Fingerprint::try_from(bundle.key().fingerprint()) Fingerprint::try_from(bundle.key().fingerprint())
.map(|fpr| (fpr, bundle.binding_signature(&*POLICY, None).and_then(|sig| sig.key_flags()))) .map(|fpr| (fpr, bundle.binding_signature(&POLICY, None).ok().and_then(|sig| sig.key_flags())))
}) })
.filter(|(fpr, flags)| { .filter(|(fpr, flags)| {
fpr == fpr_primary || fpr == fpr_primary ||

View File

@ -1,10 +1,10 @@
use failure::Fallible as Result; use openpgp::Result;
use std::convert::TryFrom; use std::convert::TryFrom;
use openpgp::{ use openpgp::{
Cert, Cert,
cert::components::ComponentBundle, cert::amalgamation::ComponentAmalgamation,
RevocationStatus, types::RevocationStatus,
armor::{Writer, Kind}, armor::{Writer, Kind},
packet::UserID, packet::UserID,
serialize::Serialize as OpenPgpSerialize, serialize::Serialize as OpenPgpSerialize,
@ -13,9 +13,7 @@ use openpgp::{
use Email; use Email;
lazy_static! { pub const POLICY: StandardPolicy = StandardPolicy::new();
pub static ref POLICY: StandardPolicy = StandardPolicy::new();
}
pub fn is_status_revoked(status: RevocationStatus) -> bool { pub fn is_status_revoked(status: RevocationStatus) -> bool {
match status { match status {
@ -28,7 +26,7 @@ pub fn is_status_revoked(status: RevocationStatus) -> bool {
pub fn tpk_to_string(tpk: &Cert) -> Result<Vec<u8>> { pub fn tpk_to_string(tpk: &Cert) -> Result<Vec<u8>> {
let mut buf = Vec::new(); let mut buf = Vec::new();
{ {
let mut armor_writer = Writer::new(&mut buf, Kind::PublicKey, &[][..])?; let mut armor_writer = Writer::new(&mut buf, Kind::PublicKey)?;
tpk.serialize(&mut armor_writer)?; tpk.serialize(&mut armor_writer)?;
armor_writer.finalize()?; armor_writer.finalize()?;
} }
@ -42,7 +40,7 @@ pub fn tpk_clean(tpk: &Cert) -> Result<Cert> {
// The primary key and related signatures. // The primary key and related signatures.
let pk_bundle = tpk.primary_key().bundle(); let pk_bundle = tpk.primary_key().bundle();
acc.push(pk_bundle.key().clone().mark_role_primary().into()); acc.push(pk_bundle.key().clone().into());
for s in pk_bundle.self_signatures() { acc.push(s.clone().into()) } for s in pk_bundle.self_signatures() { acc.push(s.clone().into()) }
for s in pk_bundle.self_revocations() { acc.push(s.clone().into()) } for s in pk_bundle.self_revocations() { acc.push(s.clone().into()) }
for s in pk_bundle.other_revocations() { acc.push(s.clone().into()) } for s in pk_bundle.other_revocations() { acc.push(s.clone().into()) }
@ -56,20 +54,20 @@ pub fn tpk_clean(tpk: &Cert) -> Result<Cert> {
} }
// Updates for UserIDs fulfilling `filter`. // Updates for UserIDs fulfilling `filter`.
for uidb in tpk.userids().bundles() { for uidb in tpk.userids() {
acc.push(uidb.userid().clone().into()); acc.push(uidb.userid().clone().into());
for s in uidb.self_signatures() { acc.push(s.clone().into()) } for s in uidb.self_signatures() { acc.push(s.clone().into()) }
for s in uidb.self_revocations() { acc.push(s.clone().into()) } for s in uidb.self_revocations() { acc.push(s.clone().into()) }
for s in uidb.other_revocations() { acc.push(s.clone().into()) } for s in uidb.other_revocations() { acc.push(s.clone().into()) }
} }
Cert::from_packet_pile(acc.into()) Cert::from_packets(acc.into_iter())
} }
/// Filters the Cert, keeping only UserIDs that aren't revoked, and whose emails match the given list /// Filters the Cert, keeping only UserIDs that aren't revoked, and whose emails match the given list
pub fn tpk_filter_alive_emails(tpk: &Cert, emails: &[Email]) -> Result<Cert> { pub fn tpk_filter_alive_emails(tpk: &Cert, emails: &[Email]) -> Result<Cert> {
tpk_filter_userids(tpk, |uid| { tpk_filter_userids(tpk, |uid| {
if is_status_revoked(uid.revoked(&*POLICY, None)) { if is_status_revoked(uid.revocation_status(&POLICY, None)) {
false false
} else if let Ok(email) = Email::try_from(uid.userid()) { } else if let Ok(email) = Email::try_from(uid.userid()) {
emails.contains(&email) emails.contains(&email)
@ -82,7 +80,7 @@ pub fn tpk_filter_alive_emails(tpk: &Cert, emails: &[Email]) -> Result<Cert> {
/// Filters the Cert, keeping only those UserIDs that fulfill the /// Filters the Cert, keeping only those UserIDs that fulfill the
/// predicate `filter`. /// predicate `filter`.
pub fn tpk_filter_userids<F>(tpk: &Cert, filter: F) -> Result<Cert> pub fn tpk_filter_userids<F>(tpk: &Cert, filter: F) -> Result<Cert>
where F: Fn(&ComponentBundle<UserID>) -> bool where F: Fn(&ComponentAmalgamation<UserID>) -> bool
{ {
// Iterate over the Cert, pushing packets we want to merge // Iterate over the Cert, pushing packets we want to merge
// into the accumulator. // into the accumulator.
@ -90,7 +88,7 @@ pub fn tpk_filter_userids<F>(tpk: &Cert, filter: F) -> Result<Cert>
// The primary key and related signatures. // The primary key and related signatures.
let pk_bundle = tpk.primary_key().bundle(); let pk_bundle = tpk.primary_key().bundle();
acc.push(pk_bundle.key().clone().mark_role_primary().into()); acc.push(pk_bundle.key().clone().into());
for s in pk_bundle.self_signatures() { acc.push(s.clone().into()) } for s in pk_bundle.self_signatures() { acc.push(s.clone().into()) }
for s in pk_bundle.certifications() { acc.push(s.clone().into()) } for s in pk_bundle.certifications() { acc.push(s.clone().into()) }
for s in pk_bundle.self_revocations() { acc.push(s.clone().into()) } for s in pk_bundle.self_revocations() { acc.push(s.clone().into()) }
@ -106,9 +104,9 @@ pub fn tpk_filter_userids<F>(tpk: &Cert, filter: F) -> Result<Cert>
} }
// Updates for UserIDs fulfilling `filter`. // Updates for UserIDs fulfilling `filter`.
for uidb in tpk.userids().bundles() { for uidb in tpk.userids() {
// Only include userids matching filter // Only include userids matching filter
if filter(uidb) { if filter(&uidb) {
acc.push(uidb.userid().clone().into()); acc.push(uidb.userid().clone().into());
for s in uidb.self_signatures() { acc.push(s.clone().into()) } for s in uidb.self_signatures() { acc.push(s.clone().into()) }
for s in uidb.certifications() { acc.push(s.clone().into()) } for s in uidb.certifications() { acc.push(s.clone().into()) }
@ -117,5 +115,5 @@ pub fn tpk_filter_userids<F>(tpk: &Cert, filter: F) -> Result<Cert>
} }
} }
Cert::from_packet_pile(acc.into()) Cert::from_packets(acc.into_iter())
} }

View File

@ -5,7 +5,8 @@ use std::str::FromStr;
use openpgp::packet::UserID; use openpgp::packet::UserID;
use serde::{Deserialize, Deserializer, Serialize, Serializer}; use serde::{Deserialize, Deserializer, Serialize, Serializer};
use {Error, Result}; use anyhow::Error;
use {Result};
/// Holds a normalized email address. /// Holds a normalized email address.
/// ///
@ -37,8 +38,7 @@ impl TryFrom<&UserID> for Email {
// Normalize Unicode in domains. // Normalize Unicode in domains.
let domain = idna::domain_to_ascii(domain) let domain = idna::domain_to_ascii(domain)
.map_err(|e| failure::format_err!( .map_err(|e| anyhow!("punycode conversion failed: {:?}", e))?;
"punycode conversion failed: {:?}", e))?;
// Join. // Join.
let address = format!("{}@{}", localpart, domain); let address = format!("{}@{}", localpart, domain);
@ -53,8 +53,7 @@ impl TryFrom<&UserID> for Email {
Ok(Email(address)) Ok(Email(address))
} else { } else {
Err(failure::err_msg( Err(anyhow!("malformed email address: '{:?}'", uid.value()))
format!("malformed email address: '{:?}'", uid.value())))
} }
} }
} }
@ -83,7 +82,8 @@ impl TryFrom<sequoia_openpgp::Fingerprint> for Fingerprint {
match fpr { match fpr {
sequoia_openpgp::Fingerprint::V4(a) => Ok(Fingerprint(a)), sequoia_openpgp::Fingerprint::V4(a) => Ok(Fingerprint(a)),
sequoia_openpgp::Fingerprint::Invalid(_) => sequoia_openpgp::Fingerprint::Invalid(_) =>
Err(failure::err_msg("invalid fingerprint")), Err(anyhow!("invalid fingerprint")),
_ => Err(anyhow!("unknown fingerprint type")),
} }
} }
} }
@ -124,7 +124,8 @@ impl FromStr for Fingerprint {
match sequoia_openpgp::Fingerprint::from_hex(s)? { match sequoia_openpgp::Fingerprint::from_hex(s)? {
sequoia_openpgp::Fingerprint::V4(a) => Ok(Fingerprint(a)), sequoia_openpgp::Fingerprint::V4(a) => Ok(Fingerprint(a)),
sequoia_openpgp::Fingerprint::Invalid(_) => sequoia_openpgp::Fingerprint::Invalid(_) =>
Err(failure::format_err!("'{}' is not a valid fingerprint", s)) Err(anyhow!("'{}' is not a valid fingerprint", s)),
_ => Err(anyhow!("unknown fingerprint type")),
} }
} }
} }
@ -139,8 +140,9 @@ impl TryFrom<sequoia_openpgp::Fingerprint> for KeyID {
match fpr { match fpr {
sequoia_openpgp::Fingerprint::V4(a) => Ok(Fingerprint(a).into()), sequoia_openpgp::Fingerprint::V4(a) => Ok(Fingerprint(a).into()),
sequoia_openpgp::Fingerprint::Invalid(_) => { sequoia_openpgp::Fingerprint::Invalid(_) => {
Err(failure::err_msg("invalid fingerprint")) Err(anyhow!("invalid fingerprint"))
} },
_ => Err(anyhow!("unknown fingerprint type")),
} }
} }
} }
@ -177,7 +179,8 @@ impl FromStr for KeyID {
match sequoia_openpgp::KeyID::from_hex(s)? { match sequoia_openpgp::KeyID::from_hex(s)? {
sequoia_openpgp::KeyID::V4(a) => Ok(KeyID(a)), sequoia_openpgp::KeyID::V4(a) => Ok(KeyID(a)),
sequoia_openpgp::KeyID::Invalid(_) => sequoia_openpgp::KeyID::Invalid(_) =>
Err(failure::format_err!("'{}' is not a valid long key ID", s)) Err(anyhow!("'{}' is not a valid long key ID", s)),
_ => Err(anyhow!("unknown keyid type")),
} }
} }
} }

View File

@ -17,7 +17,7 @@ fn split_address(email_address: impl AsRef<str>) -> Result<(String,String)> {
let email_address = email_address.as_ref(); let email_address = email_address.as_ref();
let v: Vec<&str> = email_address.split('@').collect(); let v: Vec<&str> = email_address.split('@').collect();
if v.len() != 2 { if v.len() != 2 {
Err(failure::err_msg("Malformed email address".to_owned()))?; Err(anyhow!("Malformed email address".to_owned()))?;
}; };
// Convert to lowercase without tailoring, i.e. without taking any // Convert to lowercase without tailoring, i.e. without taking any

View File

@ -436,26 +436,26 @@ msgstr "Kein Schlüssel gefunden für {address}"
msgid "A request has already been sent for this address recently." msgid "A request has already been sent for this address recently."
msgstr "Eine E-Mail für diesen Schlüssel wurde erst kürzlich versandt." msgstr "Eine E-Mail für diesen Schlüssel wurde erst kürzlich versandt."
#: src/web/vks.rs:112 #: src/web/vks.rs:111
msgid "Parsing of key data failed." msgid "Parsing of key data failed."
msgstr "Fehler bei Verarbeitung des Schlüssel-Materials." msgstr "Fehler bei Verarbeitung des Schlüssel-Materials."
#: src/web/vks.rs:121 #: src/web/vks.rs:120
msgid "Whoops, please don't upload secret keys!" msgid "Whoops, please don't upload secret keys!"
msgstr "Ups, bitte keine geheimen Schlüssel hochladen!" msgstr "Ups, bitte keine geheimen Schlüssel hochladen!"
#: src/web/vks.rs:134 #: src/web/vks.rs:133
msgid "No key uploaded." msgid "No key uploaded."
msgstr "Es wurde kein Schlüssel hochgeladen." msgstr "Es wurde kein Schlüssel hochgeladen."
#: src/web/vks.rs:178 #: src/web/vks.rs:177
msgid "Error processing uploaded key." msgid "Error processing uploaded key."
msgstr "Fehler bei Verarbeitung des hochgeladenen Schlüssels." msgstr "Fehler bei Verarbeitung des hochgeladenen Schlüssels."
#: src/web/vks.rs:248 #: src/web/vks.rs:247
msgid "Upload session expired. Please try again." msgid "Upload session expired. Please try again."
msgstr "Zeitlimit beim Hochladen abgelaufen. Bitte versuch es erneut." msgstr "Zeitlimit beim Hochladen abgelaufen. Bitte versuch es erneut."
#: src/web/vks.rs:285 #: src/web/vks.rs:284
msgid "Invalid verification link." msgid "Invalid verification link."
msgstr "Ungültiger Bestätigungs-Link." msgstr "Ungültiger Bestätigungs-Link."

View File

@ -445,28 +445,28 @@ msgstr ""
msgid "A request has already been sent for this address recently." msgid "A request has already been sent for this address recently."
msgstr "" msgstr ""
#: src/web/vks.rs:112 #: src/web/vks.rs:111
msgid "Parsing of key data failed." msgid "Parsing of key data failed."
msgstr "" msgstr ""
#: src/web/vks.rs:121 #: src/web/vks.rs:120
msgid "Whoops, please don't upload secret keys!" msgid "Whoops, please don't upload secret keys!"
msgstr "" msgstr ""
#: src/web/vks.rs:134 #: src/web/vks.rs:133
#, fuzzy #, fuzzy
msgid "No key uploaded." msgid "No key uploaded."
msgstr "Your key upload on {}" msgstr "Your key upload on {}"
#: src/web/vks.rs:178 #: src/web/vks.rs:177
msgid "Error processing uploaded key." msgid "Error processing uploaded key."
msgstr "" msgstr ""
#: src/web/vks.rs:248 #: src/web/vks.rs:247
msgid "Upload session expired. Please try again." msgid "Upload session expired. Please try again."
msgstr "" msgstr ""
#: src/web/vks.rs:285 #: src/web/vks.rs:284
#, fuzzy #, fuzzy
msgid "Invalid verification link." msgid "Invalid verification link."
msgstr "Send Verification Mail" msgstr "Send Verification Mail"

View File

@ -443,26 +443,26 @@ msgstr "Il ny a pas de clé pour cette adresse : {address}"
msgid "A request has already been sent for this address recently." msgid "A request has already been sent for this address recently."
msgstr "Une demande a déjà été envoyée récemment pour cette adresse." msgstr "Une demande a déjà été envoyée récemment pour cette adresse."
#: src/web/vks.rs:112 #: src/web/vks.rs:111
msgid "Parsing of key data failed." msgid "Parsing of key data failed."
msgstr "Échec danalyse des données de la clé." msgstr "Échec danalyse des données de la clé."
#: src/web/vks.rs:121 #: src/web/vks.rs:120
msgid "Whoops, please don't upload secret keys!" msgid "Whoops, please don't upload secret keys!"
msgstr "Attention : Veuillez ne pas téléverser de clés secrètes!" msgstr "Attention : Veuillez ne pas téléverser de clés secrètes!"
#: src/web/vks.rs:134 #: src/web/vks.rs:133
msgid "No key uploaded." msgid "No key uploaded."
msgstr "Aucune clé na été téléversée." msgstr "Aucune clé na été téléversée."
#: src/web/vks.rs:178 #: src/web/vks.rs:177
msgid "Error processing uploaded key." msgid "Error processing uploaded key."
msgstr "Erreur de traitement de la clé téléversée." msgstr "Erreur de traitement de la clé téléversée."
#: src/web/vks.rs:248 #: src/web/vks.rs:247
msgid "Upload session expired. Please try again." msgid "Upload session expired. Please try again."
msgstr "La session de téléversement est expirée. Veuillez ressayer." msgstr "La session de téléversement est expirée. Veuillez ressayer."
#: src/web/vks.rs:285 #: src/web/vks.rs:284
msgid "Invalid verification link." msgid "Invalid verification link."
msgstr "Le lien de confirmation est invalide." msgstr "Le lien de confirmation est invalide."

View File

@ -298,26 +298,26 @@ msgstr ""
msgid "A request has already been sent for this address recently." msgid "A request has already been sent for this address recently."
msgstr "" msgstr ""
#: src/web/vks.rs:112 #: src/web/vks.rs:111
msgid "Parsing of key data failed." msgid "Parsing of key data failed."
msgstr "" msgstr ""
#: src/web/vks.rs:121 #: src/web/vks.rs:120
msgid "Whoops, please don't upload secret keys!" msgid "Whoops, please don't upload secret keys!"
msgstr "" msgstr ""
#: src/web/vks.rs:134 #: src/web/vks.rs:133
msgid "No key uploaded." msgid "No key uploaded."
msgstr "" msgstr ""
#: src/web/vks.rs:178 #: src/web/vks.rs:177
msgid "Error processing uploaded key." msgid "Error processing uploaded key."
msgstr "" msgstr ""
#: src/web/vks.rs:248 #: src/web/vks.rs:247
msgid "Upload session expired. Please try again." msgid "Upload session expired. Please try again."
msgstr "" msgstr ""
#: src/web/vks.rs:285 #: src/web/vks.rs:284
msgid "Invalid verification link." msgid "Invalid verification link."
msgstr "" msgstr ""

View File

@ -436,26 +436,26 @@ msgstr "Nessuna chiave per l'indirizzo: {address}"
msgid "A request has already been sent for this address recently." msgid "A request has already been sent for this address recently."
msgstr "Una richiesta per questo indirizzo è già stata inviata recentemente." msgstr "Una richiesta per questo indirizzo è già stata inviata recentemente."
#: src/web/vks.rs:112 #: src/web/vks.rs:111
msgid "Parsing of key data failed." msgid "Parsing of key data failed."
msgstr "Impossibile elaborare i dati della chiave." msgstr "Impossibile elaborare i dati della chiave."
#: src/web/vks.rs:121 #: src/web/vks.rs:120
msgid "Whoops, please don't upload secret keys!" msgid "Whoops, please don't upload secret keys!"
msgstr "Ooops, non caricare chiavi segrete!" msgstr "Ooops, non caricare chiavi segrete!"
#: src/web/vks.rs:134 #: src/web/vks.rs:133
msgid "No key uploaded." msgid "No key uploaded."
msgstr "Nessuna chaive caricata." msgstr "Nessuna chaive caricata."
#: src/web/vks.rs:178 #: src/web/vks.rs:177
msgid "Error processing uploaded key." msgid "Error processing uploaded key."
msgstr "Errore nell'elaborazione della chiave caricata." msgstr "Errore nell'elaborazione della chiave caricata."
#: src/web/vks.rs:248 #: src/web/vks.rs:247
msgid "Upload session expired. Please try again." msgid "Upload session expired. Please try again."
msgstr "Sessione di caricamento scaduta. Si prega di riprovare." msgstr "Sessione di caricamento scaduta. Si prega di riprovare."
#: src/web/vks.rs:285 #: src/web/vks.rs:284
msgid "Invalid verification link." msgid "Invalid verification link."
msgstr "Link di verifica non valido." msgstr "Link di verifica non valido."

View File

@ -435,26 +435,26 @@ msgstr "このアドレスに対する鍵がありません: {address}"
msgid "A request has already been sent for this address recently." msgid "A request has already been sent for this address recently."
msgstr "最近、このアドレスへリクエストがすでに送信されています。" msgstr "最近、このアドレスへリクエストがすでに送信されています。"
#: src/web/vks.rs:112 #: src/web/vks.rs:111
msgid "Parsing of key data failed." msgid "Parsing of key data failed."
msgstr "鍵データのパーズが失敗しました。" msgstr "鍵データのパーズが失敗しました。"
#: src/web/vks.rs:121 #: src/web/vks.rs:120
msgid "Whoops, please don't upload secret keys!" msgid "Whoops, please don't upload secret keys!"
msgstr "あらら、秘密鍵をアップロードしないでください!" msgstr "あらら、秘密鍵をアップロードしないでください!"
#: src/web/vks.rs:134 #: src/web/vks.rs:133
msgid "No key uploaded." msgid "No key uploaded."
msgstr "鍵はアップロードされませんでした。" msgstr "鍵はアップロードされませんでした。"
#: src/web/vks.rs:178 #: src/web/vks.rs:177
msgid "Error processing uploaded key." msgid "Error processing uploaded key."
msgstr "アップロードされた鍵の処理に失敗しました。" msgstr "アップロードされた鍵の処理に失敗しました。"
#: src/web/vks.rs:248 #: src/web/vks.rs:247
msgid "Upload session expired. Please try again." msgid "Upload session expired. Please try again."
msgstr "アップロードのセッションが時間切れです。もう一度試してください。" msgstr "アップロードのセッションが時間切れです。もう一度試してください。"
#: src/web/vks.rs:285 #: src/web/vks.rs:284
msgid "Invalid verification link." msgid "Invalid verification link."
msgstr "無効な検証のリンクです。" msgstr "無効な検証のリンクです。"

View File

@ -439,26 +439,26 @@ msgstr "Ingen nøkler for adressen {address}"
msgid "A request has already been sent for this address recently." msgid "A request has already been sent for this address recently."
msgstr "En forespørsel har allerede blitt sendt for denne adressen nylig." msgstr "En forespørsel har allerede blitt sendt for denne adressen nylig."
#: src/web/vks.rs:112 #: src/web/vks.rs:111
msgid "Parsing of key data failed." msgid "Parsing of key data failed."
msgstr "Kunne ikke analysere innholdet i nøkkelen." msgstr "Kunne ikke analysere innholdet i nøkkelen."
#: src/web/vks.rs:121 #: src/web/vks.rs:120
msgid "Whoops, please don't upload secret keys!" msgid "Whoops, please don't upload secret keys!"
msgstr "Hopp sann! Vennligst ikke last opp hemmelige nøkler!" msgstr "Hopp sann! Vennligst ikke last opp hemmelige nøkler!"
#: src/web/vks.rs:134 #: src/web/vks.rs:133
msgid "No key uploaded." msgid "No key uploaded."
msgstr "Ingen nøkkel er lastet opp." msgstr "Ingen nøkkel er lastet opp."
#: src/web/vks.rs:178 #: src/web/vks.rs:177
msgid "Error processing uploaded key." msgid "Error processing uploaded key."
msgstr "Kunne ikke behandle den opplastede nøkkelen." msgstr "Kunne ikke behandle den opplastede nøkkelen."
#: src/web/vks.rs:248 #: src/web/vks.rs:247
msgid "Upload session expired. Please try again." msgid "Upload session expired. Please try again."
msgstr "Opplastingsøkten er utgått. Vennligst prøv på nytt." msgstr "Opplastingsøkten er utgått. Vennligst prøv på nytt."
#: src/web/vks.rs:285 #: src/web/vks.rs:284
msgid "Invalid verification link." msgid "Invalid verification link."
msgstr "Bekreftelseslenken er ugyldig." msgstr "Bekreftelseslenken er ugyldig."

View File

@ -435,26 +435,26 @@ msgstr "Brak klucza dla adresu: {address}"
msgid "A request has already been sent for this address recently." msgid "A request has already been sent for this address recently."
msgstr "Zapytanie o ten adres zostało niedawno wysłane." msgstr "Zapytanie o ten adres zostało niedawno wysłane."
#: src/web/vks.rs:112 #: src/web/vks.rs:111
msgid "Parsing of key data failed." msgid "Parsing of key data failed."
msgstr "Przetwarzanie danych klucza się nie powiodło." msgstr "Przetwarzanie danych klucza się nie powiodło."
#: src/web/vks.rs:121 #: src/web/vks.rs:120
msgid "Whoops, please don't upload secret keys!" msgid "Whoops, please don't upload secret keys!"
msgstr "Ups, nie wysyłaj kluczy prywatnych!" msgstr "Ups, nie wysyłaj kluczy prywatnych!"
#: src/web/vks.rs:134 #: src/web/vks.rs:133
msgid "No key uploaded." msgid "No key uploaded."
msgstr "Klucz nie został wysłany." msgstr "Klucz nie został wysłany."
#: src/web/vks.rs:178 #: src/web/vks.rs:177
msgid "Error processing uploaded key." msgid "Error processing uploaded key."
msgstr "Błąd przetwarzania wysłanego klucza." msgstr "Błąd przetwarzania wysłanego klucza."
#: src/web/vks.rs:248 #: src/web/vks.rs:247
msgid "Upload session expired. Please try again." msgid "Upload session expired. Please try again."
msgstr "Sesja wysyłania wygasła. Spróbuj ponownie." msgstr "Sesja wysyłania wygasła. Spróbuj ponownie."
#: src/web/vks.rs:285 #: src/web/vks.rs:284
msgid "Invalid verification link." msgid "Invalid verification link."
msgstr "Nieprawidłowy link weryfikacyjny." msgstr "Nieprawidłowy link weryfikacyjny."

View File

@ -434,26 +434,26 @@ msgstr "Anahtarsız adres: {address}"
msgid "A request has already been sent for this address recently." msgid "A request has already been sent for this address recently."
msgstr "Bu adres için bir istek kısa bir süre önce zaten gönderilmişti." msgstr "Bu adres için bir istek kısa bir süre önce zaten gönderilmişti."
#: src/web/vks.rs:112 #: src/web/vks.rs:111
msgid "Parsing of key data failed." msgid "Parsing of key data failed."
msgstr "Anahtar verisi çözümlemesi başarısız oldu." msgstr "Anahtar verisi çözümlemesi başarısız oldu."
#: src/web/vks.rs:121 #: src/web/vks.rs:120
msgid "Whoops, please don't upload secret keys!" msgid "Whoops, please don't upload secret keys!"
msgstr "Eyvah! Lütfen gizli anahtarınızı yüklemeyin!" msgstr "Eyvah! Lütfen gizli anahtarınızı yüklemeyin!"
#: src/web/vks.rs:134 #: src/web/vks.rs:133
msgid "No key uploaded." msgid "No key uploaded."
msgstr "Anahtar yüklenmedi." msgstr "Anahtar yüklenmedi."
#: src/web/vks.rs:178 #: src/web/vks.rs:177
msgid "Error processing uploaded key." msgid "Error processing uploaded key."
msgstr "Yüklenen anahtar işlenirken bir hata oluştu." msgstr "Yüklenen anahtar işlenirken bir hata oluştu."
#: src/web/vks.rs:248 #: src/web/vks.rs:247
msgid "Upload session expired. Please try again." msgid "Upload session expired. Please try again."
msgstr "Yükleme oturumunun süresi doldu. Lütfen tekrar deneyin." msgstr "Yükleme oturumunun süresi doldu. Lütfen tekrar deneyin."
#: src/web/vks.rs:285 #: src/web/vks.rs:284
msgid "Invalid verification link." msgid "Invalid verification link."
msgstr "Geçersiz doğrulama bağlantısı." msgstr "Geçersiz doğrulama bağlantısı."

View File

@ -422,26 +422,26 @@ msgstr "此地址下没有密钥:{address}"
msgid "A request has already been sent for this address recently." msgid "A request has already been sent for this address recently."
msgstr "对此地址的申请已经发送" msgstr "对此地址的申请已经发送"
#: src/web/vks.rs:112 #: src/web/vks.rs:111
msgid "Parsing of key data failed." msgid "Parsing of key data failed."
msgstr "密钥数据解析失败。" msgstr "密钥数据解析失败。"
#: src/web/vks.rs:121 #: src/web/vks.rs:120
msgid "Whoops, please don't upload secret keys!" msgid "Whoops, please don't upload secret keys!"
msgstr "我的天!请不要上传私钥!" msgstr "我的天!请不要上传私钥!"
#: src/web/vks.rs:134 #: src/web/vks.rs:133
msgid "No key uploaded." msgid "No key uploaded."
msgstr "没有密钥被上传" msgstr "没有密钥被上传"
#: src/web/vks.rs:178 #: src/web/vks.rs:177
msgid "Error processing uploaded key." msgid "Error processing uploaded key."
msgstr "处理已上传的密钥时出现问题" msgstr "处理已上传的密钥时出现问题"
#: src/web/vks.rs:248 #: src/web/vks.rs:247
msgid "Upload session expired. Please try again." msgid "Upload session expired. Please try again."
msgstr "上传会话过期,请重试。" msgstr "上传会话过期,请重试。"
#: src/web/vks.rs:285 #: src/web/vks.rs:284
msgid "Invalid verification link." msgid "Invalid verification link."
msgstr "无效的验证链接" msgstr "无效的验证链接"

View File

@ -3,8 +3,9 @@
use std::convert::TryInto; use std::convert::TryInto;
use std::path::PathBuf; use std::path::PathBuf;
extern crate failure; extern crate anyhow;
use failure::Fallible as Result; use anyhow::Result as Result;
extern crate structopt; extern crate structopt;
use structopt::StructOpt; use structopt::StructOpt;
@ -36,11 +37,11 @@ pub struct Opt {
fn main() { fn main() {
if let Err(e) = real_main() { if let Err(e) = real_main() {
let mut cause = e.as_fail(); eprint!("{}", e);
eprint!("{}", cause); let mut cause = e.source();
while let Some(c) = cause.cause() { while let Some(c) = cause {
eprint!(":\n {}", c); eprint!(":\n {}", c);
cause = c; cause = c.source();
} }
eprintln!(); eprintln!();
::std::process::exit(2); ::std::process::exit(2);
@ -65,7 +66,7 @@ fn delete(db: &KeyDatabase, query: &Query, all_bindings: bool, mut all: bool)
} }
let tpk = db.lookup(&query)?.ok_or_else( let tpk = db.lookup(&query)?.ok_or_else(
|| failure::format_err!("No TPK matching {:?}", query))?; || anyhow::format_err!("No TPK matching {:?}", query))?;
let fp: database::types::Fingerprint = tpk.fingerprint().try_into()?; let fp: database::types::Fingerprint = tpk.fingerprint().try_into()?;
let mut results = Vec::new(); let mut results = Vec::new();

View File

@ -5,7 +5,7 @@ use std::io::{self, Read};
extern crate sequoia_openpgp as openpgp; extern crate sequoia_openpgp as openpgp;
use self::openpgp::types::{Duration, Timestamp, SymmetricAlgorithm}; use self::openpgp::types::{Duration, Timestamp, SymmetricAlgorithm};
use self::openpgp::fmt::hex; use self::openpgp::fmt::hex;
use self::openpgp::crypto::mpis; use self::openpgp::crypto::mpi;
use self::openpgp::{Packet, Result}; use self::openpgp::{Packet, Result};
use self::openpgp::packet::prelude::*; use self::openpgp::packet::prelude::*;
use self::openpgp::packet::header::CTB; use self::openpgp::packet::header::CTB;
@ -54,21 +54,36 @@ impl Convert<chrono::DateTime<chrono::offset::Utc>> for Timestamp {
} }
} }
pub fn dump<W>(input: &mut dyn io::Read, output: &mut dyn io::Write, pub fn dump<P, S, W>(input: &mut dyn io::Read, output: &mut dyn io::Write,
mpis: bool, hex: bool, sk: Option<&SessionKey>, mpis: bool, hex: bool, mut sk: Option<SessionKey>,
width: W) decrypt_pkesk: P, decrypt_skesk: S,
-> Result<Kind> width: W)
where W: Into<Option<usize>> -> Result<(Kind, Option<SessionKey>)>
where P: Fn(&PKESK) -> Option<SessionKey>,
S: Fn(&SKESK) -> Option<SessionKey>,
W: Into<Option<usize>>
{ {
let mut ppr let mut ppr
= self::openpgp::parse::PacketParserBuilder::from_reader(input)? = self::openpgp::parse::PacketParserBuilder::from_reader(input)?
.map(hex).finalize()?; .map(hex).build()?;
let mut message_encrypted = false; let mut message_encrypted = false;
let width = width.into().unwrap_or(80); let width = width.into().unwrap_or(80);
let mut dumper = PacketDumper::new(width, mpis); let mut dumper = PacketDumper::new(width, mpis);
while let PacketParserResult::Some(mut pp) = ppr { while let PacketParserResult::Some(mut pp) = ppr {
let additional_fields = match pp.packet { let additional_fields = match pp.packet {
Packet::PKESK(ref p) => {
if sk.is_none() {
sk = decrypt_pkesk(p);
}
None
},
Packet::SKESK(ref p) => {
if sk.is_none() {
sk = decrypt_skesk(p);
}
None
},
Packet::Literal(_) => { Packet::Literal(_) => {
let mut prefix = vec![0; 40]; let mut prefix = vec![0; 40];
let n = pp.read(&mut prefix)?; let n = pp.read(&mut prefix)?;
@ -126,10 +141,10 @@ pub fn dump<W>(input: &mut dyn io::Read, output: &mut dyn io::Write,
let mut fields = Vec::new(); let mut fields = Vec::new();
fields.push(format!("Session key: {}", hex::encode(sk))); fields.push(format!("Session key: {}", hex::encode(sk)));
if pp.decrypted() { if pp.encrypted() {
fields.push("Decryption successful".into());
} else {
fields.push("Decryption failed".into()); fields.push("Decryption failed".into());
} else {
fields.push("Decryption successful".into());
} }
Some(fields) Some(fields)
}, },
@ -139,31 +154,39 @@ pub fn dump<W>(input: &mut dyn io::Read, output: &mut dyn io::Write,
let header = pp.header().clone(); let header = pp.header().clone();
let map = pp.take_map(); let map = pp.take_map();
let (packet, ppr_) = pp.recurse()?; let recursion_depth = pp.recursion_depth();
ppr = ppr_; let packet = pp.packet.clone();
let recursion_depth = ppr.last_recursion_depth().unwrap();
dumper.packet(output, recursion_depth as usize, dumper.packet(output, recursion_depth as usize,
header, packet, map, additional_fields)?; header, packet, map, additional_fields)?;
let (_, ppr_) = match pp.recurse() {
Ok(v) => Ok(v),
Err(e) => {
let _ = dumper.flush(output);
Err(e)
},
}?;
ppr = ppr_;
} }
dumper.flush(output)?; dumper.flush(output)?;
if let PacketParserResult::EOF(eof) = ppr { Ok((if let PacketParserResult::EOF(eof) = ppr {
if eof.is_message().is_ok() { if eof.is_message().is_ok() {
Ok(Kind::Message { Kind::Message {
encrypted: message_encrypted, encrypted: message_encrypted,
}) }
} else if eof.is_cert().is_ok() { } else if eof.is_cert().is_ok() {
Ok(Kind::Cert) Kind::Cert
} else if eof.is_keyring().is_ok() { } else if eof.is_keyring().is_ok() {
Ok(Kind::Keyring) Kind::Keyring
} else { } else {
Ok(Kind::Unknown) Kind::Unknown
} }
} else { } else {
unreachable!() unreachable!()
} }, sk))
} }
struct Node { struct Node {
@ -274,8 +297,19 @@ impl PacketDumper {
} }
if let Some(h) = header { if let Some(h) = header {
write!(output, ", {} CTB, {}", write!(output, ", {} CTB, {}{}",
if let CTB::Old(_) = h.ctb() { "old" } else { "new" }, if let CTB::Old(_) = h.ctb() { "old" } else { "new" },
if let Some(map) = map {
format!("{} header bytes + ",
map.iter().take(2).map(|f| f.as_bytes().len())
.sum::<usize>())
} else {
// XXX: Mapping is disabled. No can do for
// now. Once we save the header in
// packet::Common, we can use this instead of
// relying on the map.
"".into()
},
match h.length() { match h.length() {
BodyLength::Full(n) => BodyLength::Full(n) =>
format!("{} bytes", n), format!("{} bytes", n),
@ -309,35 +343,35 @@ impl PacketDumper {
let ii = format!("{} ", i); let ii = format!("{} ", i);
match k.mpis() { match k.mpis() {
mpis::PublicKey::RSA { e, n } => mpi::PublicKey::RSA { e, n } =>
pd.dump_mpis(output, &ii, pd.dump_mpis(output, &ii,
&[e.value(), n.value()], &[e.value(), n.value()],
&["e", "n"])?, &["e", "n"])?,
mpis::PublicKey::DSA { p, q, g, y } => mpi::PublicKey::DSA { p, q, g, y } =>
pd.dump_mpis(output, &ii, pd.dump_mpis(output, &ii,
&[p.value(), q.value(), g.value(), &[p.value(), q.value(), g.value(),
y.value()], y.value()],
&["p", "q", "g", "y"])?, &["p", "q", "g", "y"])?,
mpis::PublicKey::Elgamal { p, g, y } => mpi::PublicKey::ElGamal { p, g, y } =>
pd.dump_mpis(output, &ii, pd.dump_mpis(output, &ii,
&[p.value(), g.value(), y.value()], &[p.value(), g.value(), y.value()],
&["p", "g", "y"])?, &["p", "g", "y"])?,
mpis::PublicKey::EdDSA { curve, q } => { mpi::PublicKey::EdDSA { curve, q } => {
writeln!(output, "{} Curve: {}", ii, curve)?; writeln!(output, "{} Curve: {}", ii, curve)?;
pd.dump_mpis(output, &ii, &[q.value()], &["q"])?; pd.dump_mpis(output, &ii, &[q.value()], &["q"])?;
}, },
mpis::PublicKey::ECDSA { curve, q } => { mpi::PublicKey::ECDSA { curve, q } => {
writeln!(output, "{} Curve: {}", ii, curve)?; writeln!(output, "{} Curve: {}", ii, curve)?;
pd.dump_mpis(output, &ii, &[q.value()], &["q"])?; pd.dump_mpis(output, &ii, &[q.value()], &["q"])?;
}, },
mpis::PublicKey::ECDH { curve, q, hash, sym } => { mpi::PublicKey::ECDH { curve, q, hash, sym } => {
writeln!(output, "{} Curve: {}", ii, curve)?; writeln!(output, "{} Curve: {}", ii, curve)?;
writeln!(output, "{} Hash algo: {}", ii, hash)?; writeln!(output, "{} Hash algo: {}", ii, hash)?;
writeln!(output, "{} Symmetric algo: {}", ii, writeln!(output, "{} Symmetric algo: {}", ii,
sym)?; sym)?;
pd.dump_mpis(output, &ii, &[q.value()], &["q"])?; pd.dump_mpis(output, &ii, &[q.value()], &["q"])?;
}, },
mpis::PublicKey::Unknown { mpis, rest } => { mpi::PublicKey::Unknown { mpis, rest } => {
let keys: Vec<String> = let keys: Vec<String> =
(0..mpis.len()).map( (0..mpis.len()).map(
|i| format!("mpi{}", i)).collect(); |i| format!("mpi{}", i)).collect();
@ -352,42 +386,47 @@ impl PacketDumper {
pd.dump_mpis(output, &ii, &[&rest[..]], &["rest"])?; pd.dump_mpis(output, &ii, &[&rest[..]], &["rest"])?;
}, },
mpi::PublicKey::__Nonexhaustive => unreachable!(),
} }
}
if let Some(secrets) = k.secret() { if let Some(secrets) = k.optional_secret() {
writeln!(output, "{}", i)?; writeln!(output, "{}", i)?;
writeln!(output, "{} Secret Key:", i)?; writeln!(output, "{} Secret Key:", i)?;
let ii = format!("{} ", i); let ii = format!("{} ", i);
match secrets { match secrets {
SecretKeyMaterial::Unencrypted(ref u) => u.map( SecretKeyMaterial::Unencrypted(ref u) => {
|mpis| -> Result<()> { writeln!(output, "{}", i)?;
writeln!(output, "{} Unencrypted", ii)?;
if pd.mpis {
u.map(|mpis| -> Result<()> {
match mpis match mpis
{ {
mpis::SecretKeyMaterial::RSA { d, p, q, u } => mpi::SecretKeyMaterial::RSA { d, p, q, u } =>
pd.dump_mpis(output, &ii, pd.dump_mpis(output, &ii,
&[d.value(), p.value(), &[d.value(), p.value(),
q.value(), u.value()], q.value(), u.value()],
&["d", "p", "q", "u"])?, &["d", "p", "q", "u"])?,
mpis::SecretKeyMaterial::DSA { x } => mpi::SecretKeyMaterial::DSA { x } =>
pd.dump_mpis(output, &ii, &[x.value()], pd.dump_mpis(output, &ii, &[x.value()],
&["x"])?, &["x"])?,
mpis::SecretKeyMaterial::Elgamal { x } => mpi::SecretKeyMaterial::ElGamal { x } =>
pd.dump_mpis(output, &ii, &[x.value()], pd.dump_mpis(output, &ii, &[x.value()],
&["x"])?, &["x"])?,
mpis::SecretKeyMaterial::EdDSA { scalar } => mpi::SecretKeyMaterial::EdDSA { scalar } =>
pd.dump_mpis(output, &ii, pd.dump_mpis(output, &ii,
&[scalar.value()], &[scalar.value()],
&["scalar"])?, &["scalar"])?,
mpis::SecretKeyMaterial::ECDSA { scalar } => mpi::SecretKeyMaterial::ECDSA { scalar } =>
pd.dump_mpis(output, &ii, pd.dump_mpis(output, &ii,
&[scalar.value()], &[scalar.value()],
&["scalar"])?, &["scalar"])?,
mpis::SecretKeyMaterial::ECDH { scalar } => mpi::SecretKeyMaterial::ECDH { scalar } =>
pd.dump_mpis(output, &ii, pd.dump_mpis(output, &ii,
&[scalar.value()], &[scalar.value()],
&["scalar"])?, &["scalar"])?,
mpis::SecretKeyMaterial::Unknown { mpis, rest } => { mpi::SecretKeyMaterial::Unknown { mpis, rest } => {
let keys: Vec<String> = let keys: Vec<String> =
(0..mpis.len()).map( (0..mpis.len()).map(
|i| format!("mpi{}", i)).collect(); |i| format!("mpi{}", i)).collect();
@ -401,19 +440,29 @@ impl PacketDumper {
)?; )?;
pd.dump_mpis(output, &ii, &[rest], pd.dump_mpis(output, &ii, &[rest],
&["rest"])?; &["rest"])?;
}, },
} Ok(()) })?, mpi::SecretKeyMaterial::__Nonexhaustive =>
SecretKeyMaterial::Encrypted(ref e) => { unreachable!(),
writeln!(output, "{}", i)?; }
write!(output, "{} S2K: ", ii)?; Ok(())
pd.dump_s2k(output, &ii, e.s2k())?; })?;
writeln!(output, "{} Sym. algo: {}", ii, }
e.algo())?;
pd.dump_mpis(output, &ii, &[e.ciphertext()],
&["ciphertext"])?;
},
} }
SecretKeyMaterial::Encrypted(ref e) => {
writeln!(output, "{}", i)?;
writeln!(output, "{} Encrypted", ii)?;
write!(output, "{} S2K: ", ii)?;
pd.dump_s2k(output, &ii, e.s2k())?;
writeln!(output, "{} Sym. algo: {}", ii,
e.algo())?;
if pd.mpis {
if let Ok(ciphertext) = e.ciphertext() {
pd.dump_mpis(output, &ii, &[ciphertext],
&["ciphertext"])?;
}
}
},
} }
} }
@ -464,27 +513,27 @@ impl PacketDumper {
let ii = format!("{} ", i); let ii = format!("{} ", i);
match s.mpis() { match s.mpis() {
mpis::Signature::RSA { s } => mpi::Signature::RSA { s } =>
self.dump_mpis(output, &ii, self.dump_mpis(output, &ii,
&[s.value()], &[s.value()],
&["s"])?, &["s"])?,
mpis::Signature::DSA { r, s } => mpi::Signature::DSA { r, s } =>
self.dump_mpis(output, &ii, self.dump_mpis(output, &ii,
&[r.value(), s.value()], &[r.value(), s.value()],
&["r", "s"])?, &["r", "s"])?,
mpis::Signature::Elgamal { r, s } => mpi::Signature::ElGamal { r, s } =>
self.dump_mpis(output, &ii, self.dump_mpis(output, &ii,
&[r.value(), s.value()], &[r.value(), s.value()],
&["r", "s"])?, &["r", "s"])?,
mpis::Signature::EdDSA { r, s } => mpi::Signature::EdDSA { r, s } =>
self.dump_mpis(output, &ii, self.dump_mpis(output, &ii,
&[r.value(), s.value()], &[r.value(), s.value()],
&["r", "s"])?, &["r", "s"])?,
mpis::Signature::ECDSA { r, s } => mpi::Signature::ECDSA { r, s } =>
self.dump_mpis(output, &ii, self.dump_mpis(output, &ii,
&[r.value(), s.value()], &[r.value(), s.value()],
&["r", "s"])?, &["r", "s"])?,
mpis::Signature::Unknown { mpis, rest } => { mpi::Signature::Unknown { mpis, rest } => {
let keys: Vec<String> = let keys: Vec<String> =
(0..mpis.len()).map( (0..mpis.len()).map(
|i| format!("mpi{}", i)).collect(); |i| format!("mpi{}", i)).collect();
@ -499,6 +548,8 @@ impl PacketDumper {
self.dump_mpis(output, &ii, &[&rest[..]], &["rest"])?; self.dump_mpis(output, &ii, &[&rest[..]], &["rest"])?;
}, },
mpi::Signature::__Nonexhaustive => unreachable!(),
} }
} }
}, },
@ -580,19 +631,19 @@ impl PacketDumper {
let ii = format!("{} ", i); let ii = format!("{} ", i);
match p.esk() { match p.esk() {
mpis::Ciphertext::RSA { c } => mpi::Ciphertext::RSA { c } =>
self.dump_mpis(output, &ii, self.dump_mpis(output, &ii,
&[c.value()], &[c.value()],
&["c"])?, &["c"])?,
mpis::Ciphertext::Elgamal { e, c } => mpi::Ciphertext::ElGamal { e, c } =>
self.dump_mpis(output, &ii, self.dump_mpis(output, &ii,
&[e.value(), c.value()], &[e.value(), c.value()],
&["e", "c"])?, &["e", "c"])?,
mpis::Ciphertext::ECDH { e, key } => mpi::Ciphertext::ECDH { e, key } =>
self.dump_mpis(output, &ii, self.dump_mpis(output, &ii,
&[e.value(), key], &[e.value(), key],
&["e", "key"])?, &["e", "key"])?,
mpis::Ciphertext::Unknown { mpis, rest } => { mpi::Ciphertext::Unknown { mpis, rest } => {
let keys: Vec<String> = let keys: Vec<String> =
(0..mpis.len()).map( (0..mpis.len()).map(
|i| format!("mpi{}", i)).collect(); |i| format!("mpi{}", i)).collect();
@ -607,6 +658,7 @@ impl PacketDumper {
self.dump_mpis(output, &ii, &[rest], &["rest"])?; self.dump_mpis(output, &ii, &[rest], &["rest"])?;
}, },
mpi::Ciphertext::__Nonexhaustive => unreachable!(),
} }
} }
}, },
@ -619,7 +671,7 @@ impl PacketDumper {
s.symmetric_algo())?; s.symmetric_algo())?;
write!(output, "{} S2K: ", i)?; write!(output, "{} S2K: ", i)?;
self.dump_s2k(output, i, s.s2k())?; self.dump_s2k(output, i, s.s2k())?;
if let Some(esk) = s.esk() { if let Ok(Some(esk)) = s.esk() {
writeln!(output, "{} ESK: {}", i, writeln!(output, "{} ESK: {}", i,
hex::encode(esk))?; hex::encode(esk))?;
} }
@ -632,9 +684,11 @@ impl PacketDumper {
s.aead_algo())?; s.aead_algo())?;
write!(output, "{} S2K: ", i)?; write!(output, "{} S2K: ", i)?;
self.dump_s2k(output, i, s.s2k())?; self.dump_s2k(output, i, s.s2k())?;
writeln!(output, "{} IV: {}", i, if let Ok(iv) = s.aead_iv() {
hex::encode(s.aead_iv()))?; writeln!(output, "{} IV: {}", i,
if let Some(esk) = s.esk() { hex::encode(iv))?;
}
if let Ok(Some(esk)) = s.esk() {
writeln!(output, "{} ESK: {}", i, writeln!(output, "{} ESK: {}", i,
hex::encode(esk))?; hex::encode(esk))?;
} }
@ -685,24 +739,9 @@ impl PacketDumper {
for field in map.iter() { for field in map.iter() {
if field.name() == "body" { if field.name() == "body" {
hd.write_labeled(field.data(), |offset, data| { hd.write_ascii(field.as_bytes())?;
let mut l = String::new();
for _ in 0..offset {
l.push(' ');
}
for &c in data {
l.push(if c < 32 {
'.'
} else if c < 128 {
c.into()
} else {
'.'
})
}
Some(l)
})?;
} else { } else {
hd.write(field.data(), field.name())?; hd.write(field.as_bytes(), field.name())?;
} }
} }
@ -761,10 +800,15 @@ impl PacketDumper {
write!(output, "{} Symmetric algo preferences: {}", i, write!(output, "{} Symmetric algo preferences: {}", i,
c.iter().map(|c| format!("{:?}", c)) c.iter().map(|c| format!("{:?}", c))
.collect::<Vec<String>>().join(", "))?, .collect::<Vec<String>>().join(", "))?,
RevocationKey{class, pk_algo, ref fp} => RevocationKey(rk) => {
let (pk_algo, fp) = rk.revoker();
write!(output, write!(output,
"{} Revocation key: class {} algo {} fingerprint {}", i, "{} Revocation key: {}/{}", i,
class, pk_algo, fp)?, fp, pk_algo)?;
if rk.sensitive() {
write!(output, ", sensitive")?;
}
},
Issuer(ref is) => Issuer(ref is) =>
write!(output, "{} Issuer: {}", i, is)?, write!(output, "{} Issuer: {}", i, is)?,
NotationData(ref n) => NotationData(ref n) =>
@ -842,6 +886,7 @@ impl PacketDumper {
fn dump_s2k(&self, output: &mut dyn io::Write, i: &str, s2k: &S2K) fn dump_s2k(&self, output: &mut dyn io::Write, i: &str, s2k: &S2K)
-> Result<()> { -> Result<()> {
use self::S2K::*; use self::S2K::*;
#[allow(deprecated)]
match s2k { match s2k {
Simple { hash } => { Simple { hash } => {
writeln!(output, "Simple")?; writeln!(output, "Simple")?;
@ -858,10 +903,21 @@ impl PacketDumper {
writeln!(output, "{} Salt: {}", i, hex::encode(salt))?; writeln!(output, "{} Salt: {}", i, hex::encode(salt))?;
writeln!(output, "{} Hash bytes: {}", i, hash_bytes)?; writeln!(output, "{} Hash bytes: {}", i, hash_bytes)?;
}, },
Private(n) => Private { tag, parameters } => {
writeln!(output, "Private({})", n)?, writeln!(output, "Private")?;
Unknown(n) => writeln!(output, "{} Tag: {}", i, tag)?;
writeln!(output, "Unknown({})", n)?, if let Some(p) = parameters.as_ref() {
writeln!(output, "{} Parameters: {:?}", i, p)?;
}
},
Unknown { tag, parameters } => {
writeln!(output, "Unknown")?;
writeln!(output, "{} Tag: {}", i, tag)?;
if let Some(p) = parameters.as_ref() {
writeln!(output, "{} Parameters: {:?}", i, p)?;
}
},
__Nonexhaustive => unreachable!(),
} }
Ok(()) Ok(())
} }
@ -902,6 +958,4 @@ impl PacketDumper {
format!("{} ", &i.chars().take(amount).collect::<String>()) format!("{} ", &i.chars().take(amount).collect::<String>())
} }
} }

View File

@ -1,6 +1,6 @@
use std::path::{PathBuf, Path}; use std::path::{PathBuf, Path};
use failure; use anyhow;
use handlebars::Handlebars; use handlebars::Handlebars;
use lettre::{Transport as LettreTransport, SendmailTransport, file::FileTransport}; use lettre::{Transport as LettreTransport, SendmailTransport, file::FileTransport};
use lettre::builder::{EmailBuilder, PartBuilder, Mailbox, MimeMultipartType}; use lettre::builder::{EmailBuilder, PartBuilder, Mailbox, MimeMultipartType};
@ -77,7 +77,7 @@ impl Service {
let templates = template_helpers::load_handlebars(template_dir)?; let templates = template_helpers::load_handlebars(template_dir)?;
let domain = let domain =
url::Url::parse(base_uri) url::Url::parse(base_uri)
?.host_str().ok_or_else(|| failure::err_msg("No host in base-URI")) ?.host_str().ok_or_else(|| anyhow!("No host in base-URI"))
?.to_string(); ?.to_string();
Ok(Self { from: from.into(), domain, templates, transport }) Ok(Self { from: from.into(), domain, templates, transport })
} }
@ -208,10 +208,10 @@ impl Service {
) -> Result<(String, String)> { ) -> Result<(String, String)> {
let html = self.templates.render(&format!("{}/{}.htm", locale, template), &ctx) let html = self.templates.render(&format!("{}/{}.htm", locale, template), &ctx)
.or_else(|_| self.templates.render(&format!("{}.htm", template), &ctx)) .or_else(|_| self.templates.render(&format!("{}.htm", template), &ctx))
.map_err(|_| failure::err_msg("Email template failed to render"))?; .map_err(|_| anyhow!("Email template failed to render"))?;
let txt = self.templates.render(&format!("{}/{}.txt", locale, template), &ctx) let txt = self.templates.render(&format!("{}/{}.txt", locale, template), &ctx)
.or_else(|_| self.templates.render(&format!("{}.txt", template), &ctx)) .or_else(|_| self.templates.render(&format!("{}.txt", template), &ctx))
.map_err(|_| failure::err_msg("Email template failed to render"))?; .map_err(|_| anyhow!("Email template failed to render"))?;
Ok((html, txt)) Ok((html, txt))
} }

View File

@ -1,7 +1,9 @@
#![feature(proc_macro_hygiene, plugin, decl_macro)] #![feature(proc_macro_hygiene, plugin, decl_macro)]
#![recursion_limit = "1024"] #![recursion_limit = "1024"]
use failure::Fallible as Result; #[macro_use]
extern crate anyhow;
use anyhow::Result as Result;
#[macro_use] #[macro_use]
extern crate serde_derive; extern crate serde_derive;
@ -34,11 +36,11 @@ mod template_helpers;
fn main() { fn main() {
if let Err(e) = web::serve() { if let Err(e) = web::serve() {
let mut cause = e.as_fail(); eprint!("{}", e);
eprint!("{}", cause); let mut cause = e.source();
while let Some(c) = cause.cause() { while let Some(c) = cause {
eprint!(":\n {}", c); eprint!(":\n {}", c);
cause = c; cause = c.source();
} }
eprintln!(); eprintln!();

View File

@ -40,19 +40,19 @@ impl Service {
pub fn check<T>(&self, token_encoded: &str) -> Result<T> pub fn check<T>(&self, token_encoded: &str) -> Result<T>
where T: StatelessSerializable { where T: StatelessSerializable {
let token_sealed = base64::decode_config(&token_encoded, base64::URL_SAFE_NO_PAD) let token_sealed = base64::decode_config(&token_encoded, base64::URL_SAFE_NO_PAD)
.map_err(|_| failure::err_msg("invalid b64"))?; .map_err(|_| anyhow!("invalid b64"))?;
let token_str = self.sealed_state.unseal(token_sealed) let token_str = self.sealed_state.unseal(token_sealed)
.map_err(|_| failure::err_msg("failed to validate"))?; .map_err(|_| anyhow!("failed to validate"))?;
let token: Token = serde_json::from_str(&token_str) let token: Token = serde_json::from_str(&token_str)
.map_err(|_| failure::err_msg("failed to deserialize"))?; .map_err(|_| anyhow!("failed to deserialize"))?;
let elapsed = current_time() - token.creation; let elapsed = current_time() - token.creation;
if elapsed > self.validity { if elapsed > self.validity {
Err(failure::err_msg("Token has expired!"))?; Err(anyhow!("Token has expired!"))?;
} }
let payload: T = serde_json::from_str(&token.payload) let payload: T = serde_json::from_str(&token.payload)
.map_err(|_| failure::err_msg("failed to deserialize payload"))?; .map_err(|_| anyhow!("failed to deserialize payload"))?;
Ok(payload) Ok(payload)
} }

View File

@ -31,16 +31,18 @@ pub fn debug_info(
false, false,
false, false,
None, None,
|_| { None },
|_| { None },
32 * 4 + 80, 32 * 4 + 80,
); );
match dump_result { match dump_result {
Ok(Kind::Cert) => { Ok((Kind::Cert, _)) => {
match String::from_utf8(result) { match String::from_utf8(result) {
Ok(dump_text) => MyResponse::plain(dump_text), Ok(dump_text) => MyResponse::plain(dump_text),
Err(e) => MyResponse::ise(e.into()), Err(e) => MyResponse::ise(e.into()),
} }
}, },
Ok(_) => MyResponse::ise(failure::err_msg("Internal parsing error!")), Ok(_) => MyResponse::ise(anyhow!("Internal parsing error!")),
Err(e) => MyResponse::ise(e), Err(e) => MyResponse::ise(e),
} }
} }

View File

@ -254,7 +254,7 @@ pub fn pks_internal_index(
fn key_to_hkp_index(db: rocket::State<KeyDatabase>, query: Query) fn key_to_hkp_index(db: rocket::State<KeyDatabase>, query: Query)
-> MyResponse { -> MyResponse {
use sequoia_openpgp::RevocationStatus; use sequoia_openpgp::types::RevocationStatus;
use sequoia_openpgp::policy::StandardPolicy; use sequoia_openpgp::policy::StandardPolicy;
let tpk = match db.lookup(&query) { let tpk = match db.lookup(&query) {
@ -269,7 +269,7 @@ fn key_to_hkp_index(db: rocket::State<KeyDatabase>, query: Query)
let ctime = format!("{}", p.creation_time().duration_since(SystemTime::UNIX_EPOCH).unwrap().as_secs()); let ctime = format!("{}", p.creation_time().duration_since(SystemTime::UNIX_EPOCH).unwrap().as_secs());
let is_rev = let is_rev =
if tpk.revoked(policy, None) != RevocationStatus::NotAsFarAsWeKnow { if tpk.revocation_status(policy, None) != RevocationStatus::NotAsFarAsWeKnow {
"r" "r"
} else { } else {
"" ""
@ -288,16 +288,17 @@ fn key_to_hkp_index(db: rocket::State<KeyDatabase>, query: Query)
is_rev is_rev
)); ));
for uid in tpk.userids().bundles() { for uid in tpk.userids() {
let uidstr = uid.userid().to_string(); let uidstr = uid.userid().to_string();
let u = Uri::percent_encode(&uidstr); let u = Uri::percent_encode(&uidstr);
let ctime = uid let ctime = uid
.binding_signature(policy, None) .binding_signature(policy, None)
.ok()
.and_then(|x| x.signature_creation_time()) .and_then(|x| x.signature_creation_time())
.and_then(|time| time.duration_since(SystemTime::UNIX_EPOCH).ok()) .and_then(|time| time.duration_since(SystemTime::UNIX_EPOCH).ok())
.map(|x| format!("{}", x.as_secs())) .map(|x| format!("{}", x.as_secs()))
.unwrap_or_default(); .unwrap_or_default();
let is_rev = if uid.revoked(policy, None) let is_rev = if uid.revocation_status(policy, None)
!= RevocationStatus::NotAsFarAsWeKnow != RevocationStatus::NotAsFarAsWeKnow
{ {
"r" "r"

View File

@ -3,7 +3,7 @@ use rocket::State;
use rocket::request::Form; use rocket::request::Form;
use rocket_i18n::I18n; use rocket_i18n::I18n;
use failure::Fallible as Result; use crate::Result;
use gettext_macros::i18n; use gettext_macros::i18n;
@ -143,7 +143,7 @@ pub fn vks_manage_post(
if !email_exists { if !email_exists {
return MyResponse::ise( return MyResponse::ise(
failure::err_msg("Internal error: address check failed!")); anyhow!("Internal error: address check failed!"));
} }
if !rate_limiter.action_perform(format!("manage-{}", &email)) { if !rate_limiter.action_perform(format!("manage-{}", &email)) {

View File

@ -143,7 +143,7 @@ impl MyResponse {
}) })
} }
pub fn ise(e: failure::Error) -> Self { pub fn ise(e: anyhow::Error) -> Self {
eprintln!("Internal error: {:?}", e); eprintln!("Internal error: {:?}", e);
let ctx = templates::FiveHundred { let ctx = templates::FiveHundred {
internal_error: e.to_string(), internal_error: e.to_string(),
@ -154,7 +154,7 @@ impl MyResponse {
MyResponse::ServerError(Template::render("500", ctx)) MyResponse::ServerError(Template::render("500", ctx))
} }
pub fn bad_request(template: &'static str, e: failure::Error) -> Self { pub fn bad_request(template: &'static str, e: anyhow::Error) -> Self {
let ctx = templates::Error { error: format!("{}", e) }; let ctx = templates::Error { error: format!("{}", e) };
let context_json = serde_json::to_value(ctx).unwrap(); let context_json = serde_json::to_value(ctx).unwrap();
MyResponse::BadRequest(HagridTemplate(template, context_json)) MyResponse::BadRequest(HagridTemplate(template, context_json))
@ -361,10 +361,10 @@ fn errors(
template: String, template: String,
) -> Result<Custom<Template>> { ) -> Result<Custom<Template>> {
if !template.chars().all(|x| x == '-' || char::is_ascii_alphabetic(&x)) { if !template.chars().all(|x| x == '-' || char::is_ascii_alphabetic(&x)) {
return Err(failure::err_msg("bad request")); return Err(anyhow!("bad request"));
} }
let status_code = Status::from_code(code) let status_code = Status::from_code(code)
.ok_or(failure::err_msg("bad request"))?; .ok_or(anyhow!("bad request"))?;
let response_body = Template::render( let response_body = Template::render(
format!("errors/{}-{}", code, template), format!("errors/{}-{}", code, template),
templates::HagridLayout::new(templates::Bare{dummy: ()}, i18n, origin) templates::HagridLayout::new(templates::Bare{dummy: ()}, i18n, origin)

View File

@ -1,4 +1,4 @@
use failure::Fallible as Result; use crate::Result;
use crate::database::{Database, KeyDatabase, StatefulTokens, EmailAddressStatus, TpkStatus, ImportResult}; use crate::database::{Database, KeyDatabase, StatefulTokens, EmailAddressStatus, TpkStatus, ImportResult};
use crate::database::types::{Fingerprint,Email}; use crate::database::types::{Fingerprint,Email};
@ -12,6 +12,9 @@ use rocket_i18n::I18n;
use gettext_macros::i18n; use gettext_macros::i18n;
use sequoia_openpgp::Cert; use sequoia_openpgp::Cert;
use sequoia_openpgp::parse::{Parse, PacketParserBuilder, Dearmor};
use sequoia_openpgp::cert::CertParser;
use sequoia_openpgp::armor::ReaderMode;
use std::io::Read; use std::io::Read;
use std::convert::TryFrom; use std::convert::TryFrom;
@ -98,17 +101,13 @@ pub fn process_key(
rate_limiter: &RateLimiter, rate_limiter: &RateLimiter,
reader: impl Read, reader: impl Read,
) -> response::UploadResponse { ) -> response::UploadResponse {
use sequoia_openpgp::parse::{Parse, PacketParserBuilder, Dearmor};
use sequoia_openpgp::cert::CertParser;
use sequoia_openpgp::armor::ReaderMode;
// First, parse all Certs and error out if one fails. // First, parse all Certs and error out if one fails.
let parser = match PacketParserBuilder::from_reader(reader) let parser = match PacketParserBuilder::from_reader(reader)
.and_then(|ppb| { .and_then(|ppb| {
ppb.dearmor(Dearmor::Auto(ReaderMode::VeryTolerant)).finalize() ppb.dearmor(Dearmor::Auto(ReaderMode::VeryTolerant)).build()
}) })
{ {
Ok(ppr) => CertParser::from_packet_parser(ppr), Ok(ppr) => CertParser::from(ppr),
Err(_) => return UploadResponse::err(i18n!(i18n.catalog, "Parsing of key data failed.")), Err(_) => return UploadResponse::err(i18n!(i18n.catalog, "Parsing of key data failed.")),
}; };
let mut tpks = Vec::new(); let mut tpks = Vec::new();
@ -244,7 +243,7 @@ fn check_tpk_state(
token: &str, token: &str,
) -> Result<(VerifyTpkState,TpkStatus)> { ) -> Result<(VerifyTpkState,TpkStatus)> {
let verify_state = token_stateless.check::<VerifyTpkState>(token) let verify_state = token_stateless.check::<VerifyTpkState>(token)
.map_err(|_| failure::err_msg(i18n!( .map_err(|_| anyhow!(i18n!(
i18n.catalog, i18n.catalog,
"Upload session expired. Please try again." "Upload session expired. Please try again."
)))?; )))?;

View File

@ -1,5 +1,4 @@
use failure; use crate::Result;
use failure::Fallible as Result;
use multipart::server::save::Entries; use multipart::server::save::Entries;
use multipart::server::save::SaveResult::*; use multipart::server::save::SaveResult::*;
@ -105,7 +104,7 @@ impl MyResponse {
UploadResponse::OkMulti { key_fprs } => UploadResponse::OkMulti { key_fprs } =>
MyResponse::plain(format!("Uploaded {} keys. For verification, please upload keys individually.\n", key_fprs.len())), MyResponse::plain(format!("Uploaded {} keys. For verification, please upload keys individually.\n", key_fprs.len())),
UploadResponse::Error(error) => MyResponse::bad_request( UploadResponse::Error(error) => MyResponse::bad_request(
"400-plain", failure::err_msg(error)), "400-plain", anyhow!(error)),
} }
} }
@ -116,7 +115,7 @@ impl MyResponse {
UploadResponse::OkMulti { key_fprs } => UploadResponse::OkMulti { key_fprs } =>
Self::upload_ok_multi(key_fprs), Self::upload_ok_multi(key_fprs),
UploadResponse::Error(error) => MyResponse::bad_request( UploadResponse::Error(error) => MyResponse::bad_request(
"upload/upload", failure::err_msg(error)), "upload/upload", anyhow!(error)),
} }
} }
@ -217,7 +216,7 @@ pub fn process_post_form_data(
let (_, boundary) = cont_type let (_, boundary) = cont_type
.params() .params()
.find(|&(k, _)| k == "boundary") .find(|&(k, _)| k == "boundary")
.ok_or_else(|| failure::err_msg("`Content-Type: multipart/form-data` \ .ok_or_else(|| anyhow!("`Content-Type: multipart/form-data` \
boundary param not provided"))?; boundary param not provided"))?;
process_upload(&db, &tokens_stateless, &rate_limiter, &i18n, data, boundary) process_upload(&db, &tokens_stateless, &rate_limiter, &i18n, data, boundary)
@ -304,7 +303,7 @@ pub fn quick_upload(
let mut buf = Vec::default(); let mut buf = Vec::default();
if let Err(error) = std::io::copy(&mut data.open().take(UPLOAD_LIMIT), &mut buf) { if let Err(error) = std::io::copy(&mut data.open().take(UPLOAD_LIMIT), &mut buf) {
return MyResponse::bad_request("400-plain", failure::err_msg(error)); return MyResponse::bad_request("400-plain", anyhow!(error));
} }
MyResponse::upload_response_quick( MyResponse::upload_response_quick(
@ -367,7 +366,7 @@ pub fn process_post_form(
for item in FormItems::from(&*String::from_utf8_lossy(&buf)) { for item in FormItems::from(&*String::from_utf8_lossy(&buf)) {
let (key, value) = item.key_value(); let (key, value) = item.key_value();
let decoded_value = value.url_decode().or_else(|_| { let decoded_value = value.url_decode().or_else(|_| {
Err(failure::err_msg( Err(anyhow!(
"`Content-Type: application/x-www-form-urlencoded` \ "`Content-Type: application/x-www-form-urlencoded` \
not valid")) not valid"))
})?; })?;
@ -386,7 +385,7 @@ pub fn process_post_form(
} }
} }
Err(failure::err_msg("No keytext found")) Err(anyhow!("No keytext found"))
} }
@ -424,8 +423,8 @@ fn process_multipart(
let reader = ent[0].data.readable()?; let reader = ent[0].data.readable()?;
Ok(vks::process_key(db, i18n, tokens_stateless, rate_limiter, reader)) Ok(vks::process_key(db, i18n, tokens_stateless, rate_limiter, reader))
} }
Some(_) => Err(failure::err_msg("Multiple keytexts found")), Some(_) => Err(anyhow!("Multiple keytexts found")),
None => Err(failure::err_msg("No keytext found")), None => Err(anyhow!("No keytext found")),
} }
} }
@ -488,9 +487,9 @@ pub fn verify_confirm(
}, },
PublishResponse::Error(error) => { PublishResponse::Error(error) => {
let error_msg = if rate_limiter.action_check(rate_limit_id) { let error_msg = if rate_limiter.action_check(rate_limit_id) {
failure::err_msg(error) anyhow!(error)
} else { } else {
failure::err_msg(i18n!(i18n.catalog, "This address has already been verified.")) anyhow!(i18n!(i18n.catalog, "This address has already been verified."))
}; };
MyResponse::bad_request("400", error_msg) MyResponse::bad_request("400", error_msg)
} }