Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenpwcache.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
1.7.6.1
|