Beispiel #1
0
 @SuppressWarnings({"unchecked", "rawtypes"})
 @Override
 public boolean apply(Class input) {
   if (Function.class.isAssignableFrom(input) && Ats.from(input).has(ErrorMessages.class)) {
     try {
       ErrorMessages annote = Ats.from(input).get(ErrorMessages.class);
       Function<Class, String> errorFunction =
           (Function<Class, String>) Classes.builder(input).newInstance();
       ConcurrentMap<Class, String> errorMap =
           new MapMaker()
               .expireAfterAccess(60, TimeUnit.SECONDS)
               .makeComputingMap(errorFunction);
       classErrorMessages.put(annote.value(), errorMap);
       return true;
     } catch (UndeclaredThrowableException ex) {
       LOG.error(ex, ex);
       return false;
     }
   } else {
     Discovery discovery = Ats.from(ErrorMessageDiscovery.class).get(Discovery.class);
     LOG.error(
         "Annotated Discovery supplied class argument that does not conform to one of: value()="
             + discovery.value()
             + " (assignable types) or annotations()="
             + discovery.annotations());
     return false;
   }
 }
Beispiel #2
0
 private static FilteredPipeline findAccepting(final HttpRequest request) {
   final FilteredPipeline candidate = null;
   for (final FilteredPipeline f : pipelines) {
     if (f.checkAccepts(request)) {
       return f;
     }
   }
   if (request.getHeader(HttpHeaders.Names.HOST).contains("amazonaws.com")
       || request.getHeader(HttpHeaders.Names.HOST).contains(subDomain.get())) {
     String hostHeader = request.getHeader(HttpHeaders.Names.HOST);
     LOG.debug("Trying to intercept request for " + hostHeader);
     for (final FilteredPipeline f : pipelines) {
       if (Ats.from(f).has(ComponentPart.class)) {
         Class<? extends ComponentId> compIdClass = Ats.from(f).get(ComponentPart.class).value();
         ComponentId compId = ComponentIds.lookup(compIdClass);
         if (Ats.from(compIdClass).has(PublicService.class)) {
           if (request.getHeaderNames().contains("SOAPAction")
               && f.addHandlers(Channels.pipeline()).get(SoapHandler.class) == null) {
             continue; // Skip pipeline which doesn't handle SOAP for this SOAP request
           } else if (!request.getHeaderNames().contains("SOAPAction")
               && f.addHandlers(Channels.pipeline()).get(SoapHandler.class) != null) {
             continue; // Skip pipeline which handles SOAP for this non-SOAP request
           }
           LOG.debug("Maybe intercepting: " + hostHeader + " using " + f.getClass());
           if (Ats.from(compIdClass).has(AwsServiceName.class)
               && request
                   .getHeader(HttpHeaders.Names.HOST)
                   .matches(
                       "[\\w\\.-_]*" + compId.getAwsServiceName() + "\\.\\w+\\.amazonaws.com")) {
             return f; // Return pipeline which can handle the request for
                       // ${service}.${region}.amazonaws.com
           } else if (request
               .getHeader(HttpHeaders.Names.HOST)
               .matches("[\\w\\.-_]*" + compId.name() + "\\." + subDomain.get())) {
             return f; // Return pipeline which can handle the request for
                       // ${service}.${system.dns.dnsdomain}
           }
         }
       }
     }
   }
   if (candidate == null) {
     for (final FilteredPipeline f : internalPipelines) {
       if (f.checkAccepts(request)) {
         return f;
       }
     }
   }
   return candidate;
 }
