Implement password caching

Mike McCormack mike at codeweavers.com
Thu Jul 17 12:53:46 CDT 2003


Hi,

This patch should be improved to use ssh-agent to cache a key to unlock 
the stored passwords.

Mike


ChageLog:
* implement password caching

-------------- next part --------------
Index: dlls/mpr/pwcache.c
===================================================================
RCS file: /home/wine/wine/dlls/mpr/pwcache.c,v
retrieving revision 1.7
diff -u -r1.7 pwcache.c
--- dlls/mpr/pwcache.c	12 May 2003 03:29:50 -0000	1.7
+++ dlls/mpr/pwcache.c	17 Jul 2003 16:35:34 -0000
@@ -2,6 +2,7 @@
  * MPR Password Cache functions
  *
  * Copyright 1999 Ulrich Weigand
+ * Copyright 2003 Mike McCormack for Codeweavers
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -18,12 +19,33 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
+#include <stdio.h>
+
 #include "winbase.h"
 #include "winnetwk.h"
+#include "winreg.h"
 #include "wine/debug.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(mpr);
 
+static LPCSTR mpr_key = "Software\\Wine\\Wine\\Mpr\\";
+
+static LPSTR MPR_GetValueName( LPSTR pbResource, WORD cbResource, BYTE nType )
+{
+    LPSTR name;
+    DWORD  i, x = 0;
+
+    /* just a hash so the value name doesn't get too large */
+    for( i=0; i<cbResource; i++ )
+        x = ((x<<7) | (x >> 25)) ^ toupper(pbResource[i]);
+
+    name = HeapAlloc( GetProcessHeap(), 0, 0x10 );
+    if( name )
+        sprintf( name, "I-%08lX-%02X", x, nType );
+    TRACE( "Value is %s\n", name );
+    return name;
+}
+
 /**************************************************************************
  * WNetCachePassword [MPR.@]  Saves password in cache
  *
@@ -45,12 +67,36 @@
     WORD x)
 
 {
-    FIXME( "(%p(%s), %d, %p(%s), %d, %d, 0x%08x): stub\n",
+    HKEY hkey;
+    DWORD r;
+    LPSTR valname;
+
+    WARN( "(%p(%s), %d, %p(%s), %d, %d, 0x%08x): totally insecure\n",
            pbResource, debugstr_a(pbResource), cbResource,
 	   pbPassword, debugstr_a(pbPassword), cbPassword,
 	   nType, x );
 
-    return WN_NOT_SUPPORTED;
+    r = RegCreateKeyA( HKEY_CURRENT_USER, mpr_key, &hkey );
+    if( r )
+        return WN_ACCESS_DENIED;
+
+    valname = MPR_GetValueName( pbResource, cbResource, nType );
+    if( valname )
+    {
+        r = RegSetValueExA( hkey, valname, 0, REG_BINARY, 
+                            pbPassword, cbPassword );
+        if( r )
+            r = WN_ACCESS_DENIED;
+        else
+            r = WN_SUCCESS;
+        HeapFree( GetProcessHeap(), 0, valname );
+    }
+    else
+        r = WN_OUT_OF_MEMORY;
+
+    RegCloseKey( hkey );
+
+    return r;
 }
 
 /*****************************************************************
@@ -59,10 +105,31 @@
 UINT WINAPI WNetRemoveCachedPassword( LPSTR pbResource, WORD cbResource,
                                       BYTE nType )
 {
-    FIXME( "(%p(%s), %d, %d): stub\n",
+    HKEY hkey;
+    DWORD r;
+    LPSTR valname;
+
+    WARN( "(%p(%s), %d, %d): totally insecure\n",
            pbResource, debugstr_a(pbResource), cbResource, nType );
 
-    return WN_NOT_SUPPORTED;
+    r = RegCreateKeyA( HKEY_CURRENT_USER, mpr_key, &hkey );
+    if( r )
+        return WN_ACCESS_DENIED;
+
+    valname = MPR_GetValueName( pbResource, cbResource, nType );
+    if( valname )
+    {
+        r = RegDeleteValueA( hkey, valname );
+        if( r )
+            r = WN_ACCESS_DENIED;
+        else
+            r = WN_SUCCESS;
+        HeapFree( GetProcessHeap(), 0, valname );
+    }
+    else
+        r = WN_OUT_OF_MEMORY;
+
+    return r;
 }
 
 /*****************************************************************
@@ -89,11 +156,34 @@
     LPWORD pcbPassword, /* [out] Receives size of password */
     BYTE nType)         /* [in]  Type of password to retrieve */
 {
-    FIXME( "(%p(%s), %d, %p, %p, %d): stub\n",
+    HKEY hkey;
+    DWORD r, type = 0, sz;
+    LPSTR valname;
+
+    WARN( "(%p(%s), %d, %p, %p, %d): stub\n",
            pbResource, debugstr_a(pbResource), cbResource,
 	   pbPassword, pcbPassword, nType );
 
-    return WN_NOT_SUPPORTED;
+    r = RegCreateKeyA( HKEY_CURRENT_USER, mpr_key, &hkey );
+    if( r )
+        return WN_ACCESS_DENIED;
+
+    valname = MPR_GetValueName( pbResource, cbResource, nType );
+    if( valname )
+    {
+        sz = *pcbPassword;
+        r = RegQueryValueExA( hkey, valname, 0, &type, pbPassword, &sz );
+        *pcbPassword = sz;
+        if( r )
+            r = WN_ACCESS_DENIED;
+        else
+            r = WN_SUCCESS;
+        HeapFree( GetProcessHeap(), 0, valname );
+    }
+    else
+        r = WN_OUT_OF_MEMORY;
+
+    return r;
 }
 
 /*******************************************************************
@@ -101,6 +191,10 @@
  *
  * NOTES
  *	the parameter count is verifyed
+ * 
+ *  This function is a huge security risk, as virii and such can use
+ * it to grab all the passwords in the cache.  It's bad enough to 
+ * store the passwords (insecurely).
  *
  *  observed values:
  *	arg1	ptr	0x40xxxxxx -> (no string)
@@ -115,7 +209,7 @@
 UINT WINAPI WNetEnumCachedPasswords( LPSTR pbPrefix, WORD cbPrefix,
                                      BYTE nType, ENUMPASSWORDPROC enumPasswordProc, DWORD x)
 {
-    FIXME( "(%p(%s), %d, %d, %p, 0x%08lx): stub\n",
+    WARN( "(%p(%s), %d, %d, %p, 0x%08lx): don't implement this\n",
            pbPrefix, debugstr_a(pbPrefix), cbPrefix,
 	   nType, enumPasswordProc, x );
 
Index: include/winnetwk.h
===================================================================
RCS file: /home/wine/wine/include/winnetwk.h,v
retrieving revision 1.10
diff -u -r1.10 winnetwk.h
--- include/winnetwk.h	10 Mar 2002 00:02:34 -0000	1.10
+++ include/winnetwk.h	17 Jul 2003 16:35:34 -0000
@@ -68,7 +68,8 @@
 #define RESOURCEUSAGE_CONTAINER     0x00000002
 #define RESOURCEUSAGE_NOLOCALDEVICE 0x00000004
 #define RESOURCEUSAGE_SIBLING       0x00000008
-#define RESOURCEUSAGE_ALL           (RESOURCEUSAGE_CONNECTABLE | RESOURCEUSAGE_CONTAINER)
+#define RESOURCEUSAGE_ATTACHED      0x00000010
+#define RESOURCEUSAGE_ALL           (RESOURCEUSAGE_CONNECTABLE | RESOURCEUSAGE_CONTAINER | RESOURCEUSAGE_ATTACHED)
 #define RESOURCEUSAGE_RESERVED      0x80000000
 
 #define RESOURCEDISPLAYTYPE_GENERIC        0x00000000
@@ -388,5 +389,8 @@
 
 typedef BOOL (CALLBACK *ENUMPASSWORDPROC)(PASSWORD_CACHE_ENTRY *, DWORD);
 UINT WINAPI WNetEnumCachedPasswords( LPSTR, WORD, BYTE, ENUMPASSWORDPROC, DWORD);
+DWORD WINAPI WNetGetCachedPassword( LPSTR, WORD, LPSTR, LPWORD, BYTE );
+DWORD WINAPI WNetCachePassword( LPSTR, WORD, LPSTR, WORD, BYTE, WORD );
+
 
 #endif /* _WINNETWK_H_ */


More information about the wine-patches mailing list