From: Tom Clegg Date: Thu, 2 Jul 2020 14:48:15 +0000 (-0400) Subject: 15348: Look up hostname if not provided in config args. X-Git-Tag: 2.1.0~169^2~2 X-Git-Url: https://git.arvados.org/arvados.git/commitdiff_plain/183f8c6feeb8d3adbf36a1a4adf122607fb55617 15348: Look up hostname if not provided in config args. Arvados-DCO-1.1-Signed-off-by: Tom Clegg --- diff --git a/lib/pam/README b/lib/pam/README index 243a179e6c..aafff23a8c 100644 --- a/lib/pam/README +++ b/lib/pam/README @@ -1 +1,18 @@ For configuration advice, please refer to https://doc.arvados.org/install/install-webshell.html + +Usage (in pam config): + + pam_arvados.so arvados_api_host [my_vm_host_name] ["insecure"] ["debug"] + +pam_arvados.so passes authentication if (according to +arvados_api_host) the supplied PAM token belongs to an Arvados user +who is allowed to log in to my_vm_host_name with the supplied PAM +username. + +If my_vm_host_name is omitted or "-", the current hostname is used. + +"insecure" -- continue even if the TLS certificate presented by +arvados_api_host fails verification. + +"debug" -- enable debug-level log messages in syslog and (when not in +"silent" mode) on the calling application's stderr. diff --git a/lib/pam/docker_test.go b/lib/pam/docker_test.go index 5b1755496b..fa16b313be 100644 --- a/lib/pam/docker_test.go +++ b/lib/pam/docker_test.go @@ -60,7 +60,6 @@ func (s *DockerSuite) SetUpSuite(c *check.C) { } s.proxysrv = &http.Server{Handler: proxy} go s.proxysrv.ServeTLS(ln, "../../services/api/tmp/self-signed.pem", "../../services/api/tmp/self-signed.key") - proxyhost := ln.Addr().String() // Build a pam module to install & configure in the docker // container. @@ -70,20 +69,6 @@ func (s *DockerSuite) SetUpSuite(c *check.C) { err = cmd.Run() c.Assert(err, check.IsNil) - // Write a PAM config file that uses our proxy as - // ARVADOS_API_HOST. - confdata := fmt.Sprintf(`Name: Arvados authentication -Default: yes -Priority: 256 -Auth-Type: Primary -Auth: - [success=end default=ignore] /usr/lib/pam_arvados.so %s testvm2.shell insecure -Auth-Initial: - [success=end default=ignore] /usr/lib/pam_arvados.so %s testvm2.shell insecure -`, proxyhost, proxyhost) - err = ioutil.WriteFile(s.tmpdir+"/conffile", []byte(confdata), 0755) - c.Assert(err, check.IsNil) - // Build the testclient program that will (from inside the // docker container) configure the system to use the above PAM // config, and then try authentication. @@ -103,9 +88,28 @@ func (s *DockerSuite) TearDownSuite(c *check.C) { } } +func (s *DockerSuite) SetUpTest(c *check.C) { + // Write a PAM config file that uses our proxy as + // ARVADOS_API_HOST. + proxyhost := s.proxyln.Addr().String() + confdata := fmt.Sprintf(`Name: Arvados authentication +Default: yes +Priority: 256 +Auth-Type: Primary +Auth: + [success=end default=ignore] /usr/lib/pam_arvados.so %s testvm2.shell insecure +Auth-Initial: + [success=end default=ignore] /usr/lib/pam_arvados.so %s testvm2.shell insecure +`, proxyhost, proxyhost) + err := ioutil.WriteFile(s.tmpdir+"/conffile", []byte(confdata), 0755) + c.Assert(err, check.IsNil) +} + func (s *DockerSuite) runTestClient(c *check.C, args ...string) (stdout, stderr *bytes.Buffer, err error) { + cmd := exec.Command("docker", append([]string{ "run", "--rm", + "--hostname", "testvm2.shell", "--add-host", "zzzzz.arvadosapi.com:" + s.hostip, "-v", s.tmpdir + "/pam_arvados.so:/usr/lib/pam_arvados.so:ro", "-v", s.tmpdir + "/conffile:/usr/share/pam-configs/arvados:ro", @@ -147,3 +151,23 @@ func (s *DockerSuite) TestFailure(c *check.C) { c.Check(stderr.String(), check.Matches, `(?ms).*authentication failed.*`) } } + +func (s *DockerSuite) TestDefaultHostname(c *check.C) { + confdata := fmt.Sprintf(`Name: Arvados authentication +Default: yes +Priority: 256 +Auth-Type: Primary +Auth: + [success=end default=ignore] /usr/lib/pam_arvados.so %s - insecure debug +Auth-Initial: + [success=end default=ignore] /usr/lib/pam_arvados.so %s - insecure debug +`, s.proxyln.Addr().String(), s.proxyln.Addr().String()) + err := ioutil.WriteFile(s.tmpdir+"/conffile", []byte(confdata), 0755) + c.Assert(err, check.IsNil) + + stdout, stderr, err := s.runTestClient(c, "try", "active", arvadostest.ActiveTokenV2) + c.Check(err, check.IsNil) + c.Logf("%s", stderr.String()) + c.Check(stdout.String(), check.Equals, "") + c.Check(stderr.String(), check.Matches, `(?ms).*authentication succeeded.*`) +} diff --git a/lib/pam/pam_arvados.go b/lib/pam/pam_arvados.go index 389033ba96..34b9080536 100644 --- a/lib/pam/pam_arvados.go +++ b/lib/pam/pam_arvados.go @@ -24,6 +24,7 @@ package main import ( "io/ioutil" "log/syslog" + "os" "context" "errors" @@ -104,8 +105,16 @@ func authenticate(logger *logrus.Logger, username, token string, argv []string) logger.Warnf("unkown option: %s\n", arg) } } + if hostname == "" || hostname == "-" { + h, err := os.Hostname() + if err != nil { + logger.WithError(err).Warnf("cannot get hostname -- try using an explicit hostname in pam config") + return fmt.Errorf("cannot get hostname: %w", err) + } + hostname = h + } logger.Debugf("username=%q arvados_api_host=%q hostname=%q insecure=%t", username, apiHost, hostname, insecure) - if apiHost == "" || hostname == "" { + if apiHost == "" { logger.Warnf("cannot authenticate: config error: arvados_api_host and hostname must be non-empty") return errors.New("config error") }