puppy

package module
v0.0.0-...-bdb2d4d Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 17, 2020 License: MIT Imports: 39 Imported by: 0

README

The Puppy Proxy

What is this?

Puppy is a golang library that can be used to create proxies to intercept and modify HTTP and websocket messages that pass through it. Puppy itself does not provide any interactive interface, it provides an API to do proxy things in go. If you want a useful tool that uses Puppy, try Pappy.

Puppy was originally aimed to be a starting point to write a tool similar to Burp Suite and to provide a base for writing other HTTP proxy software.

Features

  • Intercept and modify any HTTP messages passing through the proxy
  • Websocket support
  • Use custom CA certificate to strip TLS from HTTPS connections
  • Built in IPC API
  • Support for transparent request redirection
  • Built in support for writing messages to SQLite database
  • Flexible history search

Example

The following example creates a simple proxy which listens on port 8080. In order to send HTTPS traffic through the proxy, you must add the generated server.pem certificate as a CA to your browser.

package main

import (
	"fmt"
	"net"
	"os"
	"path"
	"puppy"
)

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

func main() {
    // Create the proxy without a logger
    iproxy := puppy.NewInterceptingProxy(nil)

    // Load the CA certs
    ex, err := os.Executable()
    checkerr(err)
    certFile := path.Dir(ex) + "/server.pem"
    pkeyFile := path.Dir(ex) + "/server.key"
	err = iproxy.LoadCACertificates(certFile, pkeyFile)
    if err != nil {
        // Try generating the certs in case they're missing
        _, err := puppy.GenerateCACertsToDisk(certFile, pkeyFile)
        checkerr(err)
	    err = iproxy.LoadCACertificates(certFile, pkeyFile)
        checkerr(err)
    }

    // Listen on port 8080
    listener, err := net.Listen("tcp", "127.0.0.1:8080")
    checkerr(err)
    iproxy.AddListener(listener)

    // Wait for exit
    fmt.Println("Proxy is running on localhost:8080")
	select {}
}

Next, we will demonstrate editing messages by turning the proxy into a cloud2butt proxy which will replace every instance of the word "cloud" with the word "butt". This is done by writing a function that takes in a request and a response and returns a new response then adding it to the proxy:

package main

import (
	"bytes"
	"fmt"
	"net"
	"os"
	"path"
	"puppy"
)

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

func main() {
	// Create the proxy without a logger
	iproxy := puppy.NewInterceptingProxy(nil)

	// Load the CA certs
	ex, err := os.Executable()
	checkerr(err)
	certFile := path.Dir(ex) + "/server.pem"
	pkeyFile := path.Dir(ex) + "/server.key"
	err = iproxy.LoadCACertificates(certFile, pkeyFile)
	if err != nil {
		// Try generating the certs in case they're missing
		_, err := puppy.GenerateCACertsToDisk(certFile, pkeyFile)
		checkerr(err)
		err = iproxy.LoadCACertificates(certFile, pkeyFile)
		checkerr(err)
	}

	// Cloud2Butt interceptor
	var cloud2butt = func(req *puppy.ProxyRequest, rsp *puppy.ProxyResponse) (*puppy.ProxyResponse, error) {
		newBody := rsp.BodyBytes()
		newBody = bytes.Replace(newBody, []byte("cloud"), []byte("butt"), -1)
		newBody = bytes.Replace(newBody, []byte("Cloud"), []byte("Butt"), -1)
		rsp.SetBodyBytes(newBody)
		return rsp, nil
	}
	iproxy.AddRspInterceptor(cloud2butt)

	// Listen on port 8080
	listener, err := net.Listen("tcp", "127.0.0.1:8080")
	checkerr(err)
	iproxy.AddListener(listener)

	// Wait for exit
	fmt.Println("Proxy is running on localhost:8080")
	select {}
}

For more information, check out the documentation.

Documentation

Overview

Puppy provices an interface to create a proxy to intercept and modify HTTP and websocket messages passing through the proxy

Index

Constants

View Source
const (
	ToServer = iota
	ToClient
)
View Source
const (
	ProxyStopped = iota
	ProxyStarting
	ProxyRunning
)
View Source
const QueryNotSupported = ConstErr("custom query not supported")

An error to be returned if a query is not supported

Variables

This section is empty.

Functions

func BlankResponse

func BlankResponse(w http.ResponseWriter)

BlankResponse writes a blank response to a http.ResponseWriter. Used when a request/response is dropped.

func CheckArgsGoToStr

func CheckArgsGoToStr(args []interface{}) ([]string, error)

func CheckArgsStrToGo

func CheckArgsStrToGo(strArgs []string) ([]interface{}, error)

func CleanReqJSON

func CleanReqJSON(req *RequestJSON)

Clears metadata (start/end time, DbId) and dependent message data (response, websocket messages, and unmangled versions) from the RequestJSON

func CleanRspJSON

func CleanRspJSON(rsp *ResponseJSON)

Clears metadata (DbId) and dependent message data (unmangled version) from the ResponseJSON

func CleanWSJSON

func CleanWSJSON(wsm *WSMessageJSON)

Clears metadata (timestamp, DbId) and dependent message data (unmangled version) from the WSMessageJSON

func DecodeRemoteAddr

func DecodeRemoteAddr(addrStr string) (host string, port int, useTLS bool, err error)

Decode destination information from a remote address

func DuplicateBytes

func DuplicateBytes(bs []byte) []byte

func EncodeRemoteAddr

func EncodeRemoteAddr(host string, port int, useTLS bool) string

Encode the destination information to be stored in the remote address

func ErrResponse

func ErrResponse(w http.ResponseWriter, err error)

ErrResponse writes an error response to the given http.ResponseWriter. Used to give proxy error information to the browser

func ErrorResponse

func ErrorResponse(w io.Writer, reason string)

Error response writes an error message to the given writer

func IdCounter

func IdCounter() func() int

func MessageResponse

func MessageResponse(w io.Writer, m interface{})

MessageResponse writes a response to a given writer

func NullLogger

func NullLogger() *log.Logger

func PerformConnect

func PerformConnect(conn net.Conn, destHost string, destPort int) error

PerformConnect submits a CONNECT request for the given host and port over the given connection

func ReadMessage

func ReadMessage(r *bufio.Reader) ([]byte, error)

ReadMessage reads a message from the given reader

func SaveNewRequest

func SaveNewRequest(ms MessageStorage, req *ProxyRequest) error

Save a new request and new versions of all its dependant messages (response, websocket messages, and unmangled versions of everything).

func SaveNewResponse

func SaveNewResponse(ms MessageStorage, rsp *ProxyResponse) error

Save a new response/unmangled response to the message storage regardless of the existence of a DbId

func SaveNewWSMessage

