Beispiel #1
0
func (c *cliUI) enroll(conf *config.ApplicationConfig, currentConf *config.Account) bool {
	var err error
	c.warn("Enrolling new config file")

	var domain string
	for {
		c.term.SetPrompt("Account (i.e. [email protected], enter to quit): ")
		if currentConf.Account, err = c.term.ReadLine(); err != nil || len(currentConf.Account) == 0 {
			return false
		}

		parts := strings.SplitN(currentConf.Account, "@", 2)
		if len(parts) != 2 {
			c.alert("invalid username (want user@domain): " + currentConf.Account)
			continue
		}
		domain = parts[1]
		break
	}

	c.term.SetPrompt("Enable debug logging to /tmp/xmpp-client-debug.log? ")
	if debugLog, err := c.term.ReadLine(); err != nil || !config.ParseYes(debugLog) {
		c.info("Not enabling debug logging...")
	} else {
		c.info("Debug logging enabled...")
		conf.RawLogFile = "/tmp/xmpp-client-debug.log"
	}

	c.term.SetPrompt("Use Tor?: ")
	if useTorQuery, err := c.term.ReadLine(); err != nil || len(useTorQuery) == 0 || !config.ParseYes(useTorQuery) {
		c.info("Not using Tor...")
		currentConf.Proxies = []string{}
	} else {
		c.info("Using Tor...")
	}

	c.term.SetPrompt("File to import libotr private key from (enter to generate): ")

	var pkeys []otr3.PrivateKey
	for {
		importFile, err := c.term.ReadLine()
		if err != nil {
			return false
		}
		if len(importFile) > 0 {
			privKeyBytes, err := ioutil.ReadFile(importFile)
			if err != nil {
				c.alert("Failed to open private key file: " + err.Error())
				continue
			}
			var priv otr3.DSAPrivateKey
			if !priv.Import(privKeyBytes) {
				c.alert("Failed to parse libotr private key file (the parser is pretty simple I'm afraid)")
				continue
			}
			pkeys = append(pkeys, &priv)
			break
		} else {
			c.info("Generating private key...")
			pkeys, err = otr3.GenerateMissingKeys([][]byte{})
			if err != nil {
				c.alert("Failed to generate private key - this implies something is really bad with your system, so we bail out now")
				return false
			}
			break
		}
	}

	currentConf.PrivateKeys = config.SerializedKeys(pkeys)
	currentConf.OTRAutoAppendTag = true
	currentConf.OTRAutoStartSession = true
	currentConf.OTRAutoTearDown = false

	// Force Tor for servers with well known Tor hidden services.
	if _, ok := servers.Get(domain); ok && currentConf.HasTorAuto() {
		const torProxyURL = "socks5://127.0.0.1:9050"
		c.info("It appears that you are using a well known server and we will use its Tor hidden service to connect.")
		currentConf.Proxies = []string{torProxyURL}
		c.term.SetPrompt("> ")
		return true
	}

	var proxyStr string
	proxyDefaultPrompt := ", enter for none"
	if currentConf.HasTorAuto() {
		proxyDefaultPrompt = ", which is the default"
	}
	c.term.SetPrompt("Proxy (i.e socks5://127.0.0.1:9050" + proxyDefaultPrompt + "): ")

	for {
		if proxyStr, err = c.term.ReadLine(); err != nil {
			return false
		}
		if len(proxyStr) == 0 {
			if !currentConf.HasTorAuto() {
				break
			} else {
				proxyStr = "socks5://127.0.0.1:9050"
			}
		}
		u, err := url.Parse(proxyStr)
		if err != nil {
			c.alert("Failed to parse " + proxyStr + " as a URL: " + err.Error())
			continue
		}
		if _, err = proxy.FromURL(u, proxy.Direct); err != nil {
			c.alert("Failed to parse " + proxyStr + " as a proxy: " + err.Error())
			continue
		}
		break
	}

	c.term.SetPrompt("> ")

	return true
}
Beispiel #2
0
func (p *ConnectionPolicy) buildDialerFor(conf *Account, verifier ourtls.Verifier) (interfaces.Dialer, error) {
	//Account is a bare JID
	jidParts := strings.SplitN(conf.Account, "@", 2)
	if len(jidParts) != 2 {
		return nil, errors.New("invalid username (want user@domain): " + conf.Account)
	}

	domainpart := jidParts[1]

	p.initTorState()

	hasTorAuto := conf.HasTorAuto()

	if hasTorAuto {
		if err := p.isTorRunning(); err != nil {
			return nil, err
		}
	}

	xmppConfig := data.Config{
		Archive: false,

		TLSConfig: newTLSConfig(),

		Log: p.Logger,
	}

	xmppConfig.InLog, xmppConfig.OutLog = buildInOutLogs(p.XMPPLogger)

	domainRoot, err := rootCAFor(domainpart)
	if err != nil {
		//alert(term, "Tried to add CACert root for jabber.ccc.de but failed: "+err.Error())
		return nil, err
	}

	if domainRoot != nil {
		//alert(term, "Temporarily trusting only CACert root for CCC Jabber server")
		xmppConfig.TLSConfig.RootCAs = domainRoot
	}

	proxy, err := buildProxyChain(conf.Proxies)
	if err != nil {
		return nil, err
	}

	dialer := p.DialerFactory(verifier)
	dialer.SetJID(conf.Account)
	dialer.SetProxy(proxy)
	dialer.SetConfig(xmppConfig)

	// Although RFC 6120, section 3.2.3 recommends to skip the SRV lookup in this
	// case, we opt for keep compatibility with existing client implementations
	// and still make the SRV lookup. This avoids preventing imported accounts to
	// use the SRV lookup.
	if len(conf.Server) > 0 && conf.Port > 0 {
		dialer.SetServerAddress(net.JoinHostPort(conf.Server, strconv.Itoa(conf.Port)))
	}

	if hasTorAuto || p.torState.IsConnectionOverTor(proxy) {
		server := dialer.GetServer()
		host, port, err := net.SplitHostPort(server)
		if err != nil {
			return nil, err
		}

		if hidden, ok := servers.Get(host); ok {
			dialer.SetServerAddress(net.JoinHostPort(hidden.Onion, port))
		}
	}

	return dialer, nil
}
Beispiel #3
0
func (p *ConnectionPolicy) buildDialerFor(conf *Account) (*xmpp.Dialer, error) {
	//Account is a bare JID
	jidParts := strings.SplitN(conf.Account, "@", 2)
	if len(jidParts) != 2 {
		return nil, errors.New("invalid username (want user@domain): " + conf.Account)
	}

	domainpart := jidParts[1]

	if err := p.ensureTorFor(conf); err != nil {
		return nil, err
	}

	certSHA256, err := conf.ServerCertificateHash()
	if err != nil {
		return nil, err
	}

	xmppConfig := xmpp.Config{
		Archive: false,

		ServerCertificateSHA256: certSHA256,
		TLSConfig:               newTLSConfig(),

		Log: p.Logger,
	}

	xmppConfig.InLog, xmppConfig.OutLog = buildInOutLogs(p.XMPPLogger)

	domainRoot, err := rootCAFor(domainpart)
	if err != nil {
		//alert(term, "Tried to add CACert root for jabber.ccc.de but failed: "+err.Error())
		return nil, err
	}

	if domainRoot != nil {
		//alert(term, "Temporarily trusting only CACert root for CCC Jabber server")
		xmppConfig.TLSConfig.RootCAs = domainRoot
	}

	proxy, err := buildProxyChain(conf.Proxies)
	if err != nil {
		return nil, err
	}

	dialer := &xmpp.Dialer{
		JID:    conf.Account,
		Proxy:  proxy,
		Config: xmppConfig,
	}

	// Although RFC 6120, section 3.2.3 recommends to skip the SRV lookup in this
	// case, we opt for keep compatibility with existing client implementations
	// and still make the SRV lookup. This avoids preventing imported accounts to
	// use the SRV lookup.
	if len(conf.Server) > 0 && conf.Port > 0 {
		dialer.ServerAddress = net.JoinHostPort(conf.Server, strconv.Itoa(conf.Port))
	}

	if conf.RequireTor {
		server := dialer.GetServer()
		host, port, err := net.SplitHostPort(server)
		if err != nil {
			return nil, err
		}

		if hidden, ok := servers.Get(host); ok {
			dialer.ServerAddress = net.JoinHostPort(hidden.Onion, port)
		}
	}

	return dialer, nil
}