Пример #1
0
func peerFrom(entry data.RosterEntry, c *config.Account) *roster.Peer {
	belongsTo := c.ID()
	var nickname string
	p, ok := c.GetPeer(entry.Jid)
	if ok {
		nickname = p.Nickname
	}
	return roster.PeerFrom(entry, belongsTo, nickname)
}
Пример #2
0
func peerFrom(entry data.RosterEntry, c *config.Account) *roster.Peer {
	belongsTo := c.ID()

	var nickname string
	var groups []string
	if p, ok := c.GetPeer(entry.Jid); ok {
		nickname = p.Nickname
		groups = p.Groups
	}

	return roster.PeerFrom(entry, belongsTo, nickname, groups)
}
Пример #3
0
func parseFromConfig(cu *config.Account) []otr3.PrivateKey {
	var result []otr3.PrivateKey

	allKeys := cu.AllPrivateKeys()

	log.Printf("Loading %d configured keys", len(allKeys))
	for _, pp := range allKeys {
		_, ok, parsedKey := otr3.ParsePrivateKey(pp)
		if ok {
			result = append(result, parsedKey)
			log.Printf("Loaded key: %s", config.FormatFingerprint(parsedKey.PublicKey().Fingerprint()))
		}
	}

	return result
}
Пример #4
0
// PeerFrom returns a new Peer that contains the same information as the RosterEntry given
func PeerFrom(e xmpp.RosterEntry, conf *config.Account) *Peer {
	belongsTo := conf.ID()
	var nickname string
	p, ok := conf.GetPeer(e.Jid)
	if ok {
		nickname = p.Nickname
	}
	return &Peer{
		Jid:          xmpp.RemoveResourceFromJid(e.Jid),
		Subscription: e.Subscription,
		Name:         e.Name,
		Nickname:     nickname,
		Groups:       toSet(e.Group...),
		BelongsTo:    belongsTo,
	}
}
Пример #5
0
func (r *roster) renameContactPopup(conf *config.Account, jid string) {
	builder := builderForDefinition("RenameContact")
	obj, _ := builder.GetObject("RenameContactPopup")
	popup := obj.(*gtk.Dialog)
	builder.ConnectSignals(map[string]interface{}{
		"on_rename_signal": func() {
			obj, _ = builder.GetObject("rename")
			renameTxt := obj.(*gtk.Entry)
			newName, _ := renameTxt.GetText()
			conf.RenamePeer(jid, newName)
			r.ui.SaveConfig()
			r.redraw()
			popup.Destroy()
		},
	})
	popup.ShowAll()
}
Пример #6
0
func (u *gtkUI) exportKeysFor(account *config.Account, file string) bool {
	var result []*otr3.Account

	allKeys := account.AllPrivateKeys()

	for _, pp := range allKeys {
		_, ok, parsedKey := otr3.ParsePrivateKey(pp)
		if ok {
			result = append(result, &otr3.Account{
				Name:     account.Account,
				Protocol: "prpl-jabber",
				Key:      parsedKey,
			})
		}
	}

	err := otr3.ExportKeysToFile(result, file)
	return err == nil
}
Пример #7
0
func (u *gtkUI) importFingerprintsFor(account *config.Account, file string) (int, bool) {
	fprs, ok := importer.ImportFingerprintsFromPidginStyle(file, func(string) bool { return true })
	if !ok {
		return 0, false
	}

	num := 0
	for _, kfprs := range fprs {
		for _, kfpr := range kfprs {
			log.Printf("Importing fingerprint %X for %s", kfpr.Fingerprint, kfpr.UserID)
			fpr := account.EnsurePeer(kfpr.UserID).EnsureHasFingerprint(kfpr.Fingerprint)
			num = num + 1
			if !kfpr.Untrusted {
				fpr.Trusted = true
			}
		}
	}

	return num, true
}
Пример #8
0
func (u *gtkUI) importKeysFor(account *config.Account, file string) (int, bool) {
	keys, ok := importer.ImportKeysFromPidginStyle(file, func(string) bool { return true })
	if !ok {
		return 0, false
	}

	switch len(keys) {
	case 0:
		return 0, true
	case 1:
		account.PrivateKeys = [][]byte{firstItem(keys)}
		return 1, true
	default:
		kk, ok := u.chooseKeyToImport(keys)
		if ok {
			account.PrivateKeys = [][]byte{kk}
			return 1, true
		}
		return 0, false
	}
}
Пример #9
0
func (m *accountManager) removeAccount(conf *config.Account, k func()) {
	toRemove, exists := m.getAccountByID(conf.ID())
	if !exists {
		return
	}

	m.Lock()
	defer m.Unlock()

	accs := make([]*account, 0, len(m.accounts)-1)
	for _, acc := range m.accounts {
		if acc == toRemove {
			delete(m.contacts, acc)
			continue
		}

		accs = append(accs, acc)
	}

	m.accounts = accs

	k()
}
Пример #10
0
func (u *gtkUI) importKeysFor(account *config.Account, file string) (int, bool) {
	keys, ok := importer.ImportKeysFromPidginStyle(file, func(string) bool { return true })
	if !ok {
		return 0, false
	}

	newKeys := [][]byte{}
	for _, kk := range keys {
		newKeys = append(newKeys, kk)
	}
	account.PrivateKeys = newKeys

	return len(newKeys), true
}
Пример #11
0
Файл: ui.go Проект: 0x27/coyim
func (u *gtkUI) askForServerDetails(conf *config.Account, connectFn func() error) {
	builder := builderForDefinition("ConnectionSettings")

	obj, _ := builder.GetObject("ConnectionSettingsDialog")
	dialog := obj.(*gtk.Dialog)

	obj, _ = builder.GetObject("server")
	serverEntry := obj.(*gtk.Entry)

	obj, _ = builder.GetObject("port")
	portEntry := obj.(*gtk.Entry)

	if conf.Port == 0 {
		conf.Port = 5222
	}

	serverEntry.SetText(conf.Server)
	portEntry.SetText(strconv.Itoa(conf.Port))

	builder.ConnectSignals(map[string]interface{}{
		"reconnect": func() {
			defer dialog.Destroy()

			//TODO: validate
			conf.Server, _ = serverEntry.GetText()

			p, _ := portEntry.GetText()
			conf.Port, _ = strconv.Atoi(p)

			go func() {
				if connectFn() != nil {
					return
				}

				u.saveConfigOnly()
			}()
		},
	})

	dialog.SetTransientFor(u.window)
	dialog.ShowAll()
}
Пример #12
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
}
Пример #13
0
func (u *gtkUI) accountDialog(s access.Session, account *config.Account, saveFunction func()) {
	data := getBuilderAndAccountDialogDetails()

	data.otherSettings.SetActive(u.config.AdvancedOptions)
	data.acc.SetText(account.Account)
	data.server.SetText(account.Server)
	if account.Port == 0 {
		account.Port = 5222
	}
	data.port.SetText(strconv.Itoa(account.Port))

	for _, px := range account.Proxies {
		iter := data.proxies.Append()
		data.proxies.SetValue(iter, 0, net.ParseProxy(px).ForPresentation())
		data.proxies.SetValue(iter, 1, px)
	}

	data.fingerprintsMessage.SetSelectable(true)
	m := i18n.Local("Your fingerprints for %s:\n%s")
	message := fmt.Sprintf(m, account.Account, formattedFingerprintsFor(s))
	data.fingerprintsMessage.SetText(message)

	p2, _ := data.notebook.GetNthPage(1)
	p3, _ := data.notebook.GetNthPage(2)
	p4, _ := data.notebook.GetNthPage(3)

	failures := 0

	editProxy := func(iter *gtk.TreeIter, onCancel func()) {
		val, _ := data.proxies.GetValue(iter, 1)
		realProxyData, _ := val.GetString()
		u.editProxy(realProxyData, data.dialog,
			func(p net.Proxy) {
				data.proxies.SetValue(iter, 0, p.ForPresentation())
				data.proxies.SetValue(iter, 1, p.ForProcessing())
			}, onCancel)
	}

	data.builder.ConnectSignals(map[string]interface{}{
		"on_toggle_other_settings": func() {
			otherSettings := data.otherSettings.GetActive()
			u.setShowAdvancedSettings(otherSettings)
			data.notebook.SetShowTabs(otherSettings)
			if otherSettings {
				p2.Show()
				p3.Show()
				p4.Show()
			} else {
				p2.Hide()
				p3.Hide()
				p4.Hide()
			}
		},
		"on_save_signal": func() {
			accTxt, _ := data.acc.GetText()
			passTxt, _ := data.pass.GetText()
			servTxt, _ := data.server.GetText()
			portTxt, _ := data.port.GetText()

			isJid, err := verifyXmppAddress(accTxt)
			if !isJid && failures > 0 {
				failures++
				return
			}

			if !isJid {
				notification := buildBadUsernameNotification(err)
				data.notificationArea.Add(notification)
				notification.ShowAll()
				failures++
				log.Printf(err)
				return
			}

			account.Account = accTxt
			account.Server = servTxt

			if passTxt != "" {
				account.Password = passTxt
			}

			convertedPort, e := strconv.Atoi(portTxt)
			if len(strings.TrimSpace(portTxt)) == 0 || e != nil {
				convertedPort = 5222
			}

			account.Port = convertedPort

			newProxies := []string{}
			iter, ok := data.proxies.GetIterFirst()
			for ok {
				vv, _ := data.proxies.GetValue(iter, 1)
				newProxy, _ := vv.GetString()
				newProxies = append(newProxies, newProxy)
				ok = data.proxies.IterNext(iter)
			}

			account.Proxies = newProxies

			go saveFunction()
			data.dialog.Destroy()
		},
		"on_edit_proxy_signal": func() {
			ts, _ := data.proxiesView.GetSelection()
			var iter gtk.TreeIter
			if ts.GetSelected(nil, &iter) {
				editProxy(&iter, func() {})
			}
		},
		"on_remove_proxy_signal": func() {
			ts, _ := data.proxiesView.GetSelection()
			var iter gtk.TreeIter
			if ts.GetSelected(nil, &iter) {
				data.proxies.Remove(&iter)
			}
		},
		"on_add_proxy_signal": func() {
			iter := data.proxies.Append()
			data.proxies.SetValue(iter, 0, "tor-auto://")
			data.proxies.SetValue(iter, 1, "tor-auto://")
			ts, _ := data.proxiesView.GetSelection()
			ts.SelectIter(iter)
			editProxy(iter, func() {
				data.proxies.Remove(iter)
			})
		},
		"on_edit_activate_proxy_signal": func(_ *gtk.TreeView, path *gtk.TreePath) {
			iter, err := data.proxies.GetIter(path)
			if err == nil {
				editProxy(iter, func() {})
			}
		},
		"on_cancel_signal": func() {
			u.buildAccountsMenu()
			data.dialog.Destroy()
		},
		"on_import_key_signal": func() {
			u.importKeysForDialog(account, data.dialog)
		},
		"on_import_fpr_signal": func() {
			u.importFingerprintsForDialog(account, data.dialog)
		},
		"on_export_key_signal": func() {
			u.exportKeysForDialog(account, data.dialog)
		},
		"on_export_fpr_signal": func() {
			u.exportFingerprintsForDialog(account, data.dialog)
		},
	})

	data.dialog.SetTransientFor(u.window)
	data.dialog.ShowAll()
	data.notebook.SetCurrentPage(0)

	data.notebook.SetShowTabs(u.config.AdvancedOptions)
	if !u.config.AdvancedOptions {
		p2.Hide()
		p3.Hide()
		p4.Hide()
	}
}
Пример #14
0
func (u *gtkUI) accountDialog(account *config.Account, saveFunction func()) {
	dialogID := "AccountDetails"
	builder := builderForDefinition(dialogID)

	obj, _ := builder.GetObject(dialogID)
	dialog := obj.(*gtk.Dialog)

	obj, _ = builder.GetObject("notebook1")
	notebook := obj.(*gtk.Notebook)

	obj, _ = builder.GetObject("otherSettings")
	otherSettingsToggle := obj.(*gtk.CheckButton)

	obj, _ = builder.GetObject("account")
	accEntry := obj.(*gtk.Entry)
	accEntry.SetText(account.Account)

	obj, _ = builder.GetObject("password")
	passEntry := obj.(*gtk.Entry)

	obj, _ = builder.GetObject("server")
	serverEntry := obj.(*gtk.Entry)
	serverEntry.SetText(account.Server)

	obj, _ = builder.GetObject("port")
	portEntry := obj.(*gtk.Entry)
	if account.Port == 0 {
		account.Port = 5222
	}
	portEntry.SetText(strconv.Itoa(account.Port))

	obj, _ = builder.GetObject("notification-area")
	notificationArea := obj.(*gtk.Box)

	p2, _ := notebook.GetNthPage(1)
	p3, _ := notebook.GetNthPage(2)

	failures := 0

	builder.ConnectSignals(map[string]interface{}{
		"on_toggle_other_settings": func() {
			otherSettings := otherSettingsToggle.GetActive()
			if otherSettings {
				p2.Show()
				p3.Show()
			} else {
				p2.Hide()
				p3.Hide()
			}
		},
		"on_save_signal": func() {
			accTxt, _ := accEntry.GetText()
			passTxt, _ := passEntry.GetText()
			servTxt, _ := serverEntry.GetText()
			portTxt, _ := portEntry.GetText()

			isJid, err := verifyXmppAddress(accTxt)
			if !isJid && failures > 0 {
				failures++
				return
			}

			if !isJid {
				notification := buildBadUsernameNotification(err)
				notificationArea.Add(notification)
				notification.ShowAll()
				failures++
				log.Printf(err)
				return
			}

			account.Account = accTxt
			account.Server = servTxt

			if passTxt != "" {
				account.Password = passTxt
			}

			convertedPort, e := strconv.Atoi(portTxt)
			if len(strings.TrimSpace(portTxt)) == 0 || e != nil {
				convertedPort = 5222
			}

			account.Port = convertedPort

			go saveFunction()
			dialog.Destroy()
		},
		"on_cancel_signal": func() {
			u.buildAccountsMenu()
			dialog.Destroy()
		},
	})

	dialog.SetTransientFor(u.window)
	dialog.ShowAll()
	notebook.SetCurrentPage(0)

	p2.Hide()
	p3.Hide()
}