77 lines
1.8 KiB
Go
77 lines
1.8 KiB
Go
package control
|
|
|
|
import (
|
|
"strings"
|
|
|
|
"git.openprivacy.ca/openprivacy/bine/torutil"
|
|
)
|
|
|
|
// ProtocolInfo is the protocol info result of Conn.ProtocolInfo.
|
|
type ProtocolInfo struct {
|
|
AuthMethods []string
|
|
CookieFile string
|
|
TorVersion string
|
|
RawResponse *Response
|
|
}
|
|
|
|
// HasAuthMethod checks if ProtocolInfo contains the requested auth method.
|
|
func (p *ProtocolInfo) HasAuthMethod(authMethod string) bool {
|
|
for _, m := range p.AuthMethods {
|
|
if m == authMethod {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
// ProtocolInfo invokes PROTOCOLINFO on first invocation and returns a cached
|
|
// result on all others.
|
|
func (c *Conn) ProtocolInfo() (*ProtocolInfo, error) {
|
|
var err error
|
|
if c.protocolInfo == nil {
|
|
c.protocolInfo, err = c.sendProtocolInfo()
|
|
}
|
|
return c.protocolInfo, err
|
|
}
|
|
|
|
func (c *Conn) sendProtocolInfo() (*ProtocolInfo, error) {
|
|
resp, err := c.SendRequest("PROTOCOLINFO")
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
// Check data vals
|
|
ret := &ProtocolInfo{RawResponse: resp}
|
|
for _, piece := range resp.Data {
|
|
key, val, ok := torutil.PartitionString(piece, ' ')
|
|
if !ok {
|
|
continue
|
|
}
|
|
switch key {
|
|
case "PROTOCOLINFO":
|
|
if val != "1" {
|
|
return nil, c.protoErr("Invalid PIVERSION: %v", val)
|
|
}
|
|
case "AUTH":
|
|
methods, cookieFile, _ := torutil.PartitionString(val, ' ')
|
|
if !strings.HasPrefix(methods, "METHODS=") {
|
|
continue
|
|
}
|
|
if cookieFile != "" {
|
|
if !strings.HasPrefix(cookieFile, "COOKIEFILE=") {
|
|
continue
|
|
}
|
|
if ret.CookieFile, err = torutil.UnescapeSimpleQuotedString(cookieFile[11:]); err != nil {
|
|
continue
|
|
}
|
|
}
|
|
ret.AuthMethods = strings.Split(methods[8:], ",")
|
|
case "VERSION":
|
|
torVersion, _, _ := torutil.PartitionString(val, ' ')
|
|
if strings.HasPrefix(torVersion, "Tor=") {
|
|
ret.TorVersion, err = torutil.UnescapeSimpleQuotedString(torVersion[4:])
|
|
}
|
|
}
|
|
}
|
|
return ret, nil
|
|
}
|