/// <summary> /// Saves the given Network Credential into Windows Credential store /// </summary> /// <param name="target">Name of the application/Url where the credential is used for</param> /// <param name="credential">Credential to store</param> /// <returns>True:Success, throw if failed</returns> public static bool SaveCredentials(string target, NetworkCredential credential) { // Go ahead with what we have are stuff it into the CredMan structures. var cred = new Credential(credential) { TargetName = target, Persist = NativeCode.Persistance.Entrprise }; NativeCode.NativeCredential ncred = cred.GetNativeCredential(); // Write the info into the CredMan storage. if (NativeCode.CredWrite(ref ncred, 0)) { return(true); } int lastError = Marshal.GetLastWin32Error(); string message = String.Format("'CredWrite' call throw an error (Error code: {0})", lastError); throw new Win32Exception(lastError, message); }
/// <summary> /// Saves the given Network Credential into Windows Credential store /// </summary> /// <param name="Target">Name of the application/Url where the credential is used for</param> /// <param name="credential">Credential to store</param> /// <returns>True:Success, False:Failure</returns> public static bool SaveCredentials(string Target, NetworkCredential credential) { // Go ahead with what we have are stuff it into the CredMan structures. Credential cred = new Credential(credential); cred.TargetName = Target; cred.Persist = NativeCode.Persistance.Entrprise; NativeCode.NativeCredential ncred = cred.GetNativeCredential(); // Write the info into the CredMan storage. bool written = NativeCode.CredWrite(ref ncred, 0); int lastError = Marshal.GetLastWin32Error(); if (written) { return(true); } else { string message = string.Format("CredWrite failed with the error code {0}.", lastError); throw new Exception(message); } }
public bool SaveCredential(bool AllowBlankPassword = false) { IntPtr buffer = default(IntPtr); GCHandle pinned = default(GCHandle); if (!String.IsNullOrEmpty(this.Comment) && Encoding.Unicode.GetBytes(this.Comment).Length > 256) { throw new ArgumentException("Comment can't be more than 256 bytes long", "Comment"); } if (String.IsNullOrEmpty(this.TargetName)) { throw new ArgumentNullException("TargetName", "TargetName can't be Null or Empty"); } else if (this.TargetName.Length > 32767) { throw new ArgumentNullException("TargetName can't be more than 32kB", "TargetName"); } if (!AllowBlankPassword && String.IsNullOrEmpty(this.CredentialBlob)) { throw new ArgumentNullException("CredentialBlob", "CredentialBlob can't be Null or Empty"); } NativeCode.NativeCredential ncred = new NativeCode.NativeCredential { Comment = this.Comment, TargetAlias = null, Type = (UInt32)this.Type, Persist = (UInt32)this.Persistance, UserName = this.UserName, TargetName = this.TargetName, CredentialBlobSize = (UInt32)Encoding.Unicode.GetBytes(this.CredentialBlob).Length }; if (ncred.CredentialBlobSize > MaxCredentialBlobSize) { throw new ArgumentException($"Credential can't be more than {MaxCredentialBlobSize} bytes long", "CredentialBlob"); } ncred.CredentialBlob = Marshal.StringToCoTaskMemUni(this.CredentialBlob); if (this.LastWritten != DateTime.MinValue) { var fileTime = this.LastWritten.ToFileTimeUtc(); ncred.LastWritten.dwLowDateTime = (int)(fileTime & 0xFFFFFFFFL); ncred.LastWritten.dwHighDateTime = (int)((fileTime >> 32) & 0xFFFFFFFFL); } NativeCode.NativeCredentialAttribute[] nativeAttribs = null; try { if (Attributes == null || Attributes.Count == 0) { ncred.AttributeCount = 0; ncred.Attributes = IntPtr.Zero; } else { if (Attributes.Count > 64) { throw new ArgumentException("Credentials can't have more than 64 Attributes!!"); } ncred.AttributeCount = (UInt32)Attributes.Count; nativeAttribs = new NativeCode.NativeCredentialAttribute[Attributes.Count]; var attribSize = Marshal.SizeOf(typeof(NativeCode.NativeCredentialAttribute)); byte[] rawData = new byte[Attributes.Count * attribSize]; buffer = Marshal.AllocHGlobal(attribSize); var formatter = new BinaryFormatter(); var i = 0; foreach (var a in Attributes) { if (a.Key.Length > 256) { throw new ArgumentException($"Attribute names can't be more than 256 bytes long. Error with key:{a.Key}", a.Key); } if (a.Value == null) { throw new ArgumentNullException(a.Key, $"Attribute value cant'be null. Error with key:{a.Key}"); } if (!a.Value.GetType().IsSerializable) { throw new ArgumentException($"Attribute value must be Serializable. Error with key:{a.Key}", a.Key); } using var stream = new MemoryStream(); formatter.Serialize(stream, a.Value); var value = stream.ToArray(); if (value.Length > 256) { throw new ArgumentException($"Attribute values can't be more than 256 bytes long after serialization. Error with Value for key:{a.Key}", a.Key); } var attrib = new NativeCode.NativeCredentialAttribute { Keyword = a.Key, ValueSize = (UInt32)value.Length }; attrib.Value = Marshal.AllocHGlobal(value.Length); Marshal.Copy(value, 0, attrib.Value, value.Length); nativeAttribs[i] = attrib; Marshal.StructureToPtr(attrib, buffer, false); Marshal.Copy(buffer, rawData, i * attribSize, attribSize); i++; } pinned = GCHandle.Alloc(rawData, GCHandleType.Pinned); ncred.Attributes = pinned.AddrOfPinnedObject(); } // Write the info into the CredMan storage. if (NativeCode.CredWrite(ref ncred, 0)) { return(true); } else { int lastError = Marshal.GetLastWin32Error(); throw new CredentialAPIException($"Unable to Save Credential", "CredWrite", lastError); } } finally { if (ncred.CredentialBlob != default(IntPtr)) { Marshal.FreeCoTaskMem(ncred.CredentialBlob); } if (nativeAttribs != null) { foreach (var a in nativeAttribs) { if (a.Value != default(IntPtr)) { Marshal.FreeHGlobal(a.Value); } } if (pinned.IsAllocated) { pinned.Free(); } if (buffer != default(IntPtr)) { Marshal.FreeHGlobal(buffer); } } } }