Search in sources :

Example 6 with Policy

use of org.opencastproject.urlsigning.common.Policy in project opencast by opencast.

the class GenericUrlSigningProviderTest method testSign.

@Test
public void testSign() throws UrlSigningException, ConfigurationException {
    properties.put(GenericUrlSigningProvider.ID_PREFIX + ".1", KEY_ID);
    properties.put(GenericUrlSigningProvider.URL_PREFIX + ".1", MATCHING_URI);
    properties.put(GenericUrlSigningProvider.KEY_PREFIX + ".1", KEY);
    properties.put(GenericUrlSigningProvider.ID_PREFIX + ".2", KEY_ID);
    properties.put(GenericUrlSigningProvider.URL_PREFIX + ".2", RTMP_MATCHER);
    properties.put(GenericUrlSigningProvider.KEY_PREFIX + ".2", KEY);
    signer.updated(properties);
    DateTime before = new DateTime(2020, 03, 01, 00, 46, 17, 0, DateTimeZone.UTC);
    // Handles a policy without query parameters.
    Policy withoutQuery = Policy.mkSimplePolicy(RESOURCE_PATH, before);
    String result = signer.sign(withoutQuery);
    logger.info(result);
    assertEquals("http://www.opencast.org/path/to/resource.mp4?policy=eyJTdGF0ZW1lbnQiOnsiQ29uZGl0aW9uIjp7IkRhdGVMZXNzVGhhbiI6MTU4MzAyMzU3NzAwMH0sIlJlc291cmNlIjoiaHR0cDpcL1wvd3d3Lm9wZW5jYXN0Lm9yZ1wvcGF0aFwvdG9cL3Jlc291cmNlLm1wNCJ9fQ&keyId=theId&signature=5b45e678275e6bc7b06a579f7f42e9a7ea5c58f1da130701db532f121e363e98", result);
    // Handles a policy with additional query parameters.
    Policy withQuery = Policy.mkSimplePolicy(RESOURCE_PATH + "?queryparam=this", before);
    result = signer.sign(withQuery);
    logger.info(result);
    assertEquals("http://www.opencast.org/path/to/resource.mp4?queryparam=this&policy=eyJTdGF0ZW1lbnQiOnsiQ29uZGl0aW9uIjp7IkRhdGVMZXNzVGhhbiI6MTU4MzAyMzU3NzAwMH0sIlJlc291cmNlIjoiaHR0cDpcL1wvd3d3Lm9wZW5jYXN0Lm9yZ1wvcGF0aFwvdG9cL3Jlc291cmNlLm1wND9xdWVyeXBhcmFtPXRoaXMifX0&keyId=theId&signature=0f9cab4393a5d0ebe2683124a92094c3ccf06ed07e87b8f60fa2bab3963bd462", result);
    // Handles rtmp protocol
    Policy withRtmp = Policy.mkSimplePolicy("rtmp://www.opencast.org/path/to/resource.mp4", before);
    result = signer.sign(withRtmp);
    logger.info(result);
    assertEquals("rtmp://www.opencast.org/path/to/resource.mp4?policy=eyJTdGF0ZW1lbnQiOnsiQ29uZGl0aW9uIjp7IkRhdGVMZXNzVGhhbiI6MTU4MzAyMzU3NzAwMH0sIlJlc291cmNlIjoicnRtcDpcL1wvd3d3Lm9wZW5jYXN0Lm9yZ1wvcGF0aFwvdG9cL3Jlc291cmNlLm1wNCJ9fQ&keyId=theId&signature=0464d9672fa5cb62ed82e7a6c46db5552dcd76590cf11efa5ba5222f53f5bbaa", result);
}
Also used : Policy(org.opencastproject.urlsigning.common.Policy) DateTime(org.joda.time.DateTime) Test(org.junit.Test)

Example 7 with Policy

use of org.opencastproject.urlsigning.common.Policy in project opencast by opencast.

the class UrlSigningFilterTest method testDeniedOnGone.