func SaveNewWSMessage(ms MessageStorage, req *ProxyRequest, wsm *ProxyWSMessage) error

Save a new websocket emssage/unmangled version to the message storage regardless of the existence of a DbId

func SubmitRequest

func SubmitRequest(req *ProxyRequest) error

SubmitRequest opens a connection to the request's DestHost:DestPort, using TLS if DestUseTLS is set, submits the request, and sets req.Response with the response when a response is received

func SubmitRequestProxy

func SubmitRequestProxy(req *ProxyRequest, proxyHost string, proxyPort int, creds *ProxyCredentials) error

SubmitRequestProxy connects to the given HTTP proxy, performs neccessary handshakes, and submits the request to its destination. req.Response will be set once a response is received

func SubmitRequestSOCKSProxy

func SubmitRequestSOCKSProxy(req *ProxyRequest, proxyHost string, proxyPort int, creds *ProxyCredentials) error

SubmitRequestProxy connects to the given SOCKS proxy, performs neccessary handshakes, and submits the request to its destination. req.Response will be set once a response is received

func UpdateRequest

func UpdateRequest(ms MessageStorage, req *ProxyRequest) error

Update a request and all its dependent messages. If the request has a DbId it will be updated, otherwise it will be inserted into the database and have its DbId updated. Same for all dependent messages

func UpdateResponse

func UpdateResponse(ms MessageStorage, rsp *ProxyResponse) error

Update a response and its unmangled version in the database. If it has a DbId, it will be updated, otherwise a new version will be saved in the database

func UpdateSchema

func UpdateSchema(db *sql.DB, logger *log.Logger) error

func UpdateWSMessage

func UpdateWSMessage(ms MessageStorage, req *ProxyRequest, wsm *ProxyWSMessage) error

Update a websocket message and its unmangled version in the database. If it has a DbId, it will be updated, otherwise a new version will be saved in the database

Types

type CAKeyPair

type CAKeyPair struct {
	Certificate []byte
	PrivateKey  *rsa.PrivateKey
}

A certificate/private key pair

func GenerateCACerts

func GenerateCACerts() (*CAKeyPair, error)

GenerateCACerts generates a random CAKeyPair

func GenerateCACertsToDisk

func GenerateCACertsToDisk(CertificateFile string, PrivateKeyFile string) (*CAKeyPair, error)

Generate a pair of certificates and write them to the disk. Returns the generated keypair

func (*CAKeyPair) CACertPEM

func (pair *CAKeyPair) CACertPEM() []byte

PrivateKeyPEM returns the CA cert of the CAKeyPair PEM encoded

func (*CAKeyPair) PrivateKeyPEM

func (pair *CAKeyPair) PrivateKeyPEM() []byte

PrivateKeyPEM returns the private key of the CAKeyPair PEM encoded

type ConstErr

type ConstErr string

A type that can be used to create specific error types. ie `const QueryNotSupported = ConstErr("custom query not supported")`

func (ConstErr) Error

func (e ConstErr) Error() string

type GlobalStorageWatcher

type GlobalStorageWatcher interface {
	// Callback for when a new request is saved
	NewRequestSaved(storageId int, ms MessageStorage, req *ProxyRequest)
	// Callback for when a request is updated
	RequestUpdated(storageId int, ms MessageStorage, req *ProxyRequest)
	// Callback for when a request is deleted
	RequestDeleted(storageId int, ms MessageStorage, DbId string)

	// Callback for when a new response is saved
	NewResponseSaved(storageId int, ms MessageStorage, rsp *ProxyResponse)
	// Callback for when a response is updated
	ResponseUpdated(storageId int, ms MessageStorage, rsp *ProxyResponse)
	// Callback for when a response is deleted
	ResponseDeleted(storageId int, ms MessageStorage, DbId string)

	// Callback for when a new wsmessage is saved
	NewWSMessageSaved(storageId int, ms MessageStorage, req *ProxyRequest, wsm *ProxyWSMessage)
	// Callback for when a wsmessage is updated
	WSMessageUpdated(storageId int, ms MessageStorage, req *ProxyRequest, wsm *ProxyWSMessage)
	// Callback for when a wsmessage is deleted
	WSMessageDeleted(storageId int, ms MessageStorage, DbId string)
}

type InterceptingProxy

type InterceptingProxy struct {
	// contains filtered or unexported fields
}

InterceptingProxy is a struct which represents a proxy which can intercept and modify HTTP and websocket messages

func NewInterceptingProxy

func NewInterceptingProxy(logger *log.Logger) *InterceptingProxy

NewInterceptingProxy will create a new InterceptingProxy and have it log using the provided logger. If logger is nil, the proxy will log to ioutil.Discard

func (*InterceptingProxy) AddHTTPHandler

func (iproxy *InterceptingProxy) AddHTTPHandler(host string, handler ProxyWebUIHandler)

AddHTTPHandler causes the proxy to redirect requests to a host to an HTTPHandler. This can be used, for example, to create an internal web inteface. Be careful with what actions are allowed through the interface because the interface could be vulnerable to cross-site request forgery attacks.

func (*InterceptingProxy) AddListener

func (iproxy *InterceptingProxy) AddListener(l net.Listener)

AddListener will have the proxy listen for HTTP connections on a listener. Proxy will attempt to strip TLS from the connection

func (*InterceptingProxy) AddMessageStorage

func (iproxy *InterceptingProxy) AddMessageStorage(storage MessageStorage, description string) int

AddMessageStorage associates a MessageStorage with the proxy and returns an ID to be used when referencing the storage in the future

func (*InterceptingProxy) AddReqInterceptor

func (iproxy *InterceptingProxy) AddReqInterceptor(f RequestInterceptor) *ReqIntSub

AddReqInterceptor adds a RequestInterceptor to the proxy which will be used to modify HTTP requests as they pass through the proxy. Returns a struct representing the active interceptor.

func (*InterceptingProxy) AddRspInterceptor

func (iproxy *InterceptingProxy) AddRspInterceptor(f ResponseInterceptor) *RspIntSub

AddRspInterceptor adds a ResponseInterceptor to the proxy which will be used to modify HTTP responses as they pass through the proxy. Returns a struct representing the active interceptor.

func (*InterceptingProxy) AddTransparentListener

func (iproxy *InterceptingProxy) AddTransparentListener(l net.Listener, destHost string, destPort int, useTLS bool)

Have the proxy listen for HTTP connections on a listener and transparently redirect them to the destination. Listeners added this way can only redirect requests to a single destination. However, it does not rely on the client being aware that it is using an HTTP proxy.

func (*InterceptingProxy) AddWSInterceptor

func (iproxy *InterceptingProxy) AddWSInterceptor(f WSInterceptor) *WSIntSub

