private function getPostFields(HttpRequest $request) { if ($request->hasBody()) { return $request->getBody(); } else { if ($this->oldUrlConstructor) { return UrlParamsUtils::toStringOneDeepLvl($request->getPost()); } else { $fileList = array_map(array($this, 'fileFilter'), UrlParamsUtils::toParamsList($request->getFiles())); if (empty($fileList)) { return UrlParamsUtils::toString($request->getPost()); } else { $postList = UrlParamsUtils::toParamsList($request->getPost()); if (!is_null($atParam = $this->findAtParamInPost($postList))) { throw new NetworkException('Security excepion: not allowed send post param ' . $atParam . ' which begins from @ in request which contains files'); } return array_merge($postList, $fileList); } } } }
/** * Signs request with signature version 4 * * @param \HttpRequest $request Http Request * @param string $region optional Overrides region as destination region for multiregional operations * @throws QueryClientException */ protected function signRequestV4($request, $region = null) { $time = time(); //Gets the http method name $httpMethod = self::$httpMethods[$request->getMethod()]; //Region is mandatory part for this type of authentication $region = $region ?: $this->getAws()->getRegion(); //Gets host from the url $components = parse_url($request->getUrl()); $crd = gmdate('Ymd', $time) . '/' . $region . '/' . $this->getServiceName() . '/aws4_request'; $opt = ['X-Amz-Algorithm' => 'AWS4-HMAC-SHA256', 'X-Amz-Credential' => $this->awsAccessKeyId . '/' . $crd, 'X-Amz-Date' => gmdate('Ymd\\THis\\Z', $time), 'X-Amz-Expires' => '86400']; $headers = ['X-Amz-Date' => $opt['X-Amz-Date']]; //Calculating canonicalized query string $canonicalizedQueryString = ''; if (!empty($components['query'])) { parse_str($components['query'], $pars); ksort($pars); foreach ($pars as $k => $v) { $canonicalizedQueryString .= '&' . rawurlencode($k) . '=' . rawurlencode($v); } $canonicalizedQueryString = ltrim($canonicalizedQueryString, '&'); } //Calculating payload $payload = ''; if ($httpMethod == 'POST') { if ($request->getBody() != '') { $payload = $request->getBody(); } else { $pars = $request->getPostFields(); foreach ($pars as $k => $v) { //We do not use rawurlencode because httpRequest does not do this, and we need to hash payload $payload .= '&' . urlencode($k) . '=' . urlencode($v); } $payload = ltrim($payload, '&'); } } elseif ($httpMethod == 'PUT') { $payload = $request->getPutData(); if (empty($payload) && $request->getPutFile()) { $headers['X-Amz-Content-Sha256'] = hash_file('sha256', $request->getPutFile()); } } if (!isset($headers['X-Amz-Content-Sha256'])) { $headers['X-Amz-Content-Sha256'] = hash('sha256', $payload); } //Adding x-amz headers $request->addHeaders($headers); //Calculating canonical headers $allHeaders = $request->getHeaders(); $allHeaders['X-Amz-SignedHeaders'] = 'host'; $signedHeaders = ['host' => $components['host']]; foreach ($allHeaders as $k => $v) { $lk = strtolower($k); //This x-amz header does not have to be signed if ($lk == 'x-amz-signedheaders') { continue; } if (preg_match('/x-amz-/i', $k) || $lk == 'content-type' || $lk == 'content-md5') { $signedHeaders[$lk] = $v; } } ksort($signedHeaders); $allHeaders['X-Amz-SignedHeaders'] = join(';', array_keys($signedHeaders)); $canonicalHeaders = ''; foreach ($signedHeaders as $k => $v) { $canonicalHeaders .= $k . ':' . $v . "\n"; } $canonicalRequest = $httpMethod . "\n" . $components['path'] . "\n" . $canonicalizedQueryString . "\n" . $canonicalHeaders . "\n" . $allHeaders['X-Amz-SignedHeaders'] . "\n" . $headers['X-Amz-Content-Sha256']; $stringToSign = $opt['X-Amz-Algorithm'] . "\n" . $opt['X-Amz-Date'] . "\n" . $crd . "\n" . hash('sha256', $canonicalRequest); $dateKey = hash_hmac('sha256', gmdate('Ymd', $time), "AWS4" . $this->secretAccessKey, true); $dateRegionKey = hash_hmac('sha256', $region, $dateKey, true); $dateRegionServiceKey = hash_hmac('sha256', $this->getServiceName(), $dateRegionKey, true); $signingKey = hash_hmac('sha256', 'aws4_request', $dateRegionServiceKey, true); //X-Amz-Signature $signature = hash_hmac('sha256', $stringToSign, $signingKey); $headers['Authorization'] = $opt['X-Amz-Algorithm'] . ' ' . 'Credential=' . $opt['X-Amz-Credential'] . ',' . 'SignedHeaders=' . $allHeaders['X-Amz-SignedHeaders'] . ',' . 'Signature=' . $signature; $request->addHeaders($headers); }
/** Performs the actual login * @warning Beware of exceptions. * @return TRUE on Success, FALSE on Failure. */ public function login() { try { //Create a new POST request $request = new \HttpRequest($this->_loginURL, \HTTP_METH_POST); //Set the content type $request->setContentType($this->_contentType); //Add POST data $request->addPostFields(array('accountType' => $this->_accountType, 'Email' => $this->_username, 'Passwd' => $this->_password, 'service' => $this->_service, 'source' => $this->_source)); //Should we include Captcha information? if (!empty($this->_captchaText) && !empty($this->_captchaToken)) { $request->addPostFields(array('logintoken' => $this->_captchaToken, 'logincaptcha' => $this->_captchaText)); } // print '------- REQUEST -------------'; // print_r($request); // //Make the request $response = $request->send(); // print '------- RESPONSE ------------'; // print_r($response); //Success? if ($response->getResponseCode() == HTTP_RESPONSE_OK) { //Split the repsonse body into tokens $tokens = explode("\n", $response->getBody()); //Save each token into the session object foreach ($tokens as $id_val) { //Split into token_name= $token = explode('=', $id_val); if (empty($token[0])) { //Skip invalid tokens continue; } //Save the tokens in the session object for future use $_SESSION[$this->getSessionKey() . '::' . $token[0]] = $token[1]; } $this->_success = true; return true; } //Captcha? if ($response->getResponseCode() == HTTP_RESPONSE_FORBIDDEN) { $captchaURL = ''; $captchaToken = ''; //Split the response body into tokens $tokens = explode("\n", $response->getBody()); foreach ($tokens as $id_val) { //This splits the parameters we got from Google into //ID=Value strings. $token[0]=id, $token[1]=value. //'2' allows the token to contain '=' chars $token = explode('=', $id_val, 2); if ($token[0] == 'CaptchaUrl') { $captchaURL = CAPTCHA_URL_PREFIX . trim($token[1]); } elseif ($token[0] == 'CaptchaToken') { $captchaToken = trim($token[1]); } } //Should we throw a CaptchaException? if (!empty($captchaToken) && !empty($captchaURL)) { throw new ClientLoginCaptchaException($captchaURL, $captchaToken); } else { throw new ClientLoginException($request->getBody()); } } } catch (HttpException $e) { throw new ClientLoginException("An error has occurred while trying" . " to login: " . $e->getMessage(), $e); } //For all other responses, return false return false; }