Search in sources :

Example 31 with SoapFaultException

use of com.zimbra.common.soap.SoapFaultException in project zm-mailbox by Zimbra.

the class TestBatchRequest method batchReqWithCsrfToken.

@Test
public void batchReqWithCsrfToken() throws Exception {
    Account acct = provUtil.createAccount(genAcctNameLocalPart(), domain);
    boolean csrfEnabled = Boolean.TRUE;
    SoapTransport transport = authUser(acct.getName(), csrfEnabled, Boolean.TRUE);
    Element request = new Element.XMLElement(ZimbraNamespace.E_BATCH_REQUEST);
    String sigContent = "xss<script>alert(\"XSS\")</script><a href=javascript:alert(\"XSS\")><";
    Signature sig = new Signature(null, "testSig", sigContent, "text/html");
    CreateSignatureRequest req = new CreateSignatureRequest(sig);
    SoapProtocol proto = SoapProtocol.Soap12;
    Element sigReq = JaxbUtil.jaxbToElement(req, proto.getFactory());
    request.addElement(sigReq);
    try {
        Element sigResp = transport.invoke(request, false, false, null);
        String sigt = sigResp.getElement("CreateSignatureResponse").getElement("signature").getAttribute("id");
        assertNotNull(sigt);
    } catch (SoapFaultException e) {
        assertNull(e);
    }
}
Also used : Account(com.zimbra.cs.account.Account) CreateSignatureRequest(com.zimbra.soap.account.message.CreateSignatureRequest) Element(com.zimbra.common.soap.Element) Signature(com.zimbra.soap.account.type.Signature) SoapProtocol(com.zimbra.common.soap.SoapProtocol) SoapTransport(com.zimbra.common.soap.SoapTransport) SoapFaultException(com.zimbra.common.soap.SoapFaultException) Test(org.junit.Test)

Example 32 with SoapFaultException

use of com.zimbra.common.soap.SoapFaultException in project zm-mailbox by Zimbra.

the class DocumentHandler method proxyRequest.

protected Element proxyRequest(Element request, Map<String, Object> context, Server server, ZimbraSoapContext zsc) throws ServiceException {
    // figure out whether we can just re-dispatch or if we need to proxy via HTTP
    SoapEngine engine = (SoapEngine) context.get(SoapEngine.ZIMBRA_ENGINE);
    boolean isLocal = getLocalHostId().equalsIgnoreCase(server.getId());
    // reset proxy token if proxying locally; it could previously be set to wrong account
    if (isLocal) {
        zsc.resetProxyAuthToken();
    }
    // make sure proxy token is set correctly for current requested acct
    if (zsc.getRequestedAccountId() != null) {
        try {
            AuthToken at = zsc.getAuthToken();
            String proxyToken = getProxyAuthToken(zsc.getRequestedAccountId(), context);
            if (at != null && (at.getProxyAuthToken() == null || !at.getProxyAuthToken().equals(proxyToken))) {
                at.setProxyAuthToken(proxyToken);
            }
        } catch (ServiceException se) {
            ZimbraLog.soap.warn("failed to set proxy auth token", se);
        }
    }
    Element response = null;
    request.detach();
    if (isLocal && engine != null) {
        // executing on same server; just hand back to the SoapEngine
        Map<String, Object> contextTarget = new HashMap<String, Object>(context);
        contextTarget.put(SoapEngine.ZIMBRA_ENGINE, engine);
        contextTarget.put(SoapEngine.ZIMBRA_CONTEXT, zsc);
        if (ZimbraLog.soap.isDebugEnabled()) {
            ZimbraLog.soap.debug("Proxying request locally: targetServer=%s (id=%s) localHost=%s (id=%s)", server.getName(), server.getId(), LOCAL_HOST, LOCAL_HOST_ID);
        }
        response = engine.dispatchRequest(request, contextTarget, zsc);
        if (zsc.getResponseProtocol().isFault(response)) {
            zsc.getResponseProtocol().updateArgumentsForRemoteFault(response, zsc.getRequestedAccountId());
            throw new SoapFaultException("error in proxied request", true, response);
        }
    } else {
        // do any necessary operations before doing a cross-server proxy
        preProxy(request, context);
        // executing remotely; find our target and proxy there
        HttpServletRequest httpreq = (HttpServletRequest) context.get(SoapServlet.SERVLET_REQUEST);
        ProxyTarget proxy = new ProxyTarget(server.getId(), zsc.getAuthToken(), httpreq);
        if (proxyTimeout >= 0) {
            proxy.setTimeouts(proxyTimeout);
        }
        response = proxyWithNotification(request, proxy, zsc, (Session) context.get(SoapEngine.ZIMBRA_SESSION));
        // do any necessary operations after doing a cross-server proxy
        postProxy(request, response, context);
    }
    return response;
}
Also used : HashMap(java.util.HashMap) Element(com.zimbra.common.soap.Element) SoapFaultException(com.zimbra.common.soap.SoapFaultException) HttpServletRequest(javax.servlet.http.HttpServletRequest) AccountServiceException(com.zimbra.cs.account.AccountServiceException) ServiceException(com.zimbra.common.service.ServiceException) AuthToken(com.zimbra.cs.account.AuthToken) AdminSession(com.zimbra.cs.session.AdminSession) SoapSession(com.zimbra.cs.session.SoapSession) Session(com.zimbra.cs.session.Session)