AddWSInterceptor adds a WSInterceptor to the proxy which will be used to modify both incoming and outgoing websocket messages as they pass through the proxy. Returns a struct representing the active interceptor.

func (*InterceptingProxy) ClearScope

func (iproxy *InterceptingProxy) ClearScope() error

ClearScope removes all scope checks from the proxy so that all requests passing through the proxy will be considered in-scope

func (*InterceptingProxy) ClearUpstreamProxy

func (iproxy *InterceptingProxy) ClearUpstreamProxy()

ClearUpstreamProxy stops the proxy from using an upstream proxy for future connections

func (*InterceptingProxy) Close

func (iproxy *InterceptingProxy) Close()

Close closes all listeners being used by the proxy. Does not shut down internal HTTP server because there is no way to gracefully shut down an http server yet.

func (*InterceptingProxy) CloseMessageStorage

func (iproxy *InterceptingProxy) CloseMessageStorage(id int)

CloseMessageStorage closes a message storage associated with the proxy

func (*InterceptingProxy) GetCACertificate

func (iproxy *InterceptingProxy) GetCACertificate() *tls.Certificate

GetCACertificate returns certificate used to self-sign certificates for TLS connections

func (*InterceptingProxy) GetHTTPHandler

func (iproxy *InterceptingProxy) GetHTTPHandler(host string) (ProxyWebUIHandler, error)

GetHTTPHandler returns the HTTP handler for a given host

func (*InterceptingProxy) GetMessageStorage

func (iproxy *InterceptingProxy) GetMessageStorage(id int) (MessageStorage, string)

GetMessageStorage takes in a storage ID and returns the storage associated with the ID

func (*InterceptingProxy) GetProxyStorage

func (iproxy *InterceptingProxy) GetProxyStorage() MessageStorage

GetProxyStorage returns the storage being used to save messages as they pass through the proxy

func (*InterceptingProxy) GetScopeChecker

func (iproxy *InterceptingProxy) GetScopeChecker() RequestChecker

GetScopeChecker creates a RequestChecker which checks if a request matches the proxy's current scope

func (*InterceptingProxy) GetScopeQuery

func (iproxy *InterceptingProxy) GetScopeQuery() MessageQuery

GetScopeQuery returns the query associated with the proxy's scope. If the scope was set using SetScopeChecker, nil is returned

func (*InterceptingProxy) GlobalStorageEndWatch

func (iproxy *InterceptingProxy) GlobalStorageEndWatch(watcher GlobalStorageWatcher) error

Remove a global storage watcher

func (*InterceptingProxy) GlobalStorageWatch

func (iproxy *InterceptingProxy) GlobalStorageWatch(watcher GlobalStorageWatcher) error

Add a global storage watcher

func (*InterceptingProxy) ListMessageStorage

func (iproxy *InterceptingProxy) ListMessageStorage() []*SavedStorage

ListMessageStorage returns a list of storages associated with the proxy

func (*InterceptingProxy) LoadCACertificates

func (iproxy *InterceptingProxy) LoadCACertificates(certFile, keyFile string) error

LoadCACertificates loads a private/public key pair which should be used when generating self-signed certs for TLS connections

func (*InterceptingProxy) LoadScope

func (iproxy *InterceptingProxy) LoadScope(storageId int) error

LoadScope loads the scope from the given storage and applies it to the proxy

func (*InterceptingProxy) NetDial

func (iproxy *InterceptingProxy) NetDial() NetDialer

NetDial returns the dialer currently being used to create outgoing connections when submitting HTTP requests

func (*InterceptingProxy) RemoveHTTPHandler

func (iproxy *InterceptingProxy) RemoveHTTPHandler(host string)

RemoveHTTPHandler removes the HTTP handler for a given host

func (*InterceptingProxy) RemoveListener

func (iproxy *InterceptingProxy) RemoveListener(l net.Listener)

RemoveListner will have the proxy stop listening to a listener

func (*InterceptingProxy) RemoveReqInterceptor

func (iproxy *InterceptingProxy) RemoveReqInterceptor(sub *ReqIntSub)

RemoveReqInterceptor removes an active request interceptor from the proxy

func (*InterceptingProxy) RemoveRspInterceptor

func (iproxy *InterceptingProxy) RemoveRspInterceptor(sub *RspIntSub)

RemoveRspInterceptor removes an active response interceptor from the proxy

func (*InterceptingProxy) RemoveWSInterceptor

func (iproxy *InterceptingProxy) RemoveWSInterceptor(sub *WSIntSub)

RemoveWSInterceptor removes an active websocket interceptor from the proxy

func (*InterceptingProxy) ServeHTTP

func (iproxy *InterceptingProxy) ServeHTTP(w http.ResponseWriter, r *http.Request)

ServeHTTP is used to implement the interface required to have the proxy behave as an HTTP server

func (*InterceptingProxy) SetCACertificate

func (iproxy *InterceptingProxy) SetCACertificate(caCert *tls.Certificate)

SetCACertificate sets certificate which should be used when generating self-signed certs for TLS connections

func (*InterceptingProxy) SetNetDial

func (iproxy *InterceptingProxy) SetNetDial(dialer NetDialer)

SetNetDial sets the NetDialer that should be used to create outgoing connections when submitting HTTP requests. Overwrites the request's NetDialer

func (*InterceptingProxy) SetProxyStorage

func (iproxy *InterceptingProxy) SetProxyStorage(storageId int) error

SetProxyStorage sets which storage should be used to store messages as they pass through the proxy

func (*InterceptingProxy) SetScopeChecker

func (iproxy *InterceptingProxy) SetScopeChecker(checker RequestChecker) error

SetScopeChecker has the proxy use a specific RequestChecker to check if a request is in scope. If the checker returns true for a request it is considered in scope. Otherwise it is considered out of scope.

func (*InterceptingProxy) SetScopeQuery

func (iproxy *InterceptingProxy) SetScopeQuery(query MessageQuery) error

SetScopeQuery sets the scope of the proxy to include any request which matches the given MessageQuery

func (*InterceptingProxy) SetUpstreamProxy

func (iproxy *InterceptingProxy) SetUpstreamProxy(proxyHost string, proxyPort int, creds *ProxyCredentials)

SetUpstreamProxy causes the proxy to begin using an upstream HTTP proxy for submitted HTTP requests

func (*InterceptingProxy) SetUpstreamSOCKSProxy

func (iproxy *InterceptingProxy) SetUpstreamSOCKSProxy(proxyHost string, proxyPort int, creds *ProxyCredentials)

SetUpstreamSOCKSProxy causes the proxy to begin using an upstream SOCKS proxy for submitted HTTP requests

func (*InterceptingProxy) SubmitRequest

func (iproxy *InterceptingProxy) SubmitRequest(req *ProxyRequest) error

