diff options
| author | James Mills <prologic@shortcircuit.net.au> | 2020-03-21 08:20:16 +1000 |
|---|---|---|
| committer | James Mills <prologic@shortcircuit.net.au> | 2020-03-21 08:20:16 +1000 |
| commit | d7a1eab5beba4241dab4402c5cd268432d7b46cd (patch) | |
| tree | 6383b4ebf511b58597d827dc5af00b71c72caf38 /vendor/github.com/wybiral/torgo/controller.go | |
| parent | 13ffd7117180d1a3093ff291481caeb07a8b71de (diff) | |
Migrate to Go111Modules, Add Dockerfile and GoRelaser support
Diffstat (limited to 'vendor/github.com/wybiral/torgo/controller.go')
| -rw-r--r-- | vendor/github.com/wybiral/torgo/controller.go | 242 |
1 files changed, 0 insertions, 242 deletions
diff --git a/vendor/github.com/wybiral/torgo/controller.go b/vendor/github.com/wybiral/torgo/controller.go deleted file mode 100644 index 7b5e137..0000000 --- a/vendor/github.com/wybiral/torgo/controller.go +++ /dev/null @@ -1,242 +0,0 @@ -package torgo - -import ( - "encoding/hex" - "errors" - "fmt" - "io/ioutil" - "net/textproto" - "strconv" - "strings" -) - -// A Controller instance is a control port connection that provides methods for -// communicating with Tor. -type Controller struct { - // Array of available authentication methods. - AuthMethods []string - // Cookie file path (empty if not available). - CookieFile string - // Text is a textproto.Conn to the control port. - Text *textproto.Conn -} - -// NewController returns a new Controller instance connecting to the control -// port at addr. -func NewController(addr string) (*Controller, error) { - text, err := textproto.Dial("tcp", addr) - if err != nil { - return nil, err - } - c := &Controller{Text: text} - err = c.getProtocolInfo() - if err != nil { - return nil, err - } - return c, nil -} - -// Make a textproto request and expect the command to have a valid 250 status. -func (c *Controller) makeRequest(request string) (int, string, error) { - id, err := c.Text.Cmd(request) - if err != nil { - return 0, "", err - } - c.Text.StartResponse(id) - defer c.Text.EndResponse(id) - return c.Text.ReadResponse(250) -} - -// Perform PROTOCOLINFO command and parse the response. -func (c *Controller) getProtocolInfo() error { - _, msg, err := c.makeRequest("PROTOCOLINFO 1") - if err != nil { - return err - } - lines := strings.Split(msg, "\n") - authPrefix := "AUTH METHODS=" - cookiePrefix := "COOKIEFILE=" - for _, line := range lines { - // Check for AUTH METHODS line - if strings.HasPrefix(line, authPrefix) { - // This line should be in a format like: - /// AUTH METHODS=method1,method2,methodN COOKIEFILE=cookiefilepath - line = line[len(authPrefix):] - parts := strings.SplitN(line, " ", 2) - c.AuthMethods = strings.Split(parts[0], ",") - // Check for COOKIEFILE key/value - if len(parts) == 2 && strings.HasPrefix(parts[1], cookiePrefix) { - raw := parts[1][len(cookiePrefix):] - c.CookieFile, err = strconv.Unquote(raw) - if err != nil { - return err - } - } - } - } - return nil -} - -// Perform GETINFO command based on key. -func (c *Controller) getInfo(key string) (string, error) { - _, msg, err := c.makeRequest("GETINFO " + key) - if err != nil { - return "", err - } - lines := strings.Split(msg, "\n") - for _, line := range lines { - parts := strings.SplitN(line, "=", 2) - if parts[0] == key { - return parts[1], nil - } - } - return "", fmt.Errorf(key + " not found") -} - -// Perform GETINFO command and convert response to int. -func (c *Controller) getInfoInt(key string) (int, error) { - s, err := c.getInfo(key) - if err != nil { - return 0, err - } - return strconv.Atoi(s) -} - -// GetAddress returns the current external IP address. -func (c *Controller) GetAddress() (string, error) { - return c.getInfo("address") -} - -// GetBytesRead returns total bytes downloaded. -func (c *Controller) GetBytesRead() (int, error) { - return c.getInfoInt("traffic/read") -} - -// GetBytesWritten returns total bytes uploaded. -func (c *Controller) GetBytesWritten() (int, error) { - return c.getInfoInt("traffic/written") -} - -// GetConfigFile return path to Tor config file. -func (c *Controller) GetConfigFile() (string, error) { - return c.getInfo("config-file") -} - -// GetTorPid returns PID for current Tor process. -func (c *Controller) GetTorPid() (int, error) { - return c.getInfoInt("process/pid") -} - -// GetVersion returns version of Tor server. -func (c *Controller) GetVersion() (string, error) { - return c.getInfo("version") -} - -// AuthenticateNone authenticate to controller without password or cookie. -func (c *Controller) AuthenticateNone() error { - _, _, err := c.makeRequest("AUTHENTICATE") - if err != nil { - return err - } - return nil -} - -// AuthenticatePassword authenticate to controller with password. -func (c *Controller) AuthenticatePassword(password string) error { - quoted := strconv.Quote(password) - _, _, err := c.makeRequest("AUTHENTICATE " + quoted) - if err != nil { - return err - } - return nil -} - -// AuthenticateCookie authenticate to controller with cookie from current -// CookieFile path. -func (c *Controller) AuthenticateCookie() error { - rawCookie, err := ioutil.ReadFile(c.CookieFile) - if err != nil { - return err - } - cookie := hex.EncodeToString(rawCookie) - _, _, err = c.makeRequest("AUTHENTICATE " + cookie) - if err != nil { - return err - } - return nil -} - -// AddOnion adds Onion hidden service. If no private key is supplied one will -// be generated and the PrivateKeyType and PrivateKey properties will be set -// with the newly generated one. -// The hidden service will use port mapping contained in Ports map supplied. -// ServiceID will be assigned based on the private key and will be the address -// of this hidden service (without the ".onion" ending). -func (c *Controller) AddOnion(onion *Onion) error { - if onion == nil { - return errors.New("torgo: onion cannot be nil") - } - if len(onion.Ports) == 0 { - return errors.New("torgo: onion requires at least one port mapping") - } - req := "ADD_ONION " - // If no key is supplied set PrivateKeyType to NEW - if len(onion.PrivateKey) == 0 { - if onion.PrivateKeyType == "" { - onion.PrivateKey = "BEST" - } else { - onion.PrivateKey = onion.PrivateKeyType - } - onion.PrivateKeyType = "NEW" - } - req += fmt.Sprintf("%s:%s ", onion.PrivateKeyType, onion.PrivateKey) - for remotePort, localAddr := range onion.Ports { - req += fmt.Sprintf("Port=%d,%s ", remotePort, localAddr) - } - _, msg, err := c.makeRequest(req) - if err != nil { - return err - } - lines := strings.Split(msg, "\n") - for _, line := range lines { - parts := strings.SplitN(line, "=", 2) - if parts[0] == "ServiceID" { - onion.ServiceID = parts[1] - } else if parts[0] == "PrivateKey" { - key := strings.SplitN(parts[1], ":", 2) - onion.PrivateKeyType = key[0] - onion.PrivateKey = key[1] - } - } - return nil -} - -// DeleteOnion deletes an onion by its serviceID (stop hidden service created -// by this controller). -func (c *Controller) DeleteOnion(serviceID string) error { - _, _, err := c.makeRequest("DEL_ONION " + serviceID) - if err != nil { - return err - } - return nil -} - -// Signal sends a signal to the server. Tor documentations defines the -// following signals : -// * RELOAD -// * SHUTDOWN -// * DUMP -// * DEBUG -// * HALT -// * CLEARDNSCACHE -// * NEWNYM -// * HEARTBEAT -// * DORMANT -// * ACTIVE -func (c *Controller) Signal(signal string) error { - _, _, err := c.makeRequest("SIGNAL " + signal) - if err != nil { - return err - } - return nil -} |