Example 33 with SoapFaultException

use of com.zimbra.common.soap.SoapFaultException in project zm-mailbox by Zimbra.

the class SoapEngine method dispatchRequest.

/**
 * Handles individual requests, either direct or from a batch
 */
Element dispatchRequest(DocumentHandler handler, Element soapReqElem, Map<String, Object> context, ZimbraSoapContext zsc) {
    long startTime = System.currentTimeMillis();
    SoapProtocol soapProto = zsc.getResponseProtocol();
    if (soapReqElem == null) {
        return soapFault(soapProto, "cannot dispatch request", ServiceException.INVALID_REQUEST("no document specified", null));
    }
    if (handler == null) {
        return soapFault(soapProto, "cannot dispatch request", ServiceException.UNKNOWN_DOCUMENT(soapReqElem.getQualifiedName(), null));
    }
    if (RedoLogProvider.getInstance().isSlave() && !handler.isReadOnly()) {
        return soapFault(soapProto, "cannot dispatch request", ServiceException.NON_READONLY_OPERATION_DENIED());
    }
    AuthToken at = zsc.getAuthToken();
    boolean needsAuth = handler.needsAuth(context);
    boolean needsAdminAuth = handler.needsAdminAuth(context);
    if ((needsAuth || needsAdminAuth) && at == null) {
        return soapFault(soapProto, "cannot dispatch request", ServiceException.AUTH_REQUIRED());
    }
    Element response = null;
    SoapTransport.setVia(zsc.getNextVia());
    try {
        Provisioning prov = Provisioning.getInstance();
        if (!prov.getLocalServer().getBooleanAttr(Provisioning.A_zimbraUserServicesEnabled, true) && !(handler instanceof AdminDocumentHandler)) {
            return soapFault(soapProto, "cannot dispatch request", ServiceException.TEMPORARILY_UNAVAILABLE());
        }
        if (needsAdminAuth) {
            AdminAccessControl aac = AdminAccessControl.getAdminAccessControl(at);
            if (!aac.isSufficientAdminForSoap(context, handler)) {
                return soapFault(soapProto, "cannot dispatch request", ServiceException.PERM_DENIED("need adequate admin token"));
            }
        }
        String acctId = null;
        boolean isGuestAccount = true;
        boolean delegatedAuth = false;
        if (at != null) {
            acctId = at.getAccountId();
            isGuestAccount = acctId.equals(GuestAccount.GUID_PUBLIC);
            delegatedAuth = at.isDelegatedAuth();
        }
        if (!isGuestAccount) {
            Account acct = null;
            if (needsAuth || needsAdminAuth) {
                try {
                    acct = AuthProvider.validateAuthToken(prov, at, false);
                } catch (ServiceException e) {
                    return soapFault(soapProto, null, e);
                }
                // also, make sure that the target account (if any) is active
                if (zsc.isDelegatedRequest() && !handler.isAdminCommand()) {
                    Account target = DocumentHandler.getRequestedAccount(zsc);
                    // treat the account as inactive if (a) it doesn't exist, (b) it's in maintenance mode, or (c) we're non-admins and it's not "active"
                    boolean inactive = target == null || Provisioning.ACCOUNT_STATUS_MAINTENANCE.equals(target.getAccountStatus(prov));
                    if (!inactive && (!at.isAdmin() || !AccessManager.getInstance().canAccessAccount(at, target))) {
                        inactive = !target.getAccountStatus(prov).equals(Provisioning.ACCOUNT_STATUS_ACTIVE);
                    }
                    if (inactive) {
                        return soapFault(soapProto, "target account is not active", AccountServiceException.ACCOUNT_INACTIVE(target == null ? zsc.getRequestedAccountId() : target.getName()));
                    }
                }
            }
            // fault in a session for this handler (if necessary) before executing the command
            context.put(ZIMBRA_SESSION, handler.getSession(zsc));
            // try to proxy the request if necessary (don't proxy commands that don't require auth)
            if ((needsAuth || needsAdminAuth) && acct != null) {
                response = handler.proxyIfNecessary(soapReqElem, context);
            }
        }
        // if no proxy, execute the request locally
        if (response == null) {
            if (delegatedAuth) {
                handler.logAuditAccess(at.getAdminAccountId(), acctId, acctId);
            }
            response = handler.handle(soapReqElem, context);
            ZimbraPerf.SOAP_TRACKER.addStat(getStatName(soapReqElem), startTime);
            long duration = System.currentTimeMillis() - startTime;
            if (LC.zimbra_slow_logging_enabled.booleanValue() && duration > LC.zimbra_slow_logging_threshold.longValue() && !soapReqElem.getQName().getName().equals(MailConstants.SYNC_REQUEST.getName())) {
                ZimbraLog.soap.warn("Slow SOAP request (start=" + startTime + "):\n" + soapReqElem.prettyPrint(true));
                ZimbraLog.soap.warn("Slow SOAP response (time=" + duration + "):\n" + response.prettyPrint());
            }
        }
    } catch (SoapFaultException e) {
        response = e.getFault() != null ? e.getFault().detach() : soapProto.soapFault(ServiceException.FAILURE(e.toString(), e));
        if (!e.isSourceLocal()) {
            LOG.debug("handler exception", e);
        }
    } catch (AuthFailedServiceException e) {
        HttpServletRequest httpReq = (HttpServletRequest) context.get(SoapServlet.SERVLET_REQUEST);
        httpReq.setAttribute(ZimbraInvalidLoginFilter.AUTH_FAILED, Boolean.TRUE);
        String clientIp = (String) context.get(SoapEngine.REQUEST_IP);
        httpReq.setAttribute(SoapEngine.REQUEST_IP, clientIp);
        response = soapProto.soapFault(e);
        if (LOG.isDebugEnabled()) {
            LOG.debug("handler exception: %s%s", e.getMessage(), e.getReason(", %s"), e);
        } else {
            // Don't log stack trace for auth failures, since they commonly happen
            LOG.info("handler exception: %s%s", e.getMessage(), e.getReason(", %s"));
        }
    } catch (ServiceException e) {
        response = soapFault(soapProto, "handler exception", e);
    // XXX: if the session was new, do we want to delete it?
    } catch (Throwable e) {
        // don't interfere with Jetty Continuations -- pass the exception on up
        if (e.getClass().getName().equals("org.eclipse.jetty.continuation.ContinuationThrowable")) {
            throw (Error) e;
        }
        // TODO: better exception stack traces during develope?
        response = soapProto.soapFault(ServiceException.FAILURE(e.toString(), e));
        if (e instanceof OutOfMemoryError) {
            Zimbra.halt("handler exception", e);
        }
        LOG.warn("handler exception", e);
    // XXX: if the session was new, do we want to delete it?
    } finally {
        SoapTransport.clearVia();
    }
    return response;
}
Also used : GuestAccount(com.zimbra.cs.account.GuestAccount) Account(com.zimbra.cs.account.Account) AuthFailedServiceException(com.zimbra.cs.account.AccountServiceException.AuthFailedServiceException) Element(com.zimbra.common.soap.Element) SoapProtocol(com.zimbra.common.soap.SoapProtocol) AdminAccessControl(com.zimbra.cs.service.admin.AdminAccessControl) Provisioning(com.zimbra.cs.account.Provisioning) SoapFaultException(com.zimbra.common.soap.SoapFaultException) HttpServletRequest(javax.servlet.http.HttpServletRequest) AccountServiceException(com.zimbra.cs.account.AccountServiceException) ServiceException(com.zimbra.common.service.ServiceException) AuthFailedServiceException(com.zimbra.cs.account.AccountServiceException.AuthFailedServiceException) AdminDocumentHandler(com.zimbra.cs.service.admin.AdminDocumentHandler) AuthToken(com.zimbra.cs.account.AuthToken)

