Files
mRemoteNG/mRemoteV1/Security/Security.Impersonator.vb
Andreas Rehm e08c88db5f Refactoring and even more translations
* removed unneeded Imports
* renamed namespace to mRemoteNG
* changed Logfile path to %USERPROFILE%\AppData\Local\mRemoteNG\mRemoteNG.log
* fixed mRemoteNG.exe.config
* added more ignores to .gitignore
2010-05-16 19:30:27 +02:00

108 lines
5.1 KiB
VB.net

Imports System.Runtime.InteropServices
Imports System.Security.Principal
Imports System.Security.Permissions
Imports mRemoteNG.App.Runtime
<Assembly: SecurityPermissionAttribute(SecurityAction.RequestMinimum, UnmanagedCode:=True), _
Assembly: PermissionSetAttribute(SecurityAction.RequestMinimum, Name:="FullTrust")>
Namespace Security
Public Class Impersonator
#Region "Logon API"
Private Const LOGON32_PROVIDER_DEFAULT As Integer = 0
Private Const LOGON32_LOGON_INTERACTIVE As Integer = 2 ' This parameter causes LogonUser to create a primary token.
Private Const SecurityImpersonation As Integer = 2
Private Declare Auto Function LogonUser Lib "advapi32.dll" (ByVal lpszUsername As [String], _
ByVal lpszDomain As [String], ByVal lpszPassword As [String], _
ByVal dwLogonType As Integer, ByVal dwLogonProvider As Integer, _
ByRef phToken As IntPtr) As Integer
Private Const FORMAT_MESSAGE_ALLOCATE_BUFFER As Integer = &H100
Private Const FORMAT_MESSAGE_IGNORE_INSERTS As Integer = &H200
Private Const FORMAT_MESSAGE_FROM_SYSTEM As Integer = &H1000
<DllImport("kernel32.dll")> _
Private Shared Function FormatMessage(ByVal dwFlags As Integer, ByRef lpSource As IntPtr, _
ByVal dwMessageId As Integer, ByVal dwLanguageId As Integer, ByRef lpBuffer As [String], _
ByVal nSize As Integer, ByRef Arguments As IntPtr) As Integer
End Function
Private Declare Auto Function CloseHandle Lib "kernel32.dll" (ByVal handle As IntPtr) As Boolean
Private Declare Auto Function DuplicateToken Lib "advapi32.dll" (ByVal ExistingTokenHandle As IntPtr, _
ByVal SECURITY_IMPERSONATION_LEVEL As Integer, _
ByRef DuplicateTokenHandle As IntPtr) As Integer
#End Region
Private tokenHandle As New IntPtr(0)
Private dupeTokenHandle As New IntPtr(0)
Private impersonatedUser As WindowsImpersonationContext = Nothing
' GetErrorMessage formats and returns an error message corresponding to the input errorCode.
Private Function GetErrorMessage(ByVal errorCode As Integer) As String
Dim messageSize As Integer = 255
Dim lpMsgBuf As String = ""
Dim dwFlags As Integer = FORMAT_MESSAGE_ALLOCATE_BUFFER Or FORMAT_MESSAGE_FROM_SYSTEM Or FORMAT_MESSAGE_IGNORE_INSERTS
Dim ptrlpSource As IntPtr = IntPtr.Zero
Dim prtArguments As IntPtr = IntPtr.Zero
Dim retVal As Integer = FormatMessage(dwFlags, ptrlpSource, errorCode, 0, lpMsgBuf, messageSize, prtArguments)
Return lpMsgBuf.Trim(New Char() {CChar(vbCr), CChar(vbLf)})
End Function
<PermissionSetAttribute(SecurityAction.Demand, Name:="FullTrust")> _
Public Sub StartImpersonation(ByVal DomainName As String, ByVal UserName As String, ByVal Password As String)
Try
If Not (impersonatedUser Is Nothing) Then Throw New Exception("Already impersonating a user.")
tokenHandle = IntPtr.Zero
dupeTokenHandle = IntPtr.Zero
Dim returnValue As Integer = LogonUser(UserName, DomainName, Password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, tokenHandle)
If 0 = returnValue Then
Dim errCode As Integer = Marshal.GetLastWin32Error()
Dim errMsg As String = "LogonUser failed with error code: " + errCode.ToString() + "(" + GetErrorMessage(errCode) + ")"
Dim exLogon As Exception = New System.Exception(errMsg)
Throw exLogon
End If
returnValue = DuplicateToken(tokenHandle, SecurityImpersonation, dupeTokenHandle)
If 0 = returnValue Then
CloseHandle(tokenHandle)
Throw New System.Exception("Error trying to duplicate handle.")
End If
' The token that is passed to the following constructor must
' be a primary token in order to use it for impersonation.
Dim newId As New WindowsIdentity(dupeTokenHandle)
impersonatedUser = newId.Impersonate()
Catch ex As Exception
mC.AddMessage(Messages.MessageClass.WarningMsg, "Starting Impersonation failed (Sessions feature will not work)" & vbNewLine & ex.Message, True)
End Try
End Sub
<PermissionSetAttribute(SecurityAction.Demand, Name:="FullTrust")> _
Public Sub StopImpersonation()
If impersonatedUser Is Nothing Then Exit Sub
Try
impersonatedUser.Undo() ' Stop impersonating the user.
Catch ex As Exception
mC.AddMessage(Messages.MessageClass.WarningMsg, "Stopping Impersonation failed" & vbNewLine & ex.Message, True)
Throw ex
Finally
If Not System.IntPtr.op_Equality(tokenHandle, IntPtr.Zero) Then CloseHandle(tokenHandle)
If Not System.IntPtr.op_Equality(dupeTokenHandle, IntPtr.Zero) Then CloseHandle(dupeTokenHandle)
impersonatedUser = Nothing
End Try
End Sub
End Class
End Namespace