forked from uup-dump/api
		
	Rewrite WU requests and cookie handling
This commit is contained in:
		
							
								
								
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -1 +0,0 @@ | ||||
| shared/cookie.json | ||||
							
								
								
									
										10
									
								
								fetchupd.php
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								fetchupd.php
									
									
									
									
									
								
							| @@ -102,10 +102,14 @@ function uupFetchUpd( | ||||
|     if($fromCache !== false) return $fromCache; | ||||
|  | ||||
|     consoleLogger('Fetching information from the server...'); | ||||
|     $postData = composeFetchUpdRequest(uupDevice(), uupEncryptedData(), $arch, $flight, $ring, $build, $sku, $type); | ||||
|     $out = sendWuPostRequest('https://fe3cr.delivery.mp.microsoft.com/ClientWebService/client.asmx', $postData); | ||||
|     $composerArgs = [$arch, $flight, $ring, $build, $sku, $type]; | ||||
|     $out = sendWuPostRequestHelper('client', 'composeFetchUpdRequest', $composerArgs); | ||||
|     if($out['error'] != 200) { | ||||
|         consoleLogger('The request has failed'); | ||||
|         return array('error' => 'WU_REQUEST_FAILED'); | ||||
|     } | ||||
|  | ||||
|     $out = html_entity_decode($out); | ||||
|     $out = html_entity_decode($out['out']); | ||||
|     consoleLogger('Information has been successfully fetched.'); | ||||
|  | ||||
|     preg_match_all('/<UpdateInfo>.*?<\/UpdateInfo>/', $out, $updateInfos); | ||||
|   | ||||
							
								
								
									
										12
									
								
								get.php
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								get.php
									
									
									
									
									
								
							| @@ -395,8 +395,16 @@ function uupGetOnlineFiles($updateId, $rev, $info, $cacheRequests, $type) { | ||||
|     } else { | ||||
|         $fetchTime = time(); | ||||
|         consoleLogger('Fetching information from the server...'); | ||||
|         $postData = composeFileGetRequest($updateId, uupDevice(), $info, $rev, $type); | ||||
|         $out = sendWuPostRequest('https://fe3cr.delivery.mp.microsoft.com/ClientWebService/client.asmx/secured', $postData); | ||||
|  | ||||
|         $composerArgs = [$updateId, $info, $rev, $type]; | ||||
|         $out = sendWuPostRequestHelper('clientSecured', 'composeFileGetRequest', $composerArgs); | ||||
|  | ||||
|         if($out['error'] != 200) { | ||||
|             consoleLogger('The request has failed'); | ||||
|             return array('error' => 'WU_REQUEST_FAILED'); | ||||
|         } | ||||
|  | ||||
|         $out = $out['out']; | ||||
|         consoleLogger('Information has been successfully fetched.'); | ||||
|     } | ||||
|  | ||||
|   | ||||
| @@ -132,6 +132,7 @@ Parameters: | ||||
|  - ILLEGAL_MINOR | ||||
|  - NO_UPDATE_FOUND | ||||
|  - EMPTY_FILELIST | ||||
|  - WU_REQUEST_FAILED | ||||
|  | ||||
| **get.php** | ||||
|  - UNSUPPORTED_LANG | ||||
| @@ -142,6 +143,7 @@ Parameters: | ||||
|  - MISSING_FILES | ||||
|  - NO_FILES | ||||
|  - XML_PARSE_ERROR | ||||
|  - WU_REQUEST_FAILED | ||||
|  | ||||
| **listeditions.php** | ||||
|  - UNSUPPORTED_LANG | ||||
|   | ||||
| @@ -25,19 +25,43 @@ function uupDevice() { | ||||
|     return base64_encode(chunk_split($data, 1, "\0")); | ||||
| } | ||||
|  | ||||
| function uupSaveCookieFromResponse($out) { | ||||
|     $outDecoded = html_entity_decode($out); | ||||
|     preg_match('/<NewCookie>.*?<\/NewCookie>|<GetCookieResult>.*?<\/GetCookieResult>/', $outDecoded, $cookieData); | ||||
|  | ||||
|     if(empty($cookieData)) | ||||
|         return false; | ||||
|  | ||||
|     preg_match('/<Expiration>.*<\/Expiration>/', $cookieData[0], $expirationDate); | ||||
|     preg_match('/<EncryptedData>.*<\/EncryptedData>/', $cookieData[0], $encryptedData); | ||||
|  | ||||
|     $expirationDate = preg_replace('/<Expiration>|<\/Expiration>/', '', $expirationDate[0]); | ||||
|     $encryptedData = preg_replace('/<EncryptedData>|<\/EncryptedData>/', '', $encryptedData[0]); | ||||
|  | ||||
|     $cookieData = array( | ||||
|         'expirationDate' => $expirationDate, | ||||
|         'encryptedData' => $encryptedData, | ||||
|     ); | ||||
|  | ||||
|     $cookieStorage = new UupDumpCache('WuRequestCookie', false); | ||||
|     $cookieStorage->put($cookieData, false); | ||||
|  | ||||
|     return $cookieData; | ||||
| } | ||||
|  | ||||
| function uupInvalidateCookie() { | ||||
|     $cookieStorage = new UupDumpCache('WuRequestCookie', false); | ||||
|     $cookieInfo = $cookieStorage->delete(); | ||||
| } | ||||
|  | ||||
| function uupEncryptedData() { | ||||
|     $cookieInfo = @file_get_contents(dirname(__FILE__).'/cookie.json'); | ||||
|     $cookieInfo = json_decode($cookieInfo, 1); | ||||
|     $cookieStorage = new UupDumpCache('WuRequestCookie', false); | ||||
|     $cookieInfo = $cookieStorage->get(); | ||||
|  | ||||
|     if(empty($cookieInfo)) { | ||||
|         $postData = composeGetCookieRequest(uupDevice()); | ||||
|         sendWuPostRequest('https://fe3.delivery.mp.microsoft.com/ClientWebService/client.asmx', $postData); | ||||
|  | ||||
|         $encData = uupEncryptedData(); | ||||
|     } else { | ||||
|         $encData = $cookieInfo['encryptedData']; | ||||
|         $data = sendWuPostRequestHelper('client', 'composeGetCookieRequest', [], false); | ||||
|         $cookieInfo = uupSaveCookieFromResponse($data['out']); | ||||
|     } | ||||
|  | ||||
|     return $encData; | ||||
|     return $cookieInfo['encryptedData']; | ||||
| } | ||||
| ?> | ||||
|   | ||||
| @@ -16,7 +16,7 @@ limitations under the License. | ||||
| */ | ||||
|  | ||||
| function uupApiVersion() { | ||||
|     return '1.40.3'; | ||||
|     return '1.41.0'; | ||||
| } | ||||
|  | ||||
| require_once dirname(__FILE__).'/auths.php'; | ||||
|   | ||||
| @@ -298,7 +298,8 @@ function branchFromBuild($build) { | ||||
| } | ||||
|  | ||||
| // Composes POST data for gathering list of urls for download | ||||
| function composeFileGetRequest($updateId, $device, $info, $rev = 1, $type = 'Production') { | ||||
| function composeFileGetRequest($updateId, $info, $rev = 1, $type = 'Production') { | ||||
|     $device = uupDevice(); | ||||
|     $uuid = genUUID(); | ||||
|  | ||||
|     $createdTime = time(); | ||||
| @@ -359,7 +360,9 @@ XML; | ||||
| } | ||||
|  | ||||
| // Composes POST data for fetching the latest update information from Windows Update | ||||
| function composeFetchUpdRequest($device, $encData, $arch, $flight, $ring, $build, $sku = 48, $type = 'Production') { | ||||
| function composeFetchUpdRequest($arch, $flight, $ring, $build, $sku = 48, $type = 'Production') { | ||||
|     $device = uupDevice(); | ||||
|     $encData = uupEncryptedData(); | ||||
|     $uuid = genUUID(); | ||||
|  | ||||
|     $createdTime = time(); | ||||
| @@ -585,7 +588,8 @@ XML; | ||||
| } | ||||
|  | ||||
| // Composes POST data for Get Cookie request | ||||
| function composeGetCookieRequest($device) { | ||||
| function composeGetCookieRequest() { | ||||
|     $device = uupDevice(); | ||||
|     $uuid = genUUID(); | ||||
|  | ||||
|     $createdTime = time(); | ||||
|   | ||||
| @@ -51,7 +51,7 @@ function genUUID() { | ||||
|     ); | ||||
| } | ||||
|  | ||||
| function sendWuPostRequest($url, $postData) { | ||||
| function sendWuPostRequestInternal($url, $postData, $saveCookie = true) { | ||||
|     $req = curl_init($url); | ||||
|  | ||||
|     $proxy = uupDumpApiGetConfig(); | ||||
| @@ -77,38 +77,40 @@ function sendWuPostRequest($url, $postData) { | ||||
|  | ||||
|     curl_close($req); | ||||
|  | ||||
|     /* | ||||
|     Replace an expired cookie with a new one by replacing it in existing | ||||
|     postData. This has to be done this way, because handling it properly would | ||||
|     most likely require a rewrite of half of the project. | ||||
|     */ | ||||
|     if($error == 500 && preg_match('/<ErrorCode>(ConfigChanged|CookieExpired)<\/ErrorCode>/', $out)) { | ||||
|         $oldCookie = uupEncryptedData(); | ||||
|         @unlink(dirname(__FILE__).'/cookie.json'); | ||||
|         $postData = str_replace($oldCookie, uupEncryptedData(), $postData); | ||||
|     if($saveCookie === true) | ||||
|         uupSaveCookieFromResponse($out); | ||||
|  | ||||
|         return sendWuPostRequest($url, $postData); | ||||
|     return [ | ||||
|         'error' => $error, | ||||
|         'out' => $out | ||||
|     ]; | ||||
| } | ||||
|  | ||||
| function sendWuPostRequest($url, $postData) { | ||||
|     return sendWuPostRequestInternal($url, $postData)['out']; | ||||
| } | ||||
|  | ||||
| function sendWuPostRequestHelper( | ||||
|     $endpoint, | ||||
|     $postComposer, | ||||
|     $postComposerArgs, | ||||
|     $saveCookie = true | ||||
| ) { | ||||
|     $endpoints = [ | ||||
|         'client' => 'https://fe3.delivery.mp.microsoft.com/ClientWebService/client.asmx', | ||||
|         'clientSecured' => 'https://fe3cr.delivery.mp.microsoft.com/ClientWebService/client.asmx/secured' | ||||
|     ]; | ||||
|  | ||||
|     $postData = call_user_func_array($postComposer, $postComposerArgs); | ||||
|     $data = sendWuPostRequestInternal($endpoints[$endpoint], $postData, $saveCookie); | ||||
|  | ||||
|     if($data['error'] == 500 && preg_match('/<ErrorCode>(ConfigChanged|CookieExpired|InvalidCookie)<\/ErrorCode>/', $data['out'])) { | ||||
|         uupInvalidateCookie(); | ||||
|         $postData = call_user_func_array($postComposer, $postComposerArgs); | ||||
|         return sendWuPostRequestInternal($endpoints[$endpoint], $postData, $saveCookie); | ||||
|     } | ||||
|  | ||||
|     $outDecoded = html_entity_decode($out); | ||||
|     preg_match('/<NewCookie>.*?<\/NewCookie>|<GetCookieResult>.*?<\/GetCookieResult>/', $outDecoded, $cookieData); | ||||
|  | ||||
|     if(!empty($cookieData)) { | ||||
|         preg_match('/<Expiration>.*<\/Expiration>/', $cookieData[0], $expirationDate); | ||||
|         preg_match('/<EncryptedData>.*<\/EncryptedData>/', $cookieData[0], $encryptedData); | ||||
|  | ||||
|         $expirationDate = preg_replace('/<Expiration>|<\/Expiration>/', '', $expirationDate[0]); | ||||
|         $encryptedData = preg_replace('/<EncryptedData>|<\/EncryptedData>/', '', $encryptedData[0]); | ||||
|  | ||||
|         $fileData = array( | ||||
|             'expirationDate' => $expirationDate, | ||||
|             'encryptedData' => $encryptedData, | ||||
|         ); | ||||
|  | ||||
|         @file_put_contents(dirname(__FILE__).'/cookie.json', json_encode($fileData)); | ||||
|     } | ||||
|  | ||||
|     return $out; | ||||
|     return $data; | ||||
| } | ||||
|  | ||||
| function consoleLogger($message, $showTime = 1) { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user