Example 34 with SoapFaultException

use of com.zimbra.common.soap.SoapFaultException in project zm-mailbox by Zimbra.

the class TestAuth method accountStatusMaintenanceAfterAuth.

@Test
public void accountStatusMaintenanceAfterAuth() throws Exception {
    Account acct = provUtil.createAccount(genAcctNameLocalPart(), domain);
    SoapTransport transport = authUser(acct.getName());
    /*
         * change account status to maintenance
         */
    prov.modifyAccountStatus(acct, AccountStatus.maintenance.name());
    GetInfoRequest req = new GetInfoRequest();
    String errorCode = null;
    try {
        GetInfoResponse resp = invokeJaxb(transport, req);
    } catch (SoapFaultException e) {
        errorCode = e.getCode();
    }
    assertEquals(AccountServiceException.AUTH_EXPIRED, errorCode);
    provUtil.deleteAccount(acct);
}
Also used : Account(com.zimbra.cs.account.Account) GetInfoResponse(com.zimbra.soap.account.message.GetInfoResponse) GetInfoRequest(com.zimbra.soap.account.message.GetInfoRequest) SoapTransport(com.zimbra.common.soap.SoapTransport) SoapFaultException(com.zimbra.common.soap.SoapFaultException) Test(org.junit.Test)

