コード例 #1
0
        public async Task DeleteMount()
        {
            string key  = _uniqueKeys.GetKey("SYSM");
            string desc = "Test Mount DB: " + key + "KeyValue V2";

            VaultSysMountConfig config1 = new VaultSysMountConfig {
                DefaultLeaseTTL = "6556"
            };

            Assert.True(await _vaultSystemBackend.SysMountCreate(key, desc, EnumSecretBackendTypes.KeyValueV2, config1), "A10:");

            // Ensure it was created.
            VaultSysMountConfig config2 = await _vaultSystemBackend.SysMountReadConfig(key);

            Assert.AreEqual(config1.DefaultLeaseTTL, config2.DefaultLeaseTTL, "A20: Default Lease TTL's are not the same.");

            // Delete it.
            Assert.True(await _vaultSystemBackend.SysMountDelete(key), "A30:  Deletion of mount did not complete Successfully.");

            // Make sure it is gone.
            Assert.IsFalse(await _vaultSystemBackend.SysMountExists(key), "A40 - SysMount still exists");
            VaultInvalidDataException e = Assert.ThrowsAsync <VaultInvalidDataException>(async() => await _vaultSystemBackend.SysMountReadConfig(key), "A50: Error trying to retrieve Mount");
            //VaultSysMountConfig config3 = await _vaultSystemBackend.SysMountReadConfig(key);
            //Assert.IsNull(config3, "A50:  SysMount Not Deleted");
        }
コード例 #2
0
        public async Task LoginWithInvalidCredentials_GeneratesExpectedError()
        {
            string  roleName_A = _uniqueKeys.GetKey("FailLogin");
            AppRole roleA      = new AppRole(roleName_A);

            Assert.True(await _appRoleAuthEngine.SaveRole(roleA), "A1: Saving the role failed.");

            // Read the role ID back.
            string roleID = await _appRoleAuthEngine.ReadRoleID(roleA.Name);

            // Now create the a secret
            AppRoleSecret secret_A = await _appRoleAuthEngine.GenerateSecretID(roleA.Name);


            // Now attempt to login
            VaultInvalidDataException e = Assert.ThrowsAsync <VaultInvalidDataException> (async() => await _appRoleAuthEngine.Login(roleID, ""),
                                                                                          "A1: Expected Login with bad Secret to throw the [VaultInvalidDataException] but it did not.");

            Assert.AreEqual(EnumVaultExceptionCodes.LoginSecretID_NotFound, e.SpecificErrorCode, "A2: Expected to see the specificErrorCode field set to [LoginSecretID_NotFound] but it was set to " + e.SpecificErrorCode);

            // Now try with invalid Role ID.
            VaultInvalidDataException e2 = Assert.ThrowsAsync <VaultInvalidDataException>(async() => await _appRoleAuthEngine.Login("", secret_A.ID),
                                                                                          "A1: Expected Login with bad RoleID to throw the [VaultInvalidDataException] but it did not.");

            Assert.AreEqual(EnumVaultExceptionCodes.LoginRoleID_NotFound, e2.SpecificErrorCode, "A2: Expected to see the specificErrorCode field set to [LoginRoleID_NotFound] but it was set to " + e2.SpecificErrorCode);
        }
コード例 #3
0
        public async Task CreateMountBackend_Fails_IfAlreadyExists()
        {
            string mountName = _uniqueKeys.GetKey("DupMnt");

            Assert.True(await _vaultSystemBackend.SysMountCreate(mountName, "test", EnumSecretBackendTypes.KeyValueV2), "Unable to create Mount with key name: {0}", mountName);
            VaultInvalidDataException e = Assert.ThrowsAsync <VaultInvalidDataException>(async() => await _vaultSystemBackend.SysMountCreate(mountName, "test", EnumSecretBackendTypes.KeyValueV2), "Unable to create Mount with key name: {0}", mountName);

            Assert.AreEqual(EnumVaultExceptionCodes.BackendMountAlreadyExists, e.SpecificErrorCode, "A2: Expected the exception Specific Code to be BackendMountAlreadyExists, but it was set to: " + e.SpecificErrorCode);
        }