SubmitRequest submits a ProxyRequest. Does not automatically save the request/results to proxy storage

func (*InterceptingProxy) WSDial

func (iproxy *InterceptingProxy) WSDial(req *ProxyRequest) (*WSSession, error)

WSDial dials a remote server and submits the given request to initiate the handshake

type MessageHandler

type MessageHandler func(message []byte, conn net.Conn, logger *log.Logger, iproxy *InterceptingProxy)

A handler to handle a JSON message

type MessageListener

type MessageListener struct {
	Logger *log.Logger
	// contains filtered or unexported fields
}

A listener that handles reading JSON messages and sending them to the correct handler

func NewMessageListener

func NewMessageListener(l *log.Logger, iproxy *InterceptingProxy) *MessageListener

NewMessageListener creates a new message listener associated with the given intercepting proxy

func NewProxyMessageListener

func NewProxyMessageListener(logger *log.Logger, iproxy *InterceptingProxy) *MessageListener

Creates a MessageListener that implements the default puppy handlers. See the message docs for more info

func (*MessageListener) AddHandler

func (l *MessageListener) AddHandler(command string, handler MessageHandler)

AddHandler will have the listener call the given handler when the "Command" parameter matches the given value

func (*MessageListener) Handle

func (l *MessageListener) Handle(message []byte, conn net.Conn) error

func (*MessageListener) Serve

func (l *MessageListener) Serve(nl net.Listener)

Serve will have the listener serve messages on the given listener

type MessageQuery

type MessageQuery []QueryPhrase

A list of phrases. Will match if all the phrases match the request

func StrQueryToMsgQuery

func StrQueryToMsgQuery(query StrMessageQuery) (MessageQuery, error)

Converts a StrMessageQuery into a MessageQuery

type MessageStorage

type MessageStorage interface {

	// Close the storage
	Close()

	// Update an existing request in the storage. Requires that it has already been saved
	UpdateRequest(req *ProxyRequest) error
	// Save a new instance of the request in the storage regardless of if it has already been saved
	SaveNewRequest(req *ProxyRequest) error
	// Load a request given a unique id
	LoadRequest(reqid string) (*ProxyRequest, error)
	// Load the unmangled version of a request given a unique id
	LoadUnmangledRequest(reqid string) (*ProxyRequest, error)
	// Delete a request given a unique id
	DeleteRequest(reqid string) error

	// Update an existing response in the storage. Requires that it has already been saved
	UpdateResponse(rsp *ProxyResponse) error
	// Save a new instance of the response in the storage regardless of if it has already been saved
	SaveNewResponse(rsp *ProxyResponse) error
	// Load a response given a unique id
	LoadResponse(rspid string) (*ProxyResponse, error)
	// Load the unmangled version of a response given a unique id
	LoadUnmangledResponse(rspid string) (*ProxyResponse, error)
	// Delete a response given a unique id
	DeleteResponse(rspid string) error

	// Update an existing websocket message in the storage. Requires that it has already been saved
	UpdateWSMessage(req *ProxyRequest, wsm *ProxyWSMessage) error
	// Save a new instance of the websocket message in the storage regardless of if it has already been saved
	SaveNewWSMessage(req *ProxyRequest, wsm *ProxyWSMessage) error
	// Load a websocket message given a unique id
	LoadWSMessage(wsmid string) (*ProxyWSMessage, error)
	// Load the unmangled version of a websocket message given a unique id
	LoadUnmangledWSMessage(wsmid string) (*ProxyWSMessage, error)
	// Delete a websocket message given a unique id
	DeleteWSMessage(wsmid string) error

	// Get list of the keys for all of the stored requests
	RequestKeys() ([]string, error)

	// A function to perform a search of requests in the storage. Same arguments as NewRequestChecker
	Search(limit int64, args ...interface{}) ([]*ProxyRequest, error)

	// A function to naively check every function in storage with the given function and return the ones that match
	CheckRequests(limit int64, checker RequestChecker) ([]*ProxyRequest, error)

	// Return a list of all the queries stored in the MessageStorage
	AllSavedQueries() ([]*SavedQuery, error)
	// Save a query in the storage with a given name. If the name is already in storage, it should be overwritten
	SaveQuery(name string, query MessageQuery) error
	// Load a query by name from the storage
	LoadQuery(name string) (MessageQuery, error)
	// Delete a query by name from the storage
	DeleteQuery(name string) error

	// Add a storage watcher to make callbacks to on message saves
	Watch(watcher StorageWatcher) error
	// Remove a storage watcher from the storage
	EndWatch(watcher StorageWatcher) error

	// Set/get plugin values
	SetPluginValue(key string, value string) error
	GetPluginValue(key string) (string, error)
}

An interface that represents something that can be used to store data from the proxy

type NetDialer

type NetDialer func(network, addr string) (net.Conn, error)

A dialer used to create a net.Conn from a network and address

type PairValue

type PairValue struct {
	// contains filtered or unexported fields
}

A struct representing the data to be searched for a pair such as a header or url param

type ProxyConn

type ProxyConn interface {
	net.Conn

	Id() int
	Logger() *log.Logger

	// Set the CA certificate to be used to sign TLS connections
	SetCACertificate(*tls.Certificate)

	// If the connection tries to start TLS, attempt to strip it so that further reads will get the decrypted text, otherwise it will just pass the plaintext
	StartMaybeTLS(hostname string) (bool, error)

	// Have all requests produced by this connection have the given destination information. Removes the need for requests generated by this connection to be aware they are being submitted through a proxy
	SetTransparentMode(destHost string, destPort int, useTLS bool)

	// End transparent mode
	EndTransparentMode()
}

ProxyConn which is the same as a net.Conn but implements Peek() and variales to store target host data

type ProxyCredentials

type ProxyCredentials struct {
	Username string
	Password string
}

ProxyCredentials are a username/password combination used to represent an HTTP BasicAuth session

func (*ProxyCredentials) SerializeHeader

func (creds *ProxyCredentials) SerializeHeader() string

SerializeHeader serializes the ProxyCredentials into a value that can be included in an Authorization header

type ProxyListener

type ProxyListener struct {
	net.Listener

	// The current state of the listener
	State int
	// contains filtered or unexported fields
}

Implements net.Listener. Listeners can be added. Will accept connections on each listener and read HTTP messages from the connection. Will attempt to spoof TLS from incoming HTTP requests. Accept() returns a ProxyConn which transmists one unencrypted HTTP request and contains the intended destination for each request in the RemoteAddr.

func NewProxyListener

func NewProxyListener(logger *log.Logger) *ProxyListener

NewProxyListener creates and starts a new proxy listener that will log to the given logger

func (*ProxyListener) Accept

func (listener *ProxyListener) Accept() (net.Conn, error)

Accept accepts a new connection from any of its listeners