Example 35 with SoapFaultException

use of com.zimbra.common.soap.SoapFaultException in project zm-mailbox by Zimbra.

the class TestAuth method accountStatusMaintenance.

@Test
public void accountStatusMaintenance() throws Exception {
    Account acct = provUtil.createAccount(genAcctNameLocalPart(), domain, Collections.singletonMap(Provisioning.A_zimbraAccountStatus, (Object) AccountStatus.maintenance.name()));
    String errorCode = null;
    try {
        SoapTransport transport = authUser(acct.getName());
    } catch (SoapFaultException e) {
        errorCode = e.getCode();
    }
    assertEquals(AccountServiceException.MAINTENANCE_MODE, errorCode);
    provUtil.deleteAccount(acct);
}
Also used : Account(com.zimbra.cs.account.Account) SoapTransport(com.zimbra.common.soap.SoapTransport) SoapFaultException(com.zimbra.common.soap.SoapFaultException) Test(org.junit.Test)

Aggregations

SoapFaultException (com.zimbra.common.soap.SoapFaultException)81 Test (org.junit.Test)62 Element (com.zimbra.common.soap.Element)32 Account (com.zimbra.cs.account.Account)23 ServiceException (com.zimbra.common.service.ServiceException)15 SoapTransport (com.zimbra.common.soap.SoapTransport)15 Attr (com.zimbra.soap.admin.type.Attr)15 SoapHttpTransport (com.zimbra.common.soap.SoapHttpTransport)14 SoapProvisioning (com.zimbra.cs.account.soap.SoapProvisioning)14 ZMailbox (com.zimbra.client.ZMailbox)12 SoapProtocol (com.zimbra.common.soap.SoapProtocol)11 ArrayList (java.util.ArrayList)11 DeployZimletRequest (com.zimbra.soap.admin.message.DeployZimletRequest)10 CreateSignatureRequest (com.zimbra.soap.account.message.CreateSignatureRequest)9 Signature (com.zimbra.soap.account.type.Signature)9 AttachmentIdAttrib (com.zimbra.soap.admin.type.AttachmentIdAttrib)9 AdminDocumentHandler (com.zimbra.cs.service.admin.AdminDocumentHandler)8 Mailbox (com.zimbra.cs.mailbox.Mailbox)6 Provisioning (com.zimbra.cs.account.Provisioning)5 AdminRight (com.zimbra.cs.account.accesscontrol.AdminRight)5