New upstream version 2.3.3
Sophie Brun
2 years ago
21 | 21 | |
22 | 22 | [[package]] |
23 | 23 | name = "anyhow" |
24 | version = "1.0.41" | |
25 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
26 | checksum = "15af2628f6890fe2609a3b91bef4c83450512802e59489f9c1cb1fa5df064a61" | |
24 | version = "1.0.43" | |
25 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
26 | checksum = "28ae2b3dec75a406790005a200b1bd89785afc02517a00ca99ecfe093ee9e6cf" | |
27 | 27 | |
28 | 28 | [[package]] |
29 | 29 | name = "ascii-canvas" |
46 | 46 | |
47 | 47 | [[package]] |
48 | 48 | name = "assert_cmd" |
49 | version = "1.0.5" | |
50 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
51 | checksum = "a88b6bd5df287567ffdf4ddf4d33060048e1068308e5f62d81c6f9824a045a48" | |
49 | version = "2.0.0" | |
50 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
51 | checksum = "54f002ce7d0c5e809ebb02be78fd503aeed4a511fd0fcaff6e6914cbdabbfa33" | |
52 | 52 | dependencies = [ |
53 | 53 | "bstr", |
54 | 54 | "doc-comment", |
101 | 101 | |
102 | 102 | [[package]] |
103 | 103 | name = "async-io" |
104 | version = "1.4.1" | |
105 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
106 | checksum = "4bbfd5cf2794b1e908ea8457e6c45f8f8f1f6ec5f74617bf4662623f47503c3b" | |
104 | version = "1.6.0" | |
105 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
106 | checksum = "a811e6a479f2439f0c04038796b5cfb3d2ad56c230e0f2d3f7b04d68cfee607b" | |
107 | 107 | dependencies = [ |
108 | 108 | "concurrent-queue", |
109 | "fastrand", | |
110 | 109 | "futures-lite", |
111 | 110 | "libc", |
112 | 111 | "log", |
148 | 147 | |
149 | 148 | [[package]] |
150 | 149 | name = "async-process" |
151 | version = "1.1.0" | |
152 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
153 | checksum = "a8f38756dd9ac84671c428afbf7c9f7495feff9ec5b0710f17100098e5b354ac" | |
150 | version = "1.2.0" | |
151 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
152 | checksum = "b21b63ab5a0db0369deb913540af2892750e42d949faacc7a61495ac418a1692" | |
154 | 153 | dependencies = [ |
155 | 154 | "async-io", |
156 | 155 | "blocking", |
199 | 198 | |
200 | 199 | [[package]] |
201 | 200 | name = "async-trait" |
202 | version = "0.1.50" | |
203 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
204 | checksum = "0b98e84bbb4cbcdd97da190ba0c58a1bb0de2c1fdf67d159e192ed766aeca722" | |
201 | version = "0.1.51" | |
202 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
203 | checksum = "44318e776df68115a881de9a8fd1b9e53368d7a4a5ce4cc48517da3393233a5e" | |
205 | 204 | dependencies = [ |
206 | 205 | "proc-macro2", |
207 | 206 | "quote", |
314 | 313 | |
315 | 314 | [[package]] |
316 | 315 | name = "cc" |
317 | version = "1.0.68" | |
318 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
319 | checksum = "4a72c244c1ff497a746a7e1fb3d14bd08420ecda70c8f25c7112f2781652d787" | |
316 | version = "1.0.69" | |
317 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
318 | checksum = "e70cc2f62c6ce1868963827bd677764c62d07c3d9a3e1fb1177ee1a9ab199eb2" | |
320 | 319 | |
321 | 320 | [[package]] |
322 | 321 | name = "cfg-if" |
432 | 431 | |
433 | 432 | [[package]] |
434 | 433 | name = "ctrlc" |
435 | version = "3.1.9" | |
436 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
437 | checksum = "232295399409a8b7ae41276757b5a1cc21032848d42bff2352261f958b3ca29a" | |
434 | version = "3.2.0" | |
435 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
436 | checksum = "377c9b002a72a0b2c1a18c62e2f3864bdfea4a015e3683a96e24aa45dd6c02d1" | |
438 | 437 | dependencies = [ |
439 | 438 | "nix", |
440 | 439 | "winapi", |
457 | 456 | |
458 | 457 | [[package]] |
459 | 458 | name = "curl-sys" |
460 | version = "0.4.44+curl-7.77.0" | |
461 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
462 | checksum = "4b6d85e9322b193f117c966e79c2d6929ec08c02f339f950044aba12e20bbaf1" | |
459 | version = "0.4.45+curl-7.78.0" | |
460 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
461 | checksum = "de9e5a72b1c744eb5dd20b2be4d7eb84625070bb5c4ab9b347b70464ab1e62eb" | |
463 | 462 | dependencies = [ |
464 | 463 | "cc", |
465 | 464 | "libc", |
484 | 483 | checksum = "524cbf6897b527295dff137cec09ecf3a05f4fddffd7dfcd1585403449e74198" |
485 | 484 | |
486 | 485 | [[package]] |
486 | name = "difflib" | |
487 | version = "0.4.0" | |
488 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
489 | checksum = "6184e33543162437515c2e2b48714794e37845ec9851711914eec9d308f6ebe8" | |
490 | ||
491 | [[package]] | |
487 | 492 | name = "dirs" |
488 | 493 | version = "3.0.2" |
489 | 494 | source = "registry+https://github.com/rust-lang/crates.io-index" |
562 | 567 | |
563 | 568 | [[package]] |
564 | 569 | name = "env_logger" |
565 | version = "0.8.4" | |
566 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
567 | checksum = "a19187fea3ac7e84da7dacf48de0c45d63c6a76f9490dae389aead16c243fce3" | |
570 | version = "0.9.0" | |
571 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
572 | checksum = "0b2cf0344971ee6c64c31be0d530793fba457d322dfec2810c453d0ef228f9c3" | |
568 | 573 | dependencies = [ |
569 | 574 | "atty", |
570 | 575 | "humantime", |
581 | 586 | |
582 | 587 | [[package]] |
583 | 588 | name = "fastrand" |
584 | version = "1.4.1" | |
585 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
586 | checksum = "77b705829d1e87f762c2df6da140b26af5839e1033aa84aa5f56bb688e4e1bdb" | |
589 | version = "1.5.0" | |
590 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
591 | checksum = "b394ed3d285a429378d3b384b9eb1285267e7df4b166df24b7a6939a04dc392e" | |
587 | 592 | dependencies = [ |
588 | 593 | "instant", |
589 | 594 | ] |
590 | 595 | |
591 | 596 | [[package]] |
592 | 597 | name = "feroxbuster" |
593 | version = "2.3.1" | |
598 | version = "2.3.3" | |
594 | 599 | dependencies = [ |
595 | 600 | "anyhow", |
596 | 601 | "assert_cmd", |
629 | 634 | |
630 | 635 | [[package]] |
631 | 636 | name = "float-cmp" |
632 | version = "0.8.0" | |
633 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
634 | checksum = "e1267f4ac4f343772758f7b1bdcbe767c218bbab93bb432acbf5162bbf85a6c4" | |
637 | version = "0.9.0" | |
638 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
639 | checksum = "98de4bbd547a563b716d8dfa9aad1cb19bfab00f4fa09a6a4ed21dbcf44ce9c4" | |
635 | 640 | dependencies = [ |
636 | 641 | "num-traits", |
637 | 642 | ] |
669 | 674 | |
670 | 675 | [[package]] |
671 | 676 | name = "futures" |
672 | version = "0.3.15" | |
673 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
674 | checksum = "0e7e43a803dae2fa37c1f6a8fe121e1f7bf9548b4dfc0522a42f34145dadfc27" | |
677 | version = "0.3.16" | |
678 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
679 | checksum = "1adc00f486adfc9ce99f77d717836f0c5aa84965eb0b4f051f4e83f7cab53f8b" | |
675 | 680 | dependencies = [ |
676 | 681 | "futures-channel", |
677 | 682 | "futures-core", |
684 | 689 | |
685 | 690 | [[package]] |
686 | 691 | name = "futures-channel" |
687 | version = "0.3.15" | |
688 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
689 | checksum = "e682a68b29a882df0545c143dc3646daefe80ba479bcdede94d5a703de2871e2" | |
692 | version = "0.3.16" | |
693 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
694 | checksum = "74ed2411805f6e4e3d9bc904c95d5d423b89b3b25dc0250aa74729de20629ff9" | |
690 | 695 | dependencies = [ |
691 | 696 | "futures-core", |
692 | 697 | "futures-sink", |
694 | 699 | |
695 | 700 | [[package]] |
696 | 701 | name = "futures-core" |
697 | version = "0.3.15" | |
698 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
699 | checksum = "0402f765d8a89a26043b889b26ce3c4679d268fa6bb22cd7c6aad98340e179d1" | |
702 | version = "0.3.16" | |
703 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
704 | checksum = "af51b1b4a7fdff033703db39de8802c673eb91855f2e0d47dcf3bf2c0ef01f99" | |
700 | 705 | |
701 | 706 | [[package]] |
702 | 707 | name = "futures-executor" |
703 | version = "0.3.15" | |
704 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
705 | checksum = "badaa6a909fac9e7236d0620a2f57f7664640c56575b71a7552fbd68deafab79" | |
708 | version = "0.3.16" | |
709 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
710 | checksum = "4d0d535a57b87e1ae31437b892713aee90cd2d7b0ee48727cd11fc72ef54761c" | |
706 | 711 | dependencies = [ |
707 | 712 | "futures-core", |
708 | 713 | "futures-task", |
711 | 716 | |
712 | 717 | [[package]] |
713 | 718 | name = "futures-io" |
714 | version = "0.3.15" | |
715 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
716 | checksum = "acc499defb3b348f8d8f3f66415835a9131856ff7714bf10dadfc4ec4bdb29a1" | |
719 | version = "0.3.16" | |
720 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
721 | checksum = "0b0e06c393068f3a6ef246c75cdca793d6a46347e75286933e5e75fd2fd11582" | |
717 | 722 | |
718 | 723 | [[package]] |
719 | 724 | name = "futures-lite" |
732 | 737 | |
733 | 738 | [[package]] |
734 | 739 | name = "futures-macro" |
735 | version = "0.3.15" | |
736 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
737 | checksum = "a4c40298486cdf52cc00cd6d6987892ba502c7656a16a4192a9992b1ccedd121" | |
740 | version = "0.3.16" | |
741 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
742 | checksum = "c54913bae956fb8df7f4dc6fc90362aa72e69148e3f39041fbe8742d21e0ac57" | |
738 | 743 | dependencies = [ |
739 | 744 | "autocfg", |
740 | 745 | "proc-macro-hack", |
745 | 750 | |
746 | 751 | [[package]] |
747 | 752 | name = "futures-sink" |
748 | version = "0.3.15" | |
749 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
750 | checksum = "a57bead0ceff0d6dde8f465ecd96c9338121bb7717d3e7b108059531870c4282" | |
753 | version = "0.3.16" | |
754 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
755 | checksum = "c0f30aaa67363d119812743aa5f33c201a7a66329f97d1a887022971feea4b53" | |
751 | 756 | |
752 | 757 | [[package]] |
753 | 758 | name = "futures-task" |
754 | version = "0.3.15" | |
755 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
756 | checksum = "8a16bef9fc1a4dddb5bee51c989e3fbba26569cbb0e31f5b303c184e3dd33dae" | |
759 | version = "0.3.16" | |
760 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
761 | checksum = "bbe54a98670017f3be909561f6ad13e810d9a51f3f061b902062ca3da80799f2" | |
757 | 762 | |
758 | 763 | [[package]] |
759 | 764 | name = "futures-util" |
760 | version = "0.3.15" | |
761 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
762 | checksum = "feb5c238d27e2bf94ffdfd27b2c29e3df4a68c4193bb6427384259e2bf191967" | |
765 | version = "0.3.16" | |
766 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
767 | checksum = "67eb846bfd58e44a8481a00049e82c43e0ccb5d61f8dc071057cb19249dd4d78" | |
763 | 768 | dependencies = [ |
764 | 769 | "autocfg", |
765 | 770 | "futures-channel", |
808 | 813 | |
809 | 814 | [[package]] |
810 | 815 | name = "h2" |
811 | version = "0.3.3" | |
812 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
813 | checksum = "825343c4eef0b63f541f8903f395dc5beb362a979b5799a84062527ef1e37726" | |
816 | version = "0.3.4" | |
817 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
818 | checksum = "d7f3675cfef6a30c8031cf9e6493ebdc3bb3272a3fea3923c4210d1830e6a472" | |
814 | 819 | dependencies = [ |
815 | 820 | "bytes", |
816 | 821 | "fnv", |
827 | 832 | |
828 | 833 | [[package]] |
829 | 834 | name = "hashbrown" |
830 | version = "0.9.1" | |
831 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
832 | checksum = "d7afe4a420e3fe79967a00898cc1f4db7c8a49a9333a29f8a4bd76a253d5cd04" | |
835 | version = "0.11.2" | |
836 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
837 | checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" | |
833 | 838 | |
834 | 839 | [[package]] |
835 | 840 | name = "hermit-abi" |
836 | version = "0.1.18" | |
837 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
838 | checksum = "322f4de77956e22ed0e5032c359a0f1273f1f7f0d79bfa3b8ffbc730d7fbcc5c" | |
841 | version = "0.1.19" | |
842 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
843 | checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" | |
839 | 844 | dependencies = [ |
840 | 845 | "libc", |
841 | 846 | ] |
853 | 858 | |
854 | 859 | [[package]] |
855 | 860 | name = "http-body" |
856 | version = "0.4.2" | |
857 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
858 | checksum = "60daa14be0e0786db0f03a9e57cb404c9d756eed2b6c62b9ea98ec5743ec75a9" | |
861 | version = "0.4.3" | |
862 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
863 | checksum = "399c583b2979440c60be0821a6199eca73bc3c8dcd9d070d75ac726e2c6186e5" | |
859 | 864 | dependencies = [ |
860 | 865 | "bytes", |
861 | 866 | "http", |
864 | 869 | |
865 | 870 | [[package]] |
866 | 871 | name = "httparse" |
867 | version = "1.4.1" | |
868 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
869 | checksum = "f3a87b616e37e93c22fb19bcd386f02f3af5ea98a25670ad0fce773de23c5e68" | |
872 | version = "1.5.1" | |
873 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
874 | checksum = "acd94fdbe1d4ff688b67b04eee2e17bd50995534a61539e45adfefb45e5e5503" | |
870 | 875 | |
871 | 876 | [[package]] |
872 | 877 | name = "httpdate" |
876 | 881 | |
877 | 882 | [[package]] |
878 | 883 | name = "httpmock" |
879 | version = "0.5.8" | |
880 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
881 | checksum = "b217899bcbe8ad3bdee7a46727bd3754b908831462755567852fb20eac585d46" | |
884 | version = "0.6.2" | |
885 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
886 | checksum = "218c2c3dabf4497c87d042b43984a5fd03bcd8a6adb0056ade7df20f88df225a" | |
882 | 887 | dependencies = [ |
883 | 888 | "assert-json-diff", |
884 | 889 | "async-object-pool", |
887 | 892 | "basic-cookies", |
888 | 893 | "crossbeam-utils", |
889 | 894 | "difference", |
895 | "form_urlencoded", | |
890 | 896 | "futures-util", |
891 | 897 | "hyper", |
892 | 898 | "isahc", |
909 | 915 | |
910 | 916 | [[package]] |
911 | 917 | name = "hyper" |
912 | version = "0.14.9" | |
913 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
914 | checksum = "07d6baa1b441335f3ce5098ac421fb6547c46dda735ca1bc6d0153c838f9dd83" | |
918 | version = "0.14.11" | |
919 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
920 | checksum = "0b61cf2d1aebcf6e6352c97b81dc2244ca29194be1b276f5d8ad5c6330fffb11" | |
915 | 921 | dependencies = [ |
916 | 922 | "bytes", |
917 | 923 | "futures-channel", |
957 | 963 | |
958 | 964 | [[package]] |
959 | 965 | name = "indexmap" |
960 | version = "1.6.2" | |
961 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
962 | checksum = "824845a0bf897a9042383849b02c1bc219c2383772efcd5c6f9766fa4b81aef3" | |
966 | version = "1.7.0" | |
967 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
968 | checksum = "bc633605454125dec4b66843673f01c7df2b89479b32e0ed634e43a91cff62a5" | |
963 | 969 | dependencies = [ |
964 | 970 | "autocfg", |
965 | 971 | "hashbrown", |
979 | 985 | |
980 | 986 | [[package]] |
981 | 987 | name = "instant" |
982 | version = "0.1.9" | |
983 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
984 | checksum = "61124eeebbd69b8190558df225adf7e4caafce0d743919e5d6b19652314ec5ec" | |
988 | version = "0.1.10" | |
989 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
990 | checksum = "bee0328b1209d157ef001c94dd85b4f8f64139adb0eac2659f4b08382b2f474d" | |
985 | 991 | dependencies = [ |
986 | 992 | "cfg-if", |
987 | 993 | ] |
988 | 994 | |
989 | 995 | [[package]] |
990 | 996 | name = "ipnet" |
991 | version = "2.3.0" | |
992 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
993 | checksum = "47be2f14c678be2fdcab04ab1171db51b2762ce6f0a8ee87c8dd4a04ed216135" | |
997 | version = "2.3.1" | |
998 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
999 | checksum = "68f2d64f2edebec4ce84ad108148e67e1064789bee435edc5b60ad398714a3a9" | |
994 | 1000 | |
995 | 1001 | [[package]] |
996 | 1002 | name = "isahc" |
997 | version = "1.4.0" | |
998 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
999 | checksum = "81c01404730bb4574bbacb59ca0855f969f8eabd688ca22866f2cc333f1a4f69" | |
1003 | version = "1.4.1" | |
1004 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
1005 | checksum = "0b183576592898e9e007d41b7cf2bc8bb3f8b5d2733b9291e42618d50040e7ba" | |
1000 | 1006 | dependencies = [ |
1001 | 1007 | "async-channel", |
1002 | 1008 | "crossbeam-utils", |
1035 | 1041 | |
1036 | 1042 | [[package]] |
1037 | 1043 | name = "js-sys" |
1038 | version = "0.3.51" | |
1039 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
1040 | checksum = "83bdfbace3a0e81a4253f73b49e960b053e396a11012cbd49b9b74d6a2b67062" | |
1044 | version = "0.3.53" | |
1045 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
1046 | checksum = "e4bf49d50e2961077d9c99f4b7997d770a1114f087c3c2e0069b36c13fc2979d" | |
1041 | 1047 | dependencies = [ |
1042 | 1048 | "wasm-bindgen", |
1043 | 1049 | ] |
1111 | 1117 | |
1112 | 1118 | [[package]] |
1113 | 1119 | name = "libc" |
1114 | version = "0.2.97" | |
1115 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
1116 | checksum = "12b8adadd720df158f4d70dfe7ccc6adb0472d7c55ca83445f6a5ab3e36f8fb6" | |
1120 | version = "0.2.99" | |
1121 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
1122 | checksum = "a7f823d141fe0a24df1e23b4af4e3c7ba9e5966ec514ea068c93024aa7deb765" | |
1117 | 1123 | |
1118 | 1124 | [[package]] |
1119 | 1125 | name = "libnghttp2-sys" |
1158 | 1164 | |
1159 | 1165 | [[package]] |
1160 | 1166 | name = "matches" |
1161 | version = "0.1.8" | |
1162 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
1163 | checksum = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08" | |
1167 | version = "0.1.9" | |
1168 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
1169 | checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f" | |
1164 | 1170 | |
1165 | 1171 | [[package]] |
1166 | 1172 | name = "memchr" |
1167 | version = "2.4.0" | |
1168 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
1169 | checksum = "b16bd47d9e329435e309c58469fe0791c2d0d1ba96ec0954152a5ae2b04387dc" | |
1173 | version = "2.4.1" | |
1174 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
1175 | checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" | |
1176 | ||
1177 | [[package]] | |
1178 | name = "memoffset" | |
1179 | version = "0.6.4" | |
1180 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
1181 | checksum = "59accc507f1338036a0477ef61afdae33cde60840f4dfe481319ce3ad116ddf9" | |
1182 | dependencies = [ | |
1183 | "autocfg", | |
1184 | ] | |
1170 | 1185 | |
1171 | 1186 | [[package]] |
1172 | 1187 | name = "mime" |
1198 | 1213 | |
1199 | 1214 | [[package]] |
1200 | 1215 | name = "native-tls" |
1201 | version = "0.2.7" | |
1202 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
1203 | checksum = "b8d96b2e1c8da3957d58100b09f102c6d9cfdfced01b7ec5a8974044bb09dbd4" | |
1216 | version = "0.2.8" | |
1217 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
1218 | checksum = "48ba9f7719b5a0f42f338907614285fb5fd70e53858141f69898a1fb7203b24d" | |
1204 | 1219 | dependencies = [ |
1205 | 1220 | "lazy_static", |
1206 | 1221 | "libc", |
1222 | 1237 | |
1223 | 1238 | [[package]] |
1224 | 1239 | name = "nix" |
1225 | version = "0.20.0" | |
1226 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
1227 | checksum = "fa9b4819da1bc61c0ea48b63b7bc8604064dd43013e7cc325df098d49cd7c18a" | |
1240 | version = "0.22.1" | |
1241 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
1242 | checksum = "e7555d6c7164cc913be1ce7f95cbecdabda61eb2ccd89008524af306fb7f5031" | |
1228 | 1243 | dependencies = [ |
1229 | 1244 | "bitflags", |
1230 | 1245 | "cc", |
1231 | 1246 | "cfg-if", |
1232 | 1247 | "libc", |
1248 | "memoffset", | |
1233 | 1249 | ] |
1234 | 1250 | |
1235 | 1251 | [[package]] |
1280 | 1296 | |
1281 | 1297 | [[package]] |
1282 | 1298 | name = "openssl" |
1283 | version = "0.10.34" | |
1284 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
1285 | checksum = "6d7830286ad6a3973c0f1d9b73738f69c76b739301d0229c4b96501695cbe4c8" | |
1299 | version = "0.10.36" | |
1300 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
1301 | checksum = "8d9facdb76fec0b73c406f125d44d86fdad818d66fef0531eec9233ca425ff4a" | |
1286 | 1302 | dependencies = [ |
1287 | 1303 | "bitflags", |
1288 | 1304 | "cfg-if", |
1309 | 1325 | |
1310 | 1326 | [[package]] |
1311 | 1327 | name = "openssl-sys" |
1312 | version = "0.9.63" | |
1313 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
1314 | checksum = "b6b0d6fb7d80f877617dfcb014e605e2b5ab2fb0afdf27935219bb6bd984cb98" | |
1328 | version = "0.9.66" | |
1329 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
1330 | checksum = "1996d2d305e561b70d1ee0c53f1542833f4e1ac6ce9a6708b6ff2738ca67dc82" | |
1315 | 1331 | dependencies = [ |
1316 | 1332 | "autocfg", |
1317 | 1333 | "cc", |
1385 | 1401 | |
1386 | 1402 | [[package]] |
1387 | 1403 | name = "pin-project" |
1388 | version = "1.0.7" | |
1389 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
1390 | checksum = "c7509cc106041c40a4518d2af7a61530e1eed0e6285296a3d8c5472806ccc4a4" | |
1404 | version = "1.0.8" | |
1405 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
1406 | checksum = "576bc800220cc65dac09e99e97b08b358cfab6e17078de8dc5fee223bd2d0c08" | |
1391 | 1407 | dependencies = [ |
1392 | 1408 | "pin-project-internal", |
1393 | 1409 | ] |
1394 | 1410 | |
1395 | 1411 | [[package]] |
1396 | 1412 | name = "pin-project-internal" |
1397 | version = "1.0.7" | |
1398 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
1399 | checksum = "48c950132583b500556b1efd71d45b319029f2b71518d979fcc208e16b42426f" | |
1413 | version = "1.0.8" | |
1414 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
1415 | checksum = "6e8fe8163d14ce7f0cdac2e040116f22eac817edabff0be91e8aff7e9accf389" | |
1400 | 1416 | dependencies = [ |
1401 | 1417 | "proc-macro2", |
1402 | 1418 | "quote", |
1405 | 1421 | |
1406 | 1422 | [[package]] |
1407 | 1423 | name = "pin-project-lite" |
1408 | version = "0.2.6" | |
1409 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
1410 | checksum = "dc0e1f259c92177c30a4c9d177246edd0a3568b25756a977d0632cf8fa37e905" | |
1424 | version = "0.2.7" | |
1425 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
1426 | checksum = "8d31d11c69a6b52a174b42bdc0c30e5e11670f90788b2c471c31c1d17d449443" | |
1411 | 1427 | |
1412 | 1428 | [[package]] |
1413 | 1429 | name = "pin-utils" |
1448 | 1464 | |
1449 | 1465 | [[package]] |
1450 | 1466 | name = "predicates" |
1451 | version = "1.0.8" | |
1452 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
1453 | checksum = "f49cfaf7fdaa3bfacc6fa3e7054e65148878354a5cfddcf661df4c851f8021df" | |
1454 | dependencies = [ | |
1455 | "difference", | |
1467 | version = "2.0.2" | |
1468 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
1469 | checksum = "c143348f141cc87aab5b950021bac6145d0e5ae754b0591de23244cee42c9308" | |
1470 | dependencies = [ | |
1471 | "difflib", | |
1456 | 1472 | "float-cmp", |
1473 | "itertools", | |
1457 | 1474 | "normalize-line-endings", |
1458 | 1475 | "predicates-core", |
1459 | 1476 | "regex", |
1467 | 1484 | |
1468 | 1485 | [[package]] |
1469 | 1486 | name = "predicates-tree" |
1470 | version = "1.0.2" | |
1471 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
1472 | checksum = "15f553275e5721409451eb85e15fd9a860a6e5ab4496eb215987502b5f5391f2" | |
1487 | version = "1.0.3" | |
1488 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
1489 | checksum = "d7dd0fd014130206c9352efbdc92be592751b2b9274dff685348341082c6ea3d" | |
1473 | 1490 | dependencies = [ |
1474 | 1491 | "predicates-core", |
1475 | 1492 | "treeline", |
1489 | 1506 | |
1490 | 1507 | [[package]] |
1491 | 1508 | name = "proc-macro2" |
1492 | version = "1.0.27" | |
1493 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
1494 | checksum = "f0d8caf72986c1a598726adc988bb5984792ef84f5ee5aa50209145ee8077038" | |
1509 | version = "1.0.28" | |
1510 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
1511 | checksum = "5c7ed8b8c7b886ea3ed7dde405212185f423ab44682667c8c6dd14aa1d9f6612" | |
1495 | 1512 | dependencies = [ |
1496 | 1513 | "unicode-xid", |
1497 | 1514 | ] |
1516 | 1533 | |
1517 | 1534 | [[package]] |
1518 | 1535 | name = "rand" |
1519 | version = "0.8.3" | |
1520 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
1521 | checksum = "0ef9e7e66b4468674bfcb0c81af8b7fa0bb154fa9f28eb840da5c447baeb8d7e" | |
1536 | version = "0.8.4" | |
1537 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
1538 | checksum = "2e7573632e6454cf6b99d7aac4ccca54be06da05aca2ef7423d22d27d4d4bcd8" | |
1522 | 1539 | dependencies = [ |
1523 | 1540 | "libc", |
1524 | 1541 | "rand_chacha", |
1538 | 1555 | |
1539 | 1556 | [[package]] |
1540 | 1557 | name = "rand_core" |
1541 | version = "0.6.2" | |
1542 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
1543 | checksum = "34cf66eb183df1c5876e2dcf6b13d57340741e8dc255b48e40a26de954d06ae7" | |
1558 | version = "0.6.3" | |
1559 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
1560 | checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" | |
1544 | 1561 | dependencies = [ |
1545 | 1562 | "getrandom", |
1546 | 1563 | ] |
1547 | 1564 | |
1548 | 1565 | [[package]] |
1549 | 1566 | name = "rand_hc" |
1550 | version = "0.3.0" | |
1551 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
1552 | checksum = "3190ef7066a446f2e7f42e239d161e905420ccab01eb967c9eb27d21b2322a73" | |
1567 | version = "0.3.1" | |
1568 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
1569 | checksum = "d51e9f596de227fda2ea6c84607f5558e196eeaf43c986b724ba4fb8fdf497e7" | |
1553 | 1570 | dependencies = [ |
1554 | 1571 | "rand_core", |
1555 | 1572 | ] |
1556 | 1573 | |
1557 | 1574 | [[package]] |
1558 | 1575 | name = "redox_syscall" |
1559 | version = "0.2.8" | |
1560 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
1561 | checksum = "742739e41cd49414de871ea5e549afb7e2a3ac77b589bcbebe8c82fab37147fc" | |
1576 | version = "0.2.10" | |
1577 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
1578 | checksum = "8383f39639269cde97d255a32bdb68c047337295414940c68bdd30c2e13203ff" | |
1562 | 1579 | dependencies = [ |
1563 | 1580 | "bitflags", |
1564 | 1581 | ] |
1607 | 1624 | |
1608 | 1625 | [[package]] |
1609 | 1626 | name = "reqwest" |
1610 | version = "0.11.3" | |
1611 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
1612 | checksum = "2296f2fac53979e8ccbc4a1136b25dcefd37be9ed7e4a1f6b05a6029c84ff124" | |
1627 | version = "0.11.4" | |
1628 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
1629 | checksum = "246e9f61b9bb77df069a947682be06e31ac43ea37862e244a69f177694ea6d22" | |
1613 | 1630 | dependencies = [ |
1614 | 1631 | "base64", |
1615 | 1632 | "bytes", |
1642 | 1659 | |
1643 | 1660 | [[package]] |
1644 | 1661 | name = "rlimit" |
1645 | version = "0.5.4" | |
1646 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
1647 | checksum = "81a9ed03edbed449d6897c2092c71ab5f7b5fb80f6f0b1a3ed6d40a6f9fc0720" | |
1662 | version = "0.6.2" | |
1663 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
1664 | checksum = "cc0bf25554376fd362f54332b8410a625c71f15445bca32ffdfdf4ec9ac91726" | |
1648 | 1665 | dependencies = [ |
1649 | 1666 | "libc", |
1650 | 1667 | ] |
1702 | 1719 | |
1703 | 1720 | [[package]] |
1704 | 1721 | name = "serde" |
1705 | version = "1.0.126" | |
1706 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
1707 | checksum = "ec7505abeacaec74ae4778d9d9328fe5a5d04253220a85c4ee022239fc996d03" | |
1722 | version = "1.0.127" | |
1723 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
1724 | checksum = "f03b9878abf6d14e6779d3f24f07b2cfa90352cfec4acc5aab8f1ac7f146fae8" | |
1708 | 1725 | dependencies = [ |
1709 | 1726 | "serde_derive", |
1710 | 1727 | ] |
1711 | 1728 | |
1712 | 1729 | [[package]] |
1713 | 1730 | name = "serde_derive" |
1714 | version = "1.0.126" | |
1715 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
1716 | checksum = "963a7dbc9895aeac7ac90e74f34a5d5261828f79df35cbed41e10189d3804d43" | |
1731 | version = "1.0.127" | |
1732 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
1733 | checksum = "a024926d3432516606328597e0f224a51355a493b49fdd67e9209187cbe55ecc" | |
1717 | 1734 | dependencies = [ |
1718 | 1735 | "proc-macro2", |
1719 | 1736 | "quote", |
1722 | 1739 | |
1723 | 1740 | [[package]] |
1724 | 1741 | name = "serde_json" |
1725 | version = "1.0.64" | |
1726 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
1727 | checksum = "799e97dc9fdae36a5c8b8f2cae9ce2ee9fdce2058c57a93e6099d919fd982f79" | |
1742 | version = "1.0.66" | |
1743 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
1744 | checksum = "336b10da19a12ad094b59d870ebde26a45402e5b470add4b5fd03c5048a32127" | |
1728 | 1745 | dependencies = [ |
1729 | 1746 | "itoa", |
1730 | 1747 | "ryu", |
1785 | 1802 | |
1786 | 1803 | [[package]] |
1787 | 1804 | name = "siphasher" |
1788 | version = "0.3.5" | |
1789 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
1790 | checksum = "cbce6d4507c7e4a3962091436e56e95290cb71fa302d0d270e32130b75fbff27" | |
1805 | version = "0.3.6" | |
1806 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
1807 | checksum = "729a25c17d72b06c68cb47955d44fda88ad2d3e7d77e025663fdd69b93dd71a1" | |
1791 | 1808 | |
1792 | 1809 | [[package]] |
1793 | 1810 | name = "slab" |
1794 | version = "0.4.3" | |
1795 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
1796 | checksum = "f173ac3d1a7e3b28003f40de0b5ce7fe2710f9b9dc3fc38664cebee46b3b6527" | |
1811 | version = "0.4.4" | |
1812 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
1813 | checksum = "c307a32c1c5c437f38c7fd45d753050587732ba8628319fbdf12a7e289ccc590" | |
1797 | 1814 | |
1798 | 1815 | [[package]] |
1799 | 1816 | name = "sluice" |
1800 | version = "0.5.4" | |
1801 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
1802 | checksum = "8fa0333a60ff2e3474a6775cc611840c2a55610c831dd366503474c02f1a28f5" | |
1803 | dependencies = [ | |
1804 | "futures-channel", | |
1817 | version = "0.5.5" | |
1818 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
1819 | checksum = "6d7400c0eff44aa2fcb5e31a5f24ba9716ed90138769e4977a2ba6014ae63eb5" | |
1820 | dependencies = [ | |
1821 | "async-channel", | |
1805 | 1822 | "futures-core", |
1806 | 1823 | "futures-io", |
1807 | 1824 | ] |
1814 | 1831 | |
1815 | 1832 | [[package]] |
1816 | 1833 | name = "socket2" |
1817 | version = "0.4.0" | |
1818 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
1819 | checksum = "9e3dfc207c526015c632472a77be09cf1b6e46866581aecae5cc38fb4235dea2" | |
1834 | version = "0.4.1" | |
1835 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
1836 | checksum = "765f090f0e423d2b55843402a07915add955e7d60657db13707a159727326cad" | |
1820 | 1837 | dependencies = [ |
1821 | 1838 | "libc", |
1822 | 1839 | "winapi", |
1842 | 1859 | |
1843 | 1860 | [[package]] |
1844 | 1861 | name = "syn" |
1845 | version = "1.0.73" | |
1846 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
1847 | checksum = "f71489ff30030d2ae598524f61326b902466f72a0fb1a8564c001cc63425bcc7" | |
1862 | version = "1.0.75" | |
1863 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
1864 | checksum = "b7f58f7e8eaa0009c5fec437aabf511bd9933e4b2d7407bd05273c01a8906ea7" | |
1848 | 1865 | dependencies = [ |
1849 | 1866 | "proc-macro2", |
1850 | 1867 | "quote", |
1906 | 1923 | |
1907 | 1924 | [[package]] |
1908 | 1925 | name = "thiserror" |
1909 | version = "1.0.25" | |
1910 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
1911 | checksum = "fa6f76457f59514c7eeb4e59d891395fab0b2fd1d40723ae737d64153392e9c6" | |
1926 | version = "1.0.26" | |
1927 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
1928 | checksum = "93119e4feac1cbe6c798c34d3a53ea0026b0b1de6a120deef895137c0529bfe2" | |
1912 | 1929 | dependencies = [ |
1913 | 1930 | "thiserror-impl", |
1914 | 1931 | ] |
1915 | 1932 | |
1916 | 1933 | [[package]] |
1917 | 1934 | name = "thiserror-impl" |
1918 | version = "1.0.25" | |
1919 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
1920 | checksum = "8a36768c0fbf1bb15eca10defa29526bda730a2376c2ab4393ccfa16fb1a318d" | |
1935 | version = "1.0.26" | |
1936 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
1937 | checksum = "060d69a0afe7796bf42e9e2ff91f5ee691fb15c53d38b4b62a9a53eb23164745" | |
1921 | 1938 | dependencies = [ |
1922 | 1939 | "proc-macro2", |
1923 | 1940 | "quote", |
1935 | 1952 | |
1936 | 1953 | [[package]] |
1937 | 1954 | name = "tinyvec" |
1938 | version = "1.2.0" | |
1939 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
1940 | checksum = "5b5220f05bb7de7f3f53c7c065e1199b3172696fe2db9f9c4d8ad9b4ee74c342" | |
1955 | version = "1.3.1" | |
1956 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
1957 | checksum = "848a1e1181b9f6753b5e96a092749e29b11d19ede67dfbbd6c7dc7e0f49b5338" | |
1941 | 1958 | dependencies = [ |
1942 | 1959 | "tinyvec_macros", |
1943 | 1960 | ] |
1950 | 1967 | |
1951 | 1968 | [[package]] |
1952 | 1969 | name = "tokio" |
1953 | version = "1.6.2" | |
1954 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
1955 | checksum = "aea337f72e96efe29acc234d803a5981cd9a2b6ed21655cd7fc21cfe021e8ec7" | |
1970 | version = "1.10.0" | |
1971 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
1972 | checksum = "01cf844b23c6131f624accf65ce0e4e9956a8bb329400ea5bcc26ae3a5c20b0b" | |
1956 | 1973 | dependencies = [ |
1957 | 1974 | "autocfg", |
1958 | 1975 | "bytes", |
1970 | 1987 | |
1971 | 1988 | [[package]] |
1972 | 1989 | name = "tokio-macros" |
1973 | version = "1.2.0" | |
1974 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
1975 | checksum = "c49e3df43841dafb86046472506755d8501c5615673955f6aa17181125d13c37" | |
1990 | version = "1.3.0" | |
1991 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
1992 | checksum = "54473be61f4ebe4efd09cec9bd5d16fa51d70ea0192213d754d2d500457db110" | |
1976 | 1993 | dependencies = [ |
1977 | 1994 | "proc-macro2", |
1978 | 1995 | "quote", |
2003 | 2020 | |
2004 | 2021 | [[package]] |
2005 | 2022 | name = "tokio-stream" |
2006 | version = "0.1.6" | |
2007 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
2008 | checksum = "f8864d706fdb3cc0843a49647ac892720dac98a6eeb818b77190592cf4994066" | |
2023 | version = "0.1.7" | |
2024 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
2025 | checksum = "7b2f3f698253f03119ac0102beaa64f67a67e08074d03a22d18784104543727f" | |
2009 | 2026 | dependencies = [ |
2010 | 2027 | "futures-core", |
2011 | 2028 | "pin-project-lite", |
2067 | 2084 | |
2068 | 2085 | [[package]] |
2069 | 2086 | name = "tracing-core" |
2070 | version = "0.1.18" | |
2071 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
2072 | checksum = "a9ff14f98b1a4b289c6248a023c1c2fa1491062964e9fed67ab29c4e4da4a052" | |
2087 | version = "0.1.19" | |
2088 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
2089 | checksum = "2ca517f43f0fb96e0c3072ed5c275fe5eece87e8cb52f4a77b69226d3b1c9df8" | |
2073 | 2090 | dependencies = [ |
2074 | 2091 | "lazy_static", |
2075 | 2092 | ] |
2098 | 2115 | |
2099 | 2116 | [[package]] |
2100 | 2117 | name = "unicode-bidi" |
2101 | version = "0.3.5" | |
2102 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
2103 | checksum = "eeb8be209bb1c96b7c177c7420d26e04eccacb0eeae6b980e35fcb74678107e0" | |
2104 | dependencies = [ | |
2105 | "matches", | |
2106 | ] | |
2118 | version = "0.3.6" | |
2119 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
2120 | checksum = "246f4c42e67e7a4e3c6106ff716a5d067d4132a642840b242e357e468a2a0085" | |
2107 | 2121 | |
2108 | 2122 | [[package]] |
2109 | 2123 | name = "unicode-normalization" |
2159 | 2173 | |
2160 | 2174 | [[package]] |
2161 | 2175 | name = "vcpkg" |
2162 | version = "0.2.13" | |
2163 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
2164 | checksum = "025ce40a007e1907e58d5bc1a594def78e5573bb0b1160bc389634e8f12e4faa" | |
2176 | version = "0.2.15" | |
2177 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
2178 | checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" | |
2165 | 2179 | |
2166 | 2180 | [[package]] |
2167 | 2181 | name = "vec_map" |
2208 | 2222 | |
2209 | 2223 | [[package]] |
2210 | 2224 | name = "wasm-bindgen" |
2211 | version = "0.2.74" | |
2212 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
2213 | checksum = "d54ee1d4ed486f78874278e63e4069fc1ab9f6a18ca492076ffb90c5eb2997fd" | |
2225 | version = "0.2.76" | |
2226 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
2227 | checksum = "8ce9b1b516211d33767048e5d47fa2a381ed8b76fc48d2ce4aa39877f9f183e0" | |
2214 | 2228 | dependencies = [ |
2215 | 2229 | "cfg-if", |
2216 | 2230 | "serde", |
2220 | 2234 | |
2221 | 2235 | [[package]] |
2222 | 2236 | name = "wasm-bindgen-backend" |
2223 | version = "0.2.74" | |
2224 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
2225 | checksum = "3b33f6a0694ccfea53d94db8b2ed1c3a8a4c86dd936b13b9f0a15ec4a451b900" | |
2237 | version = "0.2.76" | |
2238 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
2239 | checksum = "cfe8dc78e2326ba5f845f4b5bf548401604fa20b1dd1d365fb73b6c1d6364041" | |
2226 | 2240 | dependencies = [ |
2227 | 2241 | "bumpalo", |
2228 | 2242 | "lazy_static", |
2235 | 2249 | |
2236 | 2250 | [[package]] |
2237 | 2251 | name = "wasm-bindgen-futures" |
2238 | version = "0.4.24" | |
2239 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
2240 | checksum = "5fba7978c679d53ce2d0ac80c8c175840feb849a161664365d1287b41f2e67f1" | |
2252 | version = "0.4.26" | |
2253 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
2254 | checksum = "95fded345a6559c2cfee778d562300c581f7d4ff3edb9b0d230d69800d213972" | |
2241 | 2255 | dependencies = [ |
2242 | 2256 | "cfg-if", |
2243 | 2257 | "js-sys", |
2247 | 2261 | |
2248 | 2262 | [[package]] |
2249 | 2263 | name = "wasm-bindgen-macro" |
2250 | version = "0.2.74" | |
2251 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
2252 | checksum = "088169ca61430fe1e58b8096c24975251700e7b1f6fd91cc9d59b04fb9b18bd4" | |
2264 | version = "0.2.76" | |
2265 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
2266 | checksum = "44468aa53335841d9d6b6c023eaab07c0cd4bddbcfdee3e2bb1e8d2cb8069fef" | |
2253 | 2267 | dependencies = [ |
2254 | 2268 | "quote", |
2255 | 2269 | "wasm-bindgen-macro-support", |
2257 | 2271 | |
2258 | 2272 | [[package]] |
2259 | 2273 | name = "wasm-bindgen-macro-support" |
2260 | version = "0.2.74" | |
2261 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
2262 | checksum = "be2241542ff3d9f241f5e2cb6dd09b37efe786df8851c54957683a49f0987a97" | |
2274 | version = "0.2.76" | |
2275 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
2276 | checksum = "0195807922713af1e67dc66132c7328206ed9766af3858164fb583eedc25fbad" | |
2263 | 2277 | dependencies = [ |
2264 | 2278 | "proc-macro2", |
2265 | 2279 | "quote", |
2270 | 2284 | |
2271 | 2285 | [[package]] |
2272 | 2286 | name = "wasm-bindgen-shared" |
2273 | version = "0.2.74" | |
2274 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
2275 | checksum = "d7cff876b8f18eed75a66cf49b65e7f967cb354a7aa16003fb55dbfd25b44b4f" | |
2287 | version = "0.2.76" | |
2288 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
2289 | checksum = "acdb075a845574a1fa5f09fd77e43f7747599301ea3417a9fbffdeedfc1f4a29" | |
2276 | 2290 | |
2277 | 2291 | [[package]] |
2278 | 2292 | name = "web-sys" |
2279 | version = "0.3.51" | |
2280 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
2281 | checksum = "e828417b379f3df7111d3a2a9e5753706cae29c41f7c4029ee9fd77f3e09e582" | |
2293 | version = "0.3.53" | |
2294 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
2295 | checksum = "224b2f6b67919060055ef1a67807367c2066ed520c3862cc013d26cf893a783c" | |
2282 | 2296 | dependencies = [ |
2283 | 2297 | "js-sys", |
2284 | 2298 | "wasm-bindgen", |
0 | 0 | [package] |
1 | 1 | name = "feroxbuster" |
2 | version = "2.3.1" | |
2 | version = "2.3.3" | |
3 | 3 | authors = ["Ben 'epi' Risher <[email protected]>"] |
4 | 4 | license = "MIT" |
5 | 5 | edition = "2018" |
21 | 21 | dirs = "3.0" |
22 | 22 | |
23 | 23 | [dependencies] |
24 | futures = { version = "0.3.14"} | |
25 | tokio = { version = "1.6", features = ["full"] } | |
24 | futures = { version = "0.3"} | |
25 | tokio = { version = "1.10", features = ["full"] } | |
26 | 26 | tokio-util = {version = "0.6.6", features = ["codec"]} |
27 | 27 | log = "0.4" |
28 | env_logger = "0.8" | |
28 | env_logger = "0.9" | |
29 | 29 | reqwest = { version = "0.11", features = ["socks"] } |
30 | 30 | clap = "2.33" |
31 | 31 | lazy_static = "1.4" |
32 | 32 | toml = "0.5" |
33 | 33 | serde = { version = "1.0", features = ["derive", "rc"] } |
34 | serde_json = "1.0.64" | |
34 | serde_json = "1.0" | |
35 | 35 | uuid = { version = "0.8", features = ["v4"] } |
36 | 36 | indicatif = "0.15" |
37 | 37 | console = "0.14" |
39 | 39 | dirs = "3.0" |
40 | 40 | regex = "1" |
41 | 41 | crossterm = "0.20" |
42 | rlimit = "0.5.4" | |
43 | ctrlc = "3.1.9" | |
42 | rlimit = "0.6" | |
43 | ctrlc = "3.2" | |
44 | 44 | fuzzyhash = "0.2.1" |
45 | 45 | anyhow = "1.0" |
46 | 46 | leaky-bucket = "0.10.0" |
47 | 47 | |
48 | 48 | [dev-dependencies] |
49 | 49 | tempfile = "3.1" |
50 | httpmock = "0.5.8" | |
51 | assert_cmd = "1.0" | |
52 | predicates = "1.0.8" | |
50 | httpmock = "0.6.2" | |
51 | assert_cmd = "2.0" | |
52 | predicates = "2.0" | |
53 | 53 | |
54 | 54 | [profile.release] |
55 | 55 | lto = true |
303 | 303 | - verbosity: `0` (no logging enabled) |
304 | 304 | - scan_limit: `0` (no limit imposed on concurrent scans) |
305 | 305 | - rate_limit: `0` (no limit imposed on requests per second) |
306 | - status_codes: `200 204 301 302 307 308 401 403 405` | |
306 | - status_codes: `200 204 301 302 307 308 401 403 405 500` | |
307 | 307 | - user_agent: `feroxbuster/VERSION` |
308 | 308 | - recursion depth: `4` |
309 | 309 | - auto-filter wildcards - `true` |
555 | 555 | Limit total number of concurrent scans (default: 0, i.e. no limit) |
556 | 556 | |
557 | 557 | -s, --status-codes <STATUS_CODE>... |
558 | Status Codes to include (allow list) (default: 200 204 301 302 307 308 401 403 405) | |
558 | Status Codes to include (allow list) (default: 200 204 301 302 307 308 401 403 405 500) | |
559 | 559 | |
560 | 560 | -t, --threads <THREADS> |
561 | 561 | Number of concurrent threads (default: 50) |
1000 | 1000 | cat large-target-list | ./feroxbuster --stdin --parallel 10 --extract-links --auto-bail |
1001 | 1001 | ``` |
1002 | 1002 | |
1003 | Resuling Process List (illustrative): | |
1003 | Resulting Process List (illustrative): | |
1004 | 1004 | ``` |
1005 | 1005 | feroxbuster --stdin --parallel 10 |
1006 | 1006 | \_ feroxbuster --silent --extract-links --auto-bail -u https://target-one |
1008 | 1008 | \_ feroxbuster --silent --extract-links --auto-bail -u https://target-three |
1009 | 1009 | \_ ... |
1010 | 1010 | \_ feroxbuster --silent --extract-links --auto-bail -u https://target-ten |
1011 | ``` | |
1012 | ||
1013 | As of `v2.3.2`, logging while using `--parallel` uses the value of `-o`|`--output` as a seed to create a directory named `OUTPUT_VALUE-TIMESTAMP.logs/`. Within the directory, an individual log file is created for each target passed over stdin. | |
1014 | ||
1015 | Example Command: | |
1016 | ``` | |
1017 | cat large-target-list | ./feroxbuster --stdin --parallel 10 --output super-cool-mega-scan | |
1018 | ``` | |
1019 | ||
1020 | Resulting directory structure (illustrative): | |
1021 | ``` | |
1022 | super-cool-mega-scan-1627865696.logs/ | |
1023 | ├── ferox-https_target_one_com-1627865696.log | |
1024 | ├── ... | |
1025 | └── ferox-https_target_two_net-1627865696.log | |
1011 | 1026 | ``` |
1012 | 1027 | |
1013 | 1028 | ### Prevent Specific Domain/Directory Scans aka a Deny List (new in `v2.3.0`) |
164 | 164 | } |
165 | 165 | |
166 | 166 | for denied_url in &config.url_denylist { |
167 | url_denylist.push(BannerEntry::new("🚫", "Don't Scan", &denied_url)); | |
167 | url_denylist.push(BannerEntry::new("🚫", "Don't Scan", denied_url)); | |
168 | 168 | } |
169 | 169 | |
170 | 170 | let mut codes = vec![]; |
3 | 3 | scan_manager::{FeroxState, PAUSE_SCAN}, |
4 | 4 | scanner::RESPONSES, |
5 | 5 | statistics::StatError, |
6 | utils::slugify_filename, | |
6 | 7 | utils::{open_file, write_to}, |
7 | 8 | SLEEP_DURATION, |
8 | 9 | }; |
16 | 17 | }, |
17 | 18 | thread::sleep, |
18 | 19 | time::Duration, |
19 | time::{SystemTime, UNIX_EPOCH}, | |
20 | 20 | }; |
21 | 21 | |
22 | 22 | /// Atomic boolean flag, used to determine whether or not the terminal input handler should exit |
76 | 76 | pub fn sigint_handler(handles: Arc<Handles>) -> Result<()> { |
77 | 77 | log::trace!("enter: sigint_handler({:?})", handles); |
78 | 78 | |
79 | let ts = SystemTime::now().duration_since(UNIX_EPOCH)?.as_secs(); | |
80 | ||
81 | let slug = if !handles.config.target_url.is_empty() { | |
79 | let filename = if !handles.config.target_url.is_empty() { | |
82 | 80 | // target url populated |
83 | handles | |
84 | .config | |
85 | .target_url | |
86 | .replace("://", "_") | |
87 | .replace("/", "_") | |
88 | .replace(".", "_") | |
81 | slugify_filename(&handles.config.target_url, "ferox", "state") | |
89 | 82 | } else { |
90 | 83 | // stdin used |
91 | "stdin".to_string() | |
84 | slugify_filename("stdin", "ferox", "state") | |
92 | 85 | }; |
93 | 86 | |
94 | let filename = format!("ferox-{}-{}.state", slug, ts); | |
95 | 87 | let warning = format!( |
96 | 88 | "🚨 Caught {} 🚨 saving scan state to {} ...", |
97 | 89 | style("ctrl+c").yellow(), |
212 | 212 | // should be replayed; not using logged_request due to replay proxy client |
213 | 213 | make_request( |
214 | 214 | self.config.replay_client.as_ref().unwrap(), |
215 | &resp.url(), | |
215 | resp.url(), | |
216 | 216 | self.config.output_level, |
217 | 217 | tx_stats.clone(), |
218 | 218 | ) |
148 | 148 | |
149 | 149 | let body = self.response.unwrap().text(); |
150 | 150 | |
151 | for capture in self.links_regex.captures_iter(&body) { | |
151 | for capture in self.links_regex.captures_iter(body) { | |
152 | 152 | // remove single & double quotes from both ends of the capture |
153 | 153 | // capture[0] is the entire match, additional capture groups start at [1] |
154 | 154 | let link = capture[0].trim_matches(|c| c == '\'' || c == '"'); |
274 | 274 | }; |
275 | 275 | |
276 | 276 | let new_url = old_url |
277 | .join(&link) | |
277 | .join(link) | |
278 | 278 | .with_context(|| format!("Could not join {} with {}", old_url, link))?; |
279 | 279 | |
280 | 280 | links.insert(new_url.to_string()); |
296 | 296 | pub(super) async fn request_link(&self, url: &str) -> Result<FeroxResponse> { |
297 | 297 | log::trace!("enter: request_link({})", url); |
298 | 298 | |
299 | let ferox_url = FeroxUrl::from_string(&url, self.handles.clone()); | |
299 | let ferox_url = FeroxUrl::from_string(url, self.handles.clone()); | |
300 | 300 | |
301 | 301 | // create a url based on the given command line options |
302 | let new_url = ferox_url.format(&"", None)?; | |
302 | let new_url = ferox_url.format("", None)?; | |
303 | 303 | |
304 | 304 | let scanned_urls = self.handles.ferox_scans()?; |
305 | 305 | |
350 | 350 | if let Some(new_path) = capture.name("url_path") { |
351 | 351 | let mut new_url = Url::parse(&self.url)?; |
352 | 352 | new_url.set_path(new_path.as_str()); |
353 | if self.add_all_sub_paths(&new_url.path(), &mut links).is_err() { | |
353 | if self.add_all_sub_paths(new_url.path(), &mut links).is_err() { | |
354 | 354 | log::warn!("could not add sub-paths from {} to {:?}", new_url, links); |
355 | 355 | } |
356 | 356 | } |
53 | 53 | /// in the expected array |
54 | 54 | fn extractor_get_sub_paths_from_path_with_multiple_paths() { |
55 | 55 | let path = "homepage/assets/img/icons/handshake.svg"; |
56 | let r_paths = ROBOTS_EXT.get_sub_paths_from_path(&path); | |
57 | let b_paths = BODY_EXT.get_sub_paths_from_path(&path); | |
56 | let r_paths = ROBOTS_EXT.get_sub_paths_from_path(path); | |
57 | let b_paths = BODY_EXT.get_sub_paths_from_path(path); | |
58 | 58 | let expected = vec![ |
59 | 59 | "homepage/", |
60 | 60 | "homepage/assets/", |
77 | 77 | /// returned |
78 | 78 | fn extractor_get_sub_paths_from_path_with_enclosing_slashes() { |
79 | 79 | let path = "/homepage/assets/"; |
80 | let r_paths = ROBOTS_EXT.get_sub_paths_from_path(&path); | |
81 | let b_paths = BODY_EXT.get_sub_paths_from_path(&path); | |
80 | let r_paths = ROBOTS_EXT.get_sub_paths_from_path(path); | |
81 | let b_paths = BODY_EXT.get_sub_paths_from_path(path); | |
82 | 82 | let expected = vec!["homepage/", "homepage/assets"]; |
83 | 83 | |
84 | 84 | assert_eq!(r_paths.len(), expected.len()); |
94 | 94 | /// included |
95 | 95 | fn extractor_get_sub_paths_from_path_with_only_a_word() { |
96 | 96 | let path = "homepage"; |
97 | let r_paths = ROBOTS_EXT.get_sub_paths_from_path(&path); | |
98 | let b_paths = BODY_EXT.get_sub_paths_from_path(&path); | |
97 | let r_paths = ROBOTS_EXT.get_sub_paths_from_path(path); | |
98 | let b_paths = BODY_EXT.get_sub_paths_from_path(path); | |
99 | 99 | let expected = vec!["homepage"]; |
100 | 100 | |
101 | 101 | assert_eq!(r_paths.len(), expected.len()); |
110 | 110 | /// extract sub paths from the given url fragment; expect 1 sub path, forward slash removed |
111 | 111 | fn extractor_get_sub_paths_from_path_with_an_absolute_word() { |
112 | 112 | let path = "/homepage"; |
113 | let r_paths = ROBOTS_EXT.get_sub_paths_from_path(&path); | |
114 | let b_paths = BODY_EXT.get_sub_paths_from_path(&path); | |
113 | let r_paths = ROBOTS_EXT.get_sub_paths_from_path(path); | |
114 | let b_paths = BODY_EXT.get_sub_paths_from_path(path); | |
115 | 115 | let expected = vec!["homepage"]; |
116 | 116 | |
117 | 117 | assert_eq!(r_paths.len(), expected.len()); |
40 | 40 | if let Ok(filters) = self.filters.lock() { |
41 | 41 | for filter in filters.iter() { |
42 | 42 | // wildcard.should_filter goes here |
43 | if filter.should_filter_response(&response) { | |
43 | if filter.should_filter_response(response) { | |
44 | 44 | if filter.as_any().downcast_ref::<WildcardFilter>().is_some() { |
45 | 45 | tx_stats |
46 | 46 | .send(AddToUsizeField(WildcardsFiltered, 1)) |
55 | 55 | // add any regex filters to filters handler's FeroxFilters (-X|--filter-regex) |
56 | 56 | for regex_filter in &handles.config.filter_regex { |
57 | 57 | let raw = regex_filter; |
58 | let compiled = skip_fail!(Regex::new(&raw)); | |
58 | let compiled = skip_fail!(Regex::new(raw)); | |
59 | 59 | |
60 | 60 | let filter = RegexFilter { |
61 | 61 | raw_string: raw.to_owned(), |
68 | 68 | // add any similarity filters to filters handler's FeroxFilters (--filter-similar-to) |
69 | 69 | for similarity_filter in &handles.config.filter_similar { |
70 | 70 | // url as-is based on input, ignores user-specified url manipulation options (add-slash etc) |
71 | let url = skip_fail!(Url::parse(&similarity_filter)); | |
71 | let url = skip_fail!(Url::parse(similarity_filter)); | |
72 | 72 | |
73 | 73 | // attempt to request the given url |
74 | 74 | let resp = skip_fail!(logged_request(&url, handles.clone()).await); |
127 | 127 | } |
128 | 128 | |
129 | 129 | #[test] |
130 | /// test should_filter on WilcardFilter where static logic matches but response length is 0 | |
131 | fn wildcard_should_filter_when_static_wildcard_len_is_zero() { | |
132 | let mut resp = FeroxResponse::default(); | |
133 | resp.set_wildcard(true); | |
134 | resp.set_url("http://localhost"); | |
135 | ||
136 | // default WildcardFilter is used in the code that executes when response.content_length() == 0 | |
137 | let filter = WildcardFilter::new(false); | |
138 | ||
139 | assert!(filter.should_filter_response(&resp)); | |
140 | } | |
141 | ||
142 | #[test] | |
130 | 143 | /// test should_filter on WilcardFilter where dynamic logic matches |
131 | 144 | fn wildcard_should_filter_when_dynamic_wildcard_found() { |
132 | 145 | let mut resp = FeroxResponse::default(); |
67 | 67 | return true; |
68 | 68 | } |
69 | 69 | |
70 | if self.size == u64::MAX && response.content_length() == 0 { | |
71 | // static wildcard size found during testing | |
72 | // but response length was zero; pointed out by @Tib3rius | |
73 | log::debug!("static wildcard: filtered out {}", response.url()); | |
74 | log::trace!("exit: should_filter_response -> true"); | |
75 | return true; | |
76 | } | |
77 | ||
70 | 78 | if self.dynamic != u64::MAX { |
71 | 79 | // dynamic wildcard offset found during testing |
72 | 80 | |
75 | 83 | // except that I don't want an empty string taking up the last index in the |
76 | 84 | // event that the url ends with a forward slash. It's ugly enough to be split |
77 | 85 | // into its own function for readability. |
78 | let url_len = FeroxUrl::path_length_of_url(&response.url()); | |
86 | let url_len = FeroxUrl::path_length_of_url(response.url()); | |
79 | 87 | |
80 | 88 | if url_len + self.dynamic == response.content_length() { |
81 | 89 | log::debug!("dynamic wildcard: filtered out {}", response.url()); |
206 | 206 | let mut good_urls = vec![]; |
207 | 207 | |
208 | 208 | for target_url in target_urls { |
209 | let url = FeroxUrl::from_string(&target_url, self.handles.clone()); | |
209 | let url = FeroxUrl::from_string(target_url, self.handles.clone()); | |
210 | 210 | let request = skip_fail!(url.format("", None)); |
211 | 211 | |
212 | 212 | let result = logged_request(&request, self.handles.clone()).await; |
42 | 42 | pub(crate) const VERSION: &str = env!("CARGO_PKG_VERSION"); |
43 | 43 | |
44 | 44 | /// Maximum number of file descriptors that can be opened during a scan |
45 | pub const DEFAULT_OPEN_FILE_LIMIT: usize = 8192; | |
45 | pub const DEFAULT_OPEN_FILE_LIMIT: u64 = 8192; | |
46 | 46 | |
47 | 47 | /// Default value used to determine near-duplicate web pages (equivalent to 95%) |
48 | 48 | pub const SIMILARITY_THRESHOLD: u32 = 95; |
72 | 72 | /// * 401 Unauthorized |
73 | 73 | /// * 403 Forbidden |
74 | 74 | /// * 405 Method Not Allowed |
75 | pub const DEFAULT_STATUS_CODES: [StatusCode; 9] = [ | |
75 | /// * 500 Internal Server Error | |
76 | pub const DEFAULT_STATUS_CODES: [StatusCode; 10] = [ | |
76 | 77 | StatusCode::OK, |
77 | 78 | StatusCode::NO_CONTENT, |
78 | 79 | StatusCode::MOVED_PERMANENTLY, |
82 | 83 | StatusCode::UNAUTHORIZED, |
83 | 84 | StatusCode::FORBIDDEN, |
84 | 85 | StatusCode::METHOD_NOT_ALLOWED, |
86 | StatusCode::INTERNAL_SERVER_ERROR, | |
85 | 87 | ]; |
86 | 88 | |
87 | 89 | /// Default filename for config file settings |
0 | 0 | use std::{ |
1 | 1 | env::args, |
2 | fs::File, | |
2 | fs::{create_dir, remove_file, File}, | |
3 | 3 | io::{stderr, BufRead, BufReader}, |
4 | 4 | ops::Index, |
5 | path::Path, | |
5 | 6 | process::Command, |
6 | 7 | sync::{atomic::Ordering, Arc}, |
7 | 8 | }; |
26 | 27 | progress::{PROGRESS_BAR, PROGRESS_PRINTER}, |
27 | 28 | scan_manager::{self}, |
28 | 29 | scanner, |
29 | utils::fmt_err, | |
30 | utils::{fmt_err, slugify_filename}, | |
30 | 31 | }; |
31 | 32 | #[cfg(not(target_os = "windows"))] |
32 | 33 | use feroxbuster::{utils::set_open_file_limit, DEFAULT_OPEN_FILE_LIMIT}; |
266 | 267 | // from removing --parallel) |
267 | 268 | original.remove(parallel_index); |
268 | 269 | |
270 | // to log unique files to a shared folder, we need to first check for the presence | |
271 | // of -o|--output. | |
272 | let out_dir = if !config.output.is_empty() { | |
273 | // -o|--output was used, so we'll attempt to create a directory to store the files | |
274 | let output_path = Path::new(&handles.config.output); | |
275 | ||
276 | // this only returns None if the path terminates in `..`. Since I don't want to | |
277 | // hand-hold to that degree, we'll unwrap and fail if the output path ends in `..` | |
278 | let base_name = output_path.file_name().unwrap(); | |
279 | ||
280 | let new_folder = slugify_filename(&base_name.to_string_lossy(), "", "logs"); | |
281 | ||
282 | let final_path = output_path.with_file_name(&new_folder); | |
283 | ||
284 | // create the directory or fail silently, assuming the reason for failure is that | |
285 | // the path exists already | |
286 | create_dir(&final_path).unwrap_or(()); | |
287 | ||
288 | final_path.to_string_lossy().to_string() | |
289 | } else { | |
290 | String::new() | |
291 | }; | |
292 | ||
269 | 293 | // unvalidated targets fresh from stdin, just spawn children and let them do all checks |
270 | 294 | for target in targets { |
271 | 295 | // add the current target to the provided command |
272 | 296 | let mut cloned = original.clone(); |
297 | ||
298 | if !out_dir.is_empty() { | |
299 | // output directory value is not empty, need to join output directory with | |
300 | // unique scan filename | |
301 | ||
302 | // unwrap is ok, we already know -o was used | |
303 | let out_idx = original | |
304 | .iter() | |
305 | .position(|s| *s == "--output" || *s == "-o") | |
306 | .unwrap(); | |
307 | ||
308 | let filename = slugify_filename(&target, "ferox", "log"); | |
309 | ||
310 | let full_path = Path::new(&out_dir) | |
311 | .join(filename) | |
312 | .to_string_lossy() | |
313 | .to_string(); | |
314 | ||
315 | // a +1 to the index is fine here, as clap has already validated that | |
316 | // -o|--output has a value associated with it | |
317 | cloned[out_idx + 1] = full_path; | |
318 | } | |
319 | ||
273 | 320 | cloned.push("-u".to_string()); |
274 | 321 | cloned.push(target); |
275 | 322 | |
293 | 340 | }); |
294 | 341 | } |
295 | 342 | |
343 | // the output handler creates an empty file to which it will try to write, because | |
344 | // this happens before we enter the --parallel branch, we need to remove that file | |
345 | // if it's empty | |
346 | let output = handles.config.output.to_owned(); | |
347 | ||
296 | 348 | clean_up(handles, tasks).await?; |
349 | ||
350 | let file = Path::new(&output); | |
351 | if file.exists() { | |
352 | // expectation is that this is always true for the first ferox process | |
353 | if file.metadata()?.len() == 0 { | |
354 | // empty file, attempt to remove it | |
355 | remove_file(file)?; | |
356 | } | |
357 | } | |
297 | 358 | |
298 | 359 | log::trace!("exit: parallel branch && wrapped main"); |
299 | 360 | return Ok(()); |
50 | 50 | |
51 | 51 | progress_bar.set_style(style); |
52 | 52 | |
53 | progress_bar.set_prefix(&prefix); | |
53 | progress_bar.set_prefix(prefix); | |
54 | 54 | |
55 | 55 | progress_bar |
56 | 56 | } |
120 | 120 | |
121 | 121 | /// Set `FeroxResponse`'s `url` attribute, has no affect if an error occurs |
122 | 122 | pub fn set_url(&mut self, url: &str) { |
123 | match Url::parse(&url) { | |
123 | match Url::parse(url) { | |
124 | 124 | Ok(url) => { |
125 | 125 | self.url = url; |
126 | 126 | } |
338 | 338 | lines, |
339 | 339 | words, |
340 | 340 | chars, |
341 | status_colorizer(&status), | |
341 | status_colorizer(status), | |
342 | 342 | self.url(), |
343 | 343 | FeroxUrl::path_length_of_url(&self.url) |
344 | 344 | ); |
430 | 430 | OutputLevel::Silent => BarType::Hidden, |
431 | 431 | }; |
432 | 432 | |
433 | let progress_bar = add_bar(&url, bar_length, bar_type); | |
433 | let progress_bar = add_bar(url, bar_length, bar_type); | |
434 | 434 | |
435 | 435 | progress_bar.reset_elapsed(); |
436 | 436 | |
440 | 440 | }; |
441 | 441 | |
442 | 442 | let ferox_scan = FeroxScan::new( |
443 | &url, | |
443 | url, | |
444 | 444 | scan_type, |
445 | 445 | scan_order, |
446 | 446 | bar_length, |
461 | 461 | /// |
462 | 462 | /// Also return a reference to the new `FeroxScan` |
463 | 463 | pub fn add_directory_scan(&self, url: &str, scan_order: ScanOrder) -> (bool, Arc<FeroxScan>) { |
464 | self.add_scan(&url, ScanType::Directory, scan_order) | |
464 | self.add_scan(url, ScanType::Directory, scan_order) | |
465 | 465 | } |
466 | 466 | |
467 | 467 | /// Given a url, create a new `FeroxScan` and add it to `FeroxScans` as a File Scan |
470 | 470 | /// |
471 | 471 | /// Also return a reference to the new `FeroxScan` |
472 | 472 | pub fn add_file_scan(&self, url: &str, scan_order: ScanOrder) -> (bool, Arc<FeroxScan>) { |
473 | self.add_scan(&url, ScanType::File, scan_order) | |
473 | self.add_scan(url, ScanType::File, scan_order) | |
474 | 474 | } |
475 | 475 | |
476 | 476 | /// small helper to determine whether any scans are active or not |
378 | 378 | |
379 | 379 | let json_state = ferox_state.as_json().unwrap(); |
380 | 380 | let expected = format!( |
381 | r#"{{"scans":[{{"id":"{}","url":"https://spiritanimal.com","scan_type":"Directory","status":"NotStarted","num_requests":0}}],"config":{{"type":"configuration","wordlist":"/usr/share/seclists/Discovery/Web-Content/raft-medium-directories.txt","config":"","proxy":"","replay_proxy":"","target_url":"","status_codes":[200,204,301,302,307,308,401,403,405],"replay_codes":[200,204,301,302,307,308,401,403,405],"filter_status":[],"threads":50,"timeout":7,"verbosity":0,"silent":false,"quiet":false,"auto_bail":false,"auto_tune":false,"json":false,"output":"","debug_log":"","user_agent":"feroxbuster/{}","redirects":false,"insecure":false,"extensions":[],"headers":{{}},"queries":[],"no_recursion":false,"extract_links":false,"add_slash":false,"stdin":false,"depth":4,"scan_limit":0,"parallel":0,"rate_limit":0,"filter_size":[],"filter_line_count":[],"filter_word_count":[],"filter_regex":[],"dont_filter":false,"resumed":false,"resume_from":"","save_state":false,"time_limit":"","filter_similar":[],"url_denylist":[]}},"responses":[{{"type":"response","url":"https://nerdcore.com/css","path":"/css","wildcard":true,"status":301,"content_length":173,"line_count":10,"word_count":16,"headers":{{"server":"nginx/1.16.1"}}}}]"#, | |
381 | r#"{{"scans":[{{"id":"{}","url":"https://spiritanimal.com","scan_type":"Directory","status":"NotStarted","num_requests":0}}],"config":{{"type":"configuration","wordlist":"/usr/share/seclists/Discovery/Web-Content/raft-medium-directories.txt","config":"","proxy":"","replay_proxy":"","target_url":"","status_codes":[200,204,301,302,307,308,401,403,405,500],"replay_codes":[200,204,301,302,307,308,401,403,405,500],"filter_status":[],"threads":50,"timeout":7,"verbosity":0,"silent":false,"quiet":false,"auto_bail":false,"auto_tune":false,"json":false,"output":"","debug_log":"","user_agent":"feroxbuster/{}","redirects":false,"insecure":false,"extensions":[],"headers":{{}},"queries":[],"no_recursion":false,"extract_links":false,"add_slash":false,"stdin":false,"depth":4,"scan_limit":0,"parallel":0,"rate_limit":0,"filter_size":[],"filter_line_count":[],"filter_word_count":[],"filter_regex":[],"dont_filter":false,"resumed":false,"resume_from":"","save_state":false,"time_limit":"","filter_similar":[],"url_denylist":[]}},"responses":[{{"type":"response","url":"https://nerdcore.com/css","path":"/css","wildcard":true,"status":301,"content_length":173,"line_count":10,"word_count":16,"headers":{{"server":"nginx/1.16.1"}}}}]"#, | |
382 | 382 | saved_id, VERSION |
383 | 383 | ); |
384 | 384 | println!("{}\n{}", expected, json_state); |
619 | 619 | atomic_increment!(self.expected_per_scan, value); |
620 | 620 | } |
621 | 621 | StatField::TotalScans => { |
622 | let multiplier = self.num_extensions.max(1); | |
623 | ||
624 | 622 | atomic_increment!(self.total_scans, value); |
625 | 623 | atomic_increment!( |
626 | 624 | self.total_expected, |
627 | value * self.expected_per_scan.load(Ordering::Relaxed) * multiplier | |
625 | value * self.expected_per_scan.load(Ordering::Relaxed) | |
628 | 626 | ); |
629 | 627 | } |
630 | 628 | StatField::TotalExpected => { |
54 | 54 | stats.add_status_code(StatusCode::OK); |
55 | 55 | stats.add_status_code(StatusCode::OK); |
56 | 56 | let outfile = NamedTempFile::new().unwrap(); |
57 | if stats | |
58 | .save(174.33, &outfile.path().to_str().unwrap()) | |
59 | .is_ok() | |
60 | {} | |
57 | if stats.save(174.33, outfile.path().to_str().unwrap()).is_ok() {} | |
61 | 58 | |
62 | 59 | assert!(stats.as_json().unwrap().contains("statistics")); |
63 | 60 | assert!(stats.as_json().unwrap().contains("11")); // requests made |
65 | 65 | pub fn format(&self, word: &str, extension: Option<&str>) -> Result<Url> { |
66 | 66 | log::trace!("enter: format({}, {:?})", word, extension); |
67 | 67 | |
68 | if Url::parse(&word).is_ok() { | |
68 | if Url::parse(word).is_ok() { | |
69 | 69 | // when a full url is passed in as a word to be joined to a base url using |
70 | 70 | // reqwest::Url::join, the result is that the word (url) completely overwrites the base |
71 | 71 | // url, potentially resulting in requests to places that aren't actually the target |
2 | 2 | use indicatif::ProgressBar; |
3 | 3 | use reqwest::{Client, Response, StatusCode, Url}; |
4 | 4 | #[cfg(not(target_os = "windows"))] |
5 | use rlimit::{getrlimit, setrlimit, Resource, Rlim}; | |
5 | use rlimit::{getrlimit, setrlimit, Resource}; | |
6 | 6 | use std::{ |
7 | 7 | fs, |
8 | 8 | io::{self, BufWriter, Write}, |
9 | 9 | sync::Arc, |
10 | time::Duration, | |
11 | time::{SystemTime, UNIX_EPOCH}, | |
10 | 12 | }; |
11 | 13 | use tokio::sync::mpsc::UnboundedSender; |
12 | 14 | |
216 | 218 | /// as the adjustment made here is only valid for the scan itself (and any child processes, of which |
217 | 219 | /// there are none). |
218 | 220 | #[cfg(not(target_os = "windows"))] |
219 | pub fn set_open_file_limit(limit: usize) -> bool { | |
221 | pub fn set_open_file_limit(limit: u64) -> bool { | |
220 | 222 | log::trace!("enter: set_open_file_limit"); |
221 | 223 | |
222 | 224 | if let Ok((soft, hard)) = getrlimit(Resource::NOFILE) { |
223 | if hard.as_usize() > limit { | |
225 | if hard > limit { | |
224 | 226 | // our default open file limit is less than the current hard limit, this means we can |
225 | 227 | // set the soft limit to our default |
226 | let new_soft_limit = Rlim::from_usize(limit); | |
227 | ||
228 | if setrlimit(Resource::NOFILE, new_soft_limit, hard).is_ok() { | |
228 | ||
229 | if setrlimit(Resource::NOFILE, limit, hard).is_ok() { | |
229 | 230 | log::debug!("set open file descriptor limit to {}", limit); |
230 | 231 | |
231 | 232 | log::trace!("exit: set_open_file_limit -> {}", true); |
297 | 298 | ); |
298 | 299 | // normalization for comparison is to remove the trailing / if one exists, this is done for |
299 | 300 | // the given url and any url to which it's compared |
300 | let normed_url = Url::parse(&url.to_string().trim_end_matches('/'))?; | |
301 | let normed_url = Url::parse(url.to_string().trim_end_matches('/'))?; | |
301 | 302 | |
302 | 303 | for deny_url in &handles.config.url_denylist { |
303 | 304 | // parse the denying url for easier comparison |
384 | 385 | Ok(false) |
385 | 386 | } |
386 | 387 | |
388 | /// given a url and filename-suffix, return a unique filename comprised of the slugified url, | |
389 | /// current unix timestamp and suffix | |
390 | /// | |
391 | /// ex: ferox-http_telsa_com-1606947491.state | |
392 | pub fn slugify_filename(url: &str, prefix: &str, suffix: &str) -> String { | |
393 | log::trace!("enter: slugify({:?}, {:?}, {:?})", url, prefix, suffix); | |
394 | ||
395 | let ts = SystemTime::now() | |
396 | .duration_since(UNIX_EPOCH) | |
397 | .unwrap_or_else(|_| Duration::from_secs(0)) | |
398 | .as_secs(); | |
399 | ||
400 | let altered_prefix = if !prefix.is_empty() { | |
401 | format!("{}-", prefix) | |
402 | } else { | |
403 | String::new() | |
404 | }; | |
405 | ||
406 | let slug = url.replace("://", "_").replace("/", "_").replace(".", "_"); | |
407 | ||
408 | let filename = format!("{}{}-{}.{}", altered_prefix, slug, ts, suffix); | |
409 | ||
410 | log::trace!("exit: slugify -> {}", filename); | |
411 | filename | |
412 | } | |
413 | ||
387 | 414 | #[cfg(test)] |
388 | 415 | mod tests { |
389 | 416 | use super::*; |
394 | 421 | /// set_open_file_limit with a low requested limit succeeds |
395 | 422 | fn utils_set_open_file_limit_with_low_requested_limit() { |
396 | 423 | let (_, hard) = getrlimit(Resource::NOFILE).unwrap(); |
397 | let lower_limit = hard.as_usize() - 1; | |
424 | let lower_limit = hard - 1; | |
398 | 425 | assert!(set_open_file_limit(lower_limit)); |
399 | 426 | } |
400 | 427 | |
402 | 429 | /// set_open_file_limit with a high requested limit succeeds |
403 | 430 | fn utils_set_open_file_limit_with_high_requested_limit() { |
404 | 431 | let (_, hard) = getrlimit(Resource::NOFILE).unwrap(); |
405 | let higher_limit = hard.as_usize() + 1; | |
432 | let higher_limit = hard + 1; | |
406 | 433 | // calculate a new soft to ensure soft != hard and hit that logic branch |
407 | let new_soft = Rlim::from_usize(hard.as_usize() - 1); | |
434 | let new_soft = hard - 1; | |
408 | 435 | setrlimit(Resource::NOFILE, new_soft, hard).unwrap(); |
409 | 436 | assert!(set_open_file_limit(higher_limit)); |
410 | 437 | } |
415 | 442 | let (_, hard) = getrlimit(Resource::NOFILE).unwrap(); |
416 | 443 | // calculate a new soft to ensure soft == hard and hit the failure logic branch |
417 | 444 | setrlimit(Resource::NOFILE, hard, hard).unwrap(); |
418 | assert!(!set_open_file_limit(hard.as_usize())); // returns false | |
445 | assert!(!set_open_file_limit(hard)); // returns false | |
419 | 446 | } |
420 | 447 | |
421 | 448 | #[test] |
475 | 502 | let tested_url = Url::parse("https://testdomain.com/denied/").unwrap(); |
476 | 503 | |
477 | 504 | let scans = Arc::new(FeroxScans::default()); |
478 | scans.add_directory_scan(&scan_url, ScanOrder::Initial); | |
505 | scans.add_directory_scan(scan_url, ScanOrder::Initial); | |
479 | 506 | |
480 | 507 | let mut config = Configuration::new().unwrap(); |
481 | 508 | config.url_denylist = vec![String::from(deny_url)]; |
494 | 521 | let tested_url = Url::parse("https://testdomain.com/denied/").unwrap(); |
495 | 522 | |
496 | 523 | let scans = Arc::new(FeroxScans::default()); |
497 | scans.add_directory_scan(&scan_url, ScanOrder::Initial); | |
524 | scans.add_directory_scan(scan_url, ScanOrder::Initial); | |
498 | 525 | |
499 | 526 | let mut config = Configuration::new().unwrap(); |
500 | 527 | config.url_denylist = vec![String::from(deny_url)]; |
513 | 540 | let tested_url = Url::parse("https://testdomain.com/denied/").unwrap(); |
514 | 541 | |
515 | 542 | let scans = Arc::new(FeroxScans::default()); |
516 | scans.add_directory_scan(&scan_url, ScanOrder::Initial); | |
543 | scans.add_directory_scan(scan_url, ScanOrder::Initial); | |
517 | 544 | |
518 | 545 | let mut config = Configuration::new().unwrap(); |
519 | 546 | config.url_denylist = vec![String::from(deny_url)]; |
534 | 561 | let tested_url = Url::parse("https://testdomain.com/denied/").unwrap(); |
535 | 562 | |
536 | 563 | let scans = Arc::new(FeroxScans::default()); |
537 | scans.add_directory_scan(&scan_url, ScanOrder::Initial); | |
564 | scans.add_directory_scan(scan_url, ScanOrder::Initial); | |
538 | 565 | |
539 | 566 | let mut config = Configuration::new().unwrap(); |
540 | 567 | config.url_denylist = vec![String::from(deny_url)]; |
555 | 582 | let tested_url = Url::parse("https://testdomain.com/denied/").unwrap(); |
556 | 583 | |
557 | 584 | let scans = Arc::new(FeroxScans::default()); |
558 | scans.add_directory_scan(&scan_url, ScanOrder::Initial); | |
585 | scans.add_directory_scan(scan_url, ScanOrder::Initial); | |
559 | 586 | |
560 | 587 | let mut config = Configuration::new().unwrap(); |
561 | 588 | config.url_denylist = vec![String::from(deny_url)]; |
574 | 601 | let tested_url = Url::parse("https://testdomain.com/api/denied/").unwrap(); |
575 | 602 | |
576 | 603 | let scans = Arc::new(FeroxScans::default()); |
577 | scans.add_directory_scan(&scan_url, ScanOrder::Initial); | |
604 | scans.add_directory_scan(scan_url, ScanOrder::Initial); | |
578 | 605 | |
579 | 606 | let mut config = Configuration::new().unwrap(); |
580 | 607 | config.url_denylist = vec![String::from(deny_url)]; |
593 | 620 | let tested_url = Url::parse("https://testdomain.com/not-denied/").unwrap(); |
594 | 621 | |
595 | 622 | let scans = Arc::new(FeroxScans::default()); |
596 | scans.add_directory_scan(&scan_url, ScanOrder::Initial); | |
623 | scans.add_directory_scan(scan_url, ScanOrder::Initial); | |
597 | 624 | |
598 | 625 | let mut config = Configuration::new().unwrap(); |
599 | 626 | config.url_denylist = vec![String::from(deny_url)]; |
612 | 639 | let tested_url = Url::parse("https://testdomain.com/stuff/").unwrap(); |
613 | 640 | |
614 | 641 | let scans = Arc::new(FeroxScans::default()); |
615 | scans.add_directory_scan(&scan_url, ScanOrder::Initial); | |
642 | scans.add_directory_scan(scan_url, ScanOrder::Initial); | |
616 | 643 | |
617 | 644 | let mut config = Configuration::new().unwrap(); |
618 | 645 | config.url_denylist = vec![String::from(deny_url)]; |
631 | 658 | let tested_url = Url::parse("https://testdomain.com/api/not-denied/").unwrap(); |
632 | 659 | |
633 | 660 | let scans = Arc::new(FeroxScans::default()); |
634 | scans.add_directory_scan(&scan_url, ScanOrder::Initial); | |
661 | scans.add_directory_scan(scan_url, ScanOrder::Initial); | |
635 | 662 | |
636 | 663 | let mut config = Configuration::new().unwrap(); |
637 | 664 | config.url_denylist = vec![String::from(deny_url)]; |
2 | 2 | use httpmock::Method::GET; |
3 | 3 | use httpmock::{MockServer, Regex}; |
4 | 4 | use predicates::prelude::*; |
5 | use std::fs::read_to_string; | |
5 | use std::fs::{read_dir, read_to_string}; | |
6 | 6 | use utils::{setup_tmp_directory, teardown_tmp_directory}; |
7 | 7 | |
8 | 8 | #[test] |
152 | 152 | |
153 | 153 | Ok(()) |
154 | 154 | } |
155 | ||
156 | #[test] | |
157 | /// send three targets over stdin with --output enabled, expect parallel to create a new directory | |
158 | /// and the log files therein | |
159 | fn main_parallel_creates_output_directory() -> Result<(), Box<dyn std::error::Error>> { | |
160 | let t1 = MockServer::start(); | |
161 | let t2 = MockServer::start(); | |
162 | let t3 = MockServer::start(); | |
163 | ||
164 | let words = [ | |
165 | String::from("LICENSE"), | |
166 | String::from("stuff"), | |
167 | String::from("things"), | |
168 | String::from("mostuff"), | |
169 | String::from("mothings"), | |
170 | ]; | |
171 | let (word_tmp_dir, wordlist) = setup_tmp_directory(&words, "wordlist")?; | |
172 | let (output_dir, outfile) = setup_tmp_directory(&[], "output-file")?; | |
173 | let (tgt_tmp_dir, targets) = | |
174 | setup_tmp_directory(&[t1.url("/"), t2.url("/"), t3.url("/")], "targets")?; | |
175 | ||
176 | Command::cargo_bin("feroxbuster") | |
177 | .unwrap() | |
178 | .arg("--stdin") | |
179 | .arg("--parallel") | |
180 | .arg("2") | |
181 | .arg("--output") | |
182 | .arg(outfile.as_os_str()) | |
183 | .arg("--wordlist") | |
184 | .arg(wordlist.as_os_str()) | |
185 | .pipe_stdin(targets) | |
186 | .unwrap() | |
187 | .assert() | |
188 | .success() | |
189 | .stderr( | |
190 | predicate::str::contains("Could not connect to any target provided") | |
191 | .and(predicate::str::contains("Target Url")) | |
192 | .not(), // no target url found | |
193 | ); | |
194 | ||
195 | // output_dir should return something similar to output-file-1627845244.logs with the | |
196 | // line below. if it ever fails, can use the regex below to filter out the right directory | |
197 | let sub_dir = read_dir(&output_dir)?.next().unwrap()?.file_name(); | |
198 | ||
199 | let mut num_logs = 0; | |
200 | let file_regex = Regex::new("ferox-[a-zA-Z_:0-9]+-[0-9]+.log").unwrap(); | |
201 | let dir_regex = Regex::new("output-file-[0-9]+.logs").unwrap(); | |
202 | ||
203 | let sub_dir = output_dir.as_ref().join(&sub_dir); | |
204 | ||
205 | // created directory like output-file-1627845741.logs/ | |
206 | assert!(dir_regex.is_match(&sub_dir.to_string_lossy().to_string())); | |
207 | ||
208 | for entry in sub_dir.read_dir()? { | |
209 | let entry = entry?; | |
210 | // created each file like ferox-https_localhost-1627845741.log | |
211 | println!("name: {:?}", entry.file_name().to_string_lossy()); | |
212 | assert!(file_regex.is_match(&entry.file_name().to_string_lossy())); | |
213 | num_logs += 1; | |
214 | } | |
215 | ||
216 | // should be 3 log files total | |
217 | assert_eq!(num_logs, 3); | |
218 | ||
219 | teardown_tmp_directory(word_tmp_dir); | |
220 | teardown_tmp_directory(tgt_tmp_dir); | |
221 | teardown_tmp_directory(output_dir); | |
222 | ||
223 | Ok(()) | |
224 | } |
76 | 76 | |
77 | 77 | // read debug log to get the number of errors enforced |
78 | 78 | for line in debug_log.lines() { |
79 | let log: serde_json::Value = serde_json::from_str(&line).unwrap_or_default(); | |
79 | let log: serde_json::Value = serde_json::from_str(line).unwrap_or_default(); | |
80 | 80 | if let Some(message) = log.get("message") { |
81 | 81 | let str_msg = message.as_str().unwrap_or_default().to_string(); |
82 | 82 | |
155 | 155 | |
156 | 156 | // read debug log to get the number of errors enforced |
157 | 157 | for line in debug_log.lines() { |
158 | let log: serde_json::Value = serde_json::from_str(&line).unwrap_or_default(); | |
158 | let log: serde_json::Value = serde_json::from_str(line).unwrap_or_default(); | |
159 | 159 | if let Some(message) = log.get("message") { |
160 | 160 | let str_msg = message.as_str().unwrap_or_default().to_string(); |
161 | 161 | |
237 | 237 | |
238 | 238 | // read debug log to get the number of errors enforced |
239 | 239 | for line in debug_log.lines() { |
240 | let log: serde_json::Value = serde_json::from_str(&line).unwrap_or_default(); | |
240 | let log: serde_json::Value = serde_json::from_str(line).unwrap_or_default(); | |
241 | 241 | if let Some(message) = log.get("message") { |
242 | 242 | let str_msg = message.as_str().unwrap_or_default().to_string(); |
243 | 243 |
92 | 92 | #[test] |
93 | 93 | /// kick off scan with a time limit; |
94 | 94 | fn time_limit_enforced_when_specified() { |
95 | let srv = MockServer::start(); | |
95 | let t1 = MockServer::start(); | |
96 | let t2 = MockServer::start(); | |
97 | ||
96 | 98 | let (tmp_dir, file) = |
97 | 99 | setup_tmp_directory(&["css".to_string(), "stuff".to_string()], "wordlist").unwrap(); |
100 | let (tgt_tmp_dir, targets) = | |
101 | setup_tmp_directory(&[t1.url("/"), t2.url("/")], "targets").unwrap(); | |
98 | 102 | |
99 | 103 | // ensure the command will run long enough by adding crap to the wordlist |
100 | 104 | let more_words = read_to_string(Path::new("tests/extra-words")).unwrap(); |
108 | 112 | |
109 | 113 | Command::cargo_bin("feroxbuster") |
110 | 114 | .unwrap() |
111 | .arg("--url") | |
112 | .arg(srv.url("/")) | |
115 | .arg("--stdin") | |
113 | 116 | .arg("--wordlist") |
114 | 117 | .arg(file.as_os_str()) |
115 | 118 | .arg("--time-limit") |
116 | 119 | .arg("5s") |
120 | .pipe_stdin(targets) | |
121 | .unwrap() | |
117 | 122 | .assert() |
118 | 123 | .failure(); |
119 | 124 | |
126 | 131 | assert!(now.elapsed() > lower_bound && now.elapsed() < upper_bound); |
127 | 132 | |
128 | 133 | teardown_tmp_directory(tmp_dir); |
134 | teardown_tmp_directory(tgt_tmp_dir); | |
129 | 135 | } |