Example #1
0
File: client.go Project: gaku/1pass
func main() {
	banner := fmt.Sprintf("%s is a tool for managing 1Password vaults.", os.Args[0])
	parser := cmdmodes.NewParser(commandModes)
	agentFlag := flag.Bool("agent", false, "Start 1pass in agent mode")
	vaultPathFlag := flag.String("vault", "", "Custom vault path")
	lowSecFlag := flag.Bool("low-security", false, "Use lower security but faster encryption for the master password")

	flag.Usage = func() {
		parser.PrintHelp(banner, "")
	}
	flag.Parse()

	if *agentFlag {
		agent := NewAgent()
		err := agent.Serve()
		if err != nil {
			fatalErr(err, "")
		}
		return
	}

	config := readConfig()
	if *vaultPathFlag != "" {
		config.VaultDir = *vaultPathFlag
	}

	if len(flag.Args()) < 1 || flag.Args()[0] == "help" {
		command := ""
		if len(flag.Args()) > 1 {
			command = flag.Args()[1]
		}
		parser.PrintHelp(banner, command)
		os.Exit(1)
	}

	mode := flag.Args()[0]
	cmdArgs := flag.Args()[1:]

	// handle commands which do not require
	// an existing vault
	handled := true
	switch mode {
	case "new":
		var path string
		if *vaultPathFlag != "" {
			path = *vaultPathFlag
		} else {
			_ = parser.ParseCmdArgs(mode, cmdArgs, &path)
			if len(path) == 0 {
				path = os.Getenv("HOME") + "/Dropbox/1Password/1Password.agilekeychain"
			}
		}
		createNewVault(path, *lowSecFlag)
	case "gen-password":
		fmt.Printf("%s\n", genDefaultPassword())
	case "set-vault":
		var newPath string
		_ = parser.ParseCmdArgs(mode, cmdArgs, &newPath)
		config.VaultDir = newPath
		writeConfig(&config)
	default:
		handled = false
	}
	if handled {
		return
	}

	// handle commands which require a connected but not
	// unlocked vault
	if config.VaultDir == "" {
		initVaultConfig(&config)
	}
	vault, err := onepass.OpenVault(config.VaultDir)
	if err != nil {
		fatalErr(err, "Unable to setup vault")
	}

	if mode == "info" {
		fmt.Printf("Vault path: %s\n", config.VaultDir)
		return
	}

	// remaining commands require an unlocked vault

	// connect to the 1pass agent daemon. Start it automatically
	// if not already running or the agent/client version do not
	// match

	agentClient, err := DialAgent(config.VaultDir)
	if err == nil && agentClient.Info.BinaryVersion != appBinaryVersion() {
		if agentClient.Info.Pid != 0 {
			fmt.Fprintf(os.Stderr, "Agent/client version mismatch. Restarting agent.\n")
			// kill the existing agent
			err = syscall.Kill(agentClient.Info.Pid, syscall.SIGINT)
			if err != nil {
				fatalErr(err, "Failed to shut down existing agent")
			}
			agentClient = OnePassAgentClient{}
		}
	}
	if agentClient.Info.Pid == 0 {
		err = startAgent()
		if err != nil {
			fatalErr(err, "Unable to start 1pass keychain agent")
		}
		maxWait := time.Now().Add(1 * time.Second)
		for time.Now().Before(maxWait) {
			agentClient, err = DialAgent(config.VaultDir)
			if err == nil {
				break
			} else {
				fmt.Errorf("Error starting agent: %v\n", err)
			}
			time.Sleep(10 * time.Millisecond)
		}
		if err != nil {
			fatalErr(err, "Unable to connect to 1pass keychain agent")
		}
	}

	if mode == "lock" {
		err = agentClient.Lock()
		if err != nil {
			fatalErr(err, "Failed to lock keychain")
		}
		return
	}

	if mode == "set-password" {
		fmt.Printf("Current master password: "******"Failed to check lock status")
	}

	if locked {
		fmt.Printf("Master password: "******"Unable to read password hint: %v\n", err)
				}
				fmt.Fprintf(os.Stderr, "Incorrect password (hint: %s)\n", hint)
				os.Exit(1)
			} else {
				fatalErr(err, "Unable to unlock vault")
			}
		}
	}
	err = agentClient.RefreshAccess()
	if err != nil {
		fatalErr(err, "Unable to refresh vault access")
	}
	vault.CryptoAgent = &agentClient
	handleVaultCmd(&vault, mode, cmdArgs)
}
Example #2
0
File: client.go Project: gaku/1pass
func handleVaultCmd(vault *onepass.Vault, mode string, cmdArgs []string) {
	parser := cmdmodes.NewParser(commandModes)
	var err error
	switch mode {
	case "list":
		var pattern string
		parser.ParseCmdArgs(mode, cmdArgs, &pattern)
		listMatchingItems(vault, pattern)

	case "list-folder":
		var pattern string
		parser.ParseCmdArgs(mode, cmdArgs, &pattern)
		listFolder(vault, pattern)

	case "show-json":
		fallthrough
	case "show":
		var pattern string
		err = parser.ParseCmdArgs(mode, cmdArgs, &pattern)
		if err != nil {
			fatalErr(err, "")
		}
		showItems(vault, pattern, mode == "show-json")

	case "add":
		var itemType string
		var title string
		err = parser.ParseCmdArgs(mode, cmdArgs, &itemType, &title)
		if err != nil {
			fatalErr(err, "")
		}
		addItem(vault, title, itemType)

	case "edit":
		var pattern string
		err = parser.ParseCmdArgs(mode, cmdArgs, &pattern)
		if err != nil {
			fatalErr(err, "")
		}
		editItem(vault, pattern)

	case "remove":
		var pattern string
		err = parser.ParseCmdArgs(mode, cmdArgs, &pattern)
		if err != nil {
			fatalErr(err, "")
		}
		removeItems(vault, pattern)

	case "trash":
		var pattern string
		err = parser.ParseCmdArgs(mode, cmdArgs, &pattern)
		if err != nil {
			fatalErr(err, "")
		}
		trashItems(vault, pattern)

	case "restore":
		var pattern string
		err = parser.ParseCmdArgs(mode, cmdArgs, &pattern)
		if err != nil {
			fatalErr(err, "")
		}
		restoreItems(vault, pattern)

	case "rename":
		var pattern string
		var newTitle string
		err = parser.ParseCmdArgs(mode, cmdArgs, &pattern, &newTitle)
		if err != nil {
			fatalErr(err, "")
		}
		renameItem(vault, pattern, newTitle)

	case "copy":
		var pattern string
		var field string
		err = parser.ParseCmdArgs(mode, cmdArgs, &pattern, &field)
		if err != nil {
			fatalErr(err, "")
		}
		copyToClipboard(vault, pattern, field)

	case "import":
		var path string
		err = parser.ParseCmdArgs(mode, cmdArgs, &path)
		if err != nil {
			fatalErr(err, "")
		}
		importItems(vault, path)

	case "export":
		var pattern string
		var path string
		err = parser.ParseCmdArgs(mode, cmdArgs, &pattern, &path)
		if err != nil {
			fatalErr(err, "")
		}
		exportItems(vault, pattern, path)

	case "export-item-templates":
		var pattern string
		err = parser.ParseCmdArgs(mode, cmdArgs, &pattern)
		if err != nil {
			fatalErr(err, "")
		}
		exportItemTemplates(vault, pattern)

	case "move":
		var folderPattern string
		var itemPattern string
		err = parser.ParseCmdArgs(mode, cmdArgs, &itemPattern, &folderPattern)
		if err != nil {
			fatalErr(err, "")
		}
		moveItemsToFolder(vault, itemPattern, folderPattern)

	case "list-tag":
		var tag string
		err = parser.ParseCmdArgs(mode, cmdArgs, &tag)
		if err != nil {
			fatalErr(err, "")
		}
		listTag(vault, tag)

	case "list-tags":
		listTags(vault)

	case "add-tag":
		var pattern string
		var tag string
		err = parser.ParseCmdArgs(mode, cmdArgs, &pattern, &tag)
		if err != nil {
			fatalErr(err, "")
		}
		addTag(vault, pattern, tag)

	case "remove-tag":
		var pattern string
		var tag string
		err = parser.ParseCmdArgs(mode, cmdArgs, &pattern, &tag)
		if err != nil {
			fatalErr(err, "")
		}
		removeTag(vault, pattern, tag)

	default:
		fmt.Fprintf(os.Stderr, "Unknown command: %s\n", mode)
		os.Exit(1)
	}
}