func (*ProxyListener) AddListener

func (listener *ProxyListener) AddListener(inlisten net.Listener) error

AddListener adds a listener for the ProxyListener to listen on

func (*ProxyListener) AddTransparentListener

func (listener *ProxyListener) AddTransparentListener(inlisten net.Listener, destHost string, destPort int, useTLS bool) error

AddTransparentListener is the same as AddListener, but all of the connections will be in transparent mode

func (*ProxyListener) Addr

func (listener *ProxyListener) Addr() net.Addr

func (*ProxyListener) Close

func (listener *ProxyListener) Close() error

Close closes all of the listeners associated with the ProxyListener

func (*ProxyListener) GetCACertificate

func (listener *ProxyListener) GetCACertificate() *tls.Certificate

SetCACertificate gets which certificate the listener is using when spoofing TLS

func (*ProxyListener) RemoveListener

func (listener *ProxyListener) RemoveListener(inlisten net.Listener) error

RemoveListener closes a listener and removes it from the ProxyListener. Does not kill active connections.

func (*ProxyListener) SetCACertificate

func (listener *ProxyListener) SetCACertificate(caCert *tls.Certificate)

SetCACertificate sets which certificate the listener should be used when spoofing TLS

type ProxyRequest

type ProxyRequest struct {
	http.Request

	// Host where this request is intended to be sent when submitted
	DestHost string
	// Port that should be used when this request is submitted
	DestPort int
	// Whether TLS should be used when this request is submitted
	DestUseTLS bool

	// Response received from the server when this request was submitted. If the request does not have any associated response, ServerResponse is nil.
	ServerResponse *ProxyResponse
	// If the request was the handshake for a websocket session, WSMessages will be a slice of all the messages that were sent over that session.
	WSMessages []*ProxyWSMessage
	// If the request was modified by the proxy, Unmangled will point to the unmodified version of the request. Otherwise it is nil.
	Unmangled *ProxyRequest

	// ID used to reference to this request in its associated MessageStorage
	DbId string
	// The time at which this request was submitted
	StartDatetime time.Time
	// The time at which the response to this request was received
	EndDatetime time.Time

	// The dialer that should be used when this request is submitted
	NetDial NetDialer
	// contains filtered or unexported fields
}

ProxyRequest is an http.Request with additional fields for use within the proxy

func NewProxyRequest

func NewProxyRequest(r *http.Request, destHost string, destPort int, destUseTLS bool) *ProxyRequest

NewProxyRequest creates a new proxy request with the given destination

func ParseProxyRequest

func ParseProxyRequest(r *http.Request) (*ProxyRequest, error)

ParseProxyRequest converts an http.Request read from a connection from a ProxyListener into a ProxyRequest

func ProxyRequestFromBytes

func ProxyRequestFromBytes(b []byte, destHost string, destPort int, destUseTLS bool) (*ProxyRequest, error)

ProxyRequestFromBytes parses a slice of bytes containing a well-formed HTTP request into a ProxyRequest. Does NOT correct incorrect Content-Length headers

func (*ProxyRequest) AddPostParameter

func (req *ProxyRequest) AddPostParameter(key string, value string)

AddPostParameter adds a post parameter to the body of the request even if a duplicate exists. If the body does not contain well-formed data, it is deleted replaced with a well-formed body containing only the new parameter

func (*ProxyRequest) AddTag

func (req *ProxyRequest) AddTag(tag string)

AddTag adds a tag to the request

func (*ProxyRequest) AddURLParameter

func (req *ProxyRequest) AddURLParameter(key string, value string)

AddURLParameter adds a URL parameter to the request ignoring duplicates

func (*ProxyRequest) BodyBytes

func (req *ProxyRequest) BodyBytes() []byte

BodyBytes returns the bytes of the request body

func (*ProxyRequest) CheckTag

func (req *ProxyRequest) CheckTag(tag string) bool

CheckTag returns whether the request has a given tag

func (*ProxyRequest) ClearTags

func (req *ProxyRequest) ClearTags()

ClearTag removes all of the tags associated with the request

func (*ProxyRequest) Clone

func (req *ProxyRequest) Clone() *ProxyRequest

Clone returns a request with the same contents and destination information as the original

func (*ProxyRequest) DeepClone

func (req *ProxyRequest) DeepClone() *ProxyRequest

DeepClone returns a request with the same contents, destination, and storage information information as the original along with a deep clone of the associated response, the unmangled version of the request, and any websocket messages

func (*ProxyRequest) DeletePostParameter

func (req *ProxyRequest) DeletePostParameter(key string)

DeletePostParameter removes a parameter from the body of the request. If the body does not contain well-formed data, it is deleted replaced with a well-formed body containing only the new parameter

func (*ProxyRequest) DeleteURLParameter

func (req *ProxyRequest) DeleteURLParameter(key string)

DeleteURLParameter removes a URL parameter from the request

func (*ProxyRequest) DestScheme

func (req *ProxyRequest) DestScheme() string

DestScheme returns the scheme used by the request (ws, wss, http, or https)

func (*ProxyRequest) DestURL

func (req *ProxyRequest) DestURL() *url.URL

Same as req.FullURL() but uses DestHost and DestPort for the host and port of the URL

func (*ProxyRequest) Eq

func (req *ProxyRequest) Eq(other *ProxyRequest) bool

Eq checks whether the request is the same as another request and has the same destination information

func (*ProxyRequest) FullMessage

func (req *ProxyRequest) FullMessage() []byte

FullMessage returns a slice of bytes containing the full HTTP message for the request

func (*ProxyRequest) FullURL

func (req *ProxyRequest) FullURL() *url.URL

FullURL is the same as req.URL but guarantees it will include the scheme, host, and port if necessary

func (*ProxyRequest) HTTPPath

func (req *ProxyRequest) HTTPPath() string

HTTPPath returns the path of the associated with the request

func (*ProxyRequest) HeaderSection

func (req *ProxyRequest) HeaderSection() string

HeaderSection returns the header section of the request without the additional \r\n at the end

func (*ProxyRequest) IsWSUpgrade

func (req *ProxyRequest) IsWSUpgrade() bool

IsWSUpgrade returns whether the request is used to initiate a websocket handshake

func (*ProxyRequest) PostParameters

func (req *ProxyRequest) PostParameters() (url.Values, error)

PostParameters attempts to parse POST parameters from the body of the request

func (*ProxyRequest) RemoveTag

func (req *ProxyRequest) RemoveTag(tag string)

RemoveTag removes a tag from the request

func (*ProxyRequest) RepeatableProxyWrite

func (req *ProxyRequest) RepeatableProxyWrite(w io.Writer, proxyCreds *ProxyCredentials) error

RepeatableWrite is the same as http.Request.ProxyWrite except that it can be safely called multiple times