コード例 #4
0
ファイル: AppRoleAuthEngine.cs プロジェクト: SlugEnt/VaultAPI
        /// <summary>
        /// Logs the given secretID into the Application Role identified by RoleID.  RoleID is always required; if bind_secret_id is enabled (the default) on the AppRole, secretID is required also.
        /// Returns a populated Token object if successfull.  Returns Null if it failed due to invalid Role or Secret ID
        /// </summary>
        /// <param name="roleID">Required:  The RoleID value that you wish to login to.</param>
        /// <param name="secretID">Optional: The secretID to use to login to the role with.</param>
        /// <returns>Token object that was created, that can be used to access the Vault with.  The parent token has also been set to this same token.</returns>
        /// TODO - Change the return type.
        public async Task <Token> Login(string roleID, string secretID)
        {
            string path = MountPointPath + "login";

            // Setup roleID and secret ID Parameters
            Dictionary <string, string> contentParams = new Dictionary <string, string>()
            {
                { "role_id", roleID },
                { "secret_id", secretID }
            };

            try {
                VaultDataResponseObjectB vdro = await ParentVault._httpConnector.PostAsync_B(path, "Login", contentParams);

                // Now convert the JSON returned by Vault into a LoginResponse object and then get the Client ID token value out of it.
                LoginResponse loginResponse = await vdro.GetDotNetObject <LoginResponse> ("auth");

                //TODO - CLeanup
                //string js = vdro.GetResponsePackageFieldAsJSON ("auth");
                //LoginResponse loginResponse = VaultUtilityFX.ConvertJSON<LoginResponse> (js);

                // We need to set the token and then refresh it.
                ParentVault.TokenID = loginResponse.ClientToken;
                await ParentVault.RefreshActiveToken();

                return(ParentVault.Token);
            }


            catch (VaultInvalidDataException e) {
                // This means the secret ID is incorrect.
                if (e.Message.Contains("missing secret_id"))
                {
                    VaultInvalidDataException newEx = new VaultInvalidDataException(
                        "The secret ID supplied is either not a valid Secret ID or it is not associated with the RoleID supplied.  The secretID must be valid and it must be associated with the provided RoleID.",
                        e);
                    newEx.SpecificErrorCode = EnumVaultExceptionCodes.LoginSecretID_NotFound;
                    throw newEx;
                }

                // RoleID is incorrect.
                else if (e.Message.Contains("missing role_id"))
                {
                    VaultInvalidDataException newEx = new VaultInvalidDataException("The RoleID supplied is invalid.  The RoleID must exist in the Vault.", e);
                    newEx.SpecificErrorCode = EnumVaultExceptionCodes.LoginRoleID_NotFound;
                    throw newEx;
                }

                throw e;
            }
        }
