summaryrefslogtreecommitdiff
path: root/vendor/github.com/wybiral/torgo/controller.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/wybiral/torgo/controller.go')
-rw-r--r--vendor/github.com/wybiral/torgo/controller.go242
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
-}