21720:
[arvados.git] / lib / pam / testclient.go
1 // Copyright (C) The Arvados Authors. All rights reserved.
2 //
3 // SPDX-License-Identifier: Apache-2.0
4
5 //go:build ignore
6 // +build ignore
7
8 // This file is compiled by docker_test.go to build a test client.
9 // It's not part of the pam module itself.
10
11 package main
12
13 import (
14         "fmt"
15         "os"
16         "os/exec"
17
18         "github.com/msteinert/pam"
19         "github.com/sirupsen/logrus"
20 )
21
22 func main() {
23         if len(os.Args) != 4 || os.Args[1] != "try" {
24                 logrus.Print("usage: testclient try 'username' 'password'")
25                 os.Exit(1)
26         }
27         username := os.Args[2]
28         password := os.Args[3]
29
30         // Configure PAM to use arvados token auth by default.
31         cmd := exec.Command("pam-auth-update", "--force", "arvados", "--remove", "unix")
32         cmd.Env = append([]string{"DEBIAN_FRONTEND=noninteractive"}, os.Environ()...)
33         cmd.Stdin = nil
34         cmd.Stdout = os.Stdout
35         cmd.Stderr = os.Stderr
36         err := cmd.Run()
37         if err != nil {
38                 logrus.WithError(err).Error("pam-auth-update failed")
39                 os.Exit(1)
40         }
41
42         // Check that pam-auth-update actually added arvados config.
43         cmd = exec.Command("grep", "-Hn", "arvados", "/etc/pam.d/common-auth")
44         cmd.Stdout = os.Stderr
45         cmd.Stderr = os.Stderr
46         err = cmd.Run()
47         if err != nil {
48                 panic(err)
49         }
50
51         logrus.Debugf("starting pam: username=%q password=%q", username, password)
52
53         sentPassword := false
54         errorMessage := ""
55         tx, err := pam.StartFunc("default", username, func(style pam.Style, message string) (string, error) {
56                 logrus.Debugf("pam conversation: style=%v message=%q", style, message)
57                 switch style {
58                 case pam.ErrorMsg:
59                         logrus.WithField("Message", message).Info("pam.ErrorMsg")
60                         errorMessage = message
61                         return "", nil
62                 case pam.TextInfo:
63                         logrus.WithField("Message", message).Info("pam.TextInfo")
64                         errorMessage = message
65                         return "", nil
66                 case pam.PromptEchoOn, pam.PromptEchoOff:
67                         sentPassword = true
68                         return password, nil
69                 default:
70                         return "", fmt.Errorf("unrecognized message style %d", style)
71                 }
72         })
73         if err != nil {
74                 logrus.WithError(err).Print("StartFunc failed")
75                 os.Exit(1)
76         }
77         err = tx.Authenticate(pam.DisallowNullAuthtok)
78         if err != nil {
79                 err = fmt.Errorf("PAM: %s (message = %q, sentPassword = %v)", err, errorMessage, sentPassword)
80                 logrus.WithError(err).Print("authentication failed")
81                 os.Exit(1)
82         }
83         logrus.Print("authentication succeeded")
84 }