func (*ProxyRequest) RepeatableWrite

func (req *ProxyRequest) RepeatableWrite(w io.Writer) error

RepeatableWrite is the same as http.Request.Write except that it can be safely called multiple times

func (*ProxyRequest) SetBodyBytes

func (req *ProxyRequest) SetBodyBytes(bs []byte)

SetBodyBytes sets the bytes of the request body and updates the Content-Length header

func (*ProxyRequest) SetPostParameter

func (req *ProxyRequest) SetPostParameter(key string, value string)

SetPostParameter sets the value of a post parameter in the message body. If the body does not contain well-formed data, it is deleted replaced with a well-formed body containing only the new parameter

func (*ProxyRequest) SetURLParameter

func (req *ProxyRequest) SetURLParameter(key string, value string)

SetURLParameter sets the value of a URL parameter and updates ProxyRequest.URL

func (*ProxyRequest) StatusLine

func (req *ProxyRequest) StatusLine() string

StatusLine returns the status line associated with the request

func (*ProxyRequest) StripProxyHeaders

func (req *ProxyRequest) StripProxyHeaders()

StripProxyHeaders removes headers associated with requests made to a proxy from the request

func (*ProxyRequest) Submit

func (req *ProxyRequest) Submit(conn net.Conn) error

Submit submits the request over the given connection. Does not take into account DestHost, DestPort, or DestUseTLS

func (*ProxyRequest) SubmitProxy

func (req *ProxyRequest) SubmitProxy(conn net.Conn, creds *ProxyCredentials) error

Submit submits the request in proxy form over the given connection for use with an upstream HTTP proxy. Does not take into account DestHost, DestPort, or DestUseTLS

func (*ProxyRequest) Tags

func (req *ProxyRequest) Tags() []string

Tags returns a slice containing all of the tags associated with the request

func (*ProxyRequest) URLParameters

func (req *ProxyRequest) URLParameters() url.Values

URLParameters returns the values of the request's URL parameters

func (*ProxyRequest) WSDial

func (req *ProxyRequest) WSDial(conn net.Conn) (*WSSession, error)

WSDial performs a websocket handshake over the given connection. Does not take into account DestHost, DestPort, or DestUseTLS

type ProxyResponse

type ProxyResponse struct {
	http.Response

	// Id used to reference this response in its associated MessageStorage. Blank string means it is not saved in any MessageStorage
	DbId string

	// If this response was modified by the proxy, Unmangled is the response before it was modified. If the response was not modified, Unmangled is nil.
	Unmangled *ProxyResponse
	// contains filtered or unexported fields
}

ProxyResponse is an http.Response with additional fields for use within the proxy

func NewProxyResponse

func NewProxyResponse(r *http.Response) *ProxyResponse

NewProxyResponse creates a new ProxyResponse given an http.Response

func ProxyResponseFromBytes

func ProxyResponseFromBytes(b []byte) (*ProxyResponse, error)

NewProxyResponse parses a ProxyResponse from a slice of bytes containing a well-formed HTTP response. Does NOT correct incorrect Content-Length headers

func (*ProxyResponse) BodyBytes

func (rsp *ProxyResponse) BodyBytes() []byte

BodyBytes returns the bytes contained in the body of the response

func (*ProxyResponse) Clone

func (rsp *ProxyResponse) Clone() *ProxyResponse

Clone returns a response with the same status line, headers, and body as the response

func (*ProxyResponse) DeepClone

func (rsp *ProxyResponse) DeepClone() *ProxyResponse

DeepClone returns a response with the same status line, headers, and body as the original response along with a deep clone of its unmangled version if it exists

func (*ProxyResponse) Eq

func (rsp *ProxyResponse) Eq(other *ProxyResponse) bool

Eq returns whether the response has the same contents as another response

func (*ProxyResponse) FullMessage

func (rsp *ProxyResponse) FullMessage() []byte

FullMessage returns the full HTTP message of the response

func (*ProxyResponse) HTTPStatus

func (rsp *ProxyResponse) HTTPStatus() string

Returns the status text to be used in the http request

func (*ProxyResponse) HeaderSection

func (rsp *ProxyResponse) HeaderSection() string

HeaderSection returns the header section of the response (without the extra trailing \r\n)

func (*ProxyResponse) RepeatableWrite

func (rsp *ProxyResponse) RepeatableWrite(w io.Writer) error

RepeatableWrite is the same as http.Response.Write except that it can safely be called multiple times

func (*ProxyResponse) SetBodyBytes

func (rsp *ProxyResponse) SetBodyBytes(bs []byte)

SetBodyBytes sets the bytes in the body of the response and updates the Content-Length header

func (*ProxyResponse) StatusLine

func (rsp *ProxyResponse) StatusLine() string

StatusLine returns the status line of the response

type ProxyWSMessage

type ProxyWSMessage struct {
	// The type of websocket message
	Type int

	// The contents of the message
	Message []byte

	// The direction of the message. Either ToServer or ToClient
	Direction int
	// If the message was modified by the proxy, points to the original unmodified message
	Unmangled *ProxyWSMessage
	// The time at which the message was sent (if sent to the server) or received (if received from the server)
	Timestamp time.Time
	// The request used for the handhsake for the session that this session was used for
	Request *ProxyRequest

	// ID used to reference to this message in its associated MessageStorage
	DbId string
}

ProxyWSMessage represents one message in a websocket session

func NewProxyWSMessage

func NewProxyWSMessage(mtype int, message []byte, direction int) (*ProxyWSMessage, error)

NewProxyWSMessage creates a new WSMessage given a type, message, and direction

func (*ProxyWSMessage) Clone

func (msg *ProxyWSMessage) Clone() *ProxyWSMessage

Clone returns a copy of the original message. It will have the same type, message, direction, timestamp, and request

func (*ProxyWSMessage) DeepClone

func (msg *ProxyWSMessage) DeepClone() *ProxyWSMessage

DeepClone returns a clone of the original message and a deep clone of the unmangled version if it exists

func (*ProxyWSMessage) Eq

func (msg *ProxyWSMessage) Eq(other *ProxyWSMessage) bool

Eq checks if the message has the same type, direction, and message as another message

func (*ProxyWSMessage) String

func (msg *ProxyWSMessage) String() string

type ProxyWebUIHandler

type ProxyWebUIHandler func(http.ResponseWriter, *http.Request, *InterceptingProxy)

ProxyWebUIHandler is a function that can be used for handling web requests intended to be handled by the proxy

func CreateWebUIHandler

func CreateWebUIHandler() ProxyWebUIHandler

Generate a proxy-compatible web handler that allows users to download certificates and view responses stored in the storage used by the proxyin the browser

type QueryPhrase

type QueryPhrase [][]interface{}