Beispiel #3
0
 static String lookatPersistenceContext(final Object obj) throws RuntimeException {
   final Class type = Classes.typeOf(obj);
   final Ats ats = Ats.inClassHierarchy(type);
   PersistenceContext persistenceContext = null;
   if (!ats.has(PersistenceContext.class)) {
     throw new RuntimeException(
         "Attempting to create an entity wrapper instance for non persistent type: "
             + type
             + ".  Class hierarchy contains: \n"
             + ats.toString());
   } else {
     persistenceContext = ats.get(PersistenceContext.class);
   }
   return persistenceContext.name();
 }
 public String process() {
   if (this.type.getCanonicalName() == null) {
     //          new RuntimeException( "Ignoring anonymous class: " + this.type
     // ).printStackTrace( );
   } else {
     this.elem(Elem.mapping);
     if (this.abs) {
       this.attr("abstract", "true");
     } else {
       this.attr("name", this.type.getSimpleName())
           .attr("extends", this.type.getSuperclass().getCanonicalName());
     }
     this.attr("class", this.type.getCanonicalName());
     if (BindingFileSearch.INSTANCE.MSG_BASE_CLASS.isAssignableFrom(this.type.getSuperclass())
         || BindingFileSearch.INSTANCE.MSG_DATA_CLASS.isAssignableFrom(
             this.type.getSuperclass())) {
       this.elem(Elem.structure)
           .attr("map-as", this.type.getSuperclass().getCanonicalName())
           .end();
     }
     for (Field f : this.type.getDeclaredFields()) {
       if (!Ats.from(f).has(Transient.class) || Modifier.isTransient(f.getModifiers())) {
         TypeBinding tb = getTypeBinding(f);
         if (!(tb instanceof NoopTypeBinding)) {
           //                System.out.printf( "BOUND:  %-70s [type=%s:%s]\n",
           // f.getDeclaringClass( ).getCanonicalName( ) +"."+ f.getName( ), tb.getTypeName( ),
           // f.getType( ).getCanonicalName( ) );
           this.append(tb.toString());
         }
       }
     }
     this.end();
   }
   return this.toString();
 }
 @Override
 public boolean processClass(Class candidate) throws Exception {
   if (Ats.from(candidate).has(ObjectStorageProviderClientProperty.class)
       && !Modifier.isAbstract(candidate.getModifiers())
       && !Modifier.isInterface(candidate.getModifiers())) {
     ObjectStorageProviderClientProperty candidateType =
         Ats.from(candidate).get(ObjectStorageProviderClientProperty.class);
     String propName = candidateType.value();
     if (ObjectStorageProviderClient.class.isAssignableFrom(candidate)) {
       clients.put(propName, candidate);
     }
     return true;
   } else {
     return false;
   }
 }
Beispiel #6
0
    @SuppressWarnings({"rawtypes", "unchecked", "synthetic-access"})
    @Override
    public boolean processClass(final Class candidate) throws Exception {
      if (FilteredPipeline.class.isAssignableFrom(candidate)
          && !Modifier.isAbstract(candidate.getModifiers())
          && !Modifier.isInterface(candidate.getModifiers())
          && Ats.from(candidate).has(ComponentPart.class)) {
        try {
          final ComponentId compId =
              Ats.from(candidate).get(ComponentPart.class).value().newInstance();
          final Class<? extends FilteredPipeline> pipelineClass = candidate;
          final FilteredPipeline pipeline = Classes.newInstance(pipelineClass);
          Pipelines.pipelines.add(pipeline);
          return true;
        } catch (final Exception ex) {
          LOG.trace(ex, ex);
          return false;
        }
      } else if (ChannelPipelineFactory.class.isAssignableFrom(candidate)
          && !Modifier.isAbstract(candidate.getModifiers())
          && !Modifier.isInterface(candidate.getModifiers())
          && Ats.from(candidate).has(ComponentPart.class)) {
        try {
          final ComponentId compId =
              Ats.from(candidate).get(ComponentPart.class).value().newInstance();
          final Class<? extends ChannelPipelineFactory> pipelineClass = candidate;
          final ChannelPipelineFactory pipeline = Classes.newInstance(pipelineClass);
          Pipelines.clientPipelines.put(compId.getClass(), pipeline);
          return true;
        } catch (final Exception ex) {
          LOG.trace(ex, ex);
          return false;
        }

      } else {
        return false;
      }
    }
 @SuppressWarnings("ThrowableResultOfMethodCallIgnored")
 public void handle(final ExceptionMessage exMsg) {
   EventRecord.here(getClass(), EventType.MSG_REPLY, exMsg.getPayload().getClass().getSimpleName())
       .debug();
   LOG.trace("Caught exception while servicing: " + exMsg.getPayload());
   final Throwable exception = exMsg.getException();
   if (exception instanceof MessagingException
       && exception.getCause() instanceof EucalyptusCloudException) {
     try {
       final EucalyptusCloudException cloudException =
           (EucalyptusCloudException) exception.getCause();
       final BaseMessage payload = parsePayload(exMsg.getPayload());
       final HttpResponseStatus status;
       final Role role;
       final String code;
       if (cloudException instanceof EucalyptusWebServiceException) {
         final EucalyptusWebServiceException webServiceException =
             (EucalyptusWebServiceException) cloudException;
         role = webServiceException.getRole();
         code = webServiceException.getCode();
       } else {
         role = Role.Receiver;
         code = defaultCode;
       }
       final QueryBindingInfo info =
           Ats.inClassHierarchy(cloudException.getClass()).get(QueryBindingInfo.class);
       status =
           info == null
               ? HttpResponseStatus.INTERNAL_SERVER_ERROR
               : new HttpResponseStatus(info.statusCode(), code);
       final BaseMessage errorResp =
           buildErrorResponse(payload.getCorrelationId(), role, code, cloudException.getMessage());
       Contexts.response(new BaseMessageSupplier(errorResp, status));
     } catch (final PayloadParseException e) {
       LOG.error("Failed to parse payload ", e.getCause());
     }
   } else {
     LOG.error("Unable to handle exception", exception);
     final BaseMessage errorResp = buildFatalResponse(exception);
     Contexts.response(
         new BaseMessageSupplier(errorResp, HttpResponseStatus.INTERNAL_SERVER_ERROR));
   }
 }