@Test
public void testDeniedOnGone() throws Exception {
    String encryptionKeyId = "theKey";
    String acceptedUrl = "http://accepted.com";
    String acceptedKey = "ThisIsTheKey";
    String acceptedIp = "10.0.0.1";
    DateTime future = new DateTime(4749125399000L);
    Policy policy = Policy.mkSimplePolicy(acceptedUrl, future);
    String acceptedQueryString = ResourceRequestUtil.policyToResourceRequestQueryString(policy, encryptionKeyId, acceptedKey);
    ResourceRequest acceptedRequest = new ResourceRequest();
    acceptedRequest.setStatus(Status.Gone);
    // Setup the Mock Url Signing Service
    UrlSigningVerifier urlSigningVerifier = EasyMock.createMock(UrlSigningVerifier.class);
    EasyMock.expect(urlSigningVerifier.verify(acceptedQueryString, acceptedIp, acceptedUrl, true)).andReturn(acceptedRequest);
    EasyMock.replay(urlSigningVerifier);
    UrlSigningFilter filter = new UrlSigningFilter();
    filter.updated(matchAllProperties);
    filter.setUrlSigningVerifier(urlSigningVerifier);
    // Setup the Mock Request
    HttpServletRequest request = EasyMock.createMock(HttpServletRequest.class);
    EasyMock.expect(request.getMethod()).andStubReturn("GET");
    EasyMock.expect(request.getRequestURL()).andStubReturn(new StringBuffer(acceptedUrl));
    EasyMock.expect(request.getQueryString()).andStubReturn(acceptedQueryString);
    EasyMock.expect(request.getRemoteAddr()).andStubReturn(acceptedIp);
    EasyMock.replay(request);
    HttpServletResponse response = EasyMock.createMock(HttpServletResponse.class);
    // Setup the mock filter chain.
    FilterChain chain = EasyMock.createMock(FilterChain.class);
    EasyMock.replay(chain);
    filter.doFilter(request, response, chain);
    EasyMock.verify(chain);
}
Also used : Policy(org.opencastproject.urlsigning.common.Policy) HttpServletRequest(javax.servlet.http.HttpServletRequest) FilterChain(javax.servlet.FilterChain) UrlSigningVerifier(org.opencastproject.security.urlsigning.verifier.UrlSigningVerifier) HttpServletResponse(javax.servlet.http.HttpServletResponse) ResourceRequest(org.opencastproject.urlsigning.common.ResourceRequest) DateTime(org.joda.time.DateTime) Test(org.junit.Test)

Example 8 with Policy

use of org.opencastproject.urlsigning.common.Policy in project opencast by opencast.

the class ResourceRequestUtilTest method testAuthenticatePolicyMatchesSignature.

@Test
public void testAuthenticatePolicyMatchesSignature() throws Exception {
    DateTime after = new DateTime(DateTimeZone.UTC);
    after = after.minus(2 * 60 * 60 * 1000L);
    DateTime before = new DateTime(DateTimeZone.UTC);
    before = before.plus(2 * 60 * 60 * 1000L);
    String nonMatchingResource = "http://other.com";
    Policy nonMatchingPolicy = Policy.mkSimplePolicy(nonMatchingResource, before);
    String matchingResource = "http://mh-allinone/";
    Policy matchingPolicy = Policy.mkSimplePolicy(matchingResource, before);
    String signature = PolicyUtils.getPolicySignature(matchingPolicy, key);
    // Test non-existant encryption key is forbidden.
    String wrongEncryptionKeyId = ResourceRequest.ENCRYPTION_ID_KEY + "=" + "WrongId" + "&" + ResourceRequest.POLICY_KEY + "=" + PolicyUtils.toBase64EncodedPolicy(matchingPolicy) + "&" + ResourceRequest.SIGNATURE_KEY + "=" + signature;
    assertEquals(Status.Forbidden, ResourceRequestUtil.resourceRequestFromQueryString(wrongEncryptionKeyId, clientIp, matchingResource, properties, true).getStatus());
    // Test non matching resource results is forbidden.
    String nonMatching = ResourceRequest.ENCRYPTION_ID_KEY + "=organization&" + ResourceRequest.POLICY_KEY + "=" + PolicyUtils.toBase64EncodedPolicy(nonMatchingPolicy) + "&" + ResourceRequest.SIGNATURE_KEY + "=" + signature;
    assertEquals(Status.Forbidden, ResourceRequestUtil.resourceRequestFromQueryString(nonMatching, clientIp, matchingResource, properties, true).getStatus());
    // Test non-matching client ip results in forbidden.
    Policy wrongClientPolicy = Policy.mkPolicyValidWithIP(matchingResource, before, "10.0.0.255");
    String wrongClient = ResourceRequestUtil.policyToResourceRequestQueryString(wrongClientPolicy, keyId, key);
    assertEquals(Status.Forbidden, ResourceRequestUtil.resourceRequestFromQueryString(wrongClient, clientIp, matchingResource, properties, true).getStatus());
    // Test matching client ip results in ok.
    Policy rightClientPolicy = Policy.mkPolicyValidWithIP(matchingResource, before, clientIp);
    String rightClient = ResourceRequestUtil.policyToResourceRequestQueryString(rightClientPolicy, keyId, key);
    assertEquals(Status.Ok, ResourceRequestUtil.resourceRequestFromQueryString(rightClient, clientIp, matchingResource, properties, true).getStatus());
    // Test not yet DateGreaterThan results in gone
    Policy wrongDateGreaterThanPolicy = Policy.mkPolicyValidFrom(matchingResource, before, before);
    String wrongDateGreaterThan = ResourceRequestUtil.policyToResourceRequestQueryString(wrongDateGreaterThanPolicy, keyId, key);
    assertEquals(Status.Gone, ResourceRequestUtil.resourceRequestFromQueryString(wrongDateGreaterThan, clientIp, matchingResource, properties, true).getStatus());
    // Test after DateGreaterThan results in ok
    Policy rightDateGreaterThanPolicy = Policy.mkPolicyValidFrom(matchingResource, before, after);
    String rightDateGreaterThan = ResourceRequestUtil.policyToResourceRequestQueryString(rightDateGreaterThanPolicy, keyId, key);
    assertEquals(Status.Ok, ResourceRequestUtil.resourceRequestFromQueryString(rightDateGreaterThan, clientIp, matchingResource, properties, true).getStatus());
    // Test before DateLessThan results in gone
    Policy wrongDateLessThanPolicy = Policy.mkSimplePolicy(matchingResource, after);
    String wrongDateLessThan = ResourceRequestUtil.policyToResourceRequestQueryString(wrongDateLessThanPolicy, keyId, key);
    assertEquals(Status.Gone, ResourceRequestUtil.resourceRequestFromQueryString(wrongDateLessThan, clientIp, matchingResource, properties, true).getStatus());
    // Test matching results in ok.
    String matching = ResourceRequest.ENCRYPTION_ID_KEY + "=" + keyId + "&" + ResourceRequest.POLICY_KEY + "=" + PolicyUtils.toBase64EncodedPolicy(matchingPolicy) + "&" + ResourceRequest.SIGNATURE_KEY + "=" + signature;
    assertEquals(Status.Ok, ResourceRequestUtil.resourceRequestFromQueryString(matching, clientIp, matchingResource, properties, true).getStatus());
}
Also used : Policy(org.opencastproject.urlsigning.common.Policy) DateTime(org.joda.time.DateTime) Test(org.junit.Test)

Example 9 with Policy

use of org.opencastproject.urlsigning.common.Policy in project opencast by opencast.

the class ResourceRequestUtilTest method testNonStrictResourceChecking.

@Test
public void testNonStrictResourceChecking() throws Exception {
    DateTime before = new DateTime(DateTimeZone.UTC);
    before = before.plus(2 * 60 * 60 * 1000L);
    String hostname = "signed.host.com";
    String path = "/path/to/resource";
    String rtmpResource = "rtmp://" + hostname + path;
    String httpResource = "http://" + hostname + path;
    String portResource = "rtmp://" + hostname + ":8080" + path;
    String differentHostnameResource = "rtmp://different.host.com" + path;
    Policy differentScheme = Policy.mkSimplePolicy(rtmpResource, before);
    String signature = PolicyUtils.getPolicySignature(differentScheme, key);
    String differentSchemeQueryString = ResourceRequest.ENCRYPTION_ID_KEY + "=default&" + ResourceRequest.POLICY_KEY + "=" + PolicyUtils.toBase64EncodedPolicy(differentScheme) + "&" + ResourceRequest.SIGNATURE_KEY + "=" + signature;
    assertEquals(Status.Ok, ResourceRequestUtil.resourceRequestFromQueryString(differentSchemeQueryString, clientIp, httpResource, properties, false).getStatus());
    assertEquals(Status.Forbidden, ResourceRequestUtil.resourceRequestFromQueryString(differentSchemeQueryString, clientIp, httpResource, properties, true).getStatus());
    assertEquals(Status.Ok, ResourceRequestUtil.resourceRequestFromQueryString(differentSchemeQueryString, clientIp, portResource, properties, false).getStatus());
    assertEquals(Status.Forbidden, ResourceRequestUtil.resourceRequestFromQueryString(differentSchemeQueryString, clientIp, portResource, properties, true).getStatus());
    assertEquals(Status.Ok, ResourceRequestUtil.resourceRequestFromQueryString(differentSchemeQueryString, clientIp, differentHostnameResource, properties, false).getStatus());
    assertEquals(Status.Forbidden, ResourceRequestUtil.resourceRequestFromQueryString(differentSchemeQueryString, clientIp, differentHostnameResource, properties, true).getStatus());
}
Also used : Policy(org.opencastproject.urlsigning.common.Policy) DateTime(org.joda.time.DateTime) Test(org.junit.Test)

Example 10 with Policy

use of org.opencastproject.urlsigning.common.Policy in project opencast by opencast.

the class ResourceRequestUtil method resourceRequestFromQueryString.

/**
 * @param queryString
 *          The query string for this request to determine its validity.
 * @param clientIp
 *          The IP of the client requesting the resource.
 * @param resourceUri
 *          The base uri for the resource.
 * @param encryptionKeys
 *          The available encryption key ids and their keys.
 * @param strict
 *          If false it will only compare the path to the resource instead of the entire URL including scheme,
 *          hostname, port etc.
 * @return ResourceRequest
 */
