Your locally hosted lumina server for IDAPro

Compare changes

Choose any two refs to compare.

-4
CHANGELOG.md
··· 2 3 ## [Unreleased] - _TBD_ 4 5 - ### Added 6 - 7 - - User management 8 - 9 ## [v0.4.0] - 2024-03-19 10 11 ### Added
··· 2 3 ## [Unreleased] - _TBD_ 4 5 ## [v0.4.0] - 2024-03-19 6 7 ### Added
+394 -414
Cargo.lock
··· 4 5 [[package]] 6 name = "addr2line" 7 - version = "0.21.0" 8 source = "registry+https://github.com/rust-lang/crates.io-index" 9 - checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" 10 dependencies = [ 11 "gimli", 12 ] ··· 28 29 [[package]] 30 name = "anstream" 31 - version = "0.6.13" 32 source = "registry+https://github.com/rust-lang/crates.io-index" 33 - checksum = "d96bd03f33fe50a863e394ee9718a706f988b9079b20c3784fb726e7678b62fb" 34 dependencies = [ 35 "anstyle", 36 "anstyle-parse", 37 "anstyle-query", 38 "anstyle-wincon", 39 "colorchoice", 40 "utf8parse", 41 ] 42 43 [[package]] 44 name = "anstyle" 45 - version = "1.0.6" 46 source = "registry+https://github.com/rust-lang/crates.io-index" 47 - checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc" 48 49 [[package]] 50 name = "anstyle-parse" 51 - version = "0.2.3" 52 source = "registry+https://github.com/rust-lang/crates.io-index" 53 - checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c" 54 dependencies = [ 55 "utf8parse", 56 ] 57 58 [[package]] 59 name = "anstyle-query" 60 - version = "1.0.2" 61 source = "registry+https://github.com/rust-lang/crates.io-index" 62 - checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648" 63 dependencies = [ 64 "windows-sys 0.52.0", 65 ] 66 67 [[package]] 68 name = "anstyle-wincon" 69 - version = "3.0.2" 70 source = "registry+https://github.com/rust-lang/crates.io-index" 71 - checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7" 72 dependencies = [ 73 "anstyle", 74 "windows-sys 0.52.0", ··· 76 77 [[package]] 78 name = "anyhow" 79 - version = "1.0.81" 80 source = "registry+https://github.com/rust-lang/crates.io-index" 81 - checksum = "0952808a6c2afd1aa8947271f3a60f1a6763c7b912d210184c5149b5cf147247" 82 83 [[package]] 84 name = "async-trait" 85 - version = "0.1.78" 86 source = "registry+https://github.com/rust-lang/crates.io-index" 87 - checksum = "461abc97219de0eaaf81fe3ef974a540158f3d079c2ab200f891f1a2ef201e85" 88 dependencies = [ 89 "proc-macro2", 90 "quote", ··· 93 94 [[package]] 95 name = "autocfg" 96 - version = "1.1.0" 97 source = "registry+https://github.com/rust-lang/crates.io-index" 98 - checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" 99 100 [[package]] 101 name = "backtrace" 102 - version = "0.3.70" 103 source = "registry+https://github.com/rust-lang/crates.io-index" 104 - checksum = "95d8e92cac0961e91dbd517496b00f7e9b92363dbe6d42c3198268323798860c" 105 dependencies = [ 106 "addr2line", 107 "cc", ··· 119 checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" 120 121 [[package]] 122 name = "bb8" 123 - version = "0.8.3" 124 source = "registry+https://github.com/rust-lang/crates.io-index" 125 - checksum = "df7c2093d15d6a1d33b1f972e1c5ea3177748742b97a5f392aa83a65262c6780" 126 dependencies = [ 127 "async-trait", 128 - "futures-channel", 129 "futures-util", 130 "parking_lot", 131 "tokio", ··· 145 146 [[package]] 147 name = "bitflags" 148 - version = "2.5.0" 149 source = "registry+https://github.com/rust-lang/crates.io-index" 150 - checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" 151 152 [[package]] 153 name = "block-buffer" ··· 160 161 [[package]] 162 name = "bumpalo" 163 - version = "3.15.4" 164 source = "registry+https://github.com/rust-lang/crates.io-index" 165 - checksum = "7ff69b9dd49fd426c69a0db9fc04dd934cdb6645ff000864d98f7e2af8830eaa" 166 167 [[package]] 168 name = "byteorder" ··· 172 173 [[package]] 174 name = "bytes" 175 - version = "1.5.0" 176 source = "registry+https://github.com/rust-lang/crates.io-index" 177 - checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" 178 179 [[package]] 180 name = "cc" 181 - version = "1.0.90" 182 source = "registry+https://github.com/rust-lang/crates.io-index" 183 - checksum = "8cd6604a82acf3039f1144f54b8eb34e91ffba622051189e71b781822d5ee1f5" 184 185 [[package]] 186 name = "cfg-if" ··· 190 191 [[package]] 192 name = "clap" 193 - version = "4.5.3" 194 source = "registry+https://github.com/rust-lang/crates.io-index" 195 - checksum = "949626d00e063efc93b6dca932419ceb5432f99769911c0b995f7e884c778813" 196 dependencies = [ 197 "clap_builder", 198 ] 199 200 [[package]] 201 name = "clap_builder" 202 - version = "4.5.2" 203 source = "registry+https://github.com/rust-lang/crates.io-index" 204 - checksum = "ae129e2e766ae0ec03484e609954119f123cc1fe650337e155d03b022f24f7b4" 205 dependencies = [ 206 "anstream", 207 "anstyle", ··· 211 212 [[package]] 213 name = "clap_lex" 214 - version = "0.7.0" 215 source = "registry+https://github.com/rust-lang/crates.io-index" 216 - checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce" 217 218 [[package]] 219 name = "colorchoice" 220 - version = "1.0.0" 221 source = "registry+https://github.com/rust-lang/crates.io-index" 222 - checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" 223 224 [[package]] 225 name = "common" ··· 232 "futures-util", 233 "log", 234 "native-tls", 235 - "pbkdf2", 236 "postgres-native-tls", 237 "prometheus-client", 238 - "rand", 239 "serde", 240 - "sha2", 241 "time", 242 "tokio", 243 "tokio-postgres", ··· 257 258 [[package]] 259 name = "core-foundation-sys" 260 - version = "0.8.6" 261 source = "registry+https://github.com/rust-lang/crates.io-index" 262 - checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" 263 264 [[package]] 265 name = "cpufeatures" 266 - version = "0.2.12" 267 source = "registry+https://github.com/rust-lang/crates.io-index" 268 - checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" 269 dependencies = [ 270 "libc", 271 ] ··· 281 ] 282 283 [[package]] 284 name = "data-encoding" 285 - version = "2.5.0" 286 source = "registry+https://github.com/rust-lang/crates.io-index" 287 - checksum = "7e962a19be5cfc3f3bf6dd8f61eb50107f356ad6270fbb3ed41476571db78be5" 288 289 [[package]] 290 name = "deranged" ··· 297 298 [[package]] 299 name = "diesel" 300 - version = "2.1.5" 301 source = "registry+https://github.com/rust-lang/crates.io-index" 302 - checksum = "03fc05c17098f21b89bc7d98fe1dd3cce2c11c2ad8e145f2a44fe08ed28eb559" 303 dependencies = [ 304 - "bitflags 2.5.0", 305 "byteorder", 306 "diesel_derives", 307 "itoa", ··· 310 311 [[package]] 312 name = "diesel-async" 313 - version = "0.4.1" 314 source = "registry+https://github.com/rust-lang/crates.io-index" 315 - checksum = "acada1517534c92d3f382217b485db8a8638f111b0e3f2a2a8e26165050f77be" 316 dependencies = [ 317 "async-trait", 318 "bb8", ··· 325 326 [[package]] 327 name = "diesel_derives" 328 - version = "2.1.3" 329 source = "registry+https://github.com/rust-lang/crates.io-index" 330 - checksum = "5d02eecb814ae714ffe61ddc2db2dd03e6c49a42e269b5001355500d431cce0c" 331 dependencies = [ 332 "diesel_table_macro_syntax", 333 "proc-macro2", 334 "quote", 335 "syn", ··· 337 338 [[package]] 339 name = "diesel_table_macro_syntax" 340 - version = "0.1.0" 341 source = "registry+https://github.com/rust-lang/crates.io-index" 342 - checksum = "fc5557efc453706fed5e4fa85006fe9817c224c3f480a34c7e5959fd700921c5" 343 dependencies = [ 344 "syn", 345 ] ··· 356 ] 357 358 [[package]] 359 name = "dtoa" 360 version = "1.0.9" 361 source = "registry+https://github.com/rust-lang/crates.io-index" 362 checksum = "dcbb2bf8e87535c23f7a8a321e364ce21462d0ff10cb6407820e8e96dfff6653" 363 364 [[package]] 365 name = "encoding_rs" 366 - version = "0.8.33" 367 source = "registry+https://github.com/rust-lang/crates.io-index" 368 - checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1" 369 dependencies = [ 370 "cfg-if", 371 ] ··· 391 392 [[package]] 393 name = "errno" 394 - version = "0.3.8" 395 source = "registry+https://github.com/rust-lang/crates.io-index" 396 - checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" 397 dependencies = [ 398 "libc", 399 "windows-sys 0.52.0", ··· 407 408 [[package]] 409 name = "fastrand" 410 - version = "2.0.1" 411 source = "registry+https://github.com/rust-lang/crates.io-index" 412 - checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" 413 - 414 - [[package]] 415 - name = "finl_unicode" 416 - version = "1.2.0" 417 - source = "registry+https://github.com/rust-lang/crates.io-index" 418 - checksum = "8fcfdc7a0362c9f4444381a9e697c79d435fe65b52a37466fc2c1184cee9edc6" 419 420 [[package]] 421 name = "fnv" ··· 548 549 [[package]] 550 name = "getrandom" 551 - version = "0.2.12" 552 source = "registry+https://github.com/rust-lang/crates.io-index" 553 - checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5" 554 dependencies = [ 555 "cfg-if", 556 "libc", ··· 559 560 [[package]] 561 name = "gimli" 562 - version = "0.28.1" 563 source = "registry+https://github.com/rust-lang/crates.io-index" 564 - checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" 565 566 [[package]] 567 name = "h2" 568 - version = "0.3.25" 569 source = "registry+https://github.com/rust-lang/crates.io-index" 570 - checksum = "4fbd2820c5e49886948654ab546d0688ff24530286bdcf8fca3cefb16d4618eb" 571 dependencies = [ 572 "bytes", 573 "fnv", 574 "futures-core", 575 "futures-sink", 576 "futures-util", 577 - "http", 578 "indexmap", 579 "slab", 580 "tokio", ··· 584 585 [[package]] 586 name = "hashbrown" 587 - version = "0.14.3" 588 source = "registry+https://github.com/rust-lang/crates.io-index" 589 - checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" 590 591 [[package]] 592 name = "headers" ··· 594 source = "registry+https://github.com/rust-lang/crates.io-index" 595 checksum = "06683b93020a07e3dbcf5f8c0f6d40080d725bea7936fc01ad345c01b97dc270" 596 dependencies = [ 597 - "base64", 598 "bytes", 599 "headers-core", 600 - "http", 601 "httpdate", 602 "mime", 603 "sha1", ··· 609 source = "registry+https://github.com/rust-lang/crates.io-index" 610 checksum = "e7f66481bfee273957b1f20485a4ff3362987f85b2c236580d81b4eb7a326429" 611 dependencies = [ 612 - "http", 613 ] 614 615 [[package]] 616 name = "hermit-abi" 617 version = "0.3.9" 618 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 639 ] 640 641 [[package]] 642 name = "http-body" 643 version = "0.4.6" 644 source = "registry+https://github.com/rust-lang/crates.io-index" 645 checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" 646 dependencies = [ 647 "bytes", 648 - "http", 649 "pin-project-lite", 650 ] 651 652 [[package]] 653 name = "httparse" 654 - version = "1.8.0" 655 source = "registry+https://github.com/rust-lang/crates.io-index" 656 - checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" 657 658 [[package]] 659 name = "httpdate" ··· 669 670 [[package]] 671 name = "hyper" 672 - version = "0.14.28" 673 source = "registry+https://github.com/rust-lang/crates.io-index" 674 - checksum = "bf96e135eb83a2a8ddf766e426a841d8ddd7449d5f00d34ea02b41d2f19eef80" 675 dependencies = [ 676 "bytes", 677 "futures-channel", 678 "futures-core", 679 "futures-util", 680 "h2", 681 - "http", 682 "http-body", 683 "httparse", 684 "httpdate", ··· 692 ] 693 694 [[package]] 695 name = "idna" 696 version = "0.5.0" 697 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 703 704 [[package]] 705 name = "indexmap" 706 - version = "2.2.5" 707 source = "registry+https://github.com/rust-lang/crates.io-index" 708 - checksum = "7b0b929d511467233429c45a44ac1dcaa21ba0f5ba11e4879e6ed28ddb4f9df4" 709 dependencies = [ 710 "equivalent", 711 "hashbrown", ··· 723 ] 724 725 [[package]] 726 name = "itoa" 727 - version = "1.0.10" 728 source = "registry+https://github.com/rust-lang/crates.io-index" 729 - checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" 730 731 [[package]] 732 name = "js-sys" 733 - version = "0.3.69" 734 source = "registry+https://github.com/rust-lang/crates.io-index" 735 - checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" 736 dependencies = [ 737 "wasm-bindgen", 738 ] 739 740 [[package]] 741 - name = "lazy_static" 742 - version = "1.4.0" 743 - source = "registry+https://github.com/rust-lang/crates.io-index" 744 - checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" 745 - 746 - [[package]] 747 name = "libc" 748 - version = "0.2.153" 749 source = "registry+https://github.com/rust-lang/crates.io-index" 750 - checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" 751 752 [[package]] 753 name = "linux-raw-sys" 754 - version = "0.4.13" 755 source = "registry+https://github.com/rust-lang/crates.io-index" 756 - checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" 757 758 [[package]] 759 name = "lock_api" 760 - version = "0.4.11" 761 source = "registry+https://github.com/rust-lang/crates.io-index" 762 - checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" 763 dependencies = [ 764 "autocfg", 765 "scopeguard", ··· 767 768 [[package]] 769 name = "log" 770 - version = "0.4.21" 771 source = "registry+https://github.com/rust-lang/crates.io-index" 772 - checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" 773 774 [[package]] 775 name = "lumen" ··· 781 "native-tls", 782 "pretty_env_logger", 783 "prometheus-client", 784 - "rpassword", 785 "tokio", 786 "tokio-native-tls", 787 "warp", ··· 799 800 [[package]] 801 name = "memchr" 802 - version = "2.7.1" 803 source = "registry+https://github.com/rust-lang/crates.io-index" 804 - checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" 805 806 [[package]] 807 name = "mime" ··· 811 812 [[package]] 813 name = "mime_guess" 814 - version = "2.0.4" 815 source = "registry+https://github.com/rust-lang/crates.io-index" 816 - checksum = "4192263c238a5f0d0c6bfd21f336a313a4ce1c450542449ca191bb657b4642ef" 817 dependencies = [ 818 "mime", 819 "unicase", ··· 821 822 [[package]] 823 name = "miniz_oxide" 824 - version = "0.7.2" 825 source = "registry+https://github.com/rust-lang/crates.io-index" 826 - checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7" 827 dependencies = [ 828 "adler", 829 ] 830 831 [[package]] 832 name = "mio" 833 - version = "0.8.11" 834 source = "registry+https://github.com/rust-lang/crates.io-index" 835 - checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" 836 dependencies = [ 837 "libc", 838 "wasi", 839 - "windows-sys 0.48.0", 840 ] 841 842 [[package]] ··· 848 "bytes", 849 "encoding_rs", 850 "futures-util", 851 - "http", 852 "httparse", 853 "log", 854 "memchr", ··· 859 860 [[package]] 861 name = "native-tls" 862 - version = "0.2.11" 863 source = "registry+https://github.com/rust-lang/crates.io-index" 864 - checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e" 865 dependencies = [ 866 - "lazy_static", 867 "libc", 868 "log", 869 "openssl", ··· 882 checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" 883 884 [[package]] 885 - name = "num_cpus" 886 - version = "1.16.0" 887 - source = "registry+https://github.com/rust-lang/crates.io-index" 888 - checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" 889 - dependencies = [ 890 - "hermit-abi", 891 - "libc", 892 - ] 893 - 894 - [[package]] 895 name = "object" 896 - version = "0.32.2" 897 source = "registry+https://github.com/rust-lang/crates.io-index" 898 - checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" 899 dependencies = [ 900 "memchr", 901 ] ··· 908 909 [[package]] 910 name = "openssl" 911 - version = "0.10.64" 912 source = "registry+https://github.com/rust-lang/crates.io-index" 913 - checksum = "95a0481286a310808298130d22dd1fef0fa571e05a8f44ec801801e84b216b1f" 914 dependencies = [ 915 - "bitflags 2.5.0", 916 "cfg-if", 917 "foreign-types", 918 "libc", ··· 940 941 [[package]] 942 name = "openssl-sys" 943 - version = "0.9.101" 944 source = "registry+https://github.com/rust-lang/crates.io-index" 945 - checksum = "dda2b0f344e78efc2facf7d195d098df0dd72151b26ab98da807afc26c198dff" 946 dependencies = [ 947 "cc", 948 "libc", ··· 952 953 [[package]] 954 name = "parking_lot" 955 - version = "0.12.1" 956 source = "registry+https://github.com/rust-lang/crates.io-index" 957 - checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" 958 dependencies = [ 959 "lock_api", 960 "parking_lot_core", ··· 962 963 [[package]] 964 name = "parking_lot_core" 965 - version = "0.9.9" 966 source = "registry+https://github.com/rust-lang/crates.io-index" 967 - checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" 968 dependencies = [ 969 "cfg-if", 970 "libc", 971 - "redox_syscall", 972 "smallvec", 973 - "windows-targets 0.48.5", 974 - ] 975 - 976 - [[package]] 977 - name = "pbkdf2" 978 - version = "0.12.2" 979 - source = "registry+https://github.com/rust-lang/crates.io-index" 980 - checksum = "f8ed6a7761f76e3b9f92dfb0a60a6a6477c61024b775147ff0973a02653abaf2" 981 - dependencies = [ 982 - "digest", 983 - "hmac", 984 ] 985 986 [[package]] ··· 1029 1030 [[package]] 1031 name = "pin-project-lite" 1032 - version = "0.2.13" 1033 source = "registry+https://github.com/rust-lang/crates.io-index" 1034 - checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" 1035 1036 [[package]] 1037 name = "pin-utils" ··· 1060 1061 [[package]] 1062 name = "postgres-protocol" 1063 - version = "0.6.6" 1064 source = "registry+https://github.com/rust-lang/crates.io-index" 1065 - checksum = "49b6c5ef183cd3ab4ba005f1ca64c21e8bd97ce4699cfea9e8d9a2c4958ca520" 1066 dependencies = [ 1067 - "base64", 1068 "byteorder", 1069 "bytes", 1070 "fallible-iterator", ··· 1078 1079 [[package]] 1080 name = "postgres-types" 1081 - version = "0.2.6" 1082 source = "registry+https://github.com/rust-lang/crates.io-index" 1083 - checksum = "8d2234cdee9408b523530a9b6d2d6b373d1db34f6a8e51dc03ded1828d7fb67c" 1084 dependencies = [ 1085 "bytes", 1086 "fallible-iterator", ··· 1095 1096 [[package]] 1097 name = "ppv-lite86" 1098 - version = "0.2.17" 1099 source = "registry+https://github.com/rust-lang/crates.io-index" 1100 - checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" 1101 1102 [[package]] 1103 name = "pretty_env_logger" ··· 1111 1112 [[package]] 1113 name = "proc-macro2" 1114 - version = "1.0.79" 1115 source = "registry+https://github.com/rust-lang/crates.io-index" 1116 - checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e" 1117 dependencies = [ 1118 "unicode-ident", 1119 ] 1120 1121 [[package]] 1122 name = "prometheus-client" 1123 - version = "0.22.2" 1124 source = "registry+https://github.com/rust-lang/crates.io-index" 1125 - checksum = "c1ca959da22a332509f2a73ae9e5f23f9dcfc31fd3a54d71f159495bd5909baa" 1126 dependencies = [ 1127 "dtoa", 1128 "itoa", ··· 1143 1144 [[package]] 1145 name = "quote" 1146 - version = "1.0.35" 1147 source = "registry+https://github.com/rust-lang/crates.io-index" 1148 - checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" 1149 dependencies = [ 1150 "proc-macro2", 1151 ] ··· 1190 ] 1191 1192 [[package]] 1193 name = "regex" 1194 - version = "1.10.3" 1195 source = "registry+https://github.com/rust-lang/crates.io-index" 1196 - checksum = "b62dbe01f0b06f9d8dc7d49e05a0785f153b00b2c227856282f671e0318c9b15" 1197 dependencies = [ 1198 "aho-corasick", 1199 "memchr", ··· 1203 1204 [[package]] 1205 name = "regex-automata" 1206 - version = "0.4.6" 1207 source = "registry+https://github.com/rust-lang/crates.io-index" 1208 - checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" 1209 dependencies = [ 1210 "aho-corasick", 1211 "memchr", ··· 1214 1215 [[package]] 1216 name = "regex-syntax" 1217 - version = "0.8.2" 1218 - source = "registry+https://github.com/rust-lang/crates.io-index" 1219 - checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" 1220 - 1221 - [[package]] 1222 - name = "rpassword" 1223 - version = "7.3.1" 1224 source = "registry+https://github.com/rust-lang/crates.io-index" 1225 - checksum = "80472be3c897911d0137b2d2b9055faf6eeac5b14e324073d83bc17b191d7e3f" 1226 - dependencies = [ 1227 - "libc", 1228 - "rtoolbox", 1229 - "windows-sys 0.48.0", 1230 - ] 1231 - 1232 - [[package]] 1233 - name = "rtoolbox" 1234 - version = "0.0.2" 1235 - source = "registry+https://github.com/rust-lang/crates.io-index" 1236 - checksum = "c247d24e63230cdb56463ae328478bd5eac8b8faa8c69461a77e8e323afac90e" 1237 - dependencies = [ 1238 - "libc", 1239 - "windows-sys 0.48.0", 1240 - ] 1241 1242 [[package]] 1243 name = "rustc-demangle" 1244 - version = "0.1.23" 1245 source = "registry+https://github.com/rust-lang/crates.io-index" 1246 - checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" 1247 1248 [[package]] 1249 name = "rustix" 1250 - version = "0.38.32" 1251 source = "registry+https://github.com/rust-lang/crates.io-index" 1252 - checksum = "65e04861e65f21776e67888bfbea442b3642beaa0138fdb1dd7a84a52dffdb89" 1253 dependencies = [ 1254 - "bitflags 2.5.0", 1255 "errno", 1256 "libc", 1257 "linux-raw-sys", ··· 1259 ] 1260 1261 [[package]] 1262 - name = "rustls-pemfile" 1263 - version = "1.0.4" 1264 - source = "registry+https://github.com/rust-lang/crates.io-index" 1265 - checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" 1266 - dependencies = [ 1267 - "base64", 1268 - ] 1269 - 1270 - [[package]] 1271 name = "ryu" 1272 - version = "1.0.17" 1273 source = "registry+https://github.com/rust-lang/crates.io-index" 1274 - checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1" 1275 1276 [[package]] 1277 name = "schannel" ··· 1306 1307 [[package]] 1308 name = "security-framework" 1309 - version = "2.9.2" 1310 source = "registry+https://github.com/rust-lang/crates.io-index" 1311 - checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de" 1312 dependencies = [ 1313 - "bitflags 1.3.2", 1314 "core-foundation", 1315 "core-foundation-sys", 1316 "libc", ··· 1319 1320 [[package]] 1321 name = "security-framework-sys" 1322 - version = "2.9.1" 1323 source = "registry+https://github.com/rust-lang/crates.io-index" 1324 - checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a" 1325 dependencies = [ 1326 "core-foundation-sys", 1327 "libc", ··· 1329 1330 [[package]] 1331 name = "serde" 1332 - version = "1.0.197" 1333 source = "registry+https://github.com/rust-lang/crates.io-index" 1334 - checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" 1335 dependencies = [ 1336 "serde_derive", 1337 ] 1338 1339 [[package]] 1340 name = "serde_derive" 1341 - version = "1.0.197" 1342 source = "registry+https://github.com/rust-lang/crates.io-index" 1343 - checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" 1344 dependencies = [ 1345 "proc-macro2", 1346 "quote", ··· 1349 1350 [[package]] 1351 name = "serde_json" 1352 - version = "1.0.114" 1353 source = "registry+https://github.com/rust-lang/crates.io-index" 1354 - checksum = "c5f09b1bd632ef549eaa9f60a1f8de742bdbc698e6cee2095fc84dde5f549ae0" 1355 dependencies = [ 1356 "itoa", 1357 "ryu", 1358 "serde", 1359 ] 1360 1361 [[package]] 1362 name = "serde_spanned" 1363 - version = "0.6.5" 1364 source = "registry+https://github.com/rust-lang/crates.io-index" 1365 - checksum = "eb3622f419d1296904700073ea6cc23ad690adbd66f13ea683df73298736f0c1" 1366 dependencies = [ 1367 "serde", 1368 ] ··· 1403 1404 [[package]] 1405 name = "signal-hook-registry" 1406 - version = "1.4.1" 1407 source = "registry+https://github.com/rust-lang/crates.io-index" 1408 - checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" 1409 dependencies = [ 1410 "libc", 1411 ] ··· 1433 1434 [[package]] 1435 name = "socket2" 1436 - version = "0.5.6" 1437 source = "registry+https://github.com/rust-lang/crates.io-index" 1438 - checksum = "05ffd9c0a93b7543e062e759284fcf5f5e3b098501104bfbdde4d404db792871" 1439 dependencies = [ 1440 "libc", 1441 "windows-sys 0.52.0", ··· 1449 1450 [[package]] 1451 name = "stringprep" 1452 - version = "0.1.4" 1453 source = "registry+https://github.com/rust-lang/crates.io-index" 1454 - checksum = "bb41d74e231a107a1b4ee36bd1214b11285b77768d2e3824aedafa988fd36ee6" 1455 dependencies = [ 1456 - "finl_unicode", 1457 "unicode-bidi", 1458 "unicode-normalization", 1459 ] 1460 1461 [[package]] 1462 name = "strsim" 1463 - version = "0.11.0" 1464 source = "registry+https://github.com/rust-lang/crates.io-index" 1465 - checksum = "5ee073c9e4cd00e28217186dbe12796d692868f432bf2e97ee73bed0c56dfa01" 1466 1467 [[package]] 1468 name = "subtle" 1469 - version = "2.5.0" 1470 source = "registry+https://github.com/rust-lang/crates.io-index" 1471 - checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" 1472 1473 [[package]] 1474 name = "syn" 1475 - version = "2.0.53" 1476 source = "registry+https://github.com/rust-lang/crates.io-index" 1477 - checksum = "7383cd0e49fff4b6b90ca5670bfd3e9d6a733b3f90c686605aa7eec8c4996032" 1478 dependencies = [ 1479 "proc-macro2", 1480 "quote", ··· 1483 1484 [[package]] 1485 name = "tempfile" 1486 - version = "3.10.1" 1487 source = "registry+https://github.com/rust-lang/crates.io-index" 1488 - checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" 1489 dependencies = [ 1490 "cfg-if", 1491 "fastrand", 1492 "rustix", 1493 - "windows-sys 0.52.0", 1494 ] 1495 1496 [[package]] ··· 1504 1505 [[package]] 1506 name = "thiserror" 1507 - version = "1.0.58" 1508 source = "registry+https://github.com/rust-lang/crates.io-index" 1509 - checksum = "03468839009160513471e86a034bb2c5c0e4baae3b43f79ffc55c4a5427b3297" 1510 dependencies = [ 1511 "thiserror-impl", 1512 ] 1513 1514 [[package]] 1515 name = "thiserror-impl" 1516 - version = "1.0.58" 1517 source = "registry+https://github.com/rust-lang/crates.io-index" 1518 - checksum = "c61f3ba182994efc43764a46c018c347bc492c79f024e705f46567b418f6d4f7" 1519 dependencies = [ 1520 "proc-macro2", 1521 "quote", ··· 1524 1525 [[package]] 1526 name = "time" 1527 - version = "0.3.34" 1528 source = "registry+https://github.com/rust-lang/crates.io-index" 1529 - checksum = "c8248b6521bb14bc45b4067159b9b6ad792e2d6d754d6c41fb50e29fefe38749" 1530 dependencies = [ 1531 "deranged", 1532 "num-conv", ··· 1544 1545 [[package]] 1546 name = "time-macros" 1547 - version = "0.2.17" 1548 source = "registry+https://github.com/rust-lang/crates.io-index" 1549 - checksum = "7ba3a3ef41e6672a2f0f001392bb5dcd3ff0a9992d618ca761a11c3121547774" 1550 dependencies = [ 1551 "num-conv", 1552 "time-core", ··· 1554 1555 [[package]] 1556 name = "tinyvec" 1557 - version = "1.6.0" 1558 source = "registry+https://github.com/rust-lang/crates.io-index" 1559 - checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" 1560 dependencies = [ 1561 "tinyvec_macros", 1562 ] ··· 1569 1570 [[package]] 1571 name = "tokio" 1572 - version = "1.36.0" 1573 source = "registry+https://github.com/rust-lang/crates.io-index" 1574 - checksum = "61285f6515fa018fb2d1e46eb21223fff441ee8db5d0f1435e8ab4f5cdb80931" 1575 dependencies = [ 1576 "backtrace", 1577 "bytes", 1578 "libc", 1579 "mio", 1580 - "num_cpus", 1581 "parking_lot", 1582 "pin-project-lite", 1583 "signal-hook-registry", 1584 "socket2", 1585 "tokio-macros", 1586 - "windows-sys 0.48.0", 1587 ] 1588 1589 [[package]] 1590 name = "tokio-macros" 1591 - version = "2.2.0" 1592 source = "registry+https://github.com/rust-lang/crates.io-index" 1593 - checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" 1594 dependencies = [ 1595 "proc-macro2", 1596 "quote", ··· 1609 1610 [[package]] 1611 name = "tokio-postgres" 1612 - version = "0.7.10" 1613 source = "registry+https://github.com/rust-lang/crates.io-index" 1614 - checksum = "d340244b32d920260ae7448cb72b6e238bddc3d4f7603394e7dd46ed8e48f5b8" 1615 dependencies = [ 1616 "async-trait", 1617 "byteorder", ··· 1634 ] 1635 1636 [[package]] 1637 - name = "tokio-stream" 1638 - version = "0.1.15" 1639 - source = "registry+https://github.com/rust-lang/crates.io-index" 1640 - checksum = "267ac89e0bec6e691e5813911606935d77c476ff49024f98abcea3e7b15e37af" 1641 - dependencies = [ 1642 - "futures-core", 1643 - "pin-project-lite", 1644 - "tokio", 1645 - ] 1646 - 1647 - [[package]] 1648 name = "tokio-tungstenite" 1649 - version = "0.20.1" 1650 source = "registry+https://github.com/rust-lang/crates.io-index" 1651 - checksum = "212d5dcb2a1ce06d81107c3d0ffa3121fe974b73f068c8282cb1c32328113b6c" 1652 dependencies = [ 1653 "futures-util", 1654 "log", ··· 1658 1659 [[package]] 1660 name = "tokio-util" 1661 - version = "0.7.10" 1662 source = "registry+https://github.com/rust-lang/crates.io-index" 1663 - checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15" 1664 dependencies = [ 1665 "bytes", 1666 "futures-core", 1667 "futures-sink", 1668 "pin-project-lite", 1669 "tokio", 1670 - "tracing", 1671 ] 1672 1673 [[package]] 1674 name = "toml" 1675 - version = "0.8.12" 1676 source = "registry+https://github.com/rust-lang/crates.io-index" 1677 - checksum = "e9dd1545e8208b4a5af1aa9bbd0b4cf7e9ea08fabc5d0a5c67fcaafa17433aa3" 1678 dependencies = [ 1679 "serde", 1680 "serde_spanned", ··· 1684 1685 [[package]] 1686 name = "toml_datetime" 1687 - version = "0.6.5" 1688 source = "registry+https://github.com/rust-lang/crates.io-index" 1689 - checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" 1690 dependencies = [ 1691 "serde", 1692 ] 1693 1694 [[package]] 1695 name = "toml_edit" 1696 - version = "0.22.9" 1697 source = "registry+https://github.com/rust-lang/crates.io-index" 1698 - checksum = "8e40bb779c5187258fd7aad0eb68cb8706a0a81fa712fbea808ab43c4b8374c4" 1699 dependencies = [ 1700 "indexmap", 1701 "serde", ··· 1738 1739 [[package]] 1740 name = "tungstenite" 1741 - version = "0.20.1" 1742 source = "registry+https://github.com/rust-lang/crates.io-index" 1743 - checksum = "9e3dac10fd62eaf6617d3a904ae222845979aec67c615d1c842b4002c7666fb9" 1744 dependencies = [ 1745 "byteorder", 1746 "bytes", 1747 "data-encoding", 1748 - "http", 1749 "httparse", 1750 "log", 1751 "rand", ··· 1792 ] 1793 1794 [[package]] 1795 name = "url" 1796 - version = "2.5.0" 1797 source = "registry+https://github.com/rust-lang/crates.io-index" 1798 - checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" 1799 dependencies = [ 1800 "form_urlencoded", 1801 "idna", ··· 1810 1811 [[package]] 1812 name = "utf8parse" 1813 - version = "0.2.1" 1814 source = "registry+https://github.com/rust-lang/crates.io-index" 1815 - checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" 1816 1817 [[package]] 1818 name = "vcpkg" ··· 1822 1823 [[package]] 1824 name = "version_check" 1825 - version = "0.9.4" 1826 source = "registry+https://github.com/rust-lang/crates.io-index" 1827 - checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" 1828 1829 [[package]] 1830 name = "want" ··· 1837 1838 [[package]] 1839 name = "warp" 1840 - version = "0.3.6" 1841 source = "registry+https://github.com/rust-lang/crates.io-index" 1842 - checksum = "c1e92e22e03ff1230c03a1a8ee37d2f89cd489e2e541b7550d6afad96faed169" 1843 dependencies = [ 1844 "bytes", 1845 "futures-channel", 1846 "futures-util", 1847 "headers", 1848 - "http", 1849 "hyper", 1850 "log", 1851 "mime", ··· 1853 "multer", 1854 "percent-encoding", 1855 "pin-project", 1856 - "rustls-pemfile", 1857 "scoped-tls", 1858 "serde", 1859 "serde_json", 1860 "serde_urlencoded", 1861 "tokio", 1862 - "tokio-stream", 1863 "tokio-tungstenite", 1864 "tokio-util", 1865 "tower-service", ··· 1880 1881 [[package]] 1882 name = "wasm-bindgen" 1883 - version = "0.2.92" 1884 source = "registry+https://github.com/rust-lang/crates.io-index" 1885 - checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" 1886 dependencies = [ 1887 "cfg-if", 1888 "wasm-bindgen-macro", 1889 ] 1890 1891 [[package]] 1892 name = "wasm-bindgen-backend" 1893 - version = "0.2.92" 1894 source = "registry+https://github.com/rust-lang/crates.io-index" 1895 - checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" 1896 dependencies = [ 1897 "bumpalo", 1898 "log", ··· 1905 1906 [[package]] 1907 name = "wasm-bindgen-macro" 1908 - version = "0.2.92" 1909 source = "registry+https://github.com/rust-lang/crates.io-index" 1910 - checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" 1911 dependencies = [ 1912 "quote", 1913 "wasm-bindgen-macro-support", ··· 1915 1916 [[package]] 1917 name = "wasm-bindgen-macro-support" 1918 - version = "0.2.92" 1919 source = "registry+https://github.com/rust-lang/crates.io-index" 1920 - checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" 1921 dependencies = [ 1922 "proc-macro2", 1923 "quote", ··· 1928 1929 [[package]] 1930 name = "wasm-bindgen-shared" 1931 - version = "0.2.92" 1932 source = "registry+https://github.com/rust-lang/crates.io-index" 1933 - checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" 1934 1935 [[package]] 1936 name = "web-sys" 1937 - version = "0.3.69" 1938 source = "registry+https://github.com/rust-lang/crates.io-index" 1939 - checksum = "77afa9a11836342370f4817622a2f0f418b134426d91a82dfb48f532d2ec13ef" 1940 dependencies = [ 1941 "js-sys", 1942 "wasm-bindgen", ··· 1948 source = "registry+https://github.com/rust-lang/crates.io-index" 1949 checksum = "a44ab49fad634e88f55bf8f9bb3abd2f27d7204172a112c7c9987e01c1c94ea9" 1950 dependencies = [ 1951 - "redox_syscall", 1952 "wasite", 1953 "web-sys", 1954 ] 1955 1956 [[package]] 1957 - name = "winapi" 1958 - version = "0.3.9" 1959 - source = "registry+https://github.com/rust-lang/crates.io-index" 1960 - checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" 1961 - dependencies = [ 1962 - "winapi-i686-pc-windows-gnu", 1963 - "winapi-x86_64-pc-windows-gnu", 1964 - ] 1965 - 1966 - [[package]] 1967 - name = "winapi-i686-pc-windows-gnu" 1968 - version = "0.4.0" 1969 - source = "registry+https://github.com/rust-lang/crates.io-index" 1970 - checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 1971 - 1972 - [[package]] 1973 name = "winapi-util" 1974 - version = "0.1.6" 1975 source = "registry+https://github.com/rust-lang/crates.io-index" 1976 - checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" 1977 - dependencies = [ 1978 - "winapi", 1979 - ] 1980 - 1981 - [[package]] 1982 - name = "winapi-x86_64-pc-windows-gnu" 1983 - version = "0.4.0" 1984 - source = "registry+https://github.com/rust-lang/crates.io-index" 1985 - checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 1986 - 1987 - [[package]] 1988 - name = "windows-sys" 1989 - version = "0.48.0" 1990 - source = "registry+https://github.com/rust-lang/crates.io-index" 1991 - checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" 1992 dependencies = [ 1993 - "windows-targets 0.48.5", 1994 ] 1995 1996 [[package]] ··· 1999 source = "registry+https://github.com/rust-lang/crates.io-index" 2000 checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" 2001 dependencies = [ 2002 - "windows-targets 0.52.4", 2003 ] 2004 2005 [[package]] 2006 - name = "windows-targets" 2007 - version = "0.48.5" 2008 source = "registry+https://github.com/rust-lang/crates.io-index" 2009 - checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" 2010 dependencies = [ 2011 - "windows_aarch64_gnullvm 0.48.5", 2012 - "windows_aarch64_msvc 0.48.5", 2013 - "windows_i686_gnu 0.48.5", 2014 - "windows_i686_msvc 0.48.5", 2015 - "windows_x86_64_gnu 0.48.5", 2016 - "windows_x86_64_gnullvm 0.48.5", 2017 - "windows_x86_64_msvc 0.48.5", 2018 ] 2019 2020 [[package]] 2021 name = "windows-targets" 2022 - version = "0.52.4" 2023 source = "registry+https://github.com/rust-lang/crates.io-index" 2024 - checksum = "7dd37b7e5ab9018759f893a1952c9420d060016fc19a472b4bb20d1bdd694d1b" 2025 dependencies = [ 2026 - "windows_aarch64_gnullvm 0.52.4", 2027 - "windows_aarch64_msvc 0.52.4", 2028 - "windows_i686_gnu 0.52.4", 2029 - "windows_i686_msvc 0.52.4", 2030 - "windows_x86_64_gnu 0.52.4", 2031 - "windows_x86_64_gnullvm 0.52.4", 2032 - "windows_x86_64_msvc 0.52.4", 2033 ] 2034 2035 [[package]] 2036 name = "windows_aarch64_gnullvm" 2037 - version = "0.48.5" 2038 source = "registry+https://github.com/rust-lang/crates.io-index" 2039 - checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" 2040 - 2041 - [[package]] 2042 - name = "windows_aarch64_gnullvm" 2043 - version = "0.52.4" 2044 - source = "registry+https://github.com/rust-lang/crates.io-index" 2045 - checksum = "bcf46cf4c365c6f2d1cc93ce535f2c8b244591df96ceee75d8e83deb70a9cac9" 2046 2047 [[package]] 2048 name = "windows_aarch64_msvc" 2049 - version = "0.48.5" 2050 source = "registry+https://github.com/rust-lang/crates.io-index" 2051 - checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" 2052 - 2053 - [[package]] 2054 - name = "windows_aarch64_msvc" 2055 - version = "0.52.4" 2056 - source = "registry+https://github.com/rust-lang/crates.io-index" 2057 - checksum = "da9f259dd3bcf6990b55bffd094c4f7235817ba4ceebde8e6d11cd0c5633b675" 2058 2059 [[package]] 2060 name = "windows_i686_gnu" 2061 - version = "0.48.5" 2062 source = "registry+https://github.com/rust-lang/crates.io-index" 2063 - checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" 2064 2065 [[package]] 2066 - name = "windows_i686_gnu" 2067 - version = "0.52.4" 2068 source = "registry+https://github.com/rust-lang/crates.io-index" 2069 - checksum = "b474d8268f99e0995f25b9f095bc7434632601028cf86590aea5c8a5cb7801d3" 2070 2071 [[package]] 2072 name = "windows_i686_msvc" 2073 - version = "0.48.5" 2074 source = "registry+https://github.com/rust-lang/crates.io-index" 2075 - checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" 2076 - 2077 - [[package]] 2078 - name = "windows_i686_msvc" 2079 - version = "0.52.4" 2080 - source = "registry+https://github.com/rust-lang/crates.io-index" 2081 - checksum = "1515e9a29e5bed743cb4415a9ecf5dfca648ce85ee42e15873c3cd8610ff8e02" 2082 2083 [[package]] 2084 name = "windows_x86_64_gnu" 2085 - version = "0.48.5" 2086 source = "registry+https://github.com/rust-lang/crates.io-index" 2087 - checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" 2088 - 2089 - [[package]] 2090 - name = "windows_x86_64_gnu" 2091 - version = "0.52.4" 2092 - source = "registry+https://github.com/rust-lang/crates.io-index" 2093 - checksum = "5eee091590e89cc02ad514ffe3ead9eb6b660aedca2183455434b93546371a03" 2094 2095 [[package]] 2096 name = "windows_x86_64_gnullvm" 2097 - version = "0.48.5" 2098 source = "registry+https://github.com/rust-lang/crates.io-index" 2099 - checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" 2100 2101 [[package]] 2102 - name = "windows_x86_64_gnullvm" 2103 - version = "0.52.4" 2104 source = "registry+https://github.com/rust-lang/crates.io-index" 2105 - checksum = "77ca79f2451b49fa9e2af39f0747fe999fcda4f5e241b2898624dca97a1f2177" 2106 2107 [[package]] 2108 - name = "windows_x86_64_msvc" 2109 - version = "0.48.5" 2110 source = "registry+https://github.com/rust-lang/crates.io-index" 2111 - checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" 2112 2113 [[package]] 2114 - name = "windows_x86_64_msvc" 2115 - version = "0.52.4" 2116 source = "registry+https://github.com/rust-lang/crates.io-index" 2117 - checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8" 2118 2119 [[package]] 2120 - name = "winnow" 2121 - version = "0.6.5" 2122 source = "registry+https://github.com/rust-lang/crates.io-index" 2123 - checksum = "dffa400e67ed5a4dd237983829e66475f0a4a26938c4b04c21baede6262215b8" 2124 dependencies = [ 2125 - "memchr", 2126 ]
··· 4 5 [[package]] 6 name = "addr2line" 7 + version = "0.22.0" 8 source = "registry+https://github.com/rust-lang/crates.io-index" 9 + checksum = "6e4503c46a5c0c7844e948c9a4d6acd9f50cccb4de1c48eb9e291ea17470c678" 10 dependencies = [ 11 "gimli", 12 ] ··· 28 29 [[package]] 30 name = "anstream" 31 + version = "0.6.15" 32 source = "registry+https://github.com/rust-lang/crates.io-index" 33 + checksum = "64e15c1ab1f89faffbf04a634d5e1962e9074f2741eef6d97f3c4e322426d526" 34 dependencies = [ 35 "anstyle", 36 "anstyle-parse", 37 "anstyle-query", 38 "anstyle-wincon", 39 "colorchoice", 40 + "is_terminal_polyfill", 41 "utf8parse", 42 ] 43 44 [[package]] 45 name = "anstyle" 46 + version = "1.0.8" 47 source = "registry+https://github.com/rust-lang/crates.io-index" 48 + checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1" 49 50 [[package]] 51 name = "anstyle-parse" 52 + version = "0.2.5" 53 source = "registry+https://github.com/rust-lang/crates.io-index" 54 + checksum = "eb47de1e80c2b463c735db5b217a0ddc39d612e7ac9e2e96a5aed1f57616c1cb" 55 dependencies = [ 56 "utf8parse", 57 ] 58 59 [[package]] 60 name = "anstyle-query" 61 + version = "1.1.1" 62 source = "registry+https://github.com/rust-lang/crates.io-index" 63 + checksum = "6d36fc52c7f6c869915e99412912f22093507da8d9e942ceaf66fe4b7c14422a" 64 dependencies = [ 65 "windows-sys 0.52.0", 66 ] 67 68 [[package]] 69 name = "anstyle-wincon" 70 + version = "3.0.4" 71 source = "registry+https://github.com/rust-lang/crates.io-index" 72 + checksum = "5bf74e1b6e971609db8ca7a9ce79fd5768ab6ae46441c572e46cf596f59e57f8" 73 dependencies = [ 74 "anstyle", 75 "windows-sys 0.52.0", ··· 77 78 [[package]] 79 name = "anyhow" 80 + version = "1.0.86" 81 source = "registry+https://github.com/rust-lang/crates.io-index" 82 + checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" 83 84 [[package]] 85 name = "async-trait" 86 + version = "0.1.81" 87 source = "registry+https://github.com/rust-lang/crates.io-index" 88 + checksum = "6e0c28dcc82d7c8ead5cb13beb15405b57b8546e93215673ff8ca0349a028107" 89 dependencies = [ 90 "proc-macro2", 91 "quote", ··· 94 95 [[package]] 96 name = "autocfg" 97 + version = "1.3.0" 98 source = "registry+https://github.com/rust-lang/crates.io-index" 99 + checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" 100 101 [[package]] 102 name = "backtrace" 103 + version = "0.3.73" 104 source = "registry+https://github.com/rust-lang/crates.io-index" 105 + checksum = "5cc23269a4f8976d0a4d2e7109211a419fe30e8d88d677cd60b6bc79c5732e0a" 106 dependencies = [ 107 "addr2line", 108 "cc", ··· 120 checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" 121 122 [[package]] 123 + name = "base64" 124 + version = "0.22.1" 125 + source = "registry+https://github.com/rust-lang/crates.io-index" 126 + checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" 127 + 128 + [[package]] 129 name = "bb8" 130 + version = "0.8.5" 131 source = "registry+https://github.com/rust-lang/crates.io-index" 132 + checksum = "b10cf871f3ff2ce56432fddc2615ac7acc3aa22ca321f8fea800846fbb32f188" 133 dependencies = [ 134 "async-trait", 135 "futures-util", 136 "parking_lot", 137 "tokio", ··· 151 152 [[package]] 153 name = "bitflags" 154 + version = "2.6.0" 155 source = "registry+https://github.com/rust-lang/crates.io-index" 156 + checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" 157 158 [[package]] 159 name = "block-buffer" ··· 166 167 [[package]] 168 name = "bumpalo" 169 + version = "3.16.0" 170 source = "registry+https://github.com/rust-lang/crates.io-index" 171 + checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" 172 173 [[package]] 174 name = "byteorder" ··· 178 179 [[package]] 180 name = "bytes" 181 + version = "1.7.1" 182 source = "registry+https://github.com/rust-lang/crates.io-index" 183 + checksum = "8318a53db07bb3f8dca91a600466bdb3f2eaadeedfdbcf02e1accbad9271ba50" 184 185 [[package]] 186 name = "cc" 187 + version = "1.1.10" 188 source = "registry+https://github.com/rust-lang/crates.io-index" 189 + checksum = "e9e8aabfac534be767c909e0690571677d49f41bd8465ae876fe043d52ba5292" 190 191 [[package]] 192 name = "cfg-if" ··· 196 197 [[package]] 198 name = "clap" 199 + version = "4.5.15" 200 source = "registry+https://github.com/rust-lang/crates.io-index" 201 + checksum = "11d8838454fda655dafd3accb2b6e2bea645b9e4078abe84a22ceb947235c5cc" 202 dependencies = [ 203 "clap_builder", 204 ] 205 206 [[package]] 207 name = "clap_builder" 208 + version = "4.5.15" 209 source = "registry+https://github.com/rust-lang/crates.io-index" 210 + checksum = "216aec2b177652e3846684cbfe25c9964d18ec45234f0f5da5157b207ed1aab6" 211 dependencies = [ 212 "anstream", 213 "anstyle", ··· 217 218 [[package]] 219 name = "clap_lex" 220 + version = "0.7.2" 221 source = "registry+https://github.com/rust-lang/crates.io-index" 222 + checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97" 223 224 [[package]] 225 name = "colorchoice" 226 + version = "1.0.2" 227 source = "registry+https://github.com/rust-lang/crates.io-index" 228 + checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0" 229 230 [[package]] 231 name = "common" ··· 238 "futures-util", 239 "log", 240 "native-tls", 241 "postgres-native-tls", 242 "prometheus-client", 243 "serde", 244 "time", 245 "tokio", 246 "tokio-postgres", ··· 260 261 [[package]] 262 name = "core-foundation-sys" 263 + version = "0.8.7" 264 source = "registry+https://github.com/rust-lang/crates.io-index" 265 + checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" 266 267 [[package]] 268 name = "cpufeatures" 269 + version = "0.2.13" 270 source = "registry+https://github.com/rust-lang/crates.io-index" 271 + checksum = "51e852e6dc9a5bed1fae92dd2375037bf2b768725bf3be87811edee3249d09ad" 272 dependencies = [ 273 "libc", 274 ] ··· 284 ] 285 286 [[package]] 287 + name = "darling" 288 + version = "0.20.10" 289 + source = "registry+https://github.com/rust-lang/crates.io-index" 290 + checksum = "6f63b86c8a8826a49b8c21f08a2d07338eec8d900540f8630dc76284be802989" 291 + dependencies = [ 292 + "darling_core", 293 + "darling_macro", 294 + ] 295 + 296 + [[package]] 297 + name = "darling_core" 298 + version = "0.20.10" 299 + source = "registry+https://github.com/rust-lang/crates.io-index" 300 + checksum = "95133861a8032aaea082871032f5815eb9e98cef03fa916ab4500513994df9e5" 301 + dependencies = [ 302 + "fnv", 303 + "ident_case", 304 + "proc-macro2", 305 + "quote", 306 + "strsim", 307 + "syn", 308 + ] 309 + 310 + [[package]] 311 + name = "darling_macro" 312 + version = "0.20.10" 313 + source = "registry+https://github.com/rust-lang/crates.io-index" 314 + checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" 315 + dependencies = [ 316 + "darling_core", 317 + "quote", 318 + "syn", 319 + ] 320 + 321 + [[package]] 322 name = "data-encoding" 323 + version = "2.6.0" 324 source = "registry+https://github.com/rust-lang/crates.io-index" 325 + checksum = "e8566979429cf69b49a5c740c60791108e86440e8be149bbea4fe54d2c32d6e2" 326 327 [[package]] 328 name = "deranged" ··· 335 336 [[package]] 337 name = "diesel" 338 + version = "2.2.2" 339 source = "registry+https://github.com/rust-lang/crates.io-index" 340 + checksum = "bf97ee7261bb708fa3402fa9c17a54b70e90e3cb98afb3dc8999d5512cb03f94" 341 dependencies = [ 342 + "bitflags 2.6.0", 343 "byteorder", 344 "diesel_derives", 345 "itoa", ··· 348 349 [[package]] 350 name = "diesel-async" 351 + version = "0.5.0" 352 source = "registry+https://github.com/rust-lang/crates.io-index" 353 + checksum = "fcb799bb6f8ca6a794462125d7b8983b0c86e6c93a33a9c55934a4a5de4409d3" 354 dependencies = [ 355 "async-trait", 356 "bb8", ··· 363 364 [[package]] 365 name = "diesel_derives" 366 + version = "2.2.2" 367 source = "registry+https://github.com/rust-lang/crates.io-index" 368 + checksum = "d6ff2be1e7312c858b2ef974f5c7089833ae57b5311b334b30923af58e5718d8" 369 dependencies = [ 370 "diesel_table_macro_syntax", 371 + "dsl_auto_type", 372 "proc-macro2", 373 "quote", 374 "syn", ··· 376 377 [[package]] 378 name = "diesel_table_macro_syntax" 379 + version = "0.2.0" 380 source = "registry+https://github.com/rust-lang/crates.io-index" 381 + checksum = "209c735641a413bc68c4923a9d6ad4bcb3ca306b794edaa7eb0b3228a99ffb25" 382 dependencies = [ 383 "syn", 384 ] ··· 395 ] 396 397 [[package]] 398 + name = "dsl_auto_type" 399 + version = "0.1.2" 400 + source = "registry+https://github.com/rust-lang/crates.io-index" 401 + checksum = "c5d9abe6314103864cc2d8901b7ae224e0ab1a103a0a416661b4097b0779b607" 402 + dependencies = [ 403 + "darling", 404 + "either", 405 + "heck", 406 + "proc-macro2", 407 + "quote", 408 + "syn", 409 + ] 410 + 411 + [[package]] 412 name = "dtoa" 413 version = "1.0.9" 414 source = "registry+https://github.com/rust-lang/crates.io-index" 415 checksum = "dcbb2bf8e87535c23f7a8a321e364ce21462d0ff10cb6407820e8e96dfff6653" 416 417 [[package]] 418 + name = "either" 419 + version = "1.13.0" 420 + source = "registry+https://github.com/rust-lang/crates.io-index" 421 + checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" 422 + 423 + [[package]] 424 name = "encoding_rs" 425 + version = "0.8.34" 426 source = "registry+https://github.com/rust-lang/crates.io-index" 427 + checksum = "b45de904aa0b010bce2ab45264d0631681847fa7b6f2eaa7dab7619943bc4f59" 428 dependencies = [ 429 "cfg-if", 430 ] ··· 450 451 [[package]] 452 name = "errno" 453 + version = "0.3.9" 454 source = "registry+https://github.com/rust-lang/crates.io-index" 455 + checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" 456 dependencies = [ 457 "libc", 458 "windows-sys 0.52.0", ··· 466 467 [[package]] 468 name = "fastrand" 469 + version = "2.1.0" 470 source = "registry+https://github.com/rust-lang/crates.io-index" 471 + checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" 472 473 [[package]] 474 name = "fnv" ··· 601 602 [[package]] 603 name = "getrandom" 604 + version = "0.2.15" 605 source = "registry+https://github.com/rust-lang/crates.io-index" 606 + checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" 607 dependencies = [ 608 "cfg-if", 609 "libc", ··· 612 613 [[package]] 614 name = "gimli" 615 + version = "0.29.0" 616 source = "registry+https://github.com/rust-lang/crates.io-index" 617 + checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd" 618 619 [[package]] 620 name = "h2" 621 + version = "0.3.26" 622 source = "registry+https://github.com/rust-lang/crates.io-index" 623 + checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" 624 dependencies = [ 625 "bytes", 626 "fnv", 627 "futures-core", 628 "futures-sink", 629 "futures-util", 630 + "http 0.2.12", 631 "indexmap", 632 "slab", 633 "tokio", ··· 637 638 [[package]] 639 name = "hashbrown" 640 + version = "0.14.5" 641 source = "registry+https://github.com/rust-lang/crates.io-index" 642 + checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" 643 644 [[package]] 645 name = "headers" ··· 647 source = "registry+https://github.com/rust-lang/crates.io-index" 648 checksum = "06683b93020a07e3dbcf5f8c0f6d40080d725bea7936fc01ad345c01b97dc270" 649 dependencies = [ 650 + "base64 0.21.7", 651 "bytes", 652 "headers-core", 653 + "http 0.2.12", 654 "httpdate", 655 "mime", 656 "sha1", ··· 662 source = "registry+https://github.com/rust-lang/crates.io-index" 663 checksum = "e7f66481bfee273957b1f20485a4ff3362987f85b2c236580d81b4eb7a326429" 664 dependencies = [ 665 + "http 0.2.12", 666 ] 667 668 [[package]] 669 + name = "heck" 670 + version = "0.5.0" 671 + source = "registry+https://github.com/rust-lang/crates.io-index" 672 + checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" 673 + 674 + [[package]] 675 name = "hermit-abi" 676 version = "0.3.9" 677 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 698 ] 699 700 [[package]] 701 + name = "http" 702 + version = "1.1.0" 703 + source = "registry+https://github.com/rust-lang/crates.io-index" 704 + checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" 705 + dependencies = [ 706 + "bytes", 707 + "fnv", 708 + "itoa", 709 + ] 710 + 711 + [[package]] 712 name = "http-body" 713 version = "0.4.6" 714 source = "registry+https://github.com/rust-lang/crates.io-index" 715 checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" 716 dependencies = [ 717 "bytes", 718 + "http 0.2.12", 719 "pin-project-lite", 720 ] 721 722 [[package]] 723 name = "httparse" 724 + version = "1.9.4" 725 source = "registry+https://github.com/rust-lang/crates.io-index" 726 + checksum = "0fcc0b4a115bf80b728eb8ea024ad5bd707b615bfed49e0665b6e0f86fd082d9" 727 728 [[package]] 729 name = "httpdate" ··· 739 740 [[package]] 741 name = "hyper" 742 + version = "0.14.30" 743 source = "registry+https://github.com/rust-lang/crates.io-index" 744 + checksum = "a152ddd61dfaec7273fe8419ab357f33aee0d914c5f4efbf0d96fa749eea5ec9" 745 dependencies = [ 746 "bytes", 747 "futures-channel", 748 "futures-core", 749 "futures-util", 750 "h2", 751 + "http 0.2.12", 752 "http-body", 753 "httparse", 754 "httpdate", ··· 762 ] 763 764 [[package]] 765 + name = "ident_case" 766 + version = "1.0.1" 767 + source = "registry+https://github.com/rust-lang/crates.io-index" 768 + checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" 769 + 770 + [[package]] 771 name = "idna" 772 version = "0.5.0" 773 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 779 780 [[package]] 781 name = "indexmap" 782 + version = "2.3.0" 783 source = "registry+https://github.com/rust-lang/crates.io-index" 784 + checksum = "de3fc2e30ba82dd1b3911c8de1ffc143c74a914a14e99514d7637e3099df5ea0" 785 dependencies = [ 786 "equivalent", 787 "hashbrown", ··· 799 ] 800 801 [[package]] 802 + name = "is_terminal_polyfill" 803 + version = "1.70.1" 804 + source = "registry+https://github.com/rust-lang/crates.io-index" 805 + checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" 806 + 807 + [[package]] 808 name = "itoa" 809 + version = "1.0.11" 810 source = "registry+https://github.com/rust-lang/crates.io-index" 811 + checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" 812 813 [[package]] 814 name = "js-sys" 815 + version = "0.3.70" 816 source = "registry+https://github.com/rust-lang/crates.io-index" 817 + checksum = "1868808506b929d7b0cfa8f75951347aa71bb21144b7791bae35d9bccfcfe37a" 818 dependencies = [ 819 "wasm-bindgen", 820 ] 821 822 [[package]] 823 name = "libc" 824 + version = "0.2.155" 825 source = "registry+https://github.com/rust-lang/crates.io-index" 826 + checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" 827 828 [[package]] 829 name = "linux-raw-sys" 830 + version = "0.4.14" 831 source = "registry+https://github.com/rust-lang/crates.io-index" 832 + checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" 833 834 [[package]] 835 name = "lock_api" 836 + version = "0.4.12" 837 source = "registry+https://github.com/rust-lang/crates.io-index" 838 + checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" 839 dependencies = [ 840 "autocfg", 841 "scopeguard", ··· 843 844 [[package]] 845 name = "log" 846 + version = "0.4.22" 847 source = "registry+https://github.com/rust-lang/crates.io-index" 848 + checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" 849 850 [[package]] 851 name = "lumen" ··· 857 "native-tls", 858 "pretty_env_logger", 859 "prometheus-client", 860 "tokio", 861 "tokio-native-tls", 862 "warp", ··· 874 875 [[package]] 876 name = "memchr" 877 + version = "2.7.4" 878 source = "registry+https://github.com/rust-lang/crates.io-index" 879 + checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" 880 881 [[package]] 882 name = "mime" ··· 886 887 [[package]] 888 name = "mime_guess" 889 + version = "2.0.5" 890 source = "registry+https://github.com/rust-lang/crates.io-index" 891 + checksum = "f7c44f8e672c00fe5308fa235f821cb4198414e1c77935c1ab6948d3fd78550e" 892 dependencies = [ 893 "mime", 894 "unicase", ··· 896 897 [[package]] 898 name = "miniz_oxide" 899 + version = "0.7.4" 900 source = "registry+https://github.com/rust-lang/crates.io-index" 901 + checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08" 902 dependencies = [ 903 "adler", 904 ] 905 906 [[package]] 907 name = "mio" 908 + version = "1.0.2" 909 source = "registry+https://github.com/rust-lang/crates.io-index" 910 + checksum = "80e04d1dcff3aae0704555fe5fee3bcfaf3d1fdf8a7e521d5b9d2b42acb52cec" 911 dependencies = [ 912 + "hermit-abi", 913 "libc", 914 "wasi", 915 + "windows-sys 0.52.0", 916 ] 917 918 [[package]] ··· 924 "bytes", 925 "encoding_rs", 926 "futures-util", 927 + "http 0.2.12", 928 "httparse", 929 "log", 930 "memchr", ··· 935 936 [[package]] 937 name = "native-tls" 938 + version = "0.2.12" 939 source = "registry+https://github.com/rust-lang/crates.io-index" 940 + checksum = "a8614eb2c83d59d1c8cc974dd3f920198647674a0a035e1af1fa58707e317466" 941 dependencies = [ 942 "libc", 943 "log", 944 "openssl", ··· 957 checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" 958 959 [[package]] 960 name = "object" 961 + version = "0.36.3" 962 source = "registry+https://github.com/rust-lang/crates.io-index" 963 + checksum = "27b64972346851a39438c60b341ebc01bba47464ae329e55cf343eb93964efd9" 964 dependencies = [ 965 "memchr", 966 ] ··· 973 974 [[package]] 975 name = "openssl" 976 + version = "0.10.66" 977 source = "registry+https://github.com/rust-lang/crates.io-index" 978 + checksum = "9529f4786b70a3e8c61e11179af17ab6188ad8d0ded78c5529441ed39d4bd9c1" 979 dependencies = [ 980 + "bitflags 2.6.0", 981 "cfg-if", 982 "foreign-types", 983 "libc", ··· 1005 1006 [[package]] 1007 name = "openssl-sys" 1008 + version = "0.9.103" 1009 source = "registry+https://github.com/rust-lang/crates.io-index" 1010 + checksum = "7f9e8deee91df40a943c71b917e5874b951d32a802526c85721ce3b776c929d6" 1011 dependencies = [ 1012 "cc", 1013 "libc", ··· 1017 1018 [[package]] 1019 name = "parking_lot" 1020 + version = "0.12.3" 1021 source = "registry+https://github.com/rust-lang/crates.io-index" 1022 + checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" 1023 dependencies = [ 1024 "lock_api", 1025 "parking_lot_core", ··· 1027 1028 [[package]] 1029 name = "parking_lot_core" 1030 + version = "0.9.10" 1031 source = "registry+https://github.com/rust-lang/crates.io-index" 1032 + checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" 1033 dependencies = [ 1034 "cfg-if", 1035 "libc", 1036 + "redox_syscall 0.5.3", 1037 "smallvec", 1038 + "windows-targets", 1039 ] 1040 1041 [[package]] ··· 1084 1085 [[package]] 1086 name = "pin-project-lite" 1087 + version = "0.2.14" 1088 source = "registry+https://github.com/rust-lang/crates.io-index" 1089 + checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" 1090 1091 [[package]] 1092 name = "pin-utils" ··· 1115 1116 [[package]] 1117 name = "postgres-protocol" 1118 + version = "0.6.7" 1119 source = "registry+https://github.com/rust-lang/crates.io-index" 1120 + checksum = "acda0ebdebc28befa84bee35e651e4c5f09073d668c7aed4cf7e23c3cda84b23" 1121 dependencies = [ 1122 + "base64 0.22.1", 1123 "byteorder", 1124 "bytes", 1125 "fallible-iterator", ··· 1133 1134 [[package]] 1135 name = "postgres-types" 1136 + version = "0.2.7" 1137 source = "registry+https://github.com/rust-lang/crates.io-index" 1138 + checksum = "02048d9e032fb3cc3413bbf7b83a15d84a5d419778e2628751896d856498eee9" 1139 dependencies = [ 1140 "bytes", 1141 "fallible-iterator", ··· 1150 1151 [[package]] 1152 name = "ppv-lite86" 1153 + version = "0.2.20" 1154 source = "registry+https://github.com/rust-lang/crates.io-index" 1155 + checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" 1156 + dependencies = [ 1157 + "zerocopy", 1158 + ] 1159 1160 [[package]] 1161 name = "pretty_env_logger" ··· 1169 1170 [[package]] 1171 name = "proc-macro2" 1172 + version = "1.0.86" 1173 source = "registry+https://github.com/rust-lang/crates.io-index" 1174 + checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" 1175 dependencies = [ 1176 "unicode-ident", 1177 ] 1178 1179 [[package]] 1180 name = "prometheus-client" 1181 + version = "0.22.3" 1182 source = "registry+https://github.com/rust-lang/crates.io-index" 1183 + checksum = "504ee9ff529add891127c4827eb481bd69dc0ebc72e9a682e187db4caa60c3ca" 1184 dependencies = [ 1185 "dtoa", 1186 "itoa", ··· 1201 1202 [[package]] 1203 name = "quote" 1204 + version = "1.0.36" 1205 source = "registry+https://github.com/rust-lang/crates.io-index" 1206 + checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" 1207 dependencies = [ 1208 "proc-macro2", 1209 ] ··· 1248 ] 1249 1250 [[package]] 1251 + name = "redox_syscall" 1252 + version = "0.5.3" 1253 + source = "registry+https://github.com/rust-lang/crates.io-index" 1254 + checksum = "2a908a6e00f1fdd0dfd9c0eb08ce85126f6d8bbda50017e74bc4a4b7d4a926a4" 1255 + dependencies = [ 1256 + "bitflags 2.6.0", 1257 + ] 1258 + 1259 + [[package]] 1260 name = "regex" 1261 + version = "1.10.6" 1262 source = "registry+https://github.com/rust-lang/crates.io-index" 1263 + checksum = "4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619" 1264 dependencies = [ 1265 "aho-corasick", 1266 "memchr", ··· 1270 1271 [[package]] 1272 name = "regex-automata" 1273 + version = "0.4.7" 1274 source = "registry+https://github.com/rust-lang/crates.io-index" 1275 + checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" 1276 dependencies = [ 1277 "aho-corasick", 1278 "memchr", ··· 1281 1282 [[package]] 1283 name = "regex-syntax" 1284 + version = "0.8.4" 1285 source = "registry+https://github.com/rust-lang/crates.io-index" 1286 + checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" 1287 1288 [[package]] 1289 name = "rustc-demangle" 1290 + version = "0.1.24" 1291 source = "registry+https://github.com/rust-lang/crates.io-index" 1292 + checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" 1293 1294 [[package]] 1295 name = "rustix" 1296 + version = "0.38.34" 1297 source = "registry+https://github.com/rust-lang/crates.io-index" 1298 + checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" 1299 dependencies = [ 1300 + "bitflags 2.6.0", 1301 "errno", 1302 "libc", 1303 "linux-raw-sys", ··· 1305 ] 1306 1307 [[package]] 1308 name = "ryu" 1309 + version = "1.0.18" 1310 source = "registry+https://github.com/rust-lang/crates.io-index" 1311 + checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" 1312 1313 [[package]] 1314 name = "schannel" ··· 1343 1344 [[package]] 1345 name = "security-framework" 1346 + version = "2.11.1" 1347 source = "registry+https://github.com/rust-lang/crates.io-index" 1348 + checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" 1349 dependencies = [ 1350 + "bitflags 2.6.0", 1351 "core-foundation", 1352 "core-foundation-sys", 1353 "libc", ··· 1356 1357 [[package]] 1358 name = "security-framework-sys" 1359 + version = "2.11.1" 1360 source = "registry+https://github.com/rust-lang/crates.io-index" 1361 + checksum = "75da29fe9b9b08fe9d6b22b5b4bcbc75d8db3aa31e639aa56bb62e9d46bfceaf" 1362 dependencies = [ 1363 "core-foundation-sys", 1364 "libc", ··· 1366 1367 [[package]] 1368 name = "serde" 1369 + version = "1.0.207" 1370 source = "registry+https://github.com/rust-lang/crates.io-index" 1371 + checksum = "5665e14a49a4ea1b91029ba7d3bca9f299e1f7cfa194388ccc20f14743e784f2" 1372 dependencies = [ 1373 "serde_derive", 1374 ] 1375 1376 [[package]] 1377 name = "serde_derive" 1378 + version = "1.0.207" 1379 source = "registry+https://github.com/rust-lang/crates.io-index" 1380 + checksum = "6aea2634c86b0e8ef2cfdc0c340baede54ec27b1e46febd7f80dffb2aa44a00e" 1381 dependencies = [ 1382 "proc-macro2", 1383 "quote", ··· 1386 1387 [[package]] 1388 name = "serde_json" 1389 + version = "1.0.124" 1390 source = "registry+https://github.com/rust-lang/crates.io-index" 1391 + checksum = "66ad62847a56b3dba58cc891acd13884b9c61138d330c0d7b6181713d4fce38d" 1392 dependencies = [ 1393 "itoa", 1394 + "memchr", 1395 "ryu", 1396 "serde", 1397 ] 1398 1399 [[package]] 1400 name = "serde_spanned" 1401 + version = "0.6.7" 1402 source = "registry+https://github.com/rust-lang/crates.io-index" 1403 + checksum = "eb5b1b31579f3811bf615c144393417496f152e12ac8b7663bf664f4a815306d" 1404 dependencies = [ 1405 "serde", 1406 ] ··· 1441 1442 [[package]] 1443 name = "signal-hook-registry" 1444 + version = "1.4.2" 1445 source = "registry+https://github.com/rust-lang/crates.io-index" 1446 + checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" 1447 dependencies = [ 1448 "libc", 1449 ] ··· 1471 1472 [[package]] 1473 name = "socket2" 1474 + version = "0.5.7" 1475 source = "registry+https://github.com/rust-lang/crates.io-index" 1476 + checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" 1477 dependencies = [ 1478 "libc", 1479 "windows-sys 0.52.0", ··· 1487 1488 [[package]] 1489 name = "stringprep" 1490 + version = "0.1.5" 1491 source = "registry+https://github.com/rust-lang/crates.io-index" 1492 + checksum = "7b4df3d392d81bd458a8a621b8bffbd2302a12ffe288a9d931670948749463b1" 1493 dependencies = [ 1494 "unicode-bidi", 1495 "unicode-normalization", 1496 + "unicode-properties", 1497 ] 1498 1499 [[package]] 1500 name = "strsim" 1501 + version = "0.11.1" 1502 source = "registry+https://github.com/rust-lang/crates.io-index" 1503 + checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" 1504 1505 [[package]] 1506 name = "subtle" 1507 + version = "2.6.1" 1508 source = "registry+https://github.com/rust-lang/crates.io-index" 1509 + checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" 1510 1511 [[package]] 1512 name = "syn" 1513 + version = "2.0.74" 1514 source = "registry+https://github.com/rust-lang/crates.io-index" 1515 + checksum = "1fceb41e3d546d0bd83421d3409b1460cc7444cd389341a4c880fe7a042cb3d7" 1516 dependencies = [ 1517 "proc-macro2", 1518 "quote", ··· 1521 1522 [[package]] 1523 name = "tempfile" 1524 + version = "3.12.0" 1525 source = "registry+https://github.com/rust-lang/crates.io-index" 1526 + checksum = "04cbcdd0c794ebb0d4cf35e88edd2f7d2c4c3e9a5a6dab322839b321c6a87a64" 1527 dependencies = [ 1528 "cfg-if", 1529 "fastrand", 1530 + "once_cell", 1531 "rustix", 1532 + "windows-sys 0.59.0", 1533 ] 1534 1535 [[package]] ··· 1543 1544 [[package]] 1545 name = "thiserror" 1546 + version = "1.0.63" 1547 source = "registry+https://github.com/rust-lang/crates.io-index" 1548 + checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724" 1549 dependencies = [ 1550 "thiserror-impl", 1551 ] 1552 1553 [[package]] 1554 name = "thiserror-impl" 1555 + version = "1.0.63" 1556 source = "registry+https://github.com/rust-lang/crates.io-index" 1557 + checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" 1558 dependencies = [ 1559 "proc-macro2", 1560 "quote", ··· 1563 1564 [[package]] 1565 name = "time" 1566 + version = "0.3.36" 1567 source = "registry+https://github.com/rust-lang/crates.io-index" 1568 + checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" 1569 dependencies = [ 1570 "deranged", 1571 "num-conv", ··· 1583 1584 [[package]] 1585 name = "time-macros" 1586 + version = "0.2.18" 1587 source = "registry+https://github.com/rust-lang/crates.io-index" 1588 + checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf" 1589 dependencies = [ 1590 "num-conv", 1591 "time-core", ··· 1593 1594 [[package]] 1595 name = "tinyvec" 1596 + version = "1.8.0" 1597 source = "registry+https://github.com/rust-lang/crates.io-index" 1598 + checksum = "445e881f4f6d382d5f27c034e25eb92edd7c784ceab92a0937db7f2e9471b938" 1599 dependencies = [ 1600 "tinyvec_macros", 1601 ] ··· 1608 1609 [[package]] 1610 name = "tokio" 1611 + version = "1.39.2" 1612 source = "registry+https://github.com/rust-lang/crates.io-index" 1613 + checksum = "daa4fb1bc778bd6f04cbfc4bb2d06a7396a8f299dc33ea1900cedaa316f467b1" 1614 dependencies = [ 1615 "backtrace", 1616 "bytes", 1617 "libc", 1618 "mio", 1619 "parking_lot", 1620 "pin-project-lite", 1621 "signal-hook-registry", 1622 "socket2", 1623 "tokio-macros", 1624 + "windows-sys 0.52.0", 1625 ] 1626 1627 [[package]] 1628 name = "tokio-macros" 1629 + version = "2.4.0" 1630 source = "registry+https://github.com/rust-lang/crates.io-index" 1631 + checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" 1632 dependencies = [ 1633 "proc-macro2", 1634 "quote", ··· 1647 1648 [[package]] 1649 name = "tokio-postgres" 1650 + version = "0.7.11" 1651 source = "registry+https://github.com/rust-lang/crates.io-index" 1652 + checksum = "03adcf0147e203b6032c0b2d30be1415ba03bc348901f3ff1cc0df6a733e60c3" 1653 dependencies = [ 1654 "async-trait", 1655 "byteorder", ··· 1672 ] 1673 1674 [[package]] 1675 name = "tokio-tungstenite" 1676 + version = "0.21.0" 1677 source = "registry+https://github.com/rust-lang/crates.io-index" 1678 + checksum = "c83b561d025642014097b66e6c1bb422783339e0909e4429cde4749d1990bc38" 1679 dependencies = [ 1680 "futures-util", 1681 "log", ··· 1685 1686 [[package]] 1687 name = "tokio-util" 1688 + version = "0.7.11" 1689 source = "registry+https://github.com/rust-lang/crates.io-index" 1690 + checksum = "9cf6b47b3771c49ac75ad09a6162f53ad4b8088b76ac60e8ec1455b31a189fe1" 1691 dependencies = [ 1692 "bytes", 1693 "futures-core", 1694 "futures-sink", 1695 "pin-project-lite", 1696 "tokio", 1697 ] 1698 1699 [[package]] 1700 name = "toml" 1701 + version = "0.8.19" 1702 source = "registry+https://github.com/rust-lang/crates.io-index" 1703 + checksum = "a1ed1f98e3fdc28d6d910e6737ae6ab1a93bf1985935a1193e68f93eeb68d24e" 1704 dependencies = [ 1705 "serde", 1706 "serde_spanned", ··· 1710 1711 [[package]] 1712 name = "toml_datetime" 1713 + version = "0.6.8" 1714 source = "registry+https://github.com/rust-lang/crates.io-index" 1715 + checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" 1716 dependencies = [ 1717 "serde", 1718 ] 1719 1720 [[package]] 1721 name = "toml_edit" 1722 + version = "0.22.20" 1723 source = "registry+https://github.com/rust-lang/crates.io-index" 1724 + checksum = "583c44c02ad26b0c3f3066fe629275e50627026c51ac2e595cca4c230ce1ce1d" 1725 dependencies = [ 1726 "indexmap", 1727 "serde", ··· 1764 1765 [[package]] 1766 name = "tungstenite" 1767 + version = "0.21.0" 1768 source = "registry+https://github.com/rust-lang/crates.io-index" 1769 + checksum = "9ef1a641ea34f399a848dea702823bbecfb4c486f911735368f1f137cb8257e1" 1770 dependencies = [ 1771 "byteorder", 1772 "bytes", 1773 "data-encoding", 1774 + "http 1.1.0", 1775 "httparse", 1776 "log", 1777 "rand", ··· 1818 ] 1819 1820 [[package]] 1821 + name = "unicode-properties" 1822 + version = "0.1.1" 1823 + source = "registry+https://github.com/rust-lang/crates.io-index" 1824 + checksum = "e4259d9d4425d9f0661581b804cb85fe66a4c631cadd8f490d1c13a35d5d9291" 1825 + 1826 + [[package]] 1827 name = "url" 1828 + version = "2.5.2" 1829 source = "registry+https://github.com/rust-lang/crates.io-index" 1830 + checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c" 1831 dependencies = [ 1832 "form_urlencoded", 1833 "idna", ··· 1842 1843 [[package]] 1844 name = "utf8parse" 1845 + version = "0.2.2" 1846 source = "registry+https://github.com/rust-lang/crates.io-index" 1847 + checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" 1848 1849 [[package]] 1850 name = "vcpkg" ··· 1854 1855 [[package]] 1856 name = "version_check" 1857 + version = "0.9.5" 1858 source = "registry+https://github.com/rust-lang/crates.io-index" 1859 + checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" 1860 1861 [[package]] 1862 name = "want" ··· 1869 1870 [[package]] 1871 name = "warp" 1872 + version = "0.3.7" 1873 source = "registry+https://github.com/rust-lang/crates.io-index" 1874 + checksum = "4378d202ff965b011c64817db11d5829506d3404edeadb61f190d111da3f231c" 1875 dependencies = [ 1876 "bytes", 1877 "futures-channel", 1878 "futures-util", 1879 "headers", 1880 + "http 0.2.12", 1881 "hyper", 1882 "log", 1883 "mime", ··· 1885 "multer", 1886 "percent-encoding", 1887 "pin-project", 1888 "scoped-tls", 1889 "serde", 1890 "serde_json", 1891 "serde_urlencoded", 1892 "tokio", 1893 "tokio-tungstenite", 1894 "tokio-util", 1895 "tower-service", ··· 1910 1911 [[package]] 1912 name = "wasm-bindgen" 1913 + version = "0.2.93" 1914 source = "registry+https://github.com/rust-lang/crates.io-index" 1915 + checksum = "a82edfc16a6c469f5f44dc7b571814045d60404b55a0ee849f9bcfa2e63dd9b5" 1916 dependencies = [ 1917 "cfg-if", 1918 + "once_cell", 1919 "wasm-bindgen-macro", 1920 ] 1921 1922 [[package]] 1923 name = "wasm-bindgen-backend" 1924 + version = "0.2.93" 1925 source = "registry+https://github.com/rust-lang/crates.io-index" 1926 + checksum = "9de396da306523044d3302746f1208fa71d7532227f15e347e2d93e4145dd77b" 1927 dependencies = [ 1928 "bumpalo", 1929 "log", ··· 1936 1937 [[package]] 1938 name = "wasm-bindgen-macro" 1939 + version = "0.2.93" 1940 source = "registry+https://github.com/rust-lang/crates.io-index" 1941 + checksum = "585c4c91a46b072c92e908d99cb1dcdf95c5218eeb6f3bf1efa991ee7a68cccf" 1942 dependencies = [ 1943 "quote", 1944 "wasm-bindgen-macro-support", ··· 1946 1947 [[package]] 1948 name = "wasm-bindgen-macro-support" 1949 + version = "0.2.93" 1950 source = "registry+https://github.com/rust-lang/crates.io-index" 1951 + checksum = "afc340c74d9005395cf9dd098506f7f44e38f2b4a21c6aaacf9a105ea5e1e836" 1952 dependencies = [ 1953 "proc-macro2", 1954 "quote", ··· 1959 1960 [[package]] 1961 name = "wasm-bindgen-shared" 1962 + version = "0.2.93" 1963 source = "registry+https://github.com/rust-lang/crates.io-index" 1964 + checksum = "c62a0a307cb4a311d3a07867860911ca130c3494e8c2719593806c08bc5d0484" 1965 1966 [[package]] 1967 name = "web-sys" 1968 + version = "0.3.70" 1969 source = "registry+https://github.com/rust-lang/crates.io-index" 1970 + checksum = "26fdeaafd9bd129f65e7c031593c24d62186301e0c72c8978fa1678be7d532c0" 1971 dependencies = [ 1972 "js-sys", 1973 "wasm-bindgen", ··· 1979 source = "registry+https://github.com/rust-lang/crates.io-index" 1980 checksum = "a44ab49fad634e88f55bf8f9bb3abd2f27d7204172a112c7c9987e01c1c94ea9" 1981 dependencies = [ 1982 + "redox_syscall 0.4.1", 1983 "wasite", 1984 "web-sys", 1985 ] 1986 1987 [[package]] 1988 name = "winapi-util" 1989 + version = "0.1.9" 1990 source = "registry+https://github.com/rust-lang/crates.io-index" 1991 + checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" 1992 dependencies = [ 1993 + "windows-sys 0.59.0", 1994 ] 1995 1996 [[package]] ··· 1999 source = "registry+https://github.com/rust-lang/crates.io-index" 2000 checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" 2001 dependencies = [ 2002 + "windows-targets", 2003 ] 2004 2005 [[package]] 2006 + name = "windows-sys" 2007 + version = "0.59.0" 2008 source = "registry+https://github.com/rust-lang/crates.io-index" 2009 + checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" 2010 dependencies = [ 2011 + "windows-targets", 2012 ] 2013 2014 [[package]] 2015 name = "windows-targets" 2016 + version = "0.52.6" 2017 source = "registry+https://github.com/rust-lang/crates.io-index" 2018 + checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" 2019 dependencies = [ 2020 + "windows_aarch64_gnullvm", 2021 + "windows_aarch64_msvc", 2022 + "windows_i686_gnu", 2023 + "windows_i686_gnullvm", 2024 + "windows_i686_msvc", 2025 + "windows_x86_64_gnu", 2026 + "windows_x86_64_gnullvm", 2027 + "windows_x86_64_msvc", 2028 ] 2029 2030 [[package]] 2031 name = "windows_aarch64_gnullvm" 2032 + version = "0.52.6" 2033 source = "registry+https://github.com/rust-lang/crates.io-index" 2034 + checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" 2035 2036 [[package]] 2037 name = "windows_aarch64_msvc" 2038 + version = "0.52.6" 2039 source = "registry+https://github.com/rust-lang/crates.io-index" 2040 + checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" 2041 2042 [[package]] 2043 name = "windows_i686_gnu" 2044 + version = "0.52.6" 2045 source = "registry+https://github.com/rust-lang/crates.io-index" 2046 + checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" 2047 2048 [[package]] 2049 + name = "windows_i686_gnullvm" 2050 + version = "0.52.6" 2051 source = "registry+https://github.com/rust-lang/crates.io-index" 2052 + checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" 2053 2054 [[package]] 2055 name = "windows_i686_msvc" 2056 + version = "0.52.6" 2057 source = "registry+https://github.com/rust-lang/crates.io-index" 2058 + checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" 2059 2060 [[package]] 2061 name = "windows_x86_64_gnu" 2062 + version = "0.52.6" 2063 source = "registry+https://github.com/rust-lang/crates.io-index" 2064 + checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" 2065 2066 [[package]] 2067 name = "windows_x86_64_gnullvm" 2068 + version = "0.52.6" 2069 source = "registry+https://github.com/rust-lang/crates.io-index" 2070 + checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" 2071 2072 [[package]] 2073 + name = "windows_x86_64_msvc" 2074 + version = "0.52.6" 2075 source = "registry+https://github.com/rust-lang/crates.io-index" 2076 + checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" 2077 2078 [[package]] 2079 + name = "winnow" 2080 + version = "0.6.18" 2081 source = "registry+https://github.com/rust-lang/crates.io-index" 2082 + checksum = "68a9bda4691f099d435ad181000724da8e5899daa10713c2d432552b9ccd3a6f" 2083 + dependencies = [ 2084 + "memchr", 2085 + ] 2086 2087 [[package]] 2088 + name = "zerocopy" 2089 + version = "0.7.35" 2090 source = "registry+https://github.com/rust-lang/crates.io-index" 2091 + checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" 2092 + dependencies = [ 2093 + "byteorder", 2094 + "zerocopy-derive", 2095 + ] 2096 2097 [[package]] 2098 + name = "zerocopy-derive" 2099 + version = "0.7.35" 2100 source = "registry+https://github.com/rust-lang/crates.io-index" 2101 + checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" 2102 dependencies = [ 2103 + "proc-macro2", 2104 + "quote", 2105 + "syn", 2106 ]
+4 -4
Dockerfile
··· 1 - FROM rust:1.74.1-slim-buster 2 ARG DEBIAN_FRONTEND=noninteractive 3 RUN apt-get update && apt-get install -y --no-install-recommends --no-install-suggests ca-certificates pkg-config libssl-dev libpq-dev 4 ENV CARGO_REGISTRIES_CRATES_IO_PROTOCOL=sparse 5 6 RUN --mount=type=cache,target=$CARGO_HOME/registry \ 7 - cargo install diesel_cli --version 2.1.1 --no-default-features --features postgres 8 9 COPY common /lumen/common 10 COPY lumen /lumen/lumen 11 COPY Cargo.toml /lumen/ 12 RUN --mount=type=cache,target=$CARGO_HOME/registry,target=/lumen/target \ 13 - cd /lumen && cargo build --release && cp /lumen/target/release/lumen /root/ 14 15 FROM debian:buster-slim 16 ARG DEBIAN_FRONTEND=noninteractive 17 RUN apt-get update && apt-get install -y --no-install-recommends --no-install-suggests openssl libpq5 && \ 18 - sed -i -e 's,\[ v3_req \],\[ v3_req \]\nextendedKeyUsage = serverAuth,' /etc/ssl/openssl.cnf 19 RUN mkdir /usr/lib/lumen/ 20 21 COPY --from=0 /usr/local/cargo/bin/diesel /usr/bin/diesel
··· 1 + FROM rust:1.80.1-slim 2 ARG DEBIAN_FRONTEND=noninteractive 3 RUN apt-get update && apt-get install -y --no-install-recommends --no-install-suggests ca-certificates pkg-config libssl-dev libpq-dev 4 ENV CARGO_REGISTRIES_CRATES_IO_PROTOCOL=sparse 5 6 RUN --mount=type=cache,target=$CARGO_HOME/registry \ 7 + cargo install diesel_cli --version 2.2.1 --no-default-features --features postgres 8 9 COPY common /lumen/common 10 COPY lumen /lumen/lumen 11 COPY Cargo.toml /lumen/ 12 RUN --mount=type=cache,target=$CARGO_HOME/registry,target=/lumen/target \ 13 + cd /lumen && cargo build --release && cp /lumen/target/release/lumen /root/ 14 15 FROM debian:buster-slim 16 ARG DEBIAN_FRONTEND=noninteractive 17 RUN apt-get update && apt-get install -y --no-install-recommends --no-install-suggests openssl libpq5 && \ 18 + sed -i -e 's,\[ v3_req \],\[ v3_req \]\nextendedKeyUsage = serverAuth,' /etc/ssl/openssl.cnf 19 RUN mkdir /usr/lib/lumen/ 20 21 COPY --from=0 /usr/local/cargo/bin/diesel /usr/bin/diesel
+26 -15
common/Cargo.toml
··· 7 publish = false 8 9 [dependencies] 10 - tokio = {version = "1.32", features = ["full"], optional = true} 11 - log = {version = "0.4", features = ["release_max_level_debug"]} 12 - serde = {version = "1.0", features = ["derive"]} 13 - postgres-native-tls = {version = "0.5", optional = true} 14 - native-tls = {version = "0.2", optional = true} 15 futures-util = "0.3" 16 toml = "0.8" 17 - warp = {version = "0.3", optional = true} 18 binascii = "0.1" 19 20 - tokio-postgres = {version = "0.7", default-features = false, optional = true} 21 - diesel = {version = "2.1", optional = true, default-features = false, features = ["postgres_backend", "time"]} 22 - time = {version = "0.3.31", optional = true} 23 - diesel-async = {version = "0.4.1", optional = true, features = ["postgres", "bb8"]} 24 anyhow = "1.0" 25 - prometheus-client = "0.22.0" 26 - pbkdf2 = { version = "0.12.2" } 27 - sha2 = "0.10.8" 28 - rand = "0.8.5" 29 30 [features] 31 default = ["web", "db"] 32 web = ["warp"] 33 - db = ["tokio", "postgres-native-tls", "native-tls", "diesel", "diesel-async", "tokio-postgres", "time"]
··· 7 publish = false 8 9 [dependencies] 10 + tokio = { version = "1.39", features = ["full"], optional = true } 11 + log = { version = "0.4", features = ["release_max_level_debug"] } 12 + serde = { version = "1.0", features = ["derive"] } 13 + postgres-native-tls = { version = "0.5", optional = true } 14 + native-tls = { version = "0.2", optional = true } 15 futures-util = "0.3" 16 toml = "0.8" 17 + warp = { version = "0.3", optional = true } 18 binascii = "0.1" 19 20 + tokio-postgres = { version = "0.7", default-features = false, optional = true } 21 + diesel = { version = "2.2", optional = true, default-features = false, features = [ 22 + "postgres_backend", 23 + "time", 24 + ] } 25 + time = { version = "0.3.36", optional = true } 26 + diesel-async = { version = "0.5", optional = true, features = [ 27 + "postgres", 28 + "bb8", 29 + ] } 30 anyhow = "1.0" 31 + prometheus-client = "0.22" 32 33 [features] 34 default = ["web", "db"] 35 web = ["warp"] 36 + db = [ 37 + "tokio", 38 + "postgres-native-tls", 39 + "native-tls", 40 + "diesel", 41 + "diesel-async", 42 + "tokio-postgres", 43 + "time", 44 + ]
-21
common/migrations/2024-01-20-215809_users/down.sql
··· 1 - -- don't allow table to be modified until we're done... 2 - LOCK TABLE users; 3 - 4 - -- delete funcs that belong to users 5 - DELETE FROM funcs USING dbs, users 6 - WHERE dbs.id=funcs.db_id 7 - AND users.id=dbs.user_id 8 - AND users.cred_id IS NOT NULL; 9 - 10 - -- delete dbs that belong to users 11 - DELETE FROM dbs USING users WHERE dbs.user_id=users.id AND users.cred_id IS NOT NULL; 12 - 13 - -- delete all users with creds... 14 - DELETE FROM users WHERE cred_id is NOT NULL; 15 - DROP TABLE creds CASCADE; 16 - 17 - CREATE UNIQUE INDEX IF NOT EXISTS user_rec ON users(lic_id,lic_data,hostname); 18 - CREATE UNIQUE INDEX IF NOT EXISTS user_hn_null ON users (lic_id,lic_data, (hostname IS NULL)) WHERE hostname is NULL; 19 - DROP INDEX user_cred_idx; 20 - 21 - ALTER TABLE users DROP COLUMN cred_id;
···
-22
common/migrations/2024-01-20-215809_users/up.sql
··· 1 - CREATE TABLE creds ( 2 - id SERIAL PRIMARY KEY, 3 - 4 - username VARCHAR(256) UNIQUE NOT NULL, 5 - email VARCHAR(256) UNIQUE NOT NULL, 6 - 7 - passwd_salt bytea, 8 - passwd_iters INTEGER NOT NULL DEFAULT 10000, 9 - passwd_hash bytea, 10 - 11 - last_active TIMESTAMPTZ, 12 - creation_dt TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP NOT NULL, 13 - 14 - is_admin BOOLEAN NOT NULL DEFAULT FALSE, 15 - is_enabled BOOLEAN NOT NULL DEFAULT TRUE 16 - ); 17 - 18 - ALTER TABLE users ADD COLUMN cred_id INTEGER REFERENCES creds(id) ON DELETE CASCADE; 19 - 20 - CREATE UNIQUE INDEX user_cred_idx ON users(lic_id,lic_data,hostname,cred_id) NULLS NOT DISTINCT; 21 - DROP INDEX user_hn_null; 22 - DROP INDEX user_rec;
···
+3 -36
common/src/config.rs
··· 1 use serde::Deserialize; 2 - use std::num::NonZeroU32; 3 use std::time::Duration; 4 use std::{net::SocketAddr, path::PathBuf}; 5 use toml::from_str; ··· 10 } 11 12 #[derive(Deserialize)] 13 - #[serde(default)] 14 pub struct LuminaServer { 15 pub bind_addr: SocketAddr, 16 - pub use_tls: bool, 17 pub tls: Option<TlsIdentity>, 18 pub server_name: Option<String>, 19 - pub allow_deletes: bool, 20 21 /// limit of function histories to return per function. 22 /// `None`, or `Some(0)` will disable the feature on the server. 23 - pub get_history_limit: NonZeroU32, 24 - } 25 - impl Default for LuminaServer { 26 - fn default() -> Self { 27 - Self { 28 - bind_addr: "0.0.0.0:1234".parse().unwrap(), 29 - use_tls: false, 30 - tls: None, 31 - server_name: None, 32 - allow_deletes: false, 33 - get_history_limit: NonZeroU32::new(50).unwrap(), 34 - } 35 - } 36 } 37 38 #[derive(Deserialize)] ··· 77 } 78 79 #[derive(Deserialize)] 80 - #[serde(default)] 81 - pub struct Users { 82 - /// Sets if guests are allowed to login. required for IDA<8.1 83 - pub allow_guests: bool, 84 - 85 - /// PBKDF2 iterations for newly set passwords. 86 - pub pbkdf2_iterations: NonZeroU32, 87 - } 88 - 89 - impl Default for Users { 90 - fn default() -> Self { 91 - Self { allow_guests: true, pbkdf2_iterations: NonZeroU32::new(120_000).unwrap() } 92 - } 93 - } 94 - 95 - #[derive(Deserialize)] 96 pub struct Config { 97 pub lumina: LuminaServer, 98 pub api_server: Option<WebServer>, ··· 100 101 #[serde(default)] 102 pub limits: Limits, 103 - 104 - #[serde(default)] 105 - pub users: Users, 106 } 107 108 pub trait HasConfig {
··· 1 use serde::Deserialize; 2 use std::time::Duration; 3 use std::{net::SocketAddr, path::PathBuf}; 4 use toml::from_str; ··· 9 } 10 11 #[derive(Deserialize)] 12 pub struct LuminaServer { 13 pub bind_addr: SocketAddr, 14 + pub use_tls: Option<bool>, 15 pub tls: Option<TlsIdentity>, 16 pub server_name: Option<String>, 17 + pub allow_deletes: Option<bool>, 18 19 /// limit of function histories to return per function. 20 /// `None`, or `Some(0)` will disable the feature on the server. 21 + pub get_history_limit: Option<u32>, 22 } 23 24 #[derive(Deserialize)] ··· 63 } 64 65 #[derive(Deserialize)] 66 pub struct Config { 67 pub lumina: LuminaServer, 68 pub api_server: Option<WebServer>, ··· 70 71 #[serde(default)] 72 pub limits: Limits, 73 } 74 75 pub trait HasConfig {
+17 -131
common/src/db/mod.rs
··· 1 - use crate::{ 2 - async_drop::{AsyncDropGuard, AsyncDropper}, 3 - db::schema::Creds, 4 - }; 5 use log::*; 6 use postgres_native_tls::MakeTlsConnector; 7 use serde::Serialize; ··· 15 query_builder::{Query, QueryFragment}, 16 sql_types::{Array, Binary, Integer, VarChar}, 17 upsert::excluded, 18 - ExpressionMethods, NullableExpressionMethods, QueryDsl, SelectableHelper, 19 }; 20 use diesel_async::{pooled_connection::ManagerConfig, RunQueryDsl}; 21 - 22 - use self::schema::creds; 23 24 pub type DynConfig = dyn crate::config::HasConfig + Send + Sync; 25 ··· 140 } 141 142 pub async fn get_funcs( 143 - &self, funcs: &[crate::rpc::PatternId<'_>], 144 ) -> Result<Vec<Option<FunctionInfo>>, anyhow::Error> { 145 - let chksums: Vec<&[u8]> = funcs.iter().map(|v| v.data).collect(); 146 147 let rows: Vec<(String, i32, Vec<u8>, Vec<u8>)> = { 148 let conn = &mut self.diesel.get().await?; ··· 174 } 175 176 pub async fn get_or_create_user<'a>( 177 - &self, user: &'a crate::rpc::RpcHello<'a>, cred_id: Option<i32>, hostname: &str, 178 ) -> Result<i32, anyhow::Error> { 179 use schema::users; 180 ··· 184 let lic_data = user.license_data; 185 186 let get_user = || { 187 - let query = users::table 188 - .into_boxed() 189 .select(users::id) 190 .filter(users::lic_data.eq(lic_data)) 191 .filter(users::lic_id.eq(lic_id)) 192 - .filter(users::hostname.eq(hostname)); 193 - 194 - if let Some(cred_id) = cred_id { 195 - query.filter(users::cred_id.eq(cred_id)) 196 - } else { 197 - query.filter(users::cred_id.is_null()) 198 - } 199 }; 200 201 match get_user().get_result::<i32>(conn).await { ··· 209 users::lic_id.eq(lic_id), 210 users::lic_data.eq(lic_data), 211 users::hostname.eq(hostname), 212 - users::cred_id.eq(cred_id), 213 )]) 214 .returning(users::id) // xmax = 0 if the row is new 215 .get_result::<i32>(conn) ··· 231 ) -> Result<i32, anyhow::Error> { 232 use schema::files::{chksum, id, table as files}; 233 234 - let hash = &funcs.input_md5[..]; 235 236 let conn = &mut self.diesel.get().await?; 237 ··· 260 } 261 262 async fn get_or_create_db<'a>( 263 - &self, user: &'a crate::rpc::RpcHello<'a>, cred_id: Option<i32>, 264 - funcs: &'a crate::rpc::PushMetadata<'a>, 265 ) -> Result<i32, anyhow::Error> { 266 use schema::dbs::{ 267 file_id as db_file_id, file_path, id as db_id, idb_path, table as dbs, ··· 269 }; 270 271 let file_id = self.get_or_create_file(funcs); 272 - let user_id = self.get_or_create_user(user, cred_id, funcs.hostname); 273 274 let (file_id, user_id): (i32, i32) = futures_util::try_join!(file_id, user_id)?; 275 ··· 279 dbs.select(db_id) 280 .filter(db_user.eq(user_id)) 281 .filter(db_file_id.eq(file_id)) 282 - .filter(file_path.eq(funcs.input_path)) 283 .filter(idb_path.eq(funcs.idb_path)) 284 }; 285 ··· 293 .values(vec![( 294 db_user.eq(user_id), 295 db_file_id.eq(file_id), 296 - file_path.eq(funcs.input_path), 297 idb_path.eq(funcs.idb_path), 298 )]) 299 .returning(db_id) ··· 311 } 312 313 pub async fn push_funcs<'a, 'b>( 314 - &'b self, user: &'a crate::rpc::RpcHello<'a>, cred_id: Option<i32>, 315 - funcs: &'a crate::rpc::PushMetadata<'a>, scores: &[u32], 316 ) -> Result<Vec<bool>, anyhow::Error> { 317 use futures_util::TryStreamExt; 318 319 // postgres has a limitation of binding per statement (i16::MAX). Split large push requests into smaller chunks. 320 const PUSH_FUNC_CHUNK_SIZE: usize = 3000; 321 322 - let db_id = self.get_or_create_db(user, cred_id, funcs).await?; 323 324 let mut rows = Vec::with_capacity(funcs.funcs.len().min(PUSH_FUNC_CHUNK_SIZE)); 325 let mut is_new = Vec::with_capacity(funcs.funcs.len()); ··· 329 for (idx, (func, &score)) in funcs.funcs.iter().zip(scores.iter()).enumerate() { 330 let name = func.name; 331 let len = func.func_len as i32; 332 - let chksum = func.pattern_id.data; 333 let md = func.func_data; 334 let score = score as i32; 335 ··· 432 ) -> Result<(), anyhow::Error> { 433 use schema::funcs::{chksum, table as funcs}; 434 435 - let chksums = req.calcrel_hashes.iter().map(|v| v.as_slice()).collect::<Vec<_>>(); 436 437 let conn = &mut self.diesel.get().await?; 438 let rows_modified = ··· 459 .get_results::<(time::OffsetDateTime, String, Vec<u8>)>(conn) 460 .await?; 461 Ok(rows) 462 - } 463 - 464 - pub async fn get_users(&self) -> Result<Vec<(i32, String, String, bool, bool)>, anyhow::Error> { 465 - let db = &mut self.diesel.get().await?; 466 - 467 - creds::table 468 - .select(( 469 - creds::id, 470 - creds::username, 471 - creds::email, 472 - creds::is_admin, 473 - creds::passwd_hash.is_not_null(), 474 - )) 475 - .get_results::<(i32, String, String, bool, bool)>(db) 476 - .await 477 - .map_err(|v| v.into()) 478 - } 479 - 480 - pub async fn delete_user(&self, username: &str) -> Result<(), anyhow::Error> { 481 - let db = &mut self.diesel.get().await?; 482 - 483 - let changes = 484 - diesel::delete(creds::table.filter(creds::username.eq(username))).execute(db).await?; 485 - if changes != 1 { 486 - return Err(anyhow::anyhow!("expected a single row deletion, got {changes}")); 487 - } 488 - Ok(()) 489 - } 490 - 491 - pub async fn set_password( 492 - &self, username: &str, password: String, iters: u32, 493 - ) -> Result<(), anyhow::Error> { 494 - let (salt, hash) = 495 - tokio::task::spawn_blocking(move || Creds::generate_creds(&password, iters)).await?; 496 - 497 - let db = &mut self.diesel.get().await?; 498 - let rows = diesel::update(creds::table) 499 - .filter(creds::username.eq(username)) 500 - .set(( 501 - creds::passwd_iters.eq(iters as i32), 502 - creds::passwd_salt.eq(&salt[..]), 503 - creds::passwd_hash.eq(&hash[..]), 504 - )) 505 - .execute(db) 506 - .await?; 507 - if rows != 1 { 508 - return Err(anyhow::anyhow!("updated {rows} rows, expected to update 1")); 509 - } 510 - Ok(()) 511 - } 512 - 513 - pub async fn add_user( 514 - &self, username: &str, email: &str, is_admin: bool, 515 - ) -> Result<u32, anyhow::Error> { 516 - let db = &mut self.diesel.get().await?; 517 - 518 - diesel::insert_into(creds::table) 519 - .values(&Creds { 520 - username: username.into(), 521 - email: email.into(), 522 - passwd_salt: None, 523 - passwd_iters: 10_000, 524 - passwd_hash: None, 525 - last_active: None, 526 - is_enabled: true, 527 - is_admin, 528 - }) 529 - .returning(creds::id) 530 - .get_result::<i32>(db) 531 - .await 532 - .map_err(|v| v.into()) 533 - .map(|v| v as u32) 534 - } 535 - 536 - pub async fn get_user_by_username( 537 - &self, username: &str, 538 - ) -> Result<(i32, Creds), anyhow::Error> { 539 - let db = &mut self.diesel.get().await?; 540 - 541 - Ok(creds::table 542 - .select((creds::id, Creds::as_select())) 543 - .filter(creds::username.eq(username)) 544 - .get_result::<(i32, Creds)>(db) 545 - .await?) 546 - } 547 - 548 - pub async fn get_user_by_id(&self, id: i32) -> Result<Creds, anyhow::Error> { 549 - let db = &mut self.diesel.get().await?; 550 - 551 - Ok(creds::table.select(Creds::as_select()).filter(creds::id.eq(id)).get_result(db).await?) 552 - } 553 - 554 - pub async fn update_last_active(&self, user_id: i32) -> Result<(), anyhow::Error> { 555 - let mut db = self.diesel.get().await?; 556 - diesel::update(schema::creds::table) 557 - .filter(schema::creds::id.eq(user_id)) 558 - .set((schema::creds::last_active.eq(time::OffsetDateTime::now_utc()),)) 559 - .execute(&mut db) 560 - .await?; 561 - Ok(()) 562 } 563 } 564
··· 1 + use crate::async_drop::{AsyncDropGuard, AsyncDropper}; 2 use log::*; 3 use postgres_native_tls::MakeTlsConnector; 4 use serde::Serialize; ··· 12 query_builder::{Query, QueryFragment}, 13 sql_types::{Array, Binary, Integer, VarChar}, 14 upsert::excluded, 15 + ExpressionMethods, NullableExpressionMethods, QueryDsl, 16 }; 17 use diesel_async::{pooled_connection::ManagerConfig, RunQueryDsl}; 18 19 pub type DynConfig = dyn crate::config::HasConfig + Send + Sync; 20 ··· 135 } 136 137 pub async fn get_funcs( 138 + &self, funcs: &[crate::rpc::PullMetadataFunc<'_>], 139 ) -> Result<Vec<Option<FunctionInfo>>, anyhow::Error> { 140 + let chksums: Vec<&[u8]> = funcs.iter().map(|v| v.mb_hash).collect(); 141 142 let rows: Vec<(String, i32, Vec<u8>, Vec<u8>)> = { 143 let conn = &mut self.diesel.get().await?; ··· 169 } 170 171 pub async fn get_or_create_user<'a>( 172 + &self, user: &'a crate::rpc::RpcHello<'a>, hostname: &str, 173 ) -> Result<i32, anyhow::Error> { 174 use schema::users; 175 ··· 179 let lic_data = user.license_data; 180 181 let get_user = || { 182 + users::table 183 .select(users::id) 184 .filter(users::lic_data.eq(lic_data)) 185 .filter(users::lic_id.eq(lic_id)) 186 + .filter(users::hostname.eq(hostname)) 187 }; 188 189 match get_user().get_result::<i32>(conn).await { ··· 197 users::lic_id.eq(lic_id), 198 users::lic_data.eq(lic_data), 199 users::hostname.eq(hostname), 200 )]) 201 .returning(users::id) // xmax = 0 if the row is new 202 .get_result::<i32>(conn) ··· 218 ) -> Result<i32, anyhow::Error> { 219 use schema::files::{chksum, id, table as files}; 220 221 + let hash = &funcs.md5[..]; 222 223 let conn = &mut self.diesel.get().await?; 224 ··· 247 } 248 249 async fn get_or_create_db<'a>( 250 + &self, user: &'a crate::rpc::RpcHello<'a>, funcs: &'a crate::rpc::PushMetadata<'a>, 251 ) -> Result<i32, anyhow::Error> { 252 use schema::dbs::{ 253 file_id as db_file_id, file_path, id as db_id, idb_path, table as dbs, ··· 255 }; 256 257 let file_id = self.get_or_create_file(funcs); 258 + let user_id = self.get_or_create_user(user, funcs.hostname); 259 260 let (file_id, user_id): (i32, i32) = futures_util::try_join!(file_id, user_id)?; 261 ··· 265 dbs.select(db_id) 266 .filter(db_user.eq(user_id)) 267 .filter(db_file_id.eq(file_id)) 268 + .filter(file_path.eq(funcs.file_path)) 269 .filter(idb_path.eq(funcs.idb_path)) 270 }; 271 ··· 279 .values(vec![( 280 db_user.eq(user_id), 281 db_file_id.eq(file_id), 282 + file_path.eq(funcs.file_path), 283 idb_path.eq(funcs.idb_path), 284 )]) 285 .returning(db_id) ··· 297 } 298 299 pub async fn push_funcs<'a, 'b>( 300 + &'b self, user: &'a crate::rpc::RpcHello<'a>, funcs: &'a crate::rpc::PushMetadata<'a>, 301 + scores: &[u32], 302 ) -> Result<Vec<bool>, anyhow::Error> { 303 use futures_util::TryStreamExt; 304 305 // postgres has a limitation of binding per statement (i16::MAX). Split large push requests into smaller chunks. 306 const PUSH_FUNC_CHUNK_SIZE: usize = 3000; 307 308 + let db_id = self.get_or_create_db(user, funcs).await?; 309 310 let mut rows = Vec::with_capacity(funcs.funcs.len().min(PUSH_FUNC_CHUNK_SIZE)); 311 let mut is_new = Vec::with_capacity(funcs.funcs.len()); ··· 315 for (idx, (func, &score)) in funcs.funcs.iter().zip(scores.iter()).enumerate() { 316 let name = func.name; 317 let len = func.func_len as i32; 318 + let chksum = func.hash; 319 let md = func.func_data; 320 let score = score as i32; 321 ··· 418 ) -> Result<(), anyhow::Error> { 419 use schema::funcs::{chksum, table as funcs}; 420 421 + let chksums = req.funcs.iter().map(|v| v.as_slice()).collect::<Vec<_>>(); 422 423 let conn = &mut self.diesel.get().await?; 424 let rows_modified = ··· 445 .get_results::<(time::OffsetDateTime, String, Vec<u8>)>(conn) 446 .await?; 447 Ok(rows) 448 } 449 } 450
-78
common/src/db/schema.rs
··· 1 - use std::borrow::Cow; 2 - 3 - use diesel::{Insertable, Queryable, Selectable}; 4 - use log::error; 5 - use pbkdf2::{hmac::Hmac, pbkdf2}; 6 - use sha2::Sha256; 7 - 8 pub use super::schema_auto::*; 9 10 diesel::table! { ··· 22 } 23 24 diesel::joinable!(func_ranks -> dbs (id)); 25 - 26 - #[derive(Insertable, Queryable, Selectable, Default)] 27 - #[diesel(table_name = creds)] 28 - pub struct Creds<'a> { 29 - pub username: Cow<'a, str>, 30 - pub email: Cow<'a, str>, 31 - 32 - pub passwd_salt: Option<Cow<'a, [u8]>>, 33 - pub passwd_iters: i32, 34 - pub passwd_hash: Option<Cow<'a, [u8]>>, 35 - 36 - pub last_active: Option<time::OffsetDateTime>, 37 - 38 - pub is_admin: bool, 39 - pub is_enabled: bool, 40 - } 41 - 42 - impl<'a> Creds<'a> { 43 - pub fn verify_password(&self, password: &str) -> bool { 44 - let salt = if let Some(v) = self.passwd_salt.as_ref() { 45 - v 46 - } else { 47 - return false; 48 - }; 49 - let current_hash = if let Some(v) = self.passwd_hash.as_ref() { 50 - v 51 - } else { 52 - return false; 53 - }; 54 - if self.passwd_iters <= 0 { 55 - return false; 56 - } 57 - 58 - let mut hash = vec![0u8; 32]; 59 - if pbkdf2::<Hmac<Sha256>>(password.as_bytes(), salt, self.passwd_iters as u32, &mut hash) 60 - .is_err() 61 - { 62 - error!("invalid output digest length"); 63 - return false; 64 - } 65 - 66 - hash == current_hash.as_ref() 67 - } 68 - 69 - pub(crate) fn generate_creds(password: &str, iters: u32) -> ([u8; 4], [u8; 32]) { 70 - let salt: [u8; 4] = rand::random(); 71 - let mut res = [0u8; 32]; 72 - pbkdf2::pbkdf2::<Hmac<Sha256>>(password.as_bytes(), &salt, iters, &mut res) 73 - .expect("failed to perform pbkdf2_hmac_sha256"); 74 - (salt, res) 75 - } 76 - } 77 - 78 - #[cfg(test)] 79 - mod tests { 80 - use super::*; 81 - 82 - #[test] 83 - fn generate_and_verify_password() { 84 - let password = "MyPassword1$"; 85 - let iters = 10_000; 86 - let (salt, hash) = Creds::generate_creds(password, iters); 87 - let creds = Creds { 88 - passwd_hash: Some((&hash[..]).into()), 89 - passwd_salt: Some((&salt[..]).into()), 90 - passwd_iters: iters as i32, 91 - ..Default::default() 92 - }; 93 - assert!(creds.verify_password(password), "failed to verify password"); 94 - } 95 - }
··· 1 pub use super::schema_auto::*; 2 3 diesel::table! { ··· 15 } 16 17 diesel::joinable!(func_ranks -> dbs (id));
+1 -29
common/src/db/schema_auto.rs
··· 1 // @generated automatically by Diesel CLI. 2 3 diesel::table! { 4 - creds (id) { 5 - id -> Int4, 6 - #[max_length = 256] 7 - username -> Varchar, 8 - #[max_length = 256] 9 - email -> Varchar, 10 - passwd_salt -> Nullable<Bytea>, 11 - passwd_iters -> Int4, 12 - passwd_hash -> Nullable<Bytea>, 13 - last_active -> Nullable<Timestamptz>, 14 - creation_dt -> Timestamptz, 15 - is_admin -> Bool, 16 - is_enabled -> Bool, 17 - } 18 - } 19 - 20 - diesel::table! { 21 dbs (id) { 22 id -> Int4, 23 - #[max_length = 260] 24 file_path -> Nullable<Varchar>, 25 - #[max_length = 260] 26 idb_path -> Nullable<Varchar>, 27 file_id -> Nullable<Int4>, 28 user_id -> Nullable<Int4>, ··· 55 id -> Int4, 56 lic_id -> Nullable<Bytea>, 57 lic_data -> Nullable<Bytea>, 58 - #[max_length = 260] 59 hostname -> Nullable<Varchar>, 60 first_seen -> Nullable<Timestamptz>, 61 - cred_id -> Nullable<Int4>, 62 } 63 } 64 65 diesel::joinable!(dbs -> files (file_id)); 66 diesel::joinable!(dbs -> users (user_id)); 67 diesel::joinable!(funcs -> dbs (db_id)); 68 - diesel::joinable!(users -> creds (cred_id)); 69 70 - diesel::allow_tables_to_appear_in_same_query!( 71 - creds, 72 - dbs, 73 - files, 74 - funcs, 75 - users, 76 - );
··· 1 // @generated automatically by Diesel CLI. 2 3 diesel::table! { 4 dbs (id) { 5 id -> Int4, 6 file_path -> Nullable<Varchar>, 7 idb_path -> Nullable<Varchar>, 8 file_id -> Nullable<Int4>, 9 user_id -> Nullable<Int4>, ··· 36 id -> Int4, 37 lic_id -> Nullable<Bytea>, 38 lic_data -> Nullable<Bytea>, 39 hostname -> Nullable<Varchar>, 40 first_seen -> Nullable<Timestamptz>, 41 } 42 } 43 44 diesel::joinable!(dbs -> files (file_id)); 45 diesel::joinable!(dbs -> users (user_id)); 46 diesel::joinable!(funcs -> dbs (db_id)); 47 48 + diesel::allow_tables_to_appear_in_same_query!(dbs, files, funcs, users,);
+38 -35
common/src/rpc/messages.rs
··· 3 4 #[derive(Deserialize, Serialize)] 5 pub struct RpcFail<'a> { 6 - pub result: u32, 7 - pub error: &'a str, 8 } 9 10 #[derive(Serialize, Deserialize)] 11 pub struct RpcNotify<'a> { 12 - pub ty: u32, 13 - pub text: &'a str, 14 } 15 16 #[derive(Serialize, Deserialize, Debug)] ··· 21 22 #[derive(Serialize, Deserialize)] 23 pub struct RpcHello<'a> { 24 - pub client_version: u32, 25 pub license_data: &'a [u8], 26 pub lic_number: [u8; 6], 27 - pub record_conv: u32, 28 } 29 30 #[derive(Debug, Deserialize, Serialize, Clone)] 31 - pub struct PatternId<'a> { 32 - pub ty: u32, 33 - pub data: &'a [u8], 34 } 35 36 #[derive(Deserialize, Serialize)] 37 pub struct PullMetadata<'a> { 38 - pub flags: u32, 39 - pub keys: Cow<'a, [u32]>, 40 41 #[serde(borrow)] 42 - pub pattern_ids: Cow<'a, [PatternId<'a>]>, 43 } 44 45 #[derive(Deserialize, Serialize, Clone)] ··· 52 53 #[derive(Deserialize, Serialize)] 54 pub struct PullMetadataResult<'a> { 55 - pub codes: Cow<'a, [u32]>, 56 #[serde(borrow)] 57 pub funcs: Cow<'a, [PullMetadataResultFunc<'a>]>, 58 } ··· 62 pub name: &'a str, 63 pub func_len: u32, 64 pub func_data: &'a [u8], 65 - pub pattern_id: PatternId<'a>, 66 } 67 68 #[derive(Deserialize, Serialize)] 69 pub struct PushMetadata<'a> { 70 - pub flags: u32, 71 pub idb_path: &'a str, 72 - pub input_path: &'a str, 73 - pub input_md5: [u8; 16], 74 pub hostname: &'a str, 75 pub funcs: Cow<'a, [PushMetadataFunc<'a>]>, 76 - pub ea64s: Cow<'a, [u64]>, 77 } 78 79 #[derive(Deserialize, Serialize)] ··· 84 85 #[derive(Debug, Deserialize, Serialize)] 86 pub struct DelHistory<'a> { 87 - pub flags: u32, // =0x08 88 - pub license_ids: Cow<'a, [Cow<'a, str>]>, 89 - pub time_ranges: Cow<'a, [[u64; 2]]>, 90 - pub history_id_ranges: Cow<'a, [[u64; 2]]>, 91 - pub idbs: Cow<'a, [Cow<'a, str>]>, 92 - pub inputs: Cow<'a, [Cow<'a, str>]>, 93 - pub funcs: Cow<'a, [Cow<'a, str>]>, // funcs 94 - pub usernames: Cow<'a, [Cow<'a, str>]>, 95 - pub input_hashes: Cow<'a, [Cow<'a, [u8; 16]>]>, 96 - pub calcrel_hashes: Cow<'a, [Cow<'a, [u8; 16]>]>, 97 - pub push_id_ranges: Cow<'a, [[u64; 2]]>, 98 - pub max_entries: u64, 99 } 100 101 #[derive(Deserialize, Serialize)] 102 pub struct DelHistoryResult { 103 - pub ndeleted: u32, 104 } 105 106 #[derive(Debug, Deserialize, Serialize, Default)] ··· 122 #[derive(Debug, Deserialize, Serialize)] 123 pub struct GetFuncHistories<'a> { 124 #[serde(borrow)] 125 - pub funcs: Cow<'a, [PatternId<'a>]>, 126 - pub flags: u32, 127 } 128 129 #[derive(Debug, Deserialize, Serialize, Clone)] ··· 148 pub status: Cow<'a, [u32]>, 149 #[serde(borrow)] 150 pub funcs: Cow<'a, [FunctionHistories<'a>]>, 151 - pub authors: Cow<'a, [Cow<'a, str>]>, 152 - pub idb_paths: Cow<'a, [Cow<'a, str>]>, 153 }
··· 3 4 #[derive(Deserialize, Serialize)] 5 pub struct RpcFail<'a> { 6 + pub code: u32, 7 + pub message: &'a str, 8 } 9 10 #[derive(Serialize, Deserialize)] 11 pub struct RpcNotify<'a> { 12 + pub code: u32, 13 + pub msg: &'a str, 14 } 15 16 #[derive(Serialize, Deserialize, Debug)] ··· 21 22 #[derive(Serialize, Deserialize)] 23 pub struct RpcHello<'a> { 24 + pub protocol_version: u32, 25 pub license_data: &'a [u8], 26 pub lic_number: [u8; 6], 27 + pub unk2: u32, 28 } 29 30 #[derive(Debug, Deserialize, Serialize, Clone)] 31 + pub struct PullMetadataFunc<'a> { 32 + pub unk0: u32, 33 + pub mb_hash: &'a [u8], 34 } 35 36 #[derive(Deserialize, Serialize)] 37 pub struct PullMetadata<'a> { 38 + pub unk0: u32, 39 + pub unk1: Cow<'a, [u32]>, 40 41 #[serde(borrow)] 42 + pub funcs: Cow<'a, [PullMetadataFunc<'a>]>, 43 } 44 45 #[derive(Deserialize, Serialize, Clone)] ··· 52 53 #[derive(Deserialize, Serialize)] 54 pub struct PullMetadataResult<'a> { 55 + pub unk0: Cow<'a, [u32]>, 56 #[serde(borrow)] 57 pub funcs: Cow<'a, [PullMetadataResultFunc<'a>]>, 58 } ··· 62 pub name: &'a str, 63 pub func_len: u32, 64 pub func_data: &'a [u8], 65 + 66 + // PullMetadata's fields (tuple 'unk2') are similar to these two 67 + pub unk2: u32, 68 + pub hash: &'a [u8], 69 } 70 71 #[derive(Deserialize, Serialize)] 72 pub struct PushMetadata<'a> { 73 + pub unk0: u32, 74 pub idb_path: &'a str, 75 + pub file_path: &'a str, 76 + pub md5: [u8; 16], 77 pub hostname: &'a str, 78 pub funcs: Cow<'a, [PushMetadataFunc<'a>]>, 79 + pub unk1: Cow<'a, [u64]>, 80 } 81 82 #[derive(Deserialize, Serialize)] ··· 87 88 #[derive(Debug, Deserialize, Serialize)] 89 pub struct DelHistory<'a> { 90 + pub unk0: u32, // =0x08 91 + pub unk1: Cow<'a, [Cow<'a, str>]>, 92 + pub unk2: Cow<'a, [[u64; 2]]>, 93 + pub unk3: Cow<'a, [[u64; 2]]>, 94 + pub unk4: Cow<'a, [Cow<'a, str>]>, 95 + pub unk5: Cow<'a, [Cow<'a, str>]>, 96 + pub unk6: Cow<'a, [Cow<'a, str>]>, 97 + pub unk7: Cow<'a, [Cow<'a, str>]>, 98 + pub unk8: Cow<'a, [Cow<'a, [u8; 16]>]>, 99 + pub funcs: Cow<'a, [Cow<'a, [u8; 16]>]>, 100 + pub unk10: Cow<'a, [[u64; 2]]>, 101 + pub unk11: u64, 102 } 103 104 #[derive(Deserialize, Serialize)] 105 pub struct DelHistoryResult { 106 + pub deleted_mds: u32, 107 } 108 109 #[derive(Debug, Deserialize, Serialize, Default)] ··· 125 #[derive(Debug, Deserialize, Serialize)] 126 pub struct GetFuncHistories<'a> { 127 #[serde(borrow)] 128 + pub funcs: Cow<'a, [PullMetadataFunc<'a>]>, 129 + pub unk0: u32, 130 } 131 132 #[derive(Debug, Deserialize, Serialize, Clone)] ··· 151 pub status: Cow<'a, [u32]>, 152 #[serde(borrow)] 153 pub funcs: Cow<'a, [FunctionHistories<'a>]>, 154 + pub users: Cow<'a, [Cow<'a, str>]>, 155 + pub dbs: Cow<'a, [Cow<'a, str>]>, 156 }
+21 -45
common/src/rpc/mod.rs
··· 63 } 64 } 65 66 - pub struct PacketHeader { 67 - code: u8, 68 - size: usize, 69 - } 70 - 71 - pub async fn read_packet_header<R: AsyncRead + Unpin>( 72 - mut reader: R, 73 - ) -> Result<PacketHeader, Error> { 74 let mut head = [0u8; 5]; 75 match reader.read_exact(&mut head).await { 76 Ok(_) => {}, ··· 90 .into()); 91 } 92 93 - Ok(PacketHeader { code, size: buf_len }) 94 - } 95 - 96 - impl PacketHeader { 97 - pub async fn read<R: AsyncRead + Unpin>(self, mut reader: R) -> Result<Vec<u8>, Error> { 98 - trace!("expecting {} bytes...", self.size); 99 - let buf_len = self.size + 1; 100 - 101 - let max_len = get_code_maxlen(self.code); 102 - if self.size > max_len { 103 - info!("maxium size exceeded: code={}: max={}; req={}", self.code, max_len, self.size); 104 - return Err(std::io::Error::new( 105 - std::io::ErrorKind::InvalidData, 106 - "request length exceeded maximum limit", 107 - ) 108 - .into()); 109 - } 110 - 111 - let mut data = Vec::new(); 112 - data.try_reserve_exact(buf_len)?; 113 - data.resize(buf_len, 0); 114 - data[0] = self.code; 115 - reader.read_exact(&mut data[1..]).await?; 116 117 - Ok(data) 118 } 119 120 - // returns true if this could be an http request. 121 - pub fn is_http(&self) -> bool { 122 - let mut sz = (self.size as u32).to_be_bytes(); 123 - sz.make_ascii_uppercase(); 124 - let sz = &sz[..]; 125 126 - match sz { 127 - b"GET " | b"PUT " if self.code == b'/' => true, 128 - b"POST" | b"HEAD" if self.code == b' ' => true, 129 - _ => false, 130 - } 131 - } 132 } 133 134 async fn write_packet<W: AsyncWrite + Unpin>(mut w: W, data: &[u8]) -> Result<(), std::io::Error> { ··· 217 0x0c => RpcMessage::Notify(Self::deserialize_check(payload)?), 218 0x0d => { 219 let (hello, consumed) = de::from_slice::<messages::RpcHello>(payload)?; 220 - let creds = if payload.len() > consumed && hello.client_version > 2 { 221 let payload = &payload[consumed..]; 222 let (creds, consumed) = de::from_slice::<Creds>(payload)?; 223 if payload.len() != consumed { ··· 225 } 226 Some(creds) 227 } else { 228 - if hello.client_version > 2 || payload.len() != consumed { 229 trace!("Unexpected Hello msg: {payload:02x?}"); 230 } 231 None
··· 63 } 64 } 65 66 + pub async fn read_packet<R: AsyncRead + Unpin>(mut reader: R) -> Result<Vec<u8>, Error> { 67 let mut head = [0u8; 5]; 68 match reader.read_exact(&mut head).await { 69 Ok(_) => {}, ··· 83 .into()); 84 } 85 86 + let max_len = get_code_maxlen(code); 87 88 + if buf_len > max_len { 89 + info!("maxium size exceeded: code={}: max={}; req={}", code, max_len, buf_len); 90 + return Err(std::io::Error::new( 91 + std::io::ErrorKind::InvalidData, 92 + "request length exceeded maximum limit", 93 + ) 94 + .into()); 95 } 96 97 + // the additional byte is for the RPC code 98 + trace!("expecting {} bytes...", buf_len); 99 + let buf_len = buf_len + 1; 100 + 101 + let mut data = Vec::new(); 102 + data.try_reserve_exact(buf_len)?; 103 + data.resize(buf_len, 0); 104 + data[0] = code; 105 + reader.read_exact(&mut data[1..]).await?; 106 107 + Ok(data) 108 } 109 110 async fn write_packet<W: AsyncWrite + Unpin>(mut w: W, data: &[u8]) -> Result<(), std::io::Error> { ··· 193 0x0c => RpcMessage::Notify(Self::deserialize_check(payload)?), 194 0x0d => { 195 let (hello, consumed) = de::from_slice::<messages::RpcHello>(payload)?; 196 + let creds = if payload.len() > consumed && hello.protocol_version > 2 { 197 let payload = &payload[consumed..]; 198 let (creds, consumed) = de::from_slice::<Creds>(payload)?; 199 if payload.len() != consumed { ··· 201 } 202 Some(creds) 203 } else { 204 + if hello.protocol_version > 2 || payload.len() != consumed { 205 trace!("Unexpected Hello msg: {payload:02x?}"); 206 } 207 None
+1 -1
common/src/web/api.rs
··· 111 in_files: &'a [Md5], 112 } 113 114 - let funcs = [crate::rpc::PatternId { ty: 1, data: &md5.0 }]; 115 116 let files_with = state.db.get_files_with_func(&md5.0[..]); 117 let files_info = state.db.get_funcs(&funcs);
··· 111 in_files: &'a [Md5], 112 } 113 114 + let funcs = [crate::rpc::PullMetadataFunc { unk0: 1, mb_hash: &md5.0 }]; 115 116 let files_with = state.db.get_files_with_func(&md5.0[..]); 117 let files_info = state.db.get_funcs(&funcs);
+2 -8
config-example.toml
··· 7 server_name = "lumen" 8 9 # Allow clients to delete metadata from the database? 10 - allow_deletes = true 11 # How many function histories should we return? 0=Disabled. 12 get_history_limit = 50 13 14 - [users] 15 - # Enable guest accounts? disabling this will only allow IDA 8.1+ to connect. 16 - allow_guests = true 17 - # sets the amount of PBKDF2 iterations for storing passwords. 18 - pbkdf2_iterations = 120000 19 - 20 # only required when `use_tls` is set to true. 21 [lumina.tls] 22 - # Specify the server's certificate. 23 # Clients connecting to the server must match this certificate. 24 # If the certificate is password protected, the password can be specified in the `PKCSPASSWD` environment variable. 25 server_cert = "path/to/server_crt"
··· 7 server_name = "lumen" 8 9 # Allow clients to delete metadata from the database? 10 + allow_deletes = false 11 # How many function histories should we return? 0=Disabled. 12 get_history_limit = 50 13 14 # only required when `use_tls` is set to true. 15 [lumina.tls] 16 + # Specify the server's certificate. 17 # Clients connecting to the server must match this certificate. 18 # If the certificate is password protected, the password can be specified in the `PKCSPASSWD` environment variable. 19 server_cert = "path/to/server_crt"
+3 -4
lumen/Cargo.toml
··· 8 9 [dependencies] 10 common = { path = "../common" } 11 - tokio = { version = "1.32", features = ["full"] } 12 log = { version = "0.4", features = ["release_max_level_debug"] } 13 pretty_env_logger = "0.5" 14 - clap = "4.3" 15 tokio-native-tls = "0.3" 16 native-tls = { version = "0.2" } 17 warp = "0.3" 18 - prometheus-client = "0.22.0" 19 - rpassword = "7.3.1"
··· 8 9 [dependencies] 10 common = { path = "../common" } 11 + tokio = { version = "1.39", features = ["full"] } 12 log = { version = "0.4", features = ["release_max_level_debug"] } 13 pretty_env_logger = "0.5" 14 + clap = "4.5" 15 tokio-native-tls = "0.3" 16 native-tls = { version = "0.2" } 17 warp = "0.3" 18 + prometheus-client = "0.22"
+6 -62
lumen/src/main.rs
··· 4 #![warn(unused_crate_dependencies)] 5 #![deny(clippy::all)] 6 7 - use clap::{builder::BoolishValueParser, Arg, Command}; 8 use log::*; 9 use server::do_lumen; 10 use std::sync::Arc; 11 - use users::UserMgmt; 12 13 mod server; 14 - mod users; 15 mod web; 16 17 fn setup_logger() { 18 if std::env::var("RUST_LOG").is_err() { 19 std::env::set_var("RUST_LOG", concat!(env!("CARGO_PKG_NAME"), "=info")); ··· 23 24 #[tokio::main] 25 async fn main() { 26 let matches = clap::Command::new("lumen") 27 .version(env!("CARGO_PKG_VERSION")) 28 .about("lumen is a private Lumina server for IDA.\nVisit https://github.com/naim94a/lumen/ for updates.") ··· 33 .default_value("config.toml") 34 .help("Configuration file path") 35 ) 36 - .subcommand( 37 - Command::new("users") 38 - .about("User Management") 39 - .subcommand( 40 - Command::new("add") 41 - .about("Adds a user") 42 - .arg( 43 - Arg::new("username") 44 - .required(true) 45 - ) 46 - .arg( 47 - Arg::new("email") 48 - .required(true) 49 - ) 50 - .arg( 51 - Arg::new("is_admin") 52 - .required(false) 53 - .default_value("no") 54 - .value_parser(BoolishValueParser::new()) 55 - ) 56 - ) 57 - .subcommand( 58 - Command::new("del") 59 - .about("Deletes a user") 60 - .arg(Arg::new("username")) 61 - ) 62 - ) 63 - .subcommand(Command::new("passwd").about("Set user password").arg(Arg::new("username").required(true))) 64 .get_matches(); 65 66 let config = { 67 - common::config::load_config( 68 std::fs::File::open(matches.get_one::<String>("config").unwrap()) 69 .expect("failed to read config"), 70 ) 71 }; 72 let config = Arc::new(config); 73 74 - match matches.subcommand() { 75 - Some(("users", m)) => { 76 - let users = UserMgmt::new(&config).await; 77 - match m.subcommand() { 78 - None => users.list_users().await, 79 - Some(("add", m)) => { 80 - let username = m.get_one::<String>("username").unwrap(); 81 - let email = m.get_one::<String>("email").unwrap(); 82 - let is_admin = *m.get_one::<bool>("is_admin").unwrap_or(&false); 83 - users.add_user(username, email, is_admin).await; 84 - }, 85 - Some(("del", m)) => { 86 - let username = m.get_one::<String>("username").unwrap(); 87 - users.delete_user(username).await; 88 - }, 89 - _ => unreachable!(), 90 - }; 91 - }, 92 - Some(("passwd", m)) => { 93 - let username = m.get_one::<String>("username").unwrap(); 94 - let password = rpassword::prompt_password("New Password: ").unwrap(); 95 - let users = UserMgmt::new(&config).await; 96 - users.set_password(username, &password).await; 97 - }, 98 - Some(_) => unreachable!(), 99 - None => { 100 - setup_logger(); 101 - do_lumen(config).await 102 - }, 103 - }; 104 }
··· 4 #![warn(unused_crate_dependencies)] 5 #![deny(clippy::all)] 6 7 + use clap::Arg; 8 use log::*; 9 use server::do_lumen; 10 use std::sync::Arc; 11 12 mod server; 13 mod web; 14 15 + use common::config; 16 + 17 fn setup_logger() { 18 if std::env::var("RUST_LOG").is_err() { 19 std::env::set_var("RUST_LOG", concat!(env!("CARGO_PKG_NAME"), "=info")); ··· 23 24 #[tokio::main] 25 async fn main() { 26 + setup_logger(); 27 let matches = clap::Command::new("lumen") 28 .version(env!("CARGO_PKG_VERSION")) 29 .about("lumen is a private Lumina server for IDA.\nVisit https://github.com/naim94a/lumen/ for updates.") ··· 34 .default_value("config.toml") 35 .help("Configuration file path") 36 ) 37 .get_matches(); 38 39 let config = { 40 + config::load_config( 41 std::fs::File::open(matches.get_one::<String>("config").unwrap()) 42 .expect("failed to read config"), 43 ) 44 }; 45 let config = Arc::new(config); 46 47 + do_lumen(config).await; 48 }
+61 -199
lumen/src/server.rs
··· 10 use common::{ 11 async_drop::AsyncDropper, 12 config::Config, 13 - db::{self, Database}, 14 make_pretty_hex, md, 15 metrics::LuminaVersion, 16 - rpc::{self, Creds, Error, HelloResult, RpcFail, RpcHello, RpcMessage}, 17 SharedState, SharedState_, 18 }; 19 use log::{debug, error, info, trace, warn}; ··· 26 27 use crate::web; 28 29 - struct Session<'a> { 30 - state: &'a SharedState_, 31 - hello_msg: RpcHello<'a>, 32 - _creds: db::schema::Creds<'a>, 33 - creds_id: Option<i32>, 34 - last_cred_check: Instant, 35 - } 36 - impl<'a> Session<'a> { 37 - /// Check if the user changed in the database. 38 - pub async fn is_valid(&mut self) -> bool { 39 - let db = &self.state.db; 40 - if let Some(cred_id) = self.creds_id { 41 - if self.last_cred_check.elapsed() > Duration::from_secs(60 * 5) { 42 - match db.get_user_by_id(cred_id).await { 43 - Ok(v) => { 44 - if !v.is_enabled 45 - || v.is_admin != self._creds.is_admin 46 - || v.passwd_salt != self._creds.passwd_salt 47 - { 48 - // user changed, force them to login again. 49 - return false; 50 - } 51 - self.last_cred_check = Instant::now(); 52 - return true; 53 - }, 54 - Err(err) => { 55 - error!("db error: {err}"); 56 - return false; 57 - }, 58 - } 59 - } 60 - } 61 - true 62 - } 63 - } 64 - 65 async fn handle_transaction<'a, S: AsyncRead + AsyncWrite + Unpin>( 66 - session: &mut Session<'a>, mut stream: S, 67 ) -> Result<(), Error> { 68 - let state = session.state; 69 let db = &state.db; 70 let server_name = state.server_name.as_str(); 71 72 trace!("waiting for command.."); 73 - let rpkt = async { 74 - let hdr = rpc::read_packet_header(&mut stream).await?; 75 - // we don't want to read a whole request just to find out the user was revoked... 76 - if !session.is_valid().await { 77 - return Err(Error::Timeout); 78 - } 79 - hdr.read(&mut stream).await 80 - }; 81 - let req = match timeout(Duration::from_secs(3600), rpkt).await { 82 Ok(res) => match res { 83 Ok(v) => v, 84 Err(e) => return Err(e), 85 }, 86 Err(_) => { 87 _ = RpcMessage::Fail(RpcFail { 88 - result: 0, 89 - error: &format!("{server_name} client idle for too long.\n"), 90 }) 91 .async_write(&mut stream) 92 .await; ··· 94 }, 95 }; 96 trace!("got command!"); 97 - 98 - if !session.is_valid().await { 99 - return Err(Error::Timeout); 100 - } 101 - 102 let req = match RpcMessage::deserialize(&req) { 103 Ok(v) => v, 104 Err(err) => { 105 warn!("bad message: \n{}\n", make_pretty_hex(&req)); 106 error!("failed to process rpc message: {}", err); 107 let resp = rpc::RpcFail { 108 - result: 0, 109 - error: &format!("{server_name}: error: invalid data.\n"), 110 }; 111 let resp = RpcMessage::Fail(resp); 112 resp.async_write(&mut stream).await?; ··· 117 match req { 118 RpcMessage::PullMetadata(md) => { 119 let start = Instant::now(); 120 - let funcs = match timeout(Duration::from_secs(4 * 60), db.get_funcs(&md.pattern_ids)) 121 - .await 122 - { 123 Ok(r) => match r { 124 Ok(v) => v, 125 Err(e) => { 126 error!("pull failed, db: {}", e); 127 rpc::RpcMessage::Fail(rpc::RpcFail { 128 - result: 0, 129 - error: &format!("{server_name}: db error; please try again later..\n"), 130 }) 131 .async_write(&mut stream) 132 .await?; ··· 135 }, 136 Err(_) => { 137 RpcMessage::Fail(RpcFail { 138 - result: 0, 139 - error: &format!("{server_name}: query took too long to execute.\n"), 140 }) 141 .async_write(&mut stream) 142 .await?; ··· 146 }; 147 let pulled_funcs = funcs.iter().filter(|v| v.is_some()).count(); 148 state.metrics.pulls.inc_by(pulled_funcs as _); 149 - state.metrics.queried_funcs.inc_by(md.pattern_ids.len() as _); 150 debug!( 151 "pull {pulled_funcs}/{} funcs ended after {:?}", 152 - md.pattern_ids.len(), 153 start.elapsed() 154 ); 155 ··· 166 .collect(); 167 168 RpcMessage::PullMetadataResult(rpc::PullMetadataResult { 169 - codes: Cow::Owned(statuses), 170 funcs: Cow::Owned(found), 171 }) 172 .async_write(&mut stream) ··· 177 let start = Instant::now(); 178 let scores: Vec<u32> = mds.funcs.iter().map(md::get_score).collect(); 179 180 - let status = 181 - match db.push_funcs(&session.hello_msg, session.creds_id, &mds, &scores).await { 182 - Ok(v) => v.into_iter().map(u32::from).collect::<Vec<u32>>(), 183 - Err(err) => { 184 - log::error!("push failed, db: {}", err); 185 - rpc::RpcMessage::Fail(rpc::RpcFail { 186 - result: 0, 187 - error: &format!("{server_name}: db error; please try again later.\n"), 188 - }) 189 - .async_write(&mut stream) 190 - .await?; 191 - return Ok(()); 192 - }, 193 - }; 194 state.metrics.pushes.inc_by(status.len() as _); 195 let new_funcs = 196 status.iter().fold(0u64, |counter, &v| if v > 0 { counter + 1 } else { counter }); ··· 209 let is_delete_allowed = state.config.lumina.allow_deletes.unwrap_or(false); 210 if !is_delete_allowed { 211 RpcMessage::Fail(rpc::RpcFail { 212 - result: 2, 213 - error: &format!("{server_name}: Delete command is disabled on this server."), 214 }) 215 .async_write(&mut stream) 216 .await?; ··· 218 if let Err(err) = db.delete_metadata(&req).await { 219 error!("delete failed. db: {err}"); 220 RpcMessage::Fail(rpc::RpcFail { 221 - result: 3, 222 - error: &format!("{server_name}: db error, please try again later."), 223 }) 224 .async_write(&mut stream) 225 .await?; 226 return Ok(()); 227 } 228 RpcMessage::DelHistoryResult(rpc::DelHistoryResult { 229 - ndeleted: req.calcrel_hashes.len() as u32, 230 }) 231 .async_write(&mut stream) 232 .await?; ··· 237 238 if limit == 0 { 239 RpcMessage::Fail(rpc::RpcFail { 240 - result: 4, 241 - error: &format!( 242 "{server_name}: function histories are disabled on this server." 243 ), 244 }) ··· 249 250 let mut statuses = vec![]; 251 let mut res = vec![]; 252 - for chksum in req.funcs.iter().map(|v| v.data) { 253 let history = match db.get_func_histories(chksum, limit).await { 254 Ok(v) => v, 255 Err(err) => { 256 error!("failed to get function histories: {err:?}"); 257 RpcMessage::Fail(rpc::RpcFail { 258 - result: 3, 259 - error: &format!("{server_name}: db error, please try again later."), 260 }) 261 .async_write(&mut stream) 262 .await?; ··· 288 RpcMessage::GetFuncHistoriesResult(rpc::GetFuncHistoriesResult { 289 status: statuses.into(), 290 funcs: Cow::Owned(res), 291 - authors: vec![].into(), 292 - idb_paths: vec![].into(), 293 }) 294 .async_write(&mut stream) 295 .await?; 296 }, 297 _ => { 298 RpcMessage::Fail(rpc::RpcFail { 299 - result: 0, 300 - error: &format!("{server_name}: invalid data.\n"), 301 }) 302 .async_write(&mut stream) 303 .await?; ··· 306 Ok(()) 307 } 308 309 - async fn http_reply<W: AsyncRead + AsyncWrite + Unpin>(mut stream: W) { 310 - use tokio::io::AsyncWriteExt; 311 - 312 - const HTTP_REPLY: &str = concat!( 313 - "HTTP/1.1 400 bad request\r\n", 314 - "Refresh: 2; URL=https://github.com/naim94a/lumen\r\n", 315 - "Server: lumen\r\n", 316 - "Connection: close\r\n", 317 - "Content-Type: text/html\r\n", 318 - "", 319 - "\r\n", 320 - "<pre>This is not an HTTP server. <br />Redirecting to <a href=\"https://github.com/naim94a/lumen\">lumen</a> ...</pre>\n", 321 - ); 322 - 323 - let _ = stream.write_all(HTTP_REPLY.as_bytes()).await; 324 - } 325 - 326 async fn handle_client<S: AsyncRead + AsyncWrite + Unpin>( 327 state: &SharedState, mut stream: S, 328 ) -> Result<(), rpc::Error> { 329 let server_name = &state.server_name; 330 - let rpkt = async { 331 - let hdr = rpc::read_packet_header(&mut stream).await?; 332 - if hdr.is_http() { 333 - // looks like someone is using a browser instead of IDA, what a fool. 334 - debug!("ignoring http request..."); 335 - http_reply(&mut stream).await; 336 - return Err(Error::Eof); 337 - } 338 - hdr.read(&mut stream).await 339 - }; 340 - let hello = match timeout(Duration::from_secs(15), rpkt).await { 341 Ok(v) => v?, 342 Err(_) => { 343 debug!("didn't get hello in time."); ··· 347 348 let (hello, creds) = match RpcMessage::deserialize(&hello) { 349 Ok(RpcMessage::Hello(v, creds)) => { 350 - debug!("hello protocol={}, login creds: {creds:?}", v.client_version); 351 (v, creds) 352 }, 353 _ => { 354 // send error 355 error!("got bad hello message"); 356 357 - let resp = rpc::RpcFail { result: 0, error: &format!("{server_name}: bad sequence.") }; 358 let resp = rpc::RpcMessage::Fail(resp); 359 resp.async_write(&mut stream).await?; 360 ··· 364 state 365 .metrics 366 .lumina_version 367 - .get_or_create(&LuminaVersion { protocol_version: hello.client_version }) 368 .inc(); 369 370 - let creds = creds.unwrap_or(Creds { username: "guest", password: "guest" }); 371 - 372 - let user = if creds.username != "guest" { 373 - match state.db.get_user_by_username(creds.username).await { 374 - Ok((user_id, db_creds)) if db_creds.verify_password(creds.password) => { 375 - let _ = state.db.update_last_active(user_id).await; 376 - info!("{} logged in successfully.", db_creds.username); 377 - (user_id, db_creds) 378 - }, 379 - Ok(_) => { 380 - rpc::RpcMessage::Fail(rpc::RpcFail { 381 - result: 1, 382 - error: &format!("{server_name}: invalid username or password."), 383 - }) 384 - .async_write(&mut stream) 385 - .await?; 386 - return Ok(()); 387 - }, 388 - Err(err) => { 389 - error!("error while fetching user information: {err}"); 390 - rpc::RpcMessage::Fail(rpc::RpcFail { 391 - result: 1, 392 - error: &format!("{server_name}: internal error, please try again later."), 393 - }) 394 - .async_write(&mut stream) 395 - .await?; 396 - return Ok(()); 397 - }, 398 } 399 - } else { 400 - ( 401 - -1, 402 - db::schema::Creds { 403 - username: creds.username.into(), 404 - is_enabled: state.config.users.allow_guests, 405 - ..Default::default() 406 - }, 407 - ) 408 - }; 409 - 410 - if !user.1.is_enabled { 411 - info!("attempt to login to disabled account [{}].", user.1.username); 412 - rpc::RpcMessage::Fail(rpc::RpcFail { 413 - result: 1, 414 - error: &format!("{server_name}: account disabled."), 415 - }) 416 - .async_write(&mut stream) 417 - .await?; 418 - return Ok(()); 419 } 420 421 - let resp = match hello.client_version { 422 0..=4 => rpc::RpcMessage::Ok(()), 423 424 // starting IDA 8.3 425 5.. => { 426 let mut features = 0; 427 428 - if user.1.is_admin { 429 - features |= 0x01; 430 - } 431 - 432 - if user.0 != -1 && state.config.lumina.allow_deletes.unwrap_or(false) { 433 features |= 0x02; 434 } 435 436 - let last_active = user.1.last_active.map_or(0, |v| v.unix_timestamp() as u64); 437 - 438 - rpc::RpcMessage::HelloResult(HelloResult { 439 - username: Cow::Borrowed(&user.1.username), 440 - last_active, 441 - features, 442 - ..Default::default() 443 - }) 444 }, 445 }; 446 resp.async_write(&mut stream).await?; 447 448 - let creds_id = if user.0 == -1 { None } else { Some(user.0) }; 449 - let mut session = Session { 450 - state, 451 - hello_msg: hello, 452 - _creds: user.1, 453 - creds_id, 454 - last_cred_check: Instant::now(), 455 - }; 456 - 457 loop { 458 - handle_transaction(&mut session, &mut stream).await?; 459 } 460 } 461
··· 10 use common::{ 11 async_drop::AsyncDropper, 12 config::Config, 13 + db::Database, 14 make_pretty_hex, md, 15 metrics::LuminaVersion, 16 + rpc::{self, Error, HelloResult, RpcFail, RpcHello, RpcMessage}, 17 SharedState, SharedState_, 18 }; 19 use log::{debug, error, info, trace, warn}; ··· 26 27 use crate::web; 28 29 async fn handle_transaction<'a, S: AsyncRead + AsyncWrite + Unpin>( 30 + state: &SharedState, user: &'a RpcHello<'a>, mut stream: S, 31 ) -> Result<(), Error> { 32 let db = &state.db; 33 let server_name = state.server_name.as_str(); 34 35 trace!("waiting for command.."); 36 + let req = match timeout(Duration::from_secs(3600), rpc::read_packet(&mut stream)).await { 37 Ok(res) => match res { 38 Ok(v) => v, 39 Err(e) => return Err(e), 40 }, 41 Err(_) => { 42 _ = RpcMessage::Fail(RpcFail { 43 + code: 0, 44 + message: &format!("{server_name} client idle for too long.\n"), 45 }) 46 .async_write(&mut stream) 47 .await; ··· 49 }, 50 }; 51 trace!("got command!"); 52 let req = match RpcMessage::deserialize(&req) { 53 Ok(v) => v, 54 Err(err) => { 55 warn!("bad message: \n{}\n", make_pretty_hex(&req)); 56 error!("failed to process rpc message: {}", err); 57 let resp = rpc::RpcFail { 58 + code: 0, 59 + message: &format!("{server_name}: error: invalid data.\n"), 60 }; 61 let resp = RpcMessage::Fail(resp); 62 resp.async_write(&mut stream).await?; ··· 67 match req { 68 RpcMessage::PullMetadata(md) => { 69 let start = Instant::now(); 70 + let funcs = match timeout(Duration::from_secs(4 * 60), db.get_funcs(&md.funcs)).await { 71 Ok(r) => match r { 72 Ok(v) => v, 73 Err(e) => { 74 error!("pull failed, db: {}", e); 75 rpc::RpcMessage::Fail(rpc::RpcFail { 76 + code: 0, 77 + message: &format!( 78 + "{server_name}: db error; please try again later..\n" 79 + ), 80 }) 81 .async_write(&mut stream) 82 .await?; ··· 85 }, 86 Err(_) => { 87 RpcMessage::Fail(RpcFail { 88 + code: 0, 89 + message: &format!("{server_name}: query took too long to execute.\n"), 90 }) 91 .async_write(&mut stream) 92 .await?; ··· 96 }; 97 let pulled_funcs = funcs.iter().filter(|v| v.is_some()).count(); 98 state.metrics.pulls.inc_by(pulled_funcs as _); 99 + state.metrics.queried_funcs.inc_by(md.funcs.len() as _); 100 debug!( 101 "pull {pulled_funcs}/{} funcs ended after {:?}", 102 + md.funcs.len(), 103 start.elapsed() 104 ); 105 ··· 116 .collect(); 117 118 RpcMessage::PullMetadataResult(rpc::PullMetadataResult { 119 + unk0: Cow::Owned(statuses), 120 funcs: Cow::Owned(found), 121 }) 122 .async_write(&mut stream) ··· 127 let start = Instant::now(); 128 let scores: Vec<u32> = mds.funcs.iter().map(md::get_score).collect(); 129 130 + let status = match db.push_funcs(user, &mds, &scores).await { 131 + Ok(v) => v.into_iter().map(u32::from).collect::<Vec<u32>>(), 132 + Err(err) => { 133 + log::error!("push failed, db: {}", err); 134 + rpc::RpcMessage::Fail(rpc::RpcFail { 135 + code: 0, 136 + message: &format!("{server_name}: db error; please try again later.\n"), 137 + }) 138 + .async_write(&mut stream) 139 + .await?; 140 + return Ok(()); 141 + }, 142 + }; 143 state.metrics.pushes.inc_by(status.len() as _); 144 let new_funcs = 145 status.iter().fold(0u64, |counter, &v| if v > 0 { counter + 1 } else { counter }); ··· 158 let is_delete_allowed = state.config.lumina.allow_deletes.unwrap_or(false); 159 if !is_delete_allowed { 160 RpcMessage::Fail(rpc::RpcFail { 161 + code: 2, 162 + message: &format!("{server_name}: Delete command is disabled on this server."), 163 }) 164 .async_write(&mut stream) 165 .await?; ··· 167 if let Err(err) = db.delete_metadata(&req).await { 168 error!("delete failed. db: {err}"); 169 RpcMessage::Fail(rpc::RpcFail { 170 + code: 3, 171 + message: &format!("{server_name}: db error, please try again later."), 172 }) 173 .async_write(&mut stream) 174 .await?; 175 return Ok(()); 176 } 177 RpcMessage::DelHistoryResult(rpc::DelHistoryResult { 178 + deleted_mds: req.funcs.len() as u32, 179 }) 180 .async_write(&mut stream) 181 .await?; ··· 186 187 if limit == 0 { 188 RpcMessage::Fail(rpc::RpcFail { 189 + code: 4, 190 + message: &format!( 191 "{server_name}: function histories are disabled on this server." 192 ), 193 }) ··· 198 199 let mut statuses = vec![]; 200 let mut res = vec![]; 201 + for chksum in req.funcs.iter().map(|v| v.mb_hash) { 202 let history = match db.get_func_histories(chksum, limit).await { 203 Ok(v) => v, 204 Err(err) => { 205 error!("failed to get function histories: {err:?}"); 206 RpcMessage::Fail(rpc::RpcFail { 207 + code: 3, 208 + message: &format!("{server_name}: db error, please try again later."), 209 }) 210 .async_write(&mut stream) 211 .await?; ··· 237 RpcMessage::GetFuncHistoriesResult(rpc::GetFuncHistoriesResult { 238 status: statuses.into(), 239 funcs: Cow::Owned(res), 240 + users: vec![].into(), 241 + dbs: vec![].into(), 242 }) 243 .async_write(&mut stream) 244 .await?; 245 }, 246 _ => { 247 RpcMessage::Fail(rpc::RpcFail { 248 + code: 0, 249 + message: &format!("{server_name}: invalid data.\n"), 250 }) 251 .async_write(&mut stream) 252 .await?; ··· 255 Ok(()) 256 } 257 258 async fn handle_client<S: AsyncRead + AsyncWrite + Unpin>( 259 state: &SharedState, mut stream: S, 260 ) -> Result<(), rpc::Error> { 261 let server_name = &state.server_name; 262 + let hello = match timeout(Duration::from_secs(15), rpc::read_packet(&mut stream)).await { 263 Ok(v) => v?, 264 Err(_) => { 265 debug!("didn't get hello in time."); ··· 269 270 let (hello, creds) = match RpcMessage::deserialize(&hello) { 271 Ok(RpcMessage::Hello(v, creds)) => { 272 + debug!("hello protocol={}, login creds: {creds:?}", v.protocol_version); 273 (v, creds) 274 }, 275 _ => { 276 // send error 277 error!("got bad hello message"); 278 279 + let resp = rpc::RpcFail { code: 0, message: &format!("{server_name}: bad sequence.") }; 280 let resp = rpc::RpcMessage::Fail(resp); 281 resp.async_write(&mut stream).await?; 282 ··· 286 state 287 .metrics 288 .lumina_version 289 + .get_or_create(&LuminaVersion { protocol_version: hello.protocol_version }) 290 .inc(); 291 292 + if let Some(ref creds) = creds { 293 + if creds.username != "guest" { 294 + // Only allow "guest" to connect for now. 295 + rpc::RpcMessage::Fail(rpc::RpcFail { 296 + code: 1, 297 + message: &format!("{server_name}: invalid username or password. Try logging in with `guest` instead."), 298 + }).async_write(&mut stream).await?; 299 + return Ok(()); 300 } 301 } 302 303 + let resp = match hello.protocol_version { 304 0..=4 => rpc::RpcMessage::Ok(()), 305 306 // starting IDA 8.3 307 5.. => { 308 let mut features = 0; 309 310 + if state.config.lumina.allow_deletes.unwrap_or(false) { 311 features |= 0x02; 312 } 313 314 + rpc::RpcMessage::HelloResult(HelloResult { features, ..Default::default() }) 315 }, 316 }; 317 resp.async_write(&mut stream).await?; 318 319 loop { 320 + handle_transaction(state, &hello, &mut stream).await?; 321 } 322 } 323
-43
lumen/src/users.rs
··· 1 - use std::process::exit; 2 - 3 - use common::{config::Config, db::Database}; 4 - 5 - pub struct UserMgmt { 6 - db: Database, 7 - pbkd2_iters: u32, 8 - } 9 - 10 - impl UserMgmt { 11 - pub async fn new(cfg: &Config) -> Self { 12 - let db = match Database::open(&cfg.database).await { 13 - Ok(v) => v, 14 - Err(err) => { 15 - eprintln!("failed to open database: {}", err); 16 - exit(1); 17 - }, 18 - }; 19 - 20 - Self { db, pbkd2_iters: cfg.users.pbkdf2_iterations.get() } 21 - } 22 - 23 - pub async fn list_users(&self) { 24 - let users = self.db.get_users().await.expect("failed to retreive users from database"); 25 - println!("{users:?}"); 26 - } 27 - 28 - pub async fn set_password(&self, username: &str, password: &str) { 29 - self.db 30 - .set_password(username, password.to_owned(), self.pbkd2_iters) 31 - .await 32 - .expect("failed to set user's password") 33 - } 34 - 35 - pub async fn add_user(&self, username: &str, email: &str, is_admin: bool) { 36 - let id = self.db.add_user(username, email, is_admin).await.expect("failed to add user"); 37 - println!("{username}'s id is {id}.") 38 - } 39 - 40 - pub async fn delete_user(&self, username: &str) { 41 - self.db.delete_user(username).await.expect("failed to delete user"); 42 - } 43 - }
···