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);
}
}
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;
}
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;
}
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);
}
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);
}
Aggregations