krb5 commit: Use file mapping to marshall message data

Benjamin Kaduk kaduk at MIT.EDU
Mon Aug 27 11:52:08 EDT 2012


https://github.com/krb5/krb5/commit/e2ad5d74adbf3edc8a7026cad8283c0077377e81
commit e2ad5d74adbf3edc8a7026cad8283c0077377e81
Author: Kevin Wasserman <kevin.wasserman at painless-security.com>
Date:   Thu Jun 21 15:30:24 2012 -0400

    Use file mapping to marshall message data
    
    GlobalAlloc() is no longer supported for this purpose.
    Also split out leash message marshalling code into a separate function
    acquire_tkt_send_message_leash and improve string copy safety.
    
    Signed-off-by: Kevin Wasserman <kevin.wasserman at painless-security.com>
    
    ticket: 7276 (new)
    queue: kfw
    target_version: 1.10.4
    tags: pullup

 src/windows/leash/LeashView.cpp |   15 +++-
 src/windows/leashdll/lshfunc.c  |  160 +++++++++++++++++++++++++++-----------
 2 files changed, 126 insertions(+), 49 deletions(-)

diff --git a/src/windows/leash/LeashView.cpp b/src/windows/leash/LeashView.cpp
index 96c5127..0460f2c 100644
--- a/src/windows/leash/LeashView.cpp
+++ b/src/windows/leash/LeashView.cpp
@@ -2729,7 +2729,7 @@ LRESULT
 CLeashView::OnObtainTGTWithParam(WPARAM wParam, LPARAM lParam)
 {
     LRESULT res = 0;
-    char * param = (char *) GlobalLock((HGLOBAL) lParam);
+    char *param = 0;
     LSH_DLGINFO_EX ldi;
     ldi.size = sizeof(ldi);
     ldi.dlgtype = DLGTYPE_PASSWD;
@@ -2737,6 +2737,14 @@ CLeashView::OnObtainTGTWithParam(WPARAM wParam, LPARAM lParam)
     ldi.title = ldi.in.title;
     ldi.username = ldi.in.username;
     ldi.realm = ldi.in.realm;
+
+    if (lParam)
+        param = (char *) MapViewOfFile((HANDLE)lParam,
+                                       FILE_MAP_ALL_ACCESS,
+                                       0,
+                                       0,
+                                       4096);
+
     if ( param ) {
         if ( *param )
             strcpy(ldi.in.title,param);
@@ -2757,7 +2765,10 @@ CLeashView::OnObtainTGTWithParam(WPARAM wParam, LPARAM lParam)
         ldi.dlgtype |= DLGFLAG_READONLYPRINC;
 
     res = pLeash_kinit_dlg_ex(m_hWnd, &ldi);
-    GlobalUnlock((HGLOBAL) lParam);
+    if (param)
+        UnmapViewOfFile(param);
+    if (lParam)
+        CloseHandle((HANDLE )lParam);
     ::SendMessage(m_hWnd, WM_COMMAND, ID_UPDATE_DISPLAY, 0);
     return res;
 }
diff --git a/src/windows/leashdll/lshfunc.c b/src/windows/leashdll/lshfunc.c
index bd12121..bc86634 100644
--- a/src/windows/leashdll/lshfunc.c
+++ b/src/windows/leashdll/lshfunc.c
@@ -2662,6 +2662,117 @@ Leash_reset_defaults(void)
     Leash_reset_default_preserve_kinit_settings();
 }
 