A list of queries. Will match if any queries match the request

type ReqIntSub

type ReqIntSub struct {
	Interceptor RequestInterceptor
	// contains filtered or unexported fields
}

ReqIntSub represents an active HTTP request interception session in an InterceptingProxy

type ReqSort

type ReqSort []*ProxyRequest

A helper type to sort requests by submission time: ie sort.Sort(ReqSort(reqs))

func (ReqSort) Len

func (reql ReqSort) Len() int

func (ReqSort) Less

func (reql ReqSort) Less(i int, j int) bool

func (ReqSort) Swap

func (reql ReqSort) Swap(i int, j int)

type RequestChecker

type RequestChecker func(req *ProxyRequest) bool

func CheckerFromMessageQuery

func CheckerFromMessageQuery(query MessageQuery) (RequestChecker, error)

Creates a RequestChecker from a MessageQuery

func NewRequestChecker

func NewRequestChecker(args ...interface{}) (RequestChecker, error)

Return a function that returns whether a request matches the given conditions

type RequestInterceptor

type RequestInterceptor func(req *ProxyRequest) (*ProxyRequest, error)

RequestInterceptor is a function that takes in a ProxyRequest and returns a modified ProxyRequest or nil to represent dropping the request

type RequestJSON

type RequestJSON struct {
	DestHost   string
	DestPort   int
	UseTLS     bool
	Method     string
	Path       string
	ProtoMajor int
	ProtoMinor int
	Headers    map[string][]string
	Body       string
	Tags       []string

	StartTime int64 `json:"StartTime,omitempty"`
	EndTime   int64 `json:"EndTime,omitempty"`

	Unmangled  *RequestJSON     `json:"Unmangled,omitempty"`
	Response   *ResponseJSON    `json:"Response,omitempty"`
	WSMessages []*WSMessageJSON `json:"WSMessages,omitempty"`
	DbId       string           `json:"DbId,omitempty"`
}

JSON data representing a ProxyRequest

func NewRequestJSON

func NewRequestJSON(req *ProxyRequest, headersOnly bool) *RequestJSON

Convert a ProxyRequest into JSON data. If headersOnly is true, the JSON data will only contain the headers and metadata of the message

func (*RequestJSON) Parse

func (reqd *RequestJSON) Parse() (*ProxyRequest, error)

Convert RequestJSON into a ProxyRequest

func (*RequestJSON) Validate

func (reqd *RequestJSON) Validate() error

Check that the RequestJSON contains valid data

type ResponseInterceptor

type ResponseInterceptor func(req *ProxyRequest, rsp *ProxyResponse) (*ProxyResponse, error)

ResponseInterceptor is a function that takes in a ProxyResponse and the original request and returns a modified ProxyResponse or nil to represent dropping the response

type ResponseJSON

type ResponseJSON struct {
	ProtoMajor int
	ProtoMinor int
	StatusCode int
	Reason     string

	Headers map[string][]string
	Body    string

	Unmangled *ResponseJSON `json:"Unmangled,omitempty"`
	DbId      string
}

JSON data representing a ProxyResponse

func NewResponseJSON

func NewResponseJSON(rsp *ProxyResponse, headersOnly bool) *ResponseJSON

Serialize a ProxyResponse into JSON data. If headersOnly is true, the JSON data will only contain the headers and metadata of the message

func (*ResponseJSON) Parse

func (rspd *ResponseJSON) Parse() (*ProxyResponse, error)

Convert response JSON data into a ProxyResponse

func (*ResponseJSON) Validate

func (rspd *ResponseJSON) Validate() error

Ensure that response JSON data is valid

type RspIntSub

type RspIntSub struct {
	Interceptor ResponseInterceptor
	// contains filtered or unexported fields
}

RspIntSub represents an active HTTP response interception session in an InterceptingProxy

type SQLiteStorage

type SQLiteStorage struct {
	// contains filtered or unexported fields
}

func InMemoryStorage

func InMemoryStorage(logger *log.Logger) (*SQLiteStorage, error)

func OpenSQLiteStorage

func OpenSQLiteStorage(fname string, logger *log.Logger) (*SQLiteStorage, error)

func (*SQLiteStorage) AllSavedQueries

func (ms *SQLiteStorage) AllSavedQueries() ([]*SavedQuery, error)

func (*SQLiteStorage) CheckRequests

func (ms *SQLiteStorage) CheckRequests(limit int64, checker RequestChecker) ([]*ProxyRequest, error)

func (*SQLiteStorage) Close

func (rs *SQLiteStorage) Close()

func (*SQLiteStorage) DeleteQuery

func (ms *SQLiteStorage) DeleteQuery(name string) error

func (*SQLiteStorage) DeleteRequest

func (ms *SQLiteStorage) DeleteRequest(reqid string) error

func (*SQLiteStorage) DeleteResponse

func (ms *SQLiteStorage) DeleteResponse(rspid string) error

func (*SQLiteStorage) DeleteWSMessage

func (ms *SQLiteStorage) DeleteWSMessage(wsmid string) error

func (*SQLiteStorage) EndWatch

func (ms *SQLiteStorage) EndWatch(watcher StorageWatcher) error

func (*SQLiteStorage) GetPluginValue

func (ms *SQLiteStorage) GetPluginValue(key string) (string, error)

func (*SQLiteStorage) LoadQuery

func (ms *SQLiteStorage) LoadQuery(name string) (MessageQuery, error)

func (*SQLiteStorage) LoadRequest

func (ms *SQLiteStorage) LoadRequest(reqid string) (*ProxyRequest, error)

func (*SQLiteStorage) LoadResponse

func (ms *SQLiteStorage) LoadResponse(rspid string) (*ProxyResponse, error)

func (*SQLiteStorage) LoadUnmangledRequest

func (ms *SQLiteStorage) LoadUnmangledRequest(reqid string) (*ProxyRequest, error)

func (*SQLiteStorage) LoadUnmangledResponse

func (ms *SQLiteStorage) LoadUnmangledResponse(rspid string) (*ProxyResponse, error)

func (*SQLiteStorage) LoadUnmangledWSMessage

func (ms *SQLiteStorage) LoadUnmangledWSMessage(wsmid string) (*ProxyWSMessage, error)

func (*SQLiteStorage) LoadWSMessage

func (ms *SQLiteStorage) LoadWSMessage(wsmid string) (*ProxyWSMessage, error)

func (*SQLiteStorage) RequestKeys

func (ms *SQLiteStorage) RequestKeys() ([]string, error)

func (*SQLiteStorage) SaveNewRequest

func (ms *SQLiteStorage) SaveNewRequest(req *ProxyRequest) error

func (*SQLiteStorage) SaveNewResponse

func (ms *SQLiteStorage) SaveNewResponse(rsp *ProxyResponse) error

