ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

pwcache.c
Go to the documentation of this file.
00001 /*
00002  * MPR Password Cache functions
00003  *
00004  * Copyright 1999 Ulrich Weigand
00005  * Copyright 2003,2004 Mike McCormack for CodeWeavers
00006  *
00007  * This library is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU Lesser General Public
00009  * License as published by the Free Software Foundation; either
00010  * version 2.1 of the License, or (at your option) any later version.
00011  *
00012  * This library is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015  * Lesser General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU Lesser General Public
00018  * License along with this library; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
00020  */
00021 
00022 #include <stdarg.h>
00023 #include <stdio.h>
00024 
00025 #include "windef.h"
00026 #include "winbase.h"
00027 #include "winnetwk.h"
00028 #include "winreg.h"
00029 #include "wine/debug.h"
00030 
00031 WINE_DEFAULT_DEBUG_CHANNEL(mpr);
00032 
00033 static const char mpr_key[] = "Software\\Wine\\Wine\\Mpr\\";
00034 
00035 static inline BYTE hex( BYTE x )
00036 {
00037     if( x <= 9 )
00038         return x + '0';
00039     return x + 'A' - 10;
00040 }
00041 
00042 static inline signed char ctox( CHAR x )
00043 {
00044     if( ( x >= '0' ) && ( x <= '9' ) )
00045         return x - '0';
00046     if( ( x >= 'A' ) && ( x <= 'F' ) )
00047         return x - 'A' + 10;
00048     if( ( x >= 'a' ) && ( x <= 'a' ) )
00049         return x - 'a' + 10;
00050     return -1;
00051 }
00052 
00053 static LPSTR MPR_GetValueName( LPCSTR pbResource, WORD cbResource, BYTE nType )
00054 {
00055     LPSTR name;
00056     DWORD  i;
00057 
00058     name = HeapAlloc( GetProcessHeap(), 0, 6+cbResource*2 );
00059     if( !name ) return NULL;
00060 
00061     sprintf( name, "X-%02X-", nType );
00062     for(i=0; i<cbResource; i++)
00063     {
00064         name[5+i*2]=hex((pbResource[i]&0xf0)>>4);
00065         name[6+i*2]=hex(pbResource[i]&0x0f);
00066     }
00067     name[5+i*2]=0;
00068     TRACE( "Value is %s\n", name );
00069     return name;
00070 }
00071 
00072 
00073 /**************************************************************************
00074  * WNetCachePassword [MPR.@]  Saves password in cache
00075  *
00076  * NOTES
00077  *  Only the parameter count is verified
00078  *
00079  *  ---- everything below this line might be wrong (js) -----
00080  * RETURNS
00081  *    Success: WN_SUCCESS
00082  *    Failure: WN_ACCESS_DENIED, WN_BAD_PASSWORD, WN_BADVALUE, WN_NET_ERROR,
00083  *             WN_NOT_SUPPORTED, WN_OUT_OF_MEMORY
00084  */
00085 DWORD WINAPI WNetCachePassword(
00086     LPSTR pbResource, /* [in] Name of workgroup, computer, or resource */
00087     WORD cbResource,  /* [in] Size of name */
00088     LPSTR pbPassword, /* [in] Buffer containing password */
00089     WORD cbPassword,  /* [in] Size of password */
00090     BYTE nType,       /* [in] Type of password to cache */
00091     WORD x)
00092 
00093 {
00094     HKEY hkey;
00095     DWORD r;
00096     LPSTR valname;
00097 
00098     WARN( "(%p(%s), %d, %p(%s), %d, %d, 0x%08x): totally insecure\n",
00099            pbResource, debugstr_a(pbResource), cbResource,
00100        pbPassword, debugstr_a(pbPassword), cbPassword,
00101        nType, x );
00102 
00103     /* @@ Wine registry key: HKCU\Software\Wine\Wine\Mpr */
00104     r = RegCreateKeyA( HKEY_CURRENT_USER, mpr_key, &hkey );
00105     if( r )
00106         return WN_ACCESS_DENIED;
00107 
00108     valname = MPR_GetValueName( pbResource, cbResource, nType );
00109     if( valname )
00110     {
00111         r = RegSetValueExA( hkey, valname, 0, REG_BINARY, 
00112                             (LPBYTE)pbPassword, cbPassword );
00113         if( r )
00114             r = WN_CANCEL;
00115         else
00116             r = WN_SUCCESS;
00117         HeapFree( GetProcessHeap(), 0, valname );
00118     }
00119     else
00120         r = WN_OUT_OF_MEMORY;
00121 
00122     RegCloseKey( hkey );
00123 
00124     return r;
00125 }
00126 
00127 /*****************************************************************
00128  *  WNetRemoveCachedPassword [MPR.@]
00129  */
00130 UINT WINAPI WNetRemoveCachedPassword(
00131       LPSTR pbResource,   /* [in] resource ID to delete */
00132       WORD cbResource,    /* [in] number of bytes in the resource ID */
00133       BYTE nType )        /* [in] Type of the resource to delete */
00134 {
00135     HKEY hkey;
00136     DWORD r;
00137     LPSTR valname;
00138 
00139     WARN( "(%p(%s), %d, %d): totally insecure\n",
00140            pbResource, debugstr_a(pbResource), cbResource, nType );
00141 
00142     /* @@ Wine registry key: HKCU\Software\Wine\Wine\Mpr */
00143     r = RegCreateKeyA( HKEY_CURRENT_USER, mpr_key, &hkey );
00144     if( r )
00145         return WN_ACCESS_DENIED;
00146 
00147     valname = MPR_GetValueName( pbResource, cbResource, nType );
00148     if( valname )
00149     {
00150         r = RegDeleteValueA( hkey, valname );
00151         if( r )
00152             r = WN_ACCESS_DENIED;
00153         else
00154             r = WN_SUCCESS;
00155         HeapFree( GetProcessHeap(), 0, valname );
00156     }
00157     else
00158         r = WN_OUT_OF_MEMORY;
00159 
00160     return r;
00161 }
00162 
00163 /*****************************************************************
00164  * WNetGetCachedPassword [MPR.@]  Retrieves password from cache
00165  *
00166  * NOTES
00167  *  the stub seems to be wrong:
00168  *  arg1:   ptr 0x40xxxxxx -> (no string)
00169  *  arg2:   len 36
00170  *  arg3:   ptr 0x40xxxxxx -> (no string)
00171  *  arg4:   ptr 0x40xxxxxx -> 0xc8
00172  *  arg5:   type?   4
00173  *
00174  *  ---- everything below this line might be wrong (js) -----
00175  * RETURNS
00176  *    Success: WN_SUCCESS
00177  *    Failure: WN_ACCESS_DENIED, WN_BAD_PASSWORD, WN_BAD_VALUE,
00178  *             WN_NET_ERROR, WN_NOT_SUPPORTED, WN_OUT_OF_MEMORY
00179  */
00180 DWORD WINAPI WNetGetCachedPassword(
00181     LPSTR pbResource,   /* [in]  Name of workgroup, computer, or resource */
00182     WORD cbResource,    /* [in]  Size of name */
00183     LPSTR pbPassword,   /* [out] Buffer to receive password */
00184     LPWORD pcbPassword, /* [out] Receives size of password */
00185     BYTE nType)         /* [in]  Type of password to retrieve */
00186 {
00187     HKEY hkey;
00188     DWORD r, type = 0, sz;
00189     LPSTR valname;
00190 
00191     WARN( "(%p(%s), %d, %p, %p, %d): totally insecure\n",
00192            pbResource, debugstr_a(pbResource), cbResource,
00193        pbPassword, pcbPassword, nType );
00194 
00195     memset( pbPassword, 0, *pcbPassword);
00196 
00197     /* @@ Wine registry key: HKCU\Software\Wine\Wine\Mpr */
00198     r = RegCreateKeyA( HKEY_CURRENT_USER, mpr_key, &hkey );
00199     if( r )
00200         return WN_ACCESS_DENIED;
00201 
00202     valname = MPR_GetValueName( pbResource, cbResource, nType );
00203     if( valname )
00204     {
00205         sz = *pcbPassword;
00206         r = RegQueryValueExA( hkey, valname, 0, &type, (LPBYTE)pbPassword, &sz );
00207         *pcbPassword = sz;
00208         if( r )
00209             r = WN_CANCEL;
00210         else
00211             r = WN_SUCCESS;
00212         HeapFree( GetProcessHeap(), 0, valname );
00213     }
00214     else
00215         r = WN_OUT_OF_MEMORY;
00216 
00217     return r;
00218 }
00219 
00220 /*******************************************************************
00221  * WNetEnumCachedPasswords [MPR.@]
00222  *
00223  * NOTES
00224  *  The parameter count is verified
00225  * 
00226  *  This function is a huge security risk, as virii and such can use
00227  * it to grab all the passwords in the cache.  It's bad enough to 
00228  * store the passwords (insecurely).
00229  *
00230  *  bpPrefix and cbPrefix are used to filter the returned passwords
00231  *   the first cbPrefix bytes of the password resource identifier
00232  *   should match the same number of bytes in bpPrefix
00233  *
00234  * RETURNS
00235  *   Success: WN_SUCCESS   (even if no entries were enumerated)
00236  *   Failure: WN_ACCESS_DENIED, WN_BAD_PASSWORD, WN_BAD_VALUE,
00237  *             WN_NET_ERROR, WN_NOT_SUPPORTED, WN_OUT_OF_MEMORY
00238  */
00239 
00240 UINT WINAPI WNetEnumCachedPasswords(
00241       LPSTR pbPrefix,  /* [in] prefix to filter cache entries */
00242       WORD cbPrefix,   /* [in] number of bytes in Prefix substring */
00243       BYTE nType,      /* [in] match the Type ID of the entry */
00244       ENUMPASSWORDPROC enumPasswordProc,  /* [in] callback function */
00245       DWORD param)     /* [in] parameter passed to enum function */
00246 {
00247     HKEY hkey;
00248     DWORD r, type, val_sz, data_sz, i, j, size;
00249     PASSWORD_CACHE_ENTRY *entry;
00250     CHAR val[256], prefix[6];
00251 
00252     WARN( "(%s, %d, %d, %p, 0x%08x) totally insecure\n",
00253            debugstr_an(pbPrefix,cbPrefix), cbPrefix,
00254        nType, enumPasswordProc, param );
00255 
00256     /* @@ Wine registry key: HKCU\Software\Wine\Wine\Mpr */
00257     r = RegCreateKeyA( HKEY_CURRENT_USER, mpr_key, &hkey );
00258     if( r )
00259         return WN_ACCESS_DENIED;
00260 
00261     sprintf(prefix, "X-%02X-", nType );
00262 
00263     i = 0;
00264     for( i=0;  ; i++ )
00265     {
00266         val_sz  = sizeof val;
00267         data_sz = 0;
00268         type    = 0;
00269         val[0] = 0;
00270         r = RegEnumValueA( hkey, i, val, &val_sz, NULL, &type, NULL, &data_sz );
00271         if( r != ERROR_SUCCESS )
00272             break;
00273         if( type != REG_BINARY )
00274             continue;
00275 
00276         /* check the value is in the format we expect */
00277         if( val_sz < sizeof prefix )
00278             continue;
00279         if( memcmp( prefix, val, 5 ) )
00280             continue;
00281 
00282         /* decode the value */
00283         for(j=5; j<val_sz; j+=2 )
00284         {
00285             signed char hi = ctox( val[j] ), lo = ctox( val[j+1] );
00286             if( ( hi < 0 ) || ( lo < 0 ) )
00287                 break;
00288             val[(j-5)/2] = (hi<<4) | lo;
00289         }
00290 
00291         /* find the decoded length */
00292         val_sz = (j - 5)/2;
00293         val[val_sz]=0;
00294         if( val_sz < cbPrefix )
00295             continue;
00296 
00297         /* check the prefix matches */
00298         if( memcmp(val, pbPrefix, cbPrefix) )
00299             continue;
00300 
00301         /* read the value data */
00302         size = sizeof *entry - sizeof entry->abResource[0] + val_sz + data_sz;
00303         entry = HeapAlloc( GetProcessHeap(), 0, sizeof *entry + val_sz + data_sz );
00304         memcpy( entry->abResource, val, val_sz );
00305         entry->cbEntry = size;
00306         entry->cbResource = val_sz;
00307         entry->cbPassword = data_sz;
00308         entry->iEntry = i;
00309         entry->nType = nType;
00310         r = RegEnumValueA( hkey, i, NULL, &val_sz, NULL, &type, 
00311                            &entry->abResource[val_sz], &data_sz );
00312         if( r == ERROR_SUCCESS )
00313             enumPasswordProc( entry, param );
00314         HeapFree( GetProcessHeap(), 0, entry );
00315     }
00316 
00317     RegCloseKey( hkey );
00318 
00319     return WN_SUCCESS;
00320 }

Generated on Sun May 27 2012 04:24:44 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.