+static void
+acquire_tkt_send_msg_leash(const char *title,
+                           const char *ccachename,
+                           const char *name,
+                           const char *realm)
+{
+    DWORD leashProcessId = 0;
+    DWORD bufsize = 4096;
+    DWORD step;
+    HANDLE hLeashProcess = NULL;
+    HANDLE hMapFile = NULL;
+    HANDLE hTarget = NULL;
+    HWND hLeashWnd = FindWindow("LEASH.0WNDCLASS", NULL);
+    char *strs;
+    void *view;
+    if (!hLeashWnd)
+        // no leash window
+        return;
+
+    GetWindowThreadProcessId(hLeashWnd, &leashProcessId);
+    hLeashProcess = OpenProcess(PROCESS_DUP_HANDLE,
+                                FALSE,
+                                leashProcessId);
+    if (!hLeashProcess)
+        // can't get process handle; use GetLastError() for more info
+        return;
+
+    hMapFile = CreateFileMapping(INVALID_HANDLE_VALUE, // use paging file
+                                 NULL,                 // default security
+                                 PAGE_READWRITE,       // read/write access
+                                 0,                    // max size (high 32)
+                                 bufsize,              // max size (low 32)
+                                 NULL);                // name
+    if (!hMapFile) {
+        // GetLastError() for more info
+        CloseHandle(hLeashProcess);
+        return;
+    }
+
+    SetForegroundWindow(hLeashWnd);
+
+    view = MapViewOfFile(hMapFile,
+                         FILE_MAP_ALL_ACCESS,
+                         0,
+                         0,
+                         bufsize);
+    if (view != NULL) {
+        /* construct a marshalling of data
+         *   <title><principal><realm><ccache>
+         * then send to Leash
+         */
+        strs = (char *)view;
+        // first reserve space for three more NULLs (4 strings total)
+        bufsize -= 3;
+        // Dialog title
+        if (title != NULL)
+            strcpy_s(strs, bufsize, title);
+        else if (name != NULL && realm != NULL)
+            sprintf_s(strs, bufsize,
+                      "Obtain Kerberos TGT for %s@%s", name, realm);
+        else
+            strcpy_s(strs, bufsize, "Obtain Kerberos TGT");
+        step = strlen(strs);
+        strs += step + 1;
+        bufsize -= step;
+        // name and realm
+        if (name != NULL) {
+            strcpy_s(strs, bufsize, name);
+            step = strlen(strs);
+            strs += step + 1;
+            bufsize -= step;
+            if (realm != NULL) {
+                strcpy_s(strs, bufsize, realm);
+                step = strlen(strs);
+                strs += step + 1;
+                bufsize -= step;
+            } else {
+                *strs = 0;
+                strs++;
+            }
+        } else {
+            *strs = 0;
+            strs++;
+            *strs = 0;
+            strs++;
+        }
+
+        /* Append the ccache name */
+        if (ccachename != NULL)
+            strcpy_s(strs, bufsize, ccachename);
+        else
+            *strs = 0;
+
+        UnmapViewOfFile(view);
+    }
+    // Duplicate the file mapping handle to one leash can use
+    if (DuplicateHandle(GetCurrentProcess(),
+                        hMapFile,
+                        hLeashProcess,
+                        &hTarget,
+                        PAGE_READWRITE,
+                        FALSE,
+                        DUPLICATE_SAME_ACCESS |
+                        DUPLICATE_CLOSE_SOURCE)) {
+        /* 32809 = ID_OBTAIN_TGT_WITH_LPARAM in src/windows/leash/resource.h */
+        SendMessage(hLeashWnd, 32809, 0, (LPARAM) hTarget);
+    } else {
+        // GetLastError()
+    }
+}
+
 static int
 acquire_tkt_send_msg(krb5_context ctx, const char * title,
 		     const char * ccachename,
@@ -2756,53 +2867,8 @@ acquire_tkt_send_msg(krb5_context ctx, const char * title,
 	UnmapViewOfFile(dlginfo);
 	CloseHandle(hMap);
     } else {
-	HGLOBAL 		hData;
-	HWND hLeash = FindWindow("LEASH.0WNDCLASS", NULL);
-
-	/* construct a marshalling of data
-	 *   <title><principal><realm><ccache>
-	 * then send to Leash
-	 */
-
-	hData = GlobalAlloc( GHND, 4096 );
-	SetForegroundWindow(hLeash);
-	if ( hData && hLeash ) {
-	    char * strs = GlobalLock(hData);
-	    if ( strs ) {
-		if (title)
-		    strcpy(strs, title);
-		else if (desiredName)
-		    sprintf(strs, "Obtain Kerberos TGT for %s@%s",desiredName,desiredRealm);
-		else
-		    strcpy(strs, "Obtain Kerberos TGT");
-		strs += strlen(strs) + 1;
-		if ( desiredName ) {
-		    strcpy(strs, desiredName);
-		    strs += strlen(strs) + 1;
-		    if (desiredRealm) {
-			strcpy(strs, desiredRealm);
-			strs += strlen(strs) + 1;
-		    }
-		} else {
-		    *strs = 0;
-		    strs++;
-		    *strs = 0;
-		    strs++;
-		}
-
-		/* Append the ccache name */
-		if (ccachename)
-		    strcpy(strs, ccachename);
-		else
-		    *strs = 0;
-		strs++;
-
-		GlobalUnlock( hData );
-		/* 32809 = ID_OBTAIN_TGT_WITH_LPARAM in src/windows/leash/resource.h */
-		SendMessage(hLeash, 32809, 0, (LPARAM) hData);
-	    }
-	}
-	GlobalFree( hData );
+        acquire_tkt_send_msg_leash(title,
+                                   ccachename, desiredName, desiredRealm);
     }
 
     SetForegroundWindow(hForeground);


More information about the cvs-krb5 mailing list