func (*SQLiteStorage) SaveNewWSMessage

func (ms *SQLiteStorage) SaveNewWSMessage(req *ProxyRequest, wsm *ProxyWSMessage) error

func (*SQLiteStorage) SaveQuery

func (ms *SQLiteStorage) SaveQuery(name string, query MessageQuery) error

func (*SQLiteStorage) Search

func (ms *SQLiteStorage) Search(limit int64, args ...interface{}) ([]*ProxyRequest, error)

func (*SQLiteStorage) SetPluginValue

func (ms *SQLiteStorage) SetPluginValue(key string, value string) error

func (*SQLiteStorage) UpdateRequest

func (ms *SQLiteStorage) UpdateRequest(req *ProxyRequest) error

func (*SQLiteStorage) UpdateResponse

func (ms *SQLiteStorage) UpdateResponse(rsp *ProxyResponse) error

func (*SQLiteStorage) UpdateWSMessage

func (ms *SQLiteStorage) UpdateWSMessage(req *ProxyRequest, wsm *ProxyWSMessage) error

func (*SQLiteStorage) Watch

func (ms *SQLiteStorage) Watch(watcher StorageWatcher) error

type SavedQuery

type SavedQuery struct {
	Name  string
	Query MessageQuery
}

A type representing a search query that is stored in a MessageStorage

type SavedStorage

type SavedStorage struct {
	Id          int
	Storage     MessageStorage
	Description string
}

SavedStorage represents a storage associated with the proxy

type SearchField

type SearchField int
const (
	FieldAll SearchField = iota

	FieldRequestBody
	FieldResponseBody
	FieldAllBody
	FieldWSMessage

	FieldRequestHeaders
	FieldResponseHeaders
	FieldBothHeaders

	FieldMethod
	FieldHost
	FieldPath
	FieldURL
	FieldStatusCode
	FieldTag

	FieldBothParam
	FieldURLParam
	FieldPostParam
	FieldResponseCookie
	FieldRequestCookie
	FieldBothCookie

	FieldAfter
	FieldBefore
	FieldTimeRange

	FieldInvert

	FieldId
)

Searchable fields

type StorageWatcher

type StorageWatcher interface {
	// Callback for when a new request is saved
	NewRequestSaved(ms MessageStorage, req *ProxyRequest)
	// Callback for when a request is updated
	RequestUpdated(ms MessageStorage, req *ProxyRequest)
	// Callback for when a request is deleted
	RequestDeleted(ms MessageStorage, DbId string)

	// Callback for when a new response is saved
	NewResponseSaved(ms MessageStorage, rsp *ProxyResponse)
	// Callback for when a response is updated
	ResponseUpdated(ms MessageStorage, rsp *ProxyResponse)
	// Callback for when a response is deleted
	ResponseDeleted(ms MessageStorage, DbId string)

	// Callback for when a new wsmessage is saved
	NewWSMessageSaved(ms MessageStorage, req *ProxyRequest, wsm *ProxyWSMessage)
	// Callback for when a wsmessage is updated
	WSMessageUpdated(ms MessageStorage, req *ProxyRequest, wsm *ProxyWSMessage)
	// Callback for when a wsmessage is deleted
	WSMessageDeleted(ms MessageStorage, DbId string)
}

type StrComparer

type StrComparer int
const (
	StrIs StrComparer = iota
	StrContains
	StrContainsRegexp

	StrLengthGreaterThan
	StrLengthLessThan
	StrLengthEqualTo
)

Operators for string values

type StrMessageQuery

type StrMessageQuery []StrQueryPhrase

A list of phrases in string form. Will match if all the phrases match the request

func MsgQueryToStrQuery

func MsgQueryToStrQuery(query MessageQuery) (StrMessageQuery, error)

Converts a MessageQuery into a StrMessageQuery

type StrQueryPhrase

type StrQueryPhrase [][]string

A list of queries in string form. Will match if any queries match the request

type StrSavedQuery

type StrSavedQuery struct {
	Name  string
	Query StrMessageQuery
}

type WSIntSub

type WSIntSub struct {
	Interceptor WSInterceptor
	// contains filtered or unexported fields
}

WSIntSub represents an active websocket interception session in an InterceptingProxy

type WSInterceptor

type WSInterceptor func(req *ProxyRequest, rsp *ProxyResponse, msg *ProxyWSMessage) (*ProxyWSMessage, error)

WSInterceptor is a function that takes in a ProxyWSMessage and the ProxyRequest/ProxyResponse which made up its handshake and returns and returns a modified ProxyWSMessage or nil to represent dropping the message. A WSInterceptor should be able to modify messages originating from both the client and the remote server.

type WSMessageJSON

type WSMessageJSON struct {
	Message   string
	IsBinary  bool
	ToServer  bool
	Timestamp int64

	Unmangled *WSMessageJSON `json:"Unmangled,omitempty"`
	DbId      string
}

JSON data representing a ProxyWSMessage

func NewWSMessageJSON

func NewWSMessageJSON(wsm *ProxyWSMessage) *WSMessageJSON

Serialize a websocket message into JSON data

func (*WSMessageJSON) Parse

func (wsmd *WSMessageJSON) Parse() (*ProxyWSMessage, error)

Parse websocket message JSON data into a ProxyWSMEssage

type WSSession

type WSSession struct {
	websocket.Conn

	// Request used for handshake
	Request *ProxyRequest
}

WSSession is an extension of websocket.Conn to contain a reference to the ProxyRequest used for the websocket handshake

func WSDial

func WSDial(req *ProxyRequest) (*WSSession, error)

WSDial dials the target server and performs a websocket handshake over the new connection. Uses destination information from the request.

func WSDialProxy

func WSDialProxy(req *ProxyRequest, proxyHost string, proxyPort int, creds *ProxyCredentials) (*WSSession, error)

WSDialProxy dials the HTTP proxy server, performs a CONNECT handshake to connect to the remote server, then performs a websocket handshake over the new connection. Uses destination information from the request.

func WSDialSOCKSProxy

func WSDialSOCKSProxy(req *ProxyRequest, proxyHost string, proxyPort int, creds *ProxyCredentials) (*WSSession, error)

WSDialSOCKSProxy connects to the target host through the SOCKS proxy and performs a websocket handshake over the new connection. Uses destination information from the request.

type WSSort

type WSSort []*ProxyWSMessage

A helper type to sort websocket messages by timestamp: ie sort.Sort(WSSort(req.WSMessages))

func (WSSort) Len

func (wsml WSSort) Len() int

func (WSSort) Less

func (wsml WSSort) Less(i int, j int) bool

func (WSSort) Swap

func (wsml WSSort) Swap(i int, j int)

Directories

Path Synopsis
cmd

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL