diff --git a/lib/api/apiUtils/authorization/permissionChecks.js b/lib/api/apiUtils/authorization/permissionChecks.js index d46cf05949..db763dfa42 100644 --- a/lib/api/apiUtils/authorization/permissionChecks.js +++ b/lib/api/apiUtils/authorization/permissionChecks.js @@ -255,28 +255,17 @@ function _checkBucketPolicyActions(requestType, actions, log) { return evaluators.isActionApplicable(mappedAction, actions, log); } -function _checkBucketPolicyResources(request, resource, log) { - if (!request || (Array.isArray(resource) && resource.length === 0)) { +function _checkBucketPolicyResources(requestContext, resource, log) { + if (!requestContext || (Array.isArray(resource) && resource.length === 0)) { return true; } - // build request context from the request! - const requestContext = new RequestContext(request.headers, request.query, - request.bucketName, request.objectKey, null, - request.connection.encrypted, request.resourceType, 's3'); return evaluators.isResourceApplicable(requestContext, resource, log); } -function _checkBucketPolicyConditions(request, conditions, log) { - const ip = request ? requestUtils.getClientIp(request, config) : undefined; - if (!conditions) { +function _checkBucketPolicyConditions(requestContext, conditions, log) { + if (!requestContext || !conditions) { return true; } - // build request context from the request! - const requestContext = new RequestContext(request.headers, request.query, - request.bucketName, request.objectKey, ip, - request.connection.encrypted, request.resourceType, 's3', null, null, - null, null, null, null, null, null, null, null, null, - request.objectLockRetentionDays); return evaluators.meetConditions(requestContext, conditions, log); } @@ -332,12 +321,22 @@ function checkBucketPolicy(policy, requestType, canonicalID, arn, bucketOwner, l permission = 'allow'; } let copiedStatement = JSON.parse(JSON.stringify(policy.Statement)); + + const ip = request ? requestUtils.getClientIp(request, config) : undefined; + const isSecure = request ? requestUtils.getHttpProtocolSecurity(request, config) : undefined; + const requestContext = request ? new RequestContext(request.headers, request.query, + request.bucketName, request.objectKey, ip, + isSecure, request.resourceType, 's3', null, null, + null, null, null, null, null, null, null, null, null, + request.objectLockRetentionDays) : undefined; + while (copiedStatement.length > 0) { const s = copiedStatement[0]; + const principalMatch = _checkPrincipals(canonicalID, arn, s.Principal); const actionMatch = _checkBucketPolicyActions(requestType, s.Action, log); - const resourceMatch = _checkBucketPolicyResources(request, s.Resource, log); - const conditionsMatch = _checkBucketPolicyConditions(request, s.Condition, log); + const resourceMatch = _checkBucketPolicyResources(requestContext, s.Resource, log); + const conditionsMatch = _checkBucketPolicyConditions(requestContext, s.Condition, log); if (principalMatch && actionMatch && resourceMatch && conditionsMatch && s.Effect === 'Deny') { // explicit deny trumps any allows, so return immediately diff --git a/lib/api/apiUtils/authorization/prepareRequestContexts.js b/lib/api/apiUtils/authorization/prepareRequestContexts.js index fa82b15cec..e2005901bc 100644 --- a/lib/api/apiUtils/authorization/prepareRequestContexts.js +++ b/lib/api/apiUtils/authorization/prepareRequestContexts.js @@ -45,12 +45,12 @@ function prepareRequestContexts(apiMethod, request, sourceBucket, // check. const ip = requestUtils.getClientIp(request, config); + const isSecure = requestUtils.getHttpProtocolSecurity(request, config); function generateRequestContext(apiMethod) { return new RequestContext(request.headers, request.query, request.bucketName, request.objectKey, - ip, request.connection.encrypted, - apiMethod, 's3'); + ip, isSecure, apiMethod, 's3'); } if (apiMethod === 'bucketPut') { @@ -84,7 +84,7 @@ function prepareRequestContexts(apiMethod, request, sourceBucket, { versionId: sourceVersionId }); const getRequestContext = new RequestContext(request.headers, reqQuery, sourceBucket, sourceObject, - ip, request.connection.encrypted, + ip, isSecure, objectGetAction, 's3'); const putRequestContext = generateRequestContext('objectPut'); requestContexts.push(getRequestContext, putRequestContext); diff --git a/lib/api/apiUtils/object/objectLockHelpers.js b/lib/api/apiUtils/object/objectLockHelpers.js index c1000b0e6e..4d2c9eb95d 100644 --- a/lib/api/apiUtils/object/objectLockHelpers.js +++ b/lib/api/apiUtils/object/objectLockHelpers.js @@ -283,6 +283,7 @@ function checkUserGovernanceBypass(request, authInfo, bucketMD, objectKey, log, const authParams = auth.server.extractParams(request, log, 's3', request.query); const ip = policies.requestUtils.getClientIp(request, config); + const isSecure = policies.requestUtils.getHttpProtocolSecurity(request, config); const requestContextParams = { constantParams: { headers: request.headers, @@ -290,7 +291,7 @@ function checkUserGovernanceBypass(request, authInfo, bucketMD, objectKey, log, generalResource: bucketMD.getName(), specificResource: { key: objectKey }, requesterIp: ip, - sslEnabled: request.connection.encrypted, + sslEnabled: isSecure, apiMethod: 'bypassGovernanceRetention', awsService: 's3', locationConstraint: bucketMD.getLocationConstraint(), diff --git a/lib/api/bucketPut.js b/lib/api/bucketPut.js index 60edb556c9..ecb71d50f0 100644 --- a/lib/api/bucketPut.js +++ b/lib/api/bucketPut.js @@ -111,7 +111,8 @@ function _parseXML(request, log, cb) { }); } -function _buildConstantParams({ request, bucketName, authInfo, authParams, ip, locationConstraint, apiMethod }) { +function _buildConstantParams({ + request, bucketName, authInfo, authParams, ip, isSecure, locationConstraint, apiMethod }) { return { constantParams: { headers: request.headers, @@ -121,7 +122,7 @@ function _buildConstantParams({ request, bucketName, authInfo, authParams, ip, l key: '', }, requesterIp: ip, - sslEnabled: request.connection.encrypted, + sslEnabled: isSecure, awsService: 's3', requesterInfo: authInfo, signatureVersion: authParams.params.data.authType, @@ -165,9 +166,11 @@ function _isAclProvided(headers) { function authBucketPut(authParams, bucketName, locationConstraint, request, authInfo) { const ip = requestUtils.getClientIp(request, config); + const isSecure = requestUtils.getHttpProtocolSecurity(request, config); const baseParams = { authParams, ip, + isSecure, bucketName, request, authInfo, diff --git a/lib/api/multiObjectDelete.js b/lib/api/multiObjectDelete.js index 36620d7f2f..b1a1949f3d 100644 --- a/lib/api/multiObjectDelete.js +++ b/lib/api/multiObjectDelete.js @@ -464,7 +464,6 @@ function getObjMetadataAndDelete(authInfo, canonicalID, request, * @param {string} request.post - concatenation of request body * @param {string} request.bucketName - parsed bucketName * @param {string} request.socket.remoteAddress - requester IP - * @param {boolean} request.connection.encrypted - whether request was encrypted * @param {object} log - Werelogs logger * @param {function} callback - callback to server * @return {undefined} @@ -487,6 +486,8 @@ function multiObjectDelete(authInfo, request, log, callback) { const inPlayInternal = []; const bucketName = request.bucketName; const canonicalID = authInfo.getCanonicalID(); + const ip = requestUtils.getClientIp(request, config); + const isSecure = requestUtils.getHttpProtocolSecurity(request, config); return async.waterfall([ function parseXML(next) { @@ -546,14 +547,13 @@ function multiObjectDelete(authInfo, request, log, callback) { // params on to this api const authParams = auth.server.extractParams(request, log, 's3', request.query); - const ip = requestUtils.getClientIp(request, config); const requestContextParams = { constantParams: { headers: request.headers, query: request.query, generalResource: request.bucketName, requesterIp: ip, - sslEnabled: request.connection.encrypted, + sslEnabled: isSecure, apiMethod: 'objectDelete', awsService: 's3', locationConstraint: null, diff --git a/lib/routes/routeMetadata.js b/lib/routes/routeMetadata.js index 24b22385c1..a5cac213e2 100644 --- a/lib/routes/routeMetadata.js +++ b/lib/routes/routeMetadata.js @@ -50,9 +50,10 @@ function routeMetadata(clientIP, request, response, log) { return responseJSONBody(errors.NotImplemented, null, response, log); } const ip = requestUtils.getClientIp(request, config); + const isSecure = requestUtils.getHttpProtocolSecurity(request, config); const requestContexts = [new RequestContext(request.headers, request.query, request.generalResource, request.specificResource, ip, - request.connection.encrypted, request.resourceType, 'metadata')]; + isSecure, request.resourceType, 'metadata')]; return waterfall([ next => auth.server.doAuth(request, log, (err, userInfo, authRes) => { if (err) { diff --git a/tests/unit/api/deleteMarker.js b/tests/unit/api/deleteMarker.js index 59df47a2c9..a5610c057e 100644 --- a/tests/unit/api/deleteMarker.js +++ b/tests/unit/api/deleteMarker.js @@ -64,6 +64,9 @@ function _createMultiObjectDeleteRequest(numObjects) { }, url: '/?delete', query: { delete: '' }, + socket: { + remoteAddress: '127.0.0.1', + }, actionImplicitDenies: false, }; const xml = []; diff --git a/tests/unit/api/multiObjectDelete.js b/tests/unit/api/multiObjectDelete.js index bb339cc968..3ce076af02 100644 --- a/tests/unit/api/multiObjectDelete.js +++ b/tests/unit/api/multiObjectDelete.js @@ -380,6 +380,9 @@ describe('multiObjectDelete function', () => { 'content-md5': crypto.createHash('md5').update(post, 'utf8').digest('base64') }, post, + socket: { + remoteAddress: '127.0.0.1', + }, url: '/bucketname', }); const authInfo = makeAuthInfo('123456');