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.
}
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.
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.
}
}
+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",
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.*`)
+}
import (
"io/ioutil"
"log/syslog"
+ "os"
"context"
"errors"
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")
}