// NewAccount creates a new account func NewAccount() (*Account, error) { pkeys, err := otr3.GenerateMissingKeys([][]byte{}) if err != nil { return nil, err } return &Account{ PrivateKeys: SerializedKeys(pkeys), AlwaysEncrypt: true, OTRAutoStartSession: true, OTRAutoTearDown: true, //See #48 OTRAutoAppendTag: true, Proxies: []string{ "tor-auto://", }, }, nil }
// EnsurePrivateKey generates a private key for the account in case it's missing func (a *Account) EnsurePrivateKey() (hasUpdate bool, e error) { log.Printf("[%s] ensureConfigHasKey()\n", a.Account) prevKeys := a.AllPrivateKeys() newKeys, err := otr3.GenerateMissingKeys(prevKeys) if err != nil { return false, err } if len(newKeys) == 0 { return false, nil } a.DeprecatedPrivateKey = nil a.PrivateKeys = append(prevKeys, SerializedKeys(newKeys)...) return true, nil }
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 }