Add initial support for key file exporting and importing
Warning: the passphrase is currently hardcoded to "gomuks"
This commit is contained in:
		@@ -105,10 +105,13 @@ func NewCommandProcessor(parent *MainView) *CommandProcessor {
 | 
			
		||||
			"o":          {"open"},
 | 
			
		||||
		},
 | 
			
		||||
		autocompleters: map[string]CommandAutocompleter{
 | 
			
		||||
			"devices":  autocompleteDevice,
 | 
			
		||||
			"device":   autocompleteDevice,
 | 
			
		||||
			"verify":   autocompleteDevice,
 | 
			
		||||
			"unverify": autocompleteDevice,
 | 
			
		||||
			"devices":     autocompleteDevice,
 | 
			
		||||
			"device":      autocompleteDevice,
 | 
			
		||||
			"verify":      autocompleteDevice,
 | 
			
		||||
			"unverify":    autocompleteDevice,
 | 
			
		||||
			"import":      autocompleteFile,
 | 
			
		||||
			"export":      autocompleteFile,
 | 
			
		||||
			"export-room": autocompleteFile,
 | 
			
		||||
		},
 | 
			
		||||
		commands: map[string]CommandHandler{
 | 
			
		||||
			"unknown-command": cmdUnknownCommand,
 | 
			
		||||
@@ -159,6 +162,9 @@ func NewCommandProcessor(parent *MainView) *CommandProcessor {
 | 
			
		||||
			"unverify":      cmdUnverify,
 | 
			
		||||
			"blacklist":     cmdBlacklist,
 | 
			
		||||
			"reset-session": cmdResetSession,
 | 
			
		||||
			"import":        cmdImportKeys,
 | 
			
		||||
			"export":        cmdExportKeys,
 | 
			
		||||
			"export-room":   cmdExportRoomKeys,
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -461,6 +461,11 @@ Things: rooms, users, baremessages, images, typingnotif, unverified
 | 
			
		||||
/verify <user id> <device id> [fingerprint]
 | 
			
		||||
    - Verify a device. If the fingerprint is not provided,
 | 
			
		||||
      interactive emoji verification will be started.
 | 
			
		||||
/reset-session - Reset the outbound Megolm session in the current room.
 | 
			
		||||
 | 
			
		||||
/import <file> - Import encryption keys
 | 
			
		||||
/export <file> - Export encryption keys
 | 
			
		||||
/export-room <file> - Export encryption keys for the current room.
 | 
			
		||||
 | 
			
		||||
# Rooms
 | 
			
		||||
/pm <user id> <...>   - Create a private chat with the given user(s).
 | 
			
		||||
 
 | 
			
		||||
@@ -20,6 +20,7 @@ package ui
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"io/ioutil"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"time"
 | 
			
		||||
	"unicode"
 | 
			
		||||
@@ -229,3 +230,59 @@ func cmdResetSession(cmd *Command) {
 | 
			
		||||
		cmd.Reply("Removed outbound group session for this room")
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func autocompleteFile(cmd *CommandAutocomplete) (completions []string, newText string) {
 | 
			
		||||
	// TODO implement
 | 
			
		||||
	return []string{}, ""
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// TODO add dialog for asking passphrase
 | 
			
		||||
const extremelyTemporaryHardcodedPassphrase = "gomuks"
 | 
			
		||||
 | 
			
		||||
func cmdImportKeys(cmd *Command) {
 | 
			
		||||
	data, err := ioutil.ReadFile(cmd.RawArgs)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		cmd.Reply("Failed to read %s: %v", cmd.RawArgs, err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	mach := cmd.Matrix.Crypto().(*crypto.OlmMachine)
 | 
			
		||||
	imported, total, err := mach.ImportKeys(extremelyTemporaryHardcodedPassphrase, string(data))
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		cmd.Reply("Failed to import sessions: %v", err)
 | 
			
		||||
	} else {
 | 
			
		||||
		cmd.Reply("Successfully imported %d/%d sessions", imported, total)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func exportKeys(cmd *Command, sessions []*crypto.InboundGroupSession) {
 | 
			
		||||
	export, err := crypto.ExportKeys(extremelyTemporaryHardcodedPassphrase, sessions)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		cmd.Reply("Failed to export sessions: %v", err)
 | 
			
		||||
	}
 | 
			
		||||
	err = ioutil.WriteFile(cmd.RawArgs, []byte(export), 0400)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		cmd.Reply("Failed to write sessions to %s: %v", cmd.RawArgs, err)
 | 
			
		||||
	} else {
 | 
			
		||||
		cmd.Reply("Successfully exported %d sessions to %s", len(sessions), cmd.RawArgs)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func cmdExportKeys(cmd *Command) {
 | 
			
		||||
	mach := cmd.Matrix.Crypto().(*crypto.OlmMachine)
 | 
			
		||||
	sessions, err := mach.CryptoStore.GetAllGroupSessions()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		cmd.Reply("Failed to get sessions to export: %v", err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	exportKeys(cmd, sessions)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func cmdExportRoomKeys(cmd *Command) {
 | 
			
		||||
	mach := cmd.Matrix.Crypto().(*crypto.OlmMachine)
 | 
			
		||||
	sessions, err := mach.CryptoStore.GetGroupSessionsForRoom(cmd.Room.MxRoom().ID)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		cmd.Reply("Failed to get sessions to export: %v", err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	exportKeys(cmd, sessions)
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -22,6 +22,10 @@ func autocompleteDevice(cmd *CommandAutocomplete) ([]string, string) {
 | 
			
		||||
	return []string{}, ""
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func autocompleteFile(cmd *CommandAutocomplete) ([]string, string) {
 | 
			
		||||
	return []string{}, ""
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func cmdNoCrypto(cmd *Command) {
 | 
			
		||||
	cmd.Reply("This gomuks was built without encryption support")
 | 
			
		||||
}
 | 
			
		||||
@@ -33,4 +37,7 @@ var (
 | 
			
		||||
	cmdUnverify = cmdNoCrypto
 | 
			
		||||
	cmdBlacklist = cmdNoCrypto
 | 
			
		||||
	cmdResetSession = cmdNoCrypto
 | 
			
		||||
	cmdImportKeys = cmdNoCrypto
 | 
			
		||||
	cmdExportKeys = cmdNoCrypto
 | 
			
		||||
	cmdExportRoomKeys = cmdNoCrypto
 | 
			
		||||
)
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user