open-vault/builtin/logical/ssh/backend_test.go

640 lines
19 KiB
Go
Raw Normal View History

2015-07-10 15:56:14 +00:00
package ssh
import (
"fmt"
2015-08-30 18:17:50 +00:00
"reflect"
2015-07-10 15:56:14 +00:00
"testing"
"time"
2015-07-10 15:56:14 +00:00
"golang.org/x/crypto/ssh"
2015-08-18 23:48:50 +00:00
"github.com/hashicorp/vault/api"
2015-07-10 15:56:14 +00:00
"github.com/hashicorp/vault/logical"
logicaltest "github.com/hashicorp/vault/logical/testing"
2015-07-10 22:18:02 +00:00
"github.com/hashicorp/vault/vault"
2015-07-10 15:56:14 +00:00
"github.com/mitchellh/mapstructure"
)
2016-02-02 17:32:50 +00:00
// Before the following tests are run, a username going by the name 'vaultssh' has
// to be created and its ~/.ssh/authorized_keys file should contain the below key.
//
// ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC9i+hFxZHGo6KblVme4zrAcJstR6I0PTJozW286X4WyvPnkMYDQ5mnhEYC7UWCvjoTWbPEXPX7NjhRtwQTGD67bV+lrxgfyzK1JZbUXK4PwgKJvQD+XyyWYMzDgGSQY61KUSqCxymSm/9NZkPU3ElaQ9xQuTzPpztM4ROfb8f2Yv6/ZESZsTo0MTAkp8Pcy+WkioI/uJ1H7zqs0EA4OMY4aDJRu0UtP4rTVeYNEAuRXdX+eH4aW3KMvhzpFTjMbaJHJXlEeUm2SaX5TNQyTOvghCeQILfYIL/Ca2ij8iwCmulwdV6eQGfd4VDu40PvSnmfoaE38o6HaPnX0kUcnKiT
2015-07-10 15:56:14 +00:00
const (
2016-02-02 17:32:50 +00:00
testIP = "127.0.0.1"
testUserName = "vaultssh"
testAdminUser = "vaultssh"
2015-07-31 17:24:23 +00:00
testOTPKeyType = "otp"
testDynamicKeyType = "dynamic"
2015-08-13 15:46:55 +00:00
testCIDRList = "127.0.0.1/32"
2015-07-31 17:24:23 +00:00
testDynamicRoleName = "testDynamicRoleName"
testOTPRoleName = "testOTPRoleName"
2015-07-31 19:17:40 +00:00
testKeyName = "testKeyName"
2015-07-10 22:18:02 +00:00
testSharedPrivateKey = `
2015-07-10 15:56:14 +00:00
-----BEGIN RSA PRIVATE KEY-----
2015-07-10 22:18:02 +00:00
MIIEogIBAAKCAQEAvYvoRcWRxqOim5VZnuM6wHCbLUeiND0yaM1tvOl+Fsrz55DG
A0OZp4RGAu1Fgr46E1mzxFz1+zY4UbcEExg+u21fpa8YH8sytSWW1FyuD8ICib0A
/l8slmDMw4BkkGOtSlEqgscpkpv/TWZD1NxJWkPcULk8z6c7TOETn2/H9mL+v2RE
mbE6NDEwJKfD3MvlpIqCP7idR+86rNBAODjGOGgyUbtFLT+K01XmDRALkV3V/nh+
GltyjL4c6RU4zG2iRyV5RHlJtkml+UzUMkzr4IQnkCC32CC/wmtoo/IsAprpcHVe
nkBn3eFQ7uND70p5n6GhN/KOh2j519JFHJyokwIDAQABAoIBAHX7VOvBC3kCN9/x
+aPdup84OE7Z7MvpX6w+WlUhXVugnmsAAVDczhKoUc/WktLLx2huCGhsmKvyVuH+
MioUiE+vx75gm3qGx5xbtmOfALVMRLopjCnJYf6EaFA0ZeQ+NwowNW7Lu0PHmAU8
Z3JiX8IwxTz14DU82buDyewO7v+cEr97AnERe3PUcSTDoUXNaoNxjNpEJkKREY6h
4hAY676RT/GsRcQ8tqe/rnCqPHNd7JGqL+207FK4tJw7daoBjQyijWuB7K5chSal
oPInylM6b13ASXuOAOT/2uSUBWmFVCZPDCmnZxy2SdnJGbsJAMl7Ma3MUlaGvVI+
Tfh1aQkCgYEA4JlNOabTb3z42wz6mz+Nz3JRwbawD+PJXOk5JsSnV7DtPtfgkK9y
6FTQdhnozGWShAvJvc+C4QAihs9AlHXoaBY5bEU7R/8UK/pSqwzam+MmxmhVDV7G
IMQPV0FteoXTaJSikhZ88mETTegI2mik+zleBpVxvfdhE5TR+lq8Br0CgYEA2AwJ
CUD5CYUSj09PluR0HHqamWOrJkKPFPwa+5eiTTCzfBBxImYZh7nXnWuoviXC0sg2
AuvCW+uZ48ygv/D8gcz3j1JfbErKZJuV+TotK9rRtNIF5Ub7qysP7UjyI7zCssVM
kuDd9LfRXaB/qGAHNkcDA8NxmHW3gpln4CFdSY8CgYANs4xwfercHEWaJ1qKagAe
rZyrMpffAEhicJ/Z65lB0jtG4CiE6w8ZeUMWUVJQVcnwYD+4YpZbX4S7sJ0B8Ydy
AhkSr86D/92dKTIt2STk6aCN7gNyQ1vW198PtaAWH1/cO2UHgHOy3ZUt5X/Uwxl9
cex4flln+1Viumts2GgsCQKBgCJH7psgSyPekK5auFdKEr5+Gc/jB8I/Z3K9+g4X
5nH3G1PBTCJYLw7hRzw8W/8oALzvddqKzEFHphiGXK94Lqjt/A4q1OdbCrhiE68D
My21P/dAKB1UYRSs9Y8CNyHCjuZM9jSMJ8vv6vG/SOJPsnVDWVAckAbQDvlTHC9t
O98zAoGAcbW6uFDkrv0XMCpB9Su3KaNXOR0wzag+WIFQRXCcoTvxVi9iYfUReQPi
oOyBJU/HMVvBfv4g+OVFLVgSwwm6owwsouZ0+D/LasbuHqYyqYqdyPJQYzWA2Y+F
+B6f4RoPdSXj24JHPg/ioRxjaj094UXJxua2yfkcecGNEuBQHSs=
2015-07-10 15:56:14 +00:00
-----END RSA PRIVATE KEY-----
`
)
func TestBackend_allowed_users(t *testing.T) {
config := logical.TestBackendConfig()
config.StorageView = &logical.InmemStorage{}
b, err := Backend(config)
if err != nil {
t.Fatal(err)
}
_, err = b.Setup(config)
if err != nil {
t.Fatal(err)
}
roleData := map[string]interface{}{
"key_type": "otp",
"default_user": "ubuntu",
"cidr_list": "52.207.235.245/16",
"allowed_users": "test",
}
roleReq := &logical.Request{
Operation: logical.UpdateOperation,
Path: "roles/role1",
Storage: config.StorageView,
Data: roleData,
}
resp, err := b.HandleRequest(roleReq)
if err != nil || (resp != nil && resp.IsError()) || resp != nil {
t.Fatalf("failed to create role: resp:%#v err:%s", resp, err)
}
credsData := map[string]interface{}{
"ip": "52.207.235.245",
"username": "ubuntu",
}
credsReq := &logical.Request{
Operation: logical.UpdateOperation,
Storage: config.StorageView,
Path: "creds/role1",
Data: credsData,
}
resp, err = b.HandleRequest(credsReq)
if err != nil || (resp != nil && resp.IsError()) || resp == nil {
t.Fatalf("failed to create role: resp:%#v err:%s", resp, err)
}
if resp.Data["key"] == "" ||
resp.Data["key_type"] != "otp" ||
resp.Data["ip"] != "52.207.235.245" ||
resp.Data["username"] != "ubuntu" {
t.Fatalf("failed to create credential: resp:%#v", resp)
}
credsData["username"] = "test"
resp, err = b.HandleRequest(credsReq)
if err != nil || (resp != nil && resp.IsError()) || resp == nil {
t.Fatalf("failed to create role: resp:%#v err:%s", resp, err)
}
if resp.Data["key"] == "" ||
resp.Data["key_type"] != "otp" ||
resp.Data["ip"] != "52.207.235.245" ||
resp.Data["username"] != "test" {
t.Fatalf("failed to create credential: resp:%#v", resp)
}
credsData["username"] = "random"
resp, err = b.HandleRequest(credsReq)
if err != nil || resp == nil || (resp != nil && !resp.IsError()) {
t.Fatalf("expected failure: resp:%#v err:%s", resp, err)
}
delete(roleData, "allowed_users")
resp, err = b.HandleRequest(roleReq)
if err != nil || (resp != nil && resp.IsError()) || resp != nil {
t.Fatalf("failed to create role: resp:%#v err:%s", resp, err)
}
credsData["username"] = "ubuntu"
resp, err = b.HandleRequest(credsReq)
if err != nil || (resp != nil && resp.IsError()) || resp == nil {
t.Fatalf("failed to create role: resp:%#v err:%s", resp, err)
}
if resp.Data["key"] == "" ||
resp.Data["key_type"] != "otp" ||
resp.Data["ip"] != "52.207.235.245" ||
resp.Data["username"] != "ubuntu" {
t.Fatalf("failed to create credential: resp:%#v", resp)
}
credsData["username"] = "test"
resp, err = b.HandleRequest(credsReq)
if err != nil || resp == nil || (resp != nil && !resp.IsError()) {
t.Fatalf("expected failure: resp:%#v err:%s", resp, err)
}
2016-05-30 07:12:43 +00:00
roleData["allowed_users"] = "*"
resp, err = b.HandleRequest(roleReq)
if err != nil || (resp != nil && resp.IsError()) || resp != nil {
t.Fatalf("failed to create role: resp:%#v err:%s", resp, err)
}
resp, err = b.HandleRequest(credsReq)
if err != nil || (resp != nil && resp.IsError()) || resp == nil {
t.Fatalf("failed to create role: resp:%#v err:%s", resp, err)
}
if resp.Data["key"] == "" ||
resp.Data["key_type"] != "otp" ||
resp.Data["ip"] != "52.207.235.245" ||
resp.Data["username"] != "test" {
t.Fatalf("failed to create credential: resp:%#v", resp)
}
}
func testingFactory(conf *logical.BackendConfig) (logical.Backend, error) {
2016-02-02 17:32:50 +00:00
_, err := vault.StartSSHHostTestServer()
if err != nil {
panic(fmt.Sprintf("error starting mock server:%s", err))
}
defaultLeaseTTLVal := 2 * time.Minute
maxLeaseTTLVal := 10 * time.Minute
return Factory(&logical.BackendConfig{
Logger: nil,
StorageView: &logical.InmemStorage{},
System: &logical.StaticSystemView{
DefaultLeaseTTLVal: defaultLeaseTTLVal,
MaxLeaseTTLVal: maxLeaseTTLVal,
},
})
}
2016-02-02 17:32:50 +00:00
func TestSSHBackend_Lookup(t *testing.T) {
testOTPRoleData := map[string]interface{}{
2015-08-03 20:18:14 +00:00
"key_type": testOTPKeyType,
"default_user": testUserName,
2015-08-13 15:46:55 +00:00
"cidr_list": testCIDRList,
2015-08-03 20:18:14 +00:00
}
2016-02-02 17:32:50 +00:00
testDynamicRoleData := map[string]interface{}{
2015-08-30 18:17:50 +00:00
"key_type": testDynamicKeyType,
"key": testKeyName,
"admin_user": testAdminUser,
"default_user": testAdminUser,
"cidr_list": testCIDRList,
2015-08-03 20:18:14 +00:00
}
2015-08-30 18:30:59 +00:00
data := map[string]interface{}{
"ip": testIP,
}
2015-09-03 22:43:53 +00:00
resp1 := []string(nil)
resp2 := []string{testOTPRoleName}
resp3 := []string{testDynamicRoleName, testOTPRoleName}
resp4 := []string{testDynamicRoleName}
2015-08-03 20:18:14 +00:00
logicaltest.Test(t, logicaltest.TestCase{
AcceptanceTest: true,
Factory: testingFactory,
2015-08-03 20:18:14 +00:00
Steps: []logicaltest.TestStep{
2015-09-03 22:43:53 +00:00
testLookupRead(t, data, resp1),
2015-08-30 18:30:59 +00:00
testRoleWrite(t, testOTPRoleName, testOTPRoleData),
2015-09-03 22:43:53 +00:00
testLookupRead(t, data, resp2),
2015-09-03 22:50:44 +00:00
testNamedKeysWrite(t, testKeyName, testSharedPrivateKey),
2015-08-30 18:30:59 +00:00
testRoleWrite(t, testDynamicRoleName, testDynamicRoleData),
2015-09-03 22:43:53 +00:00
testLookupRead(t, data, resp3),
2015-08-03 20:18:14 +00:00
testRoleDelete(t, testOTPRoleName),
2015-09-03 22:43:53 +00:00
testLookupRead(t, data, resp4),
2015-08-03 20:18:14 +00:00
testRoleDelete(t, testDynamicRoleName),
2015-09-03 22:43:53 +00:00
testLookupRead(t, data, resp1),
2015-08-03 20:18:14 +00:00
},
})
}
2015-08-03 15:22:00 +00:00
func TestSSHBackend_DynamicKeyCreate(t *testing.T) {
2016-02-02 17:32:50 +00:00
testDynamicRoleData := map[string]interface{}{
"key_type": testDynamicKeyType,
"key": testKeyName,
"admin_user": testAdminUser,
"default_user": testAdminUser,
"cidr_list": testCIDRList,
}
2015-09-03 22:11:04 +00:00
data := map[string]interface{}{
"username": testUserName,
"ip": testIP,
}
2015-07-10 15:56:14 +00:00
logicaltest.Test(t, logicaltest.TestCase{
AcceptanceTest: true,
Factory: testingFactory,
2015-07-10 15:56:14 +00:00
Steps: []logicaltest.TestStep{
2015-09-03 22:50:44 +00:00
testNamedKeysWrite(t, testKeyName, testSharedPrivateKey),
2015-09-03 22:11:04 +00:00
testRoleWrite(t, testDynamicRoleName, testDynamicRoleData),
testCredsWrite(t, testDynamicRoleName, data, false),
2015-07-10 15:56:14 +00:00
},
})
}
2015-07-31 17:24:23 +00:00
func TestSSHBackend_OTPRoleCrud(t *testing.T) {
2016-02-02 17:32:50 +00:00
testOTPRoleData := map[string]interface{}{
"key_type": testOTPKeyType,
"default_user": testUserName,
"cidr_list": testCIDRList,
}
respOTPRoleData := map[string]interface{}{
"key_type": testOTPKeyType,
"port": 22,
"default_user": testUserName,
"cidr_list": testCIDRList,
}
2015-07-31 19:17:40 +00:00
logicaltest.Test(t, logicaltest.TestCase{
AcceptanceTest: true,
Factory: testingFactory,
2015-07-31 19:17:40 +00:00
Steps: []logicaltest.TestStep{
2015-08-30 18:30:59 +00:00
testRoleWrite(t, testOTPRoleName, testOTPRoleData),
testRoleRead(t, testOTPRoleName, respOTPRoleData),
2015-07-31 19:17:40 +00:00
testRoleDelete(t, testOTPRoleName),
testRoleRead(t, testOTPRoleName, nil),
},
})
}
func TestSSHBackend_DynamicRoleCrud(t *testing.T) {
2016-02-02 17:32:50 +00:00
testDynamicRoleData := map[string]interface{}{
"key_type": testDynamicKeyType,
"key": testKeyName,
"admin_user": testAdminUser,
"default_user": testAdminUser,
"cidr_list": testCIDRList,
}
respDynamicRoleData := map[string]interface{}{
"cidr_list": testCIDRList,
"port": 22,
"install_script": DefaultPublicKeyInstallScript,
"key_bits": 1024,
"key": testKeyName,
"admin_user": testUserName,
"default_user": testUserName,
"key_type": testDynamicKeyType,
}
2015-07-31 17:24:23 +00:00
logicaltest.Test(t, logicaltest.TestCase{
AcceptanceTest: true,
Factory: testingFactory,
2015-07-31 17:24:23 +00:00
Steps: []logicaltest.TestStep{
2015-09-03 22:50:44 +00:00
testNamedKeysWrite(t, testKeyName, testSharedPrivateKey),
2015-08-30 18:30:59 +00:00
testRoleWrite(t, testDynamicRoleName, testDynamicRoleData),
testRoleRead(t, testDynamicRoleName, respDynamicRoleData),
2015-07-31 19:17:40 +00:00
testRoleDelete(t, testDynamicRoleName),
testRoleRead(t, testDynamicRoleName, nil),
2015-07-31 17:24:23 +00:00
},
})
}
2015-08-03 20:18:14 +00:00
func TestSSHBackend_NamedKeysCrud(t *testing.T) {
2015-08-03 15:22:00 +00:00
logicaltest.Test(t, logicaltest.TestCase{
AcceptanceTest: true,
Factory: testingFactory,
2015-08-03 15:22:00 +00:00
Steps: []logicaltest.TestStep{
2015-09-03 22:50:44 +00:00
testNamedKeysWrite(t, testKeyName, testSharedPrivateKey),
2015-08-03 20:18:14 +00:00
testNamedKeysDelete(t),
2015-08-03 15:22:00 +00:00
},
})
}
2015-08-03 23:04:07 +00:00
func TestSSHBackend_OTPCreate(t *testing.T) {
2016-02-02 17:32:50 +00:00
testOTPRoleData := map[string]interface{}{
"key_type": testOTPKeyType,
"default_user": testUserName,
"cidr_list": testCIDRList,
}
2015-09-03 22:11:04 +00:00
data := map[string]interface{}{
"username": testUserName,
"ip": testIP,
}
2015-08-03 23:04:07 +00:00
logicaltest.Test(t, logicaltest.TestCase{
AcceptanceTest: true,
Factory: testingFactory,
2015-08-03 23:04:07 +00:00
Steps: []logicaltest.TestStep{
2015-08-30 18:30:59 +00:00
testRoleWrite(t, testOTPRoleName, testOTPRoleData),
testCredsWrite(t, testOTPRoleName, data, false),
2015-08-03 23:04:07 +00:00
},
})
}
2015-08-18 23:48:50 +00:00
func TestSSHBackend_VerifyEcho(t *testing.T) {
verifyData := map[string]interface{}{
"otp": api.VerifyEchoRequest,
}
expectedData := map[string]interface{}{
"message": api.VerifyEchoResponse,
}
logicaltest.Test(t, logicaltest.TestCase{
AcceptanceTest: true,
Factory: testingFactory,
2015-08-18 23:48:50 +00:00
Steps: []logicaltest.TestStep{
testVerifyWrite(t, verifyData, expectedData),
},
})
}
2015-08-30 18:17:50 +00:00
func TestSSHBackend_ConfigZeroAddressCRUD(t *testing.T) {
2016-02-02 17:32:50 +00:00
testOTPRoleData := map[string]interface{}{
"key_type": testOTPKeyType,
"default_user": testUserName,
"cidr_list": testCIDRList,
}
testDynamicRoleData := map[string]interface{}{
"key_type": testDynamicKeyType,
"key": testKeyName,
"admin_user": testAdminUser,
"default_user": testAdminUser,
"cidr_list": testCIDRList,
}
req1 := map[string]interface{}{
2015-08-30 18:17:50 +00:00
"roles": testOTPRoleName,
}
resp1 := map[string]interface{}{
"roles": []string{testOTPRoleName},
}
req2 := map[string]interface{}{
2015-08-30 18:17:50 +00:00
"roles": fmt.Sprintf("%s,%s", testOTPRoleName, testDynamicRoleName),
}
resp2 := map[string]interface{}{
"roles": []string{testOTPRoleName, testDynamicRoleName},
}
resp3 := map[string]interface{}{
"roles": []string{},
2015-08-30 18:17:50 +00:00
}
logicaltest.Test(t, logicaltest.TestCase{
AcceptanceTest: true,
Factory: testingFactory,
2015-08-30 18:17:50 +00:00
Steps: []logicaltest.TestStep{
2015-08-30 18:30:59 +00:00
testRoleWrite(t, testOTPRoleName, testOTPRoleData),
testConfigZeroAddressWrite(t, req1),
testConfigZeroAddressRead(t, resp1),
2015-09-03 22:50:44 +00:00
testNamedKeysWrite(t, testKeyName, testSharedPrivateKey),
2015-08-30 18:30:59 +00:00
testRoleWrite(t, testDynamicRoleName, testDynamicRoleData),
testConfigZeroAddressWrite(t, req2),
testConfigZeroAddressRead(t, resp2),
2015-08-30 18:17:50 +00:00
testRoleDelete(t, testDynamicRoleName),
testConfigZeroAddressRead(t, resp1),
2015-08-30 18:17:50 +00:00
testRoleDelete(t, testOTPRoleName),
testConfigZeroAddressRead(t, resp3),
2015-08-30 18:17:50 +00:00
testConfigZeroAddressDelete(t),
},
})
}
func TestSSHBackend_CredsForZeroAddressRoles(t *testing.T) {
dynamicRoleData := map[string]interface{}{
"key_type": testDynamicKeyType,
"key": testKeyName,
"admin_user": testAdminUser,
"default_user": testAdminUser,
}
otpRoleData := map[string]interface{}{
"key_type": testOTPKeyType,
"default_user": testUserName,
}
data := map[string]interface{}{
"username": testUserName,
"ip": testIP,
}
req1 := map[string]interface{}{
"roles": testOTPRoleName,
}
req2 := map[string]interface{}{
"roles": fmt.Sprintf("%s,%s", testOTPRoleName, testDynamicRoleName),
}
2015-09-03 22:11:04 +00:00
logicaltest.Test(t, logicaltest.TestCase{
AcceptanceTest: true,
Factory: testingFactory,
2015-09-03 22:11:04 +00:00
Steps: []logicaltest.TestStep{
testRoleWrite(t, testOTPRoleName, otpRoleData),
testCredsWrite(t, testOTPRoleName, data, true),
testConfigZeroAddressWrite(t, req1),
testCredsWrite(t, testOTPRoleName, data, false),
testNamedKeysWrite(t, testKeyName, testSharedPrivateKey),
testRoleWrite(t, testDynamicRoleName, dynamicRoleData),
testCredsWrite(t, testDynamicRoleName, data, true),
testConfigZeroAddressWrite(t, req2),
testCredsWrite(t, testDynamicRoleName, data, false),
testConfigZeroAddressDelete(t),
testCredsWrite(t, testOTPRoleName, data, true),
testCredsWrite(t, testDynamicRoleName, data, true),
2015-09-03 22:11:04 +00:00
},
})
}
2015-08-30 18:17:50 +00:00
func testConfigZeroAddressDelete(t *testing.T) logicaltest.TestStep {
return logicaltest.TestStep{
Operation: logical.DeleteOperation,
Path: "config/zeroaddress",
}
}
2015-09-03 22:50:44 +00:00
func testConfigZeroAddressWrite(t *testing.T, data map[string]interface{}) logicaltest.TestStep {
2015-08-30 18:17:50 +00:00
return logicaltest.TestStep{
2016-01-07 15:30:47 +00:00
Operation: logical.UpdateOperation,
2015-08-30 18:17:50 +00:00
Path: "config/zeroaddress",
2015-09-03 22:50:44 +00:00
Data: data,
2015-08-30 18:17:50 +00:00
}
}
func testConfigZeroAddressRead(t *testing.T, expected map[string]interface{}) logicaltest.TestStep {
return logicaltest.TestStep{
Operation: logical.ReadOperation,
Path: "config/zeroaddress",
Check: func(resp *logical.Response) error {
var d zeroAddressRoles
if err := mapstructure.Decode(resp.Data, &d); err != nil {
return err
}
var ex zeroAddressRoles
if err := mapstructure.Decode(expected, &ex); err != nil {
return err
}
if !reflect.DeepEqual(d, ex) {
return fmt.Errorf("Response mismatch:\nActual:%#v\nExpected:%#v", d, ex)
}
return nil
},
}
}
2015-09-03 22:50:44 +00:00
func testVerifyWrite(t *testing.T, data map[string]interface{}, expected map[string]interface{}) logicaltest.TestStep {
2015-08-18 23:48:50 +00:00
return logicaltest.TestStep{
2016-01-07 15:30:47 +00:00
Operation: logical.UpdateOperation,
2015-08-18 23:48:50 +00:00
Path: fmt.Sprintf("verify"),
2015-09-03 22:50:44 +00:00
Data: data,
2015-08-18 23:48:50 +00:00
Check: func(resp *logical.Response) error {
var ac api.SSHVerifyResponse
if err := mapstructure.Decode(resp.Data, &ac); err != nil {
return err
}
var ex api.SSHVerifyResponse
if err := mapstructure.Decode(expected, &ex); err != nil {
return err
}
2015-08-30 18:17:50 +00:00
if !reflect.DeepEqual(ac, ex) {
2015-08-18 23:48:50 +00:00
return fmt.Errorf("Invalid response")
}
return nil
},
}
}
2015-09-03 22:50:44 +00:00
func testNamedKeysWrite(t *testing.T, name, key string) logicaltest.TestStep {
2015-08-03 20:18:14 +00:00
return logicaltest.TestStep{
2016-01-07 15:30:47 +00:00
Operation: logical.UpdateOperation,
2015-09-03 22:50:44 +00:00
Path: fmt.Sprintf("keys/%s", name),
2015-08-03 20:18:14 +00:00
Data: map[string]interface{}{
2015-09-03 22:50:44 +00:00
"key": key,
2015-08-03 20:18:14 +00:00
},
}
}
func testNamedKeysDelete(t *testing.T) logicaltest.TestStep {
return logicaltest.TestStep{
Operation: logical.DeleteOperation,
Path: fmt.Sprintf("keys/%s", testKeyName),
}
}
2015-09-03 22:43:53 +00:00
func testLookupRead(t *testing.T, data map[string]interface{}, expected []string) logicaltest.TestStep {
2015-08-03 15:22:00 +00:00
return logicaltest.TestStep{
2016-01-07 15:30:47 +00:00
Operation: logical.UpdateOperation,
2015-08-03 15:22:00 +00:00
Path: "lookup",
Data: data,
Check: func(resp *logical.Response) error {
if resp.Data == nil || resp.Data["roles"] == nil {
return fmt.Errorf("Missing roles information")
}
2015-09-03 22:43:53 +00:00
if !reflect.DeepEqual(resp.Data["roles"].([]string), expected) {
return fmt.Errorf("Invalid response: \nactual:%#v\nexpected:%#v", resp.Data["roles"].([]string), expected)
2015-08-03 15:22:00 +00:00
}
return nil
},
}
}
2015-07-31 19:17:40 +00:00
func testRoleWrite(t *testing.T, name string, data map[string]interface{}) logicaltest.TestStep {
2015-07-31 17:24:23 +00:00
return logicaltest.TestStep{
2016-01-07 15:30:47 +00:00
Operation: logical.UpdateOperation,
2015-07-31 19:17:40 +00:00
Path: "roles/" + name,
2015-07-31 17:24:23 +00:00
Data: data,
}
}
func testRoleRead(t *testing.T, roleName string, expected map[string]interface{}) logicaltest.TestStep {
2015-07-31 17:24:23 +00:00
return logicaltest.TestStep{
Operation: logical.ReadOperation,
Path: "roles/" + roleName,
2015-07-31 17:24:23 +00:00
Check: func(resp *logical.Response) error {
if resp == nil {
if expected == nil {
2015-07-31 17:24:23 +00:00
return nil
}
return fmt.Errorf("bad: %#v", resp)
}
2015-07-31 19:17:40 +00:00
var d sshRole
2015-07-31 17:24:23 +00:00
if err := mapstructure.Decode(resp.Data, &d); err != nil {
2015-07-31 19:17:40 +00:00
return fmt.Errorf("error decoding response:%s", err)
2015-07-31 17:24:23 +00:00
}
if roleName == testOTPRoleName {
if d.KeyType != expected["key_type"] || d.DefaultUser != expected["default_user"] || d.CIDRList != expected["cidr_list"] {
2015-07-31 19:17:40 +00:00
return fmt.Errorf("data mismatch. bad: %#v", resp)
}
} else {
if d.AdminUser != expected["admin_user"] || d.CIDRList != expected["cidr_list"] || d.KeyName != expected["key"] || d.KeyType != expected["key_type"] {
2015-07-31 19:17:40 +00:00
return fmt.Errorf("data mismatch. bad: %#v", resp)
}
2015-07-31 17:24:23 +00:00
}
return nil
},
}
}
2015-07-31 19:17:40 +00:00
func testRoleDelete(t *testing.T, name string) logicaltest.TestStep {
2015-07-31 17:24:23 +00:00
return logicaltest.TestStep{
Operation: logical.DeleteOperation,
2015-07-31 19:17:40 +00:00
Path: "roles/" + name,
2015-07-31 17:24:23 +00:00
}
}
func testCredsWrite(t *testing.T, roleName string, data map[string]interface{}, expectError bool) logicaltest.TestStep {
2015-07-10 15:56:14 +00:00
return logicaltest.TestStep{
2016-01-07 15:30:47 +00:00
Operation: logical.UpdateOperation,
2015-09-03 22:11:04 +00:00
Path: fmt.Sprintf("creds/%s", roleName),
2015-09-03 22:50:44 +00:00
Data: data,
ErrorOk: true,
2015-07-10 15:56:14 +00:00
Check: func(resp *logical.Response) error {
if resp == nil {
return fmt.Errorf("response is nil")
}
if resp.Data == nil {
return fmt.Errorf("data is nil")
}
if expectError {
var e struct {
Error string `mapstructure:"error"`
}
if err := mapstructure.Decode(resp.Data, &e); err != nil {
return err
}
if len(e.Error) == 0 {
return fmt.Errorf("expected error, but write succeeded.")
}
return nil
}
2015-09-03 22:11:04 +00:00
if roleName == testDynamicRoleName {
var d struct {
Key string `mapstructure:"key"`
}
if err := mapstructure.Decode(resp.Data, &d); err != nil {
return err
}
if d.Key == "" {
return fmt.Errorf("Generated key is an empty string")
}
// Checking only for a parsable key
_, err := ssh.ParsePrivateKey([]byte(d.Key))
if err != nil {
return fmt.Errorf("Generated key is invalid")
}
} else {
if resp.Data["key_type"] != KeyTypeOTP {
return fmt.Errorf("Incorrect key_type")
}
if resp.Data["key"] == nil {
return fmt.Errorf("Invalid key")
}
2015-07-10 15:56:14 +00:00
}
return nil
},
}
}