/** * @brief Create an AWS V3 Signature authorization header value. * * This function builds a V3 signature, and returns it to the caller. The returned * header value is then suitable for adding as an `Authorization` header in the HTTP * request, to be accepted by Amazon. * * @param credentials The AWS credentials to use to sign the request. * @param operation The HTTP method being used for the request. * @param request The network request to generate a signature for. * @param payload Optional data being submitted in the request (eg for `PUT` and `POST` operations). * * @return An AWS V3 Signature authorization header value. * * @see http://docs.aws.amazon.com/Route53/latest/DeveloperGuide/RESTAuthentication.html * @see setAuthorizationHeader */ QByteArray AwsSignatureV3Private::authorizationHeaderValue(const AwsAbstractCredentials &credentials, const QNetworkAccessManager::Operation operation, QNetworkRequest &request, const QByteArray &payload) const { // Calculate the signature. QByteArray signedHeaders; QByteArray stringToSign = canonicalRequest(operation, request, payload, &signedHeaders); if (!isHttps(request)) { stringToSign = QCryptographicHash::hash(stringToSign, hashAlgorithm); } const QByteArray signature = QMessageAuthenticationCode::hash( stringToSign, credentials.secretKey().toUtf8(), hashAlgorithm); // Build and return the authorization header value. return QByteArray((isHttps(request)) ? "AWS3-HTTPS " : "AWS3 ") + "AWSAccessKeyId=" + credentials.accessKeyId().toUtf8() + "," "Algorithm=" + algorithmDesignation(hashAlgorithm) + "," + ((!isHttps(request)) ? "SignedHeaders=" + signedHeaders + ',' : "") + "Signature=" + signature.toBase64(); }
/** * @brief Create an AWS V3 Signature canonical request. * * Note, this function implments both `AWS3` and `AWS3-HTTPS` variants of the * AWS Signature version 3 - which are quite different. * * @param[in] operation The HTTP method being used for the request. * @param[in] request The network request to generate a canonical request for. * @param[in] payload Optional data being submitted in the request (eg for `PUT` and `POST` operations). * @param[out] signedHeaders A semi-colon separated list of the names of all headers * included in the result. * * @return An AWS V3 Signature canonical request. * * @see http://docs.aws.amazon.com/amazonswf/latest/developerguide/HMACAuth-swf.html (AWS3) * @see http://docs.aws.amazon.com/Route53/latest/DeveloperGuide/RESTAuthentication.html (AWS3-HTTPS) */ QByteArray AwsSignatureV3Private::canonicalRequest(const QNetworkAccessManager::Operation operation, const QNetworkRequest &request, const QByteArray &payload, QByteArray * const signedHeaders) const { // AWS3-HTTPS if (isHttps(request)) { Q_ASSERT((request.hasRawHeader("x-amz-date")) || (request.hasRawHeader("Date"))); QByteArray canonicalRequest = request.rawHeader(request.hasRawHeader("x-amz-date") ? "x-amz-date" : "Date"); if (request.hasRawHeader("x-amz-nonce")) { canonicalRequest += request.rawHeader("x-amz-nonce"); } return canonicalRequest; } // AWS3 return httpMethod(operation).toUtf8() + '\n' + canonicalPath(request.url()).toUtf8() + '\n' + canonicalQuery(QUrlQuery(request.url())) + '\n' + canonicalHeaders(request, signedHeaders) + '\n' + payload; }
nsresult nsDownloadScanner::Scan::Start() { mStartTime = PR_Now(); mThread = (HANDLE)_beginthreadex(NULL, 0, ScannerThreadFunction, this, CREATE_SUSPENDED, NULL); if (!mThread) return NS_ERROR_OUT_OF_MEMORY; nsresult rv = NS_OK; // Default is to try to clean downloads mIsReadOnlyRequest = PR_FALSE; nsCOMPtr<nsIPrefBranch> pref = do_GetService(NS_PREFSERVICE_CONTRACTID); if (pref) rv = pref->GetBoolPref(PREF_BDA_DONTCLEAN, &mIsReadOnlyRequest); // Get the path to the file on disk nsCOMPtr<nsILocalFile> file; rv = mDownload->GetTargetFile(getter_AddRefs(file)); NS_ENSURE_SUCCESS(rv, rv); rv = file->GetPath(mPath); NS_ENSURE_SUCCESS(rv, rv); // Grab the app name nsCOMPtr<nsIXULAppInfo> appinfo = do_GetService(XULAPPINFO_SERVICE_CONTRACTID, &rv); NS_ENSURE_SUCCESS(rv, rv); nsCAutoString name; rv = appinfo->GetName(name); NS_ENSURE_SUCCESS(rv, rv); CopyUTF8toUTF16(name, mName); // Get the origin nsCOMPtr<nsIURI> uri; rv = mDownload->GetSource(getter_AddRefs(uri)); NS_ENSURE_SUCCESS(rv, rv); nsCAutoString origin; rv = uri->GetSpec(origin); NS_ENSURE_SUCCESS(rv, rv); CopyUTF8toUTF16(origin, mOrigin); // We count https/ftp/http as an http download PRBool isHttp(PR_FALSE), isFtp(PR_FALSE), isHttps(PR_FALSE); nsCOMPtr<nsIURI> innerURI = NS_GetInnermostURI(uri); if (!innerURI) innerURI = uri; (void)innerURI->SchemeIs("http", &isHttp); (void)innerURI->SchemeIs("ftp", &isFtp); (void)innerURI->SchemeIs("https", &isHttps); mIsHttpDownload = isHttp || isFtp || isHttps; // IAttachementExecute prohibits src data: schemes by default but we // support them. Mark the download if it's a data scheme, so we // can skip off supplying the src to IAttachementExecute when we scan // the resulting file. (void)innerURI->SchemeIs("data", &mSkipSource); // ResumeThread returns the previous suspend count if (1 != ::ResumeThread(mThread)) { CloseHandle(mThread); return NS_ERROR_UNEXPECTED; } return NS_OK; }