public static ResourceRequest resourceRequestFromQueryString(String queryString, String clientIp, String resourceUri, Properties encryptionKeys, boolean strict) {
    ResourceRequest resourceRequest = new ResourceRequest();
    List<NameValuePair> queryParameters = parseQueryString(queryString);
    if (!getQueryStringParameters(resourceRequest, queryParameters)) {
        return resourceRequest;
    }
    // Get the encryption key by its id.
    String encryptionKey = encryptionKeys.getProperty(resourceRequest.getEncryptionKeyId());
    if (StringUtils.isBlank(encryptionKey)) {
        resourceRequest.setStatus(Status.Forbidden);
        resourceRequest.setRejectionReason(String.format("Forbidden because unable to find an encryption key with ID '%s'.", resourceRequest.getEncryptionKeyId()));
        return resourceRequest;
    }
    // Get Policy
    Policy policy = PolicyUtils.fromBase64EncodedPolicy(resourceRequest.getEncodedPolicy());
    resourceRequest.setPolicy(policy);
    // return a Forbidden 403.
    if (!policyMatchesSignature(policy, resourceRequest.getSignature(), encryptionKey)) {
        resourceRequest.setStatus(Status.Forbidden);
        try {
            String policySignature = PolicyUtils.getPolicySignature(policy, encryptionKey);
            resourceRequest.setRejectionReason(String.format("Forbidden because policy and signature do not match. Policy: '%s' created Signature from this policy '%s' and query string Signature: '%s'.", PolicyUtils.toJson(resourceRequest.getPolicy()).toJSONString(), policySignature, resourceRequest.getSignature()));
        } catch (Exception e) {
            resourceRequest.setRejectionReason(String.format("Forbidden because policy and signature do not match. Policy: '%s' and query string Signature: '%s'. Unable to sign policy because: %s", PolicyUtils.toJson(resourceRequest.getPolicy()).toJSONString(), resourceRequest.getSignature(), ExceptionUtils.getStackTrace(e)));
        }
        return resourceRequest;
    }
    // If the IP address is specified, check it against the requestor's ip, if it doesn't match return a Forbidden 403.
    if (policy.getClientIpAddress().isPresent() && !policy.getClientIpAddress().get().getHostAddress().equalsIgnoreCase(clientIp)) {
        resourceRequest.setStatus(Status.Forbidden);
        resourceRequest.setRejectionReason(String.format("Forbidden because client trying to access the resource '%s' doesn't match the policy client '%s'", clientIp, resourceRequest.getPolicy().getClientIpAddress()));
        return resourceRequest;
    }
    // If the resource value in the policy doesn't match the requested resource return a Forbidden 403.
    if (strict && !policy.getResource().equals(resourceUri)) {
        resourceRequest.setStatus(Status.Forbidden);
        resourceRequest.setRejectionReason(String.format("Forbidden because resource trying to be accessed '%s' doesn't match policy resource '%s'", resourceUri, resourceRequest.getPolicy().getBaseUrl()));
        return resourceRequest;
    } else if (!strict) {
        try {
            String requestedPath = new URI(resourceUri).getPath();
            String policyPath = new URI(policy.getResource()).getPath();
            if (!policyPath.endsWith(requestedPath)) {
                resourceRequest.setStatus(Status.Forbidden);
                resourceRequest.setRejectionReason(String.format("Forbidden because resource trying to be accessed '%s' doesn't match policy resource '%s'", resourceUri, resourceRequest.getPolicy().getBaseUrl()));
                return resourceRequest;
            }
        } catch (URISyntaxException e) {
            resourceRequest.setStatus(Status.Forbidden);
            resourceRequest.setRejectionReason(String.format("Forbidden because either the policy or requested URI cannot be parsed. Policy Path: '%s' and Request Path: '%s'. Unable to sign policy because: %s", policy.getResource(), resourceUri, ExceptionUtils.getStackTrace(e)));
            return resourceRequest;
        }
    }
    // value of 410.
    if (new DateTime(DateTimeZone.UTC).isAfter(policy.getValidUntil().getMillis())) {
        resourceRequest.setStatus(Status.Gone);
        resourceRequest.setRejectionReason(String.format("The resource is gone because now '%s' is after the expiry time of '%s'", humanReadableFormat.print(new DateTime(DateTimeZone.UTC)), humanReadableFormat.print(new DateTime(policy.getValidUntil().getMillis(), DateTimeZone.UTC))));
        return resourceRequest;
    }
    if (policy.getValidFrom().isPresent() && new DateTime(DateTimeZone.UTC).isBefore(policy.getValidFrom().get().getMillis())) {
        resourceRequest.setStatus(Status.Gone);
        resourceRequest.setRejectionReason(String.format("The resource is gone because now '%s' is before the available time of ", humanReadableFormat.print(new DateTime(DateTimeZone.UTC)), humanReadableFormat.print(policy.getValidFrom().get())));
        return resourceRequest;
    }
    // If all of the above conditions pass, then allow the video to be played.
    resourceRequest.setStatus(Status.Ok);
    return resourceRequest;
}
Also used : Policy(org.opencastproject.urlsigning.common.Policy) BasicNameValuePair(org.apache.http.message.BasicNameValuePair) NameValuePair(org.apache.http.NameValuePair) ResourceRequest(org.opencastproject.urlsigning.common.ResourceRequest) URISyntaxException(java.net.URISyntaxException) URI(java.net.URI) URISyntaxException(java.net.URISyntaxException) DateTime(org.joda.time.DateTime)

Aggregations

Policy (org.opencastproject.urlsigning.common.Policy)17 DateTime (org.joda.time.DateTime)16 Test (org.junit.Test)14 ResourceRequest (org.opencastproject.urlsigning.common.ResourceRequest)7 HttpServletRequest (javax.servlet.http.HttpServletRequest)6 FilterChain (javax.servlet.FilterChain)5 HttpServletResponse (javax.servlet.http.HttpServletResponse)5 UrlSigningVerifier (org.opencastproject.security.urlsigning.verifier.UrlSigningVerifier)5 URI (java.net.URI)1 URISyntaxException (java.net.URISyntaxException)1 Properties (java.util.Properties)1 NameValuePair (org.apache.http.NameValuePair)1 BasicNameValuePair (org.apache.http.message.BasicNameValuePair)1 UrlSigningException (org.opencastproject.security.urlsigning.exception.UrlSigningException)1 UrlSigningProvider (org.opencastproject.security.urlsigning.provider.UrlSigningProvider)1