MITM proxy
This commit is contained in:
99
mitmproxy/mitm_http.go
Normal file
99
mitmproxy/mitm_http.go
Normal file
@@ -0,0 +1,99 @@
|
||||
package mitmproxy
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"github.com/AdguardTeam/golibs/jsonutil"
|
||||
"github.com/AdguardTeam/golibs/log"
|
||||
)
|
||||
|
||||
// Print to log and set HTTP error message
|
||||
func httpError(r *http.Request, w http.ResponseWriter, code int, format string, args ...interface{}) {
|
||||
text := fmt.Sprintf(format, args...)
|
||||
log.Info("MITM: %s %s: %s", r.Method, r.URL, text)
|
||||
http.Error(w, text, code)
|
||||
}
|
||||
|
||||
type mitmConfigJSON struct {
|
||||
Enabled bool `json:"enabled"`
|
||||
ListenAddr string `json:"listen_address"`
|
||||
ListenPort int `json:"listen_port"`
|
||||
|
||||
UserName string `json:"auth_username"`
|
||||
Password string `json:"auth_password"`
|
||||
|
||||
CertData string `json:"cert_data"`
|
||||
PKeyData string `json:"pkey_data"`
|
||||
}
|
||||
|
||||
func (p *MITMProxy) handleGetConfig(w http.ResponseWriter, r *http.Request) {
|
||||
resp := mitmConfigJSON{}
|
||||
p.confLock.Lock()
|
||||
resp.Enabled = p.conf.Enabled
|
||||
host, port, _ := net.SplitHostPort(p.conf.ListenAddr)
|
||||
resp.ListenAddr = host
|
||||
resp.ListenPort, _ = strconv.Atoi(port)
|
||||
resp.UserName = p.conf.UserName
|
||||
resp.Password = p.conf.Password
|
||||
p.confLock.Unlock()
|
||||
|
||||
js, err := json.Marshal(resp)
|
||||
if err != nil {
|
||||
httpError(r, w, http.StatusInternalServerError, "json.Marshal: %s", err)
|
||||
return
|
||||
}
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
_, _ = w.Write(js)
|
||||
}
|
||||
|
||||
func (p *MITMProxy) handleSetConfig(w http.ResponseWriter, r *http.Request) {
|
||||
req := mitmConfigJSON{}
|
||||
_, err := jsonutil.DecodeObject(&req, r.Body)
|
||||
if err != nil {
|
||||
httpError(r, w, http.StatusBadRequest, "json.Decode: %s", err)
|
||||
return
|
||||
}
|
||||
|
||||
if !((len(req.CertData) != 0 && len(req.PKeyData) != 0) ||
|
||||
(len(req.CertData) == 0 && len(req.PKeyData) == 0)) {
|
||||
httpError(r, w, http.StatusBadRequest, "certificate & private key must be both empty or specified")
|
||||
return
|
||||
}
|
||||
|
||||
p.confLock.Lock()
|
||||
if len(req.CertData) != 0 {
|
||||
err = p.storeCert([]byte(req.CertData), []byte(req.PKeyData))
|
||||
if err != nil {
|
||||
httpError(r, w, http.StatusInternalServerError, "%s", err)
|
||||
p.confLock.Unlock()
|
||||
return
|
||||
}
|
||||
p.conf.RegenCert = false
|
||||
} else {
|
||||
p.conf.RegenCert = true
|
||||
}
|
||||
p.conf.Enabled = req.Enabled
|
||||
p.conf.ListenAddr = net.JoinHostPort(req.ListenAddr, strconv.Itoa(req.ListenPort))
|
||||
p.conf.UserName = req.UserName
|
||||
p.conf.Password = req.Password
|
||||
p.confLock.Unlock()
|
||||
|
||||
p.conf.ConfigModified()
|
||||
|
||||
p.Close()
|
||||
err = p.Restart()
|
||||
if err != nil {
|
||||
httpError(r, w, http.StatusInternalServerError, "%s", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize web handlers
|
||||
func (p *MITMProxy) initWeb() {
|
||||
p.conf.HTTPRegister("GET", "/control/proxy_info", p.handleGetConfig)
|
||||
p.conf.HTTPRegister("POST", "/control/proxy_config", p.handleSetConfig)
|
||||
}
|
||||
Reference in New Issue
Block a user