Beispiel #8
0
    @Override
    public void handleUpstream(
        final ChannelHandlerContext channelHandlerContext, final ChannelEvent channelEvent)
        throws Exception {
      if (channelEvent instanceof MessageEvent && componentIdClass != null) {
        final BaseMessage message = BaseMessage.extractMessage(channelEvent);
        final ComponentMessage componentMessage =
            message == null
                ? null
                : Ats.inClassHierarchy(message.getClass()).get(ComponentMessage.class);
        if (message != null
            && (componentMessage == null || !componentIdClass.equals(componentMessage.value()))) {
          LOG.warn(
              String.format(
                  "Message %s does not match pipeline component %s",
                  message.getClass(), componentIdClass.getSimpleName()));

          final MappingHttpMessage mappingHttpMessage =
              MappingHttpMessage.extractMessage(channelEvent);
          final BaseMessage baseMessage = BaseMessage.extractMessage(channelEvent);
          if (baseMessage != null) {
            Contexts.clear(Contexts.lookup(baseMessage.getCorrelationId()));
          }
          channelHandlerContext
              .getChannel()
              .write(
                  new MappingHttpResponse(
                      mappingHttpMessage == null
                          ? HttpVersion.HTTP_1_1
                          : mappingHttpMessage.getProtocolVersion(),
                      HttpResponseStatus.BAD_REQUEST));
          return;
        }
      }
      channelHandlerContext.sendUpstream(channelEvent);
    }
  /**
   * Evaluates the authorization for the operation requested, evaluates IAM, ACL, and bucket policy
   * (bucket policy not yet supported).
   *
   * @param request
   * @param bucketResourceEntity
   * @param objectResourceEntity
   * @param resourceAllocationSize the size for the quota check(s) if applicable
   * @return
   */
  public <T extends ObjectStorageRequestType> boolean operationAllowed(
      @Nonnull T request,
      @Nullable final S3AccessControlledEntity bucketResourceEntity,
      @Nullable final S3AccessControlledEntity objectResourceEntity,
      long resourceAllocationSize)
      throws IllegalArgumentException {
    /*
     * Process the operation's authz requirements based on the request type annotations
     */
    Ats requestAuthzProperties = Ats.from(request);
    ObjectStorageProperties.Permission[] requiredBucketACLPermissions = null;
    ObjectStorageProperties.Permission[] requiredObjectACLPermissions = null;
    Boolean allowOwnerOnly = null;
    RequiresACLPermission requiredACLs = requestAuthzProperties.get(RequiresACLPermission.class);
    if (requiredACLs != null) {
      requiredBucketACLPermissions = requiredACLs.bucket();
      requiredObjectACLPermissions = requiredACLs.object();
      allowOwnerOnly = requiredACLs.ownerOnly();
    } else {
      // No ACL annotation is ok, maybe a admin only op
    }

    String[] requiredActions = null;
    RequiresPermission perms = requestAuthzProperties.get(RequiresPermission.class);
    if (perms != null) {
      requiredActions = perms.value();
    }

    Boolean allowAdmin = (requestAuthzProperties.get(AdminOverrideAllowed.class) != null);
    Boolean allowOnlyAdmin =
        (requestAuthzProperties.get(AdminOverrideAllowed.class) != null)
            && requestAuthzProperties.get(AdminOverrideAllowed.class).adminOnly();

    // Must have at least one of: admin-only, owner-only, ACL, or IAM.
    if (requiredBucketACLPermissions == null
        && requiredObjectACLPermissions == null
        && requiredActions == null
        && !allowAdmin) {
      // Insufficient permission set on the message type.
      LOG.error(
          "Insufficient permission annotations on type: "
              + request.getClass().getName()
              + " cannot evaluate authorization");
      return false;
    }

    String resourceType = null;
    if (requestAuthzProperties.get(ResourceType.class) != null) {
      resourceType = requestAuthzProperties.get(ResourceType.class).value();
    }

    // Use these variables to isolate where all the AuthExceptions can happen on account/user
    // lookups
    User requestUser = null;
    String securityToken = null;
    Account requestAccount = null;
    AuthContextSupplier authContext = null;
    try {
      // Use context if available as it saves a DB lookup
      try {
        Context ctx = Contexts.lookup(request.getCorrelationId());
        requestUser = ctx.getUser();
        securityToken = ctx.getSecurityToken();
        requestAccount = requestUser.getAccount();
        authContext = ctx.getAuthContext();
      } catch (NoSuchContextException e) {
        requestUser = null;
        securityToken = null;
        requestAccount = null;
        authContext = null;
      }

      // This is not an expected path, but if no context found use the request credentials itself
      if (requestUser == null && !Strings.isNullOrEmpty(request.getEffectiveUserId())) {
        requestUser = Accounts.lookupUserById(request.getEffectiveUserId());
        requestAccount = requestUser.getAccount();
      }

      if (requestUser == null) {
        if (!Strings.isNullOrEmpty(request.getAccessKeyID())) {
          if (securityToken != null) {
            requestUser = SecurityTokenManager.lookupUser(request.getAccessKeyID(), securityToken);
          } else {
            requestUser = Accounts.lookupUserByAccessKeyId(request.getAccessKeyID());
          }
          requestAccount = requestUser.getAccount();
        } else {
          // Set to anonymous user since all else failed
          requestUser = Principals.nobodyUser();
          requestAccount = requestUser.getAccount();
        }
      }
    } catch (AuthException e) {
      LOG.error(
          "Failed to get user for request, cannot verify authorization: " + e.getMessage(), e);
      return false;
    }

    if (allowAdmin && requestUser.isSystemAdmin()) {
      // Admin override
      return true;
    }

    if (authContext == null) {
      authContext =
          Permissions.createAuthContextSupplier(
              requestUser, Collections.<String, String>emptyMap());
    }

    Account resourceOwnerAccount = null;
    if (resourceType == null) {
      LOG.error("No resource type found in request class annotations, cannot process.");
      return false;
    } else {
      try {
        // Ensure we have the proper resource entities present and get owner info
        if (PolicySpec.S3_RESOURCE_BUCKET.equals(resourceType)) {
          // Get the bucket owner.
          if (bucketResourceEntity == null) {
            LOG.error(
                "Could not check access for operation due to no bucket resource entity found");
            return false;
          } else {
            resourceOwnerAccount =
                Accounts.lookupAccountByCanonicalId(bucketResourceEntity.getOwnerCanonicalId());
          }
        } else if (PolicySpec.S3_RESOURCE_OBJECT.equals(resourceType)) {
          if (objectResourceEntity == null) {
            LOG.error(
                "Could not check access for operation due to no object resource entity found");
            return false;
          } else {
            resourceOwnerAccount =
                Accounts.lookupAccountByCanonicalId(objectResourceEntity.getOwnerCanonicalId());
          }
        }
      } catch (AuthException e) {
        LOG.error("Exception caught looking up resource owner. Disallowing operation.", e);
        return false;
      }
    }

    // Get the resourceId based on IAM resource type
    String resourceId = null;
    if (resourceId == null) {
      if (PolicySpec.S3_RESOURCE_BUCKET.equals(resourceType)) {
        resourceId = request.getBucket();
      } else if (PolicySpec.S3_RESOURCE_OBJECT.equals(resourceType)) {
        resourceId = request.getFullResource();
      }
    }

    if (allowAdmin
        && requestUser.isSystemUser()
        && iamPermissionsAllow(
            authContext, requiredActions, resourceType, resourceId, resourceAllocationSize)) {
      // Admin override
      return true;
    }

    if (requiredBucketACLPermissions == null && requiredObjectACLPermissions == null) {
      throw new IllegalArgumentException(
          "No requires-permission actions found in request class annotations, cannot process.");
    }

    /* ACL Checks: Is the user's account allowed? */
    Boolean aclAllow = false;
    if (requiredBucketACLPermissions != null && requiredBucketACLPermissions.length > 0) {
      // Check bucket ACLs

      if (bucketResourceEntity == null) {
        // There are bucket ACL requirements but no bucket entity to check. fail.
        // Don't bother with other checks, this is an invalid state
        LOG.error("Null bucket resource, cannot evaluate bucket ACL");
        return false;
      }

      // Evaluate the bucket ACL, any matching grant gives permission
      for (ObjectStorageProperties.Permission permission : requiredBucketACLPermissions) {
        aclAllow =
            aclAllow || bucketResourceEntity.can(permission, requestAccount.getCanonicalId());
      }
    }

    // Check object ACLs, if any
    if (requiredObjectACLPermissions != null && requiredObjectACLPermissions.length > 0) {
      if (objectResourceEntity == null) {
        // There are object ACL requirements but no object entity to check. fail.
        // Don't bother with other checks, this is an invalid state
        LOG.error("Null bucket resource, cannot evaluate bucket ACL");
        return false;
      }
      for (ObjectStorageProperties.Permission permission : requiredObjectACLPermissions) {
        aclAllow =
            aclAllow || objectResourceEntity.can(permission, requestAccount.getCanonicalId());
      }
    }

    /* Resource owner only? if so, override any previous acl decisions
     * It is not expected that owneronly is set as well as other ACL permissions,
     * Regular owner permissions (READ, WRITE, READ_ACP, WRITE_ACP) are handled by the regular acl checks.
     * OwnerOnly should be only used for operations not covered by the other Permissions (e.g. logging, or versioning)
     */
    aclAllow =
        (allowOwnerOnly
            ? resourceOwnerAccount.getAccountNumber().equals(requestAccount.getAccountNumber())
            : aclAllow);
    if (aclAllow && isUserAnonymous(requestUser)) {
      // Skip the IAM checks for anonymous access since they will always fail and aren't valid for
      // anonymous users.
      return true;
    } else {
      Boolean iamAllow =
          iamPermissionsAllow(
              authContext, requiredActions, resourceType, resourceId, resourceAllocationSize);
      // Must have both acl and iam allow (account & user)
      return aclAllow && iamAllow;
    }
  }
Beispiel #10
0
 @Override
 public PolicyKey apply(final Class<? extends Key> keyClass) {
   return Ats.from(keyClass).get(PolicyKey.class);
 }