/// <summary> /// Performs CredSSP authentication. /// </summary> /// <param name="x509Cert">The certificate used by TLS.</param> /// <exception cref="IOException">Raised when attempting to read from/write to the remote connection which /// has been closed</exception> /// <exception cref="EndOfStreamException">Raised when the username or password doesn't match or authentication /// fails</exception> public void Authenticate(X509Certificate x509Cert, string principal) { if (principal == null) { throw new ArgumentNullException("principal"); } // Authenticated already, do nothing if (isAuthenticated) { return; } credential = new CertificateCredential(x509Cert); byte[] receivedBuffer = new byte[MaxBufferSize]; int bytesReceived = 0; // Dispose the context as it may be timed out if (context != null) { context.Dispose(); } context = new SspiServerSecurityContext( SecurityPackageType.CredSsp, credential, principal, attribute, SecurityTargetDataRepresentation.SecurityNativeDrep); // Get first token byte[] token = context.Token; // Credssp handshake while (context.NeedContinueProcessing) { // Get handshake resopnse bytesReceived = serverStream.Read(receivedBuffer, 0, receivedBuffer.Length); // The remote connection has been closed if (bytesReceived == 0) { throw new EndOfStreamException("Authentication failed: remote connection has been closed."); } byte[] inToken = new byte[bytesReceived]; Array.Copy(receivedBuffer, inToken, bytesReceived); // Get next token from response context.Accept(inToken); token = context.Token; if (token != null) { // Send handshake request serverStream.Write(token, 0, token.Length); } } isAuthenticated = true; }
/// <summary> /// dispose the gssapi /// </summary> internal void DisposeGssApi() { if (this.GssApi == null) { return; } SspiServerSecurityContext sspiSecurityContext = this.GssApi as SspiServerSecurityContext; if (sspiSecurityContext != null) { sspiSecurityContext.Dispose(); } }