Exemplo n.º 1
0
// ListKeys connects to the local SSH Agent and lists all the public keys
// loaded into it. It returns user friendly error message when it has trouble.
func ListKeys() ([]*agent.Key, error) {
	sshAuthSock := os.Getenv("SSH_AUTH_SOCK")
	if sshAuthSock == "" {
		return nil, fmt.Errorf(
			"The SSH_AUTH_SOCK environment variable is not set, which normally\n" +
				"means that no SSH Agent is running.")
	}

	conn, err := net.Dial("unix", sshAuthSock)
	if err != nil {
		return nil, fmt.Errorf(
			"Error connecting to agent: %s\n\n"+
				"The agent address is detected using the SSH_AUTH_SOCK environment\n"+
				"variable. Please verify this variable is correct and the SSH agent\n"+
				"is properly set up.",
			err)
	}
	defer conn.Close()

	agent := agent.NewClient(conn)
	loadedKeys, err := agent.List()
	if err != nil {
		return nil, fmt.Errorf("Error listing keys: %s", err)
	}
	return loadedKeys, err
}
Exemplo n.º 2
0
func getAgentSSHKey() string {
	// Check to see if we have an SSH agent running.
	sshAuthSock := os.Getenv("SSH_AUTH_SOCK")
	d, err := net.Dial("unix", sshAuthSock)
	if err != nil {
		return ""
	}

	agent := agent.NewClient(d)

	keys, _ := agent.List()
	if len(keys) == 0 {
		return ""
	}
	return base64.StdEncoding.EncodeToString(keys[0].Marshal())
}
Exemplo n.º 3
0
// ListKeys connects to the local SSH Agent and lists all the public keys
// loaded into it. It returns user friendly error message when it has trouble.
func ListKeys() ([]*agent.Key, error) {
	sshAuthSock := os.Getenv("SSH_AUTH_SOCK")
	if sshAuthSock == "" {
		return nil, fmt.Errorf(
			"The SSH_AUTH_SOCK environment variable is not set, which normally\n" +
				"means that no SSH Agent is running.")
	}

	conn, err := net.Dial("unix", sshAuthSock)
	if err != nil {
		return nil, fmt.Errorf("Error connecting to agent: %s", err)
	}
	defer conn.Close()

	agent := agent.NewClient(conn)
	loadedKeys, err := agent.List()
	if err != nil {
		return nil, fmt.Errorf("Error listing keys: %s", err)
	}
	return loadedKeys, err
}
Exemplo n.º 4
0
func TestLDAPUserCache(t *testing.T) {
	Convey("Given an LDAP user cache connected to our server", t, func() {
		// The SSH agent stuff was moved up here so that we can use it to
		// dynamically create the LDAP result object.
		sshSock := os.Getenv("SSH_AUTH_SOCK")
		if sshSock == "" {
			t.Skip()
		}

		c, err := net.Dial("unix", sshSock)
		if err != nil {
			t.Fatal(err)
		}
		agent := agent.NewClient(c)
		keys, err := agent.List()
		if err != nil {
			t.Fatal(err)
		}

		keyValue := base64.StdEncoding.EncodeToString(keys[0].Blob)

		// Load in an additional key from the test data.
		privateKey, _ := ssh.ParsePrivateKey(testKey)
		testPublicKey := base64.StdEncoding.EncodeToString(privateKey.PublicKey().Marshal())

		s := &StubLDAPServer{
			Keys: []string{keyValue, testPublicKey},
		}
		lc, err := server.NewLDAPUserCache(s, g2s.Noop(), "cn", "dc=testdn,dc=com")
		So(err, ShouldBeNil)
		So(lc, ShouldNotBeNil)

		Convey("It should retrieve users from LDAP", func() {
			So(lc.Users(), ShouldNotBeEmpty)
		})

		Convey("It should verify the current user positively.", func() {
			success := false

			for i := 0; i < len(keys); i++ {
				challenge := randomBytes(64)
				sig, err := agent.Sign(keys[i], challenge)
				if err != nil {
					t.Fatal(err)
				}
				verifiedUser, err := lc.Authenticate("ericallen", challenge, sig)
				success = success || (verifiedUser != nil)
			}

			So(success, ShouldEqual, true)
		})

		Convey("When a user is requested that cannot be found in the cache", func() {
			// Use an SSH key we're guaranteed to not have.
			oldKey := s.Keys[0]
			s.Keys[0] = testPublicKey
			lc.Update()

			// Swap the key back and try verifying.
			// We should still get a result back.
			s.Keys[0] = oldKey
			success := false

			for i := 0; i < len(keys); i++ {
				challenge := randomBytes(64)
				sig, err := agent.Sign(keys[i], challenge)
				if err != nil {
					t.Fatal(err)
				}
				verifiedUser, err := lc.Authenticate("ericallen", challenge, sig)
				success = success || (verifiedUser != nil)
			}

			Convey("Then it should update LDAP again and find the user.", func() {
				So(success, ShouldEqual, true)
			})
		})

		Convey("When a user with multiple SSH keys assigned tries to use Hologram", func() {
			Convey("The system should allow them to use any key.", func() {
				success := false

				for i := 0; i < len(keys); i++ {
					challenge := randomBytes(64)
					sig, err := privateKey.Sign(cryptrand.Reader, challenge)
					if err != nil {
						t.Fatal(err)
					}
					verifiedUser, err := lc.Authenticate("ericallen", challenge, sig)
					success = success || (verifiedUser != nil)
				}

				So(success, ShouldEqual, true)

			})
		})

		testAuthorizedKey := string(ssh.MarshalAuthorizedKey(privateKey.PublicKey()))

		s = &StubLDAPServer{
			Keys: []string{testAuthorizedKey},
		}
		lc, err = server.NewLDAPUserCache(s, g2s.Noop(), "cn", "dc=testdn,dc=com")
		So(err, ShouldBeNil)
		So(lc, ShouldNotBeNil)

		Convey("The usercache should understand the SSH authorized_keys format", func() {
			challenge := randomBytes(64)
			sig, err := privateKey.Sign(cryptrand.Reader, challenge)
			if err != nil {
				t.Fatal(err)
			}
			verifiedUser, err := lc.Authenticate("ericallen", challenge, sig)
			So(verifiedUser, ShouldNotBeNil)
			So(err, ShouldBeNil)
		})
	})
}