コード例 #5
0
ファイル: KV2SecretEngine.cs プロジェクト: SlugEnt/VaultAPI
        /// <summary>
        ///     Saves the provided K2Secret object.  You must specify a save option and optionally what the current version of
        ///     the secret is.  The KV2Secret object's version # will be updated on success with what the new version of the
        ///     secret it.
        ///     If the CAS setting is set on the backend then the following errors may be returned:
        ///     <para></para>
        ///     <para>Commonly Throws the Following Errors:</para>
        ///     <para>
        ///         [VaultForbiddenException] - Errors with access.  The SpecifiedErrorCode field will be set to
        ///         EnumVaultExceptionCodes.PermissionDenied if token does not have
        ///         appropriate permissions to access the path.
        ///     </para>
        ///     <para>   [VaultInvalidDataException]</para>
        ///     <para>
        ///         [SpecificErrorCode] = EnumVaultExceptionCodes.CheckAndSetMissing - You specified an invalid casSaveOption
        ///         (AlwaysAllow is not valid for backend with CAS Set)
        ///         or the currentVersion parameter was invalid.
        ///     </para>
        ///     <para>
        ///         [SpecificErrorCode] = EnumVaultExceptionCodes.CAS_SecretExistsAlready - You set the casSaveOption to
        ///         only allow save to succeed if the secret does not yet exist.
        ///     </para>
        ///     <para>
        ///         [SpecificErrorCode] = EnumVaultExceptionCodes.CAS_VersionMissing - The version you specified was
        ///         invalid.  It must be equal to the current version number of the secret.
        ///     </para>
        /// </summary>
        /// <param name="secret">
        ///     IKV2Secret object to be saved.  This must contain minimally the Name and the Path of the secret
        ///     and one or more optional attributes.
        /// </param>
        /// <param name="casSaveOption">
        ///     This must be set to the CAS option you desired:
        ///     - OnlyIfKeyDoesNotExist = 0,
        ///     - OnlyOnExistingVersionMatch = 1,
        ///     - AlwaysAllow = 2  - Set to this value if the backend is not CAS enabled.  If CAS is enabled then this option will
        ///     result in an error.
        /// </param>
        /// <param name="currentVersion">
        ///     What the current version of the secret is.  Required if the backend is in CAS mode
        ///     (Default mode).
        /// </param>
        /// <returns></returns>
        //public async Task<bool> SaveSecret(IKV2Secret secret, KV2EnumSecretSaveOptions casSaveOption,
        //    int currentVersion = 0)
        public async Task <bool> SaveSecret <T>(T secret, KV2EnumSecretSaveOptions casSaveOption,
                                                int currentVersion = 0) where T : KV2SecretBase <T>
        {
            string path = MountPointPath + "data/" + secret.FullPath;


            Dictionary <string, object> reqData = new Dictionary <string, object>();
            Dictionary <string, string> options = new Dictionary <string, string>();

            // Set CAS depending on option coming from caller.
            switch (casSaveOption)
            {
            case KV2EnumSecretSaveOptions.OnlyIfKeyDoesNotExist:
                options.Add("cas", "0");
                break;

            case KV2EnumSecretSaveOptions.OnlyOnExistingVersionMatch:
                if (currentVersion != 0)
                {
                    options.Add("cas", currentVersion.ToString());
                }
                else
                {
                    throw new ArgumentException(
                              "The option OnlyOnExistingVersionMatch was chosen, but the currentVersion parameter was not set.  It must be set to the value of the current version of the key as stored in Vault.");
                }

                break;
            }


            // CAS - Check and Set needs to be passed in from caller.
            reqData.Add("options", options);
            reqData.Add("data", secret);

            try {
                VaultDataResponseObjectB vdro = await ParentVault._httpConnector.PostAsync_B(path, "SaveSecret", reqData);

                if (vdro.Success)
                {
                    KV2VaultReadSaveReturnObj obj = await vdro.GetDotNetObject <KV2VaultReadSaveReturnObj>();

                    if (obj != null)
                    {
                        secret.Version      = obj.Version;
                        secret.CreatedTime  = obj.CreatedTime;
                        secret.DeletionTime = (DateTimeOffset)obj.DeletionTime;
                        secret.IsDestroyed  = obj.Destroyed;
                    }

                    return(true);
                }

                return(false);
            }
            catch (VaultInvalidDataException e) {
                if (e.Message.Contains("check-and-set parameter required for this call"))
                {
                    VaultInvalidDataException eNew = new VaultInvalidDataException(Constants.Error_CAS_Set + " | Original Error message was: " + e.Message);
                    eNew.SpecificErrorCode = EnumVaultExceptionCodes.CheckAndSetMissing;
                    throw eNew;
                }

                // Check for Version errors:

                if (e.Message.Contains("did not match the current version"))
                {
                    // If user requested that the save happen only if the key does not already exist then return customized error message.
                    if (casSaveOption == KV2EnumSecretSaveOptions.OnlyIfKeyDoesNotExist)
                    {
                        VaultInvalidDataException eNew = new VaultInvalidDataException(
                            Constants.Error_CAS_SecretAlreadyExists + " | Original Error message was: " + e.Message);
                        eNew.SpecificErrorCode = EnumVaultExceptionCodes.CAS_SecretExistsAlready;
                        throw eNew;
                    }

                    // Customize the version discrepancy message
                    else
                    {
                        VaultInvalidDataException eNew = new VaultInvalidDataException(
                            Constants.Error_CAS_InvalidVersion + " Version specified was: " + currentVersion + " | Original Error message was: " + e.Message);
                        eNew.SpecificErrorCode = EnumVaultExceptionCodes.CAS_VersionMissing;
                        throw eNew;
                    }
                }

                throw new VaultInvalidDataException(e.Message);
            }
            catch (VaultForbiddenException e) {
                if (e.Message.Contains("* permission denied"))
                {
                    e.SpecificErrorCode = EnumVaultExceptionCodes.PermissionDenied;
                }

                throw e;
            }
            catch (Exception e) { throw e; }
        }