func PAM(ctx *cli.Context) { // We need to find the user's home first. username := os.Getenv("PAM_USER") homedir := mustLookupHomeDir(username) nullok := ctx.Bool("nullok") conf, err := client.ReadDefaultConfig(homedir) if err != nil { if nullok { os.Exit(0) } else { fatalf("Error reading config: %v\n", err) } } if len(conf.Registrations) == 0 { if nullok { os.Exit(0) } else { fatalf("Error: no registrations found\n") } } c := mustGRPCClient(conf.Addr, conf.Token, ctx.GlobalString("ca_file")) hostname, err := os.Hostname() if err != nil { fatalf("Error getting hostname: %v", err) } msg := fmt.Sprintf("%s@%s", username, hostname) pa, err := c.PrepareAuthentication( msg, conf.AppID, conf.RegistrationValues()) if err != nil { fatalf("Error preparing authentication: %v\n", err) } fmt.Printf("Authenticate here and press enter: %s\n", pa.Key.Url) // Closing stdout makes pam_prompt_exec send the prompt over. os.Stdout.Close() // Read input, and check if it's a backup code. // Never take a backup code of less than 6 characters, just in case some // data handling error makes them appear in conf.BackupCodes. input := readLine() if _, ok := conf.BackupCodes[input]; len(input) >= 6 && ok { delete(conf.BackupCodes, input) mustWriteConfig(conf, homedir) os.Exit(0) } err = c.CompleteAuthentication(pa) if err != nil { fatalf("Error completing authentication: %v\n", err) } os.Exit(0) }
func mustReadConfig() *client.Config { conf, err := client.ReadDefaultConfig("") if err != nil { fatalf("Error reading config: %v\n", err) } return conf }
func Init(ctx *cli.Context) { if !ctx.Bool("override") { // We don't want to accidentally override the config. _, err := client.ReadDefaultConfig("") if err == nil { fmt.Printf("Configuration already exists at %s\n", client.DefaultConfigFullPath("")) fmt.Printf("Use --override to continue anyway.\n") os.Exit(1) } } fmt.Printf("- GRPC server address to use? (e.g. 'mydomain.com:8801')\n") addr := readLine() fmt.Printf("- Authorization token? (given to you by the server admin)\n") token := readLine() fmt.Printf("- Contacting server...\n") c, err := client.GRPCClient(addr, token, ctx.GlobalString("ca_file")) if err != nil { fmt.Printf("Error connecting with the server: %v\n", err) fmt.Printf("Check the parameters above and try again.\n") os.Exit(1) } appID, err := c.GetAppID() if err != nil { fmt.Printf("RPC error: %v\n", err) fmt.Printf("Check the parameters above and try again.\n") os.Exit(1) } fmt.Printf("It worked! AppID: %s\n", appID) conf := &client.Config{ Addr: addr, Token: token, AppID: appID, Registrations: map[string][]byte{}, } err = conf.NewBackupCodes() if err != nil { fatalf("Error generating backup codes: %v\n", err) } mustWriteConfig(conf, "") fmt.Printf("Config written to %s\n", client.DefaultConfigFullPath("")) fmt.Printf("\n") fmt.Printf("Please write down your backup codes:\n") printBackupCodes(conf) fmt.Printf("\n") fmt.Printf("All done!\n") fmt.Printf("To register a security key, run: remoteu2f-cli register\n") }