Search in sources :

Example 66 with AuthToken

use of com.zimbra.cs.account.AuthToken in project zm-mailbox by Zimbra.

the class ZimbraAuthenticator method validateRequest.

@Override
public Authentication validateRequest(ServletRequest req, ServletResponse resp, boolean mandatory) throws ServerAuthException {
    if (mandatory && req instanceof HttpServletRequest) {
        HttpServletRequest httpReq = (HttpServletRequest) req;
        //we want to just ignore rather than potentially flooding auth provider (which may be external)
        if (PathMap.match(urlPattern, httpReq.getRequestURI())) {
            Cookie[] cookies = httpReq.getCookies();
            if (cookies != null) {
                for (Cookie cookie : cookies) {
                    if (ZimbraCookie.authTokenCookieName(true).equalsIgnoreCase(cookie.getName()) || ZimbraCookie.authTokenCookieName(false).equalsIgnoreCase(cookie.getName())) {
                        String encoded = cookie.getValue();
                        AuthToken token;
                        try {
                            token = AuthProvider.getAuthToken(encoded);
                            Account authAcct = AuthProvider.validateAuthToken(Provisioning.getInstance(), token, false);
                            if (authAcct != null) {
                                if (_loginService instanceof ZimbraLoginService) {
                                    UserIdentity user = ((ZimbraLoginService) _loginService).makeUserIdentity(authAcct.getMail());
                                    ZimbraLog.security.debug("Auth token validated");
                                    return new UserAuthentication(getAuthMethod(), user);
                                } else {
                                    ZimbraLog.security.warn("Misconfigured? _loginService not ZimbraLoginService");
                                    assert (false);
                                }
                            }
                        } catch (AuthTokenException e) {
                            ZimbraLog.security.error("Unable to authenticate due to AuthTokenException", e);
                        } catch (ServiceException e) {
                            ZimbraLog.security.error("Unable to authenticate due to ServiceException", e);
                        }
                    }
                }
                ZimbraLog.security.debug("no valid auth token, fallback to basic");
            }
        }
    }
    return super.validateRequest(req, resp, mandatory);
}
Also used : HttpServletRequest(javax.servlet.http.HttpServletRequest) ZimbraCookie(com.zimbra.common.util.ZimbraCookie) Cookie(javax.servlet.http.Cookie) Account(com.zimbra.cs.account.Account) ServiceException(com.zimbra.common.service.ServiceException) UserIdentity(org.eclipse.jetty.server.UserIdentity) AuthTokenException(com.zimbra.cs.account.AuthTokenException) AuthToken(com.zimbra.cs.account.AuthToken) UserAuthentication(org.eclipse.jetty.security.UserAuthentication)

Example 67 with AuthToken

use of com.zimbra.cs.account.AuthToken in project zm-mailbox by Zimbra.

the class UserServletUtil method getAccount.

//    public synchronized static void addFormatter(Formatter f) {
//        mFormatters.put(f.getType(), f);
//        for (String mimeType : f.getDefaultMimeTypes())
//            mDefaultFormatters.put(mimeType, f);
//    }
//
//    public Formatter getFormatter(String type) {
//        return mFormatters.get(type);
//    }
public static void getAccount(UserServletContext context) throws IOException, ServletException, UserServletException {
    try {
        boolean isAdminRequest = AuthUtil.isAdminRequest(context.req);
        // check cookie or access key
        if (context.cookieAuthAllowed() || AuthProvider.allowAccessKeyAuth(context.req, context.getServlet())) {
            try {
                AuthToken at = AuthProvider.getAuthToken(context.req, isAdminRequest);
                if (at != null) {
                    if (at.isZimbraUser()) {
                        if (!at.isRegistered()) {
                            throw new UserServletException(HttpServletResponse.SC_UNAUTHORIZED, L10nUtil.getMessage(MsgKey.errMustAuthenticate, context.req));
                        }
                        try {
                            context.setAuthAccount(AuthProvider.validateAuthToken(Provisioning.getInstance(), at, false));
                        } catch (ServiceException e) {
                            throw new UserServletException(HttpServletResponse.SC_UNAUTHORIZED, L10nUtil.getMessage(MsgKey.errMustAuthenticate, context.req));
                        }
                        context.cookieAuthHappened = true;
                        context.authToken = at;
                        return;
                    } else {
                        if (at.isExpired()) {
                            throw new UserServletException(HttpServletResponse.SC_UNAUTHORIZED, L10nUtil.getMessage(MsgKey.errMustAuthenticate, context.req));
                        }
                        context.setAuthAccount(new GuestAccount(at));
                        // pretend that we basic authed
                        context.basicAuthHappened = true;
                        context.authToken = at;
                        return;
                    }
                }
            } catch (AuthTokenException e) {
                // bug 35917: malformed auth token means auth failure
                throw new UserServletException(HttpServletResponse.SC_UNAUTHORIZED, L10nUtil.getMessage(MsgKey.errMustAuthenticate, context.req));
            }
        }
        // check query string
        if (context.queryParamAuthAllowed()) {
            String auth = context.params.get(ZimbraServlet.QP_ZAUTHTOKEN);
            if (auth == null)
                // not sure who uses this parameter; zauthtoken is preferred
                auth = context.params.get(UserServlet.QP_AUTHTOKEN);
            if (auth != null) {
                try {
                    // Only supported by ZimbraAuthProvider
                    AuthToken at = AuthProvider.getAuthToken(auth);
                    try {
                        context.setAuthAccount(AuthProvider.validateAuthToken(Provisioning.getInstance(), at, false));
                        context.qpAuthHappened = true;
                        context.authToken = at;
                        return;
                    } catch (ServiceException e) {
                        throw new UserServletException(HttpServletResponse.SC_UNAUTHORIZED, L10nUtil.getMessage(MsgKey.errMustAuthenticate, context.req));
                    }
                } catch (AuthTokenException e) {
                    // bug 35917: malformed auth token means auth failure
                    throw new UserServletException(HttpServletResponse.SC_UNAUTHORIZED, L10nUtil.getMessage(MsgKey.errMustAuthenticate, context.req));
                }
            }
        }
        // fallback to basic auth
        if (context.basicAuthAllowed()) {
            context.setAuthAccount(AuthUtil.basicAuthRequest(context.req, context.resp, context.servlet, false));
            if (context.getAuthAccount() != null) {
                context.basicAuthHappened = true;
                context.authToken = AuthProvider.getAuthToken(context.getAuthAccount(), isAdminRequest);
                // send cookie back if need be.
                if (context.setCookie()) {
                    boolean secureCookie = context.req.getScheme().equals("https");
                    context.authToken.encode(context.resp, isAdminRequest, secureCookie);
                }
            }
            // always return
            return;
        }
    // there is no credential at this point.  assume anonymous public access and continue.
    } catch (ServiceException e) {
        throw new ServletException(e);
    }
}
Also used : ServletException(javax.servlet.ServletException) UserServletException(com.zimbra.cs.service.UserServletException) GuestAccount(com.zimbra.cs.account.GuestAccount) ServiceException(com.zimbra.common.service.ServiceException) MailServiceException(com.zimbra.cs.mailbox.MailServiceException) UserServletException(com.zimbra.cs.service.UserServletException) AuthTokenException(com.zimbra.cs.account.AuthTokenException) AuthToken(com.zimbra.cs.account.AuthToken)

Example 68 with AuthToken

use of com.zimbra.cs.account.AuthToken in project zm-mailbox by Zimbra.

the class DavServlet method service.

@Override
public void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    ZimbraLog.clearContext();
    addRemoteIpToLoggingContext(req);
    ZimbraLog.addUserAgentToContext(req.getHeader(DavProtocol.HEADER_USER_AGENT));
    //bug fix - send 400 for Range requests
    String rangeHeader = req.getHeader(DavProtocol.HEADER_RANGE);
    if (null != rangeHeader) {
        sendError(resp, HttpServletResponse.SC_BAD_REQUEST, "Range header not supported", null, Level.debug);
        return;
    }
    RequestType rtype = getAllowedRequestType(req);
    ZimbraLog.dav.debug("Allowable request types %s", rtype);
    if (rtype == RequestType.none) {
        sendError(resp, HttpServletResponse.SC_NOT_ACCEPTABLE, "Not an allowed request type", null, Level.debug);
        return;
    }
    logRequestInfo(req);
    Account authUser = null;
    DavContext ctxt;
    try {
        AuthToken at = AuthProvider.getAuthToken(req, false);
        if (at != null && (at.isExpired() || !at.isRegistered())) {
            at = null;
        }
        if (at != null && (rtype == RequestType.both || rtype == RequestType.authtoken)) {
            authUser = Provisioning.getInstance().get(AccountBy.id, at.getAccountId());
        } else if (at == null && (rtype == RequestType.both || rtype == RequestType.password)) {
            AuthUtil.AuthResult result = AuthUtil.basicAuthRequest(req, resp, true, this);
            if (result.sendErrorCalled) {
                logResponseInfo(resp);
                return;
            }
            authUser = result.authorizedAccount;
        }
        if (authUser == null) {
            try {
                sendError(resp, HttpServletResponse.SC_UNAUTHORIZED, "Authentication failed", null, Level.debug);
            } catch (Exception e) {
            }
            return;
        }
        ZimbraLog.addToContext(ZimbraLog.C_ANAME, authUser.getName());
        ctxt = new DavContext(req, resp, authUser);
    } catch (AuthTokenException e) {
        sendError(resp, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "error getting authenticated user", e);
        return;
    } catch (ServiceException e) {
        sendError(resp, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "error getting authenticated user", e);
        return;
    }
    DavMethod method = sMethods.get(req.getMethod());
    if (method == null) {
        setAllowHeader(resp);
        sendError(resp, HttpServletResponse.SC_METHOD_NOT_ALLOWED, "Not an allowed method", null, Level.debug);
        return;
    }
    long t0 = System.currentTimeMillis();
    CacheStates cache = null;
    try {
        if (ZimbraLog.dav.isDebugEnabled()) {
            try {
                Upload upload = ctxt.getUpload();
                if (upload.getSize() > 0 && upload.getContentType().startsWith("text")) {
                    if (ZimbraLog.dav.isDebugEnabled()) {
                        StringBuilder logMsg = new StringBuilder("REQUEST\n").append(new String(ByteUtil.readInput(upload.getInputStream(), -1, 20480), "UTF-8"));
                        ZimbraLog.dav.debug(logMsg.toString());
                    }
                }
            } catch (DavException de) {
                throw de;
            } catch (Exception e) {
                ZimbraLog.dav.debug("ouch", e);
            }
        }
        cache = checkCachedResponse(ctxt, authUser);
        if (!ctxt.isResponseSent() && !isProxyRequest(ctxt, method)) {
            method.checkPrecondition(ctxt);
            method.handle(ctxt);
            method.checkPostcondition(ctxt);
            if (!ctxt.isResponseSent()) {
                resp.setStatus(ctxt.getStatus());
            }
        }
        if (!ctxt.isResponseSent()) {
            logResponseInfo(resp);
        }
    } catch (DavException e) {
        if (e.getCause() instanceof MailServiceException.NoSuchItemException || e.getStatus() == HttpServletResponse.SC_NOT_FOUND)
            ZimbraLog.dav.info(ctxt.getUri() + " not found");
        else if (e.getStatus() == HttpServletResponse.SC_MOVED_TEMPORARILY || e.getStatus() == HttpServletResponse.SC_MOVED_PERMANENTLY)
            ZimbraLog.dav.info("sending redirect");
        try {
            if (e.isStatusSet()) {
                resp.setStatus(e.getStatus());
                if (e.hasErrorMessage())
                    e.writeErrorMsg(resp.getOutputStream());
                if (ZimbraLog.dav.isDebugEnabled()) {
                    ZimbraLog.dav.info("sending http error %d because: %s", e.getStatus(), e.getMessage(), e);
                } else {
                    ZimbraLog.dav.info("sending http error %d because: %s", e.getStatus(), e.getMessage());
                }
                if (e.getCause() != null)
                    ZimbraLog.dav.debug("exception: ", e.getCause());
            } else {
                sendError(resp, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "error handling method " + method.getName(), e);
            }
        } catch (IllegalStateException ise) {
            ZimbraLog.dav.debug("can't write error msg", ise);
        }
    } catch (ServiceException e) {
        if (e instanceof MailServiceException.NoSuchItemException) {
            sendError(resp, HttpServletResponse.SC_NOT_FOUND, ctxt.getUri() + " not found", null, Level.info);
            return;
        }
        sendError(resp, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "error handling method " + method.getName(), e);
    } catch (Exception e) {
        try {
            sendError(resp, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "error handling method " + method.getName(), e);
        } catch (Exception ex) {
        }
    } finally {
        long t1 = System.currentTimeMillis();
        ZimbraLog.dav.info("DavServlet operation " + method.getName() + " to " + req.getPathInfo() + " (depth: " + ctxt.getDepth().name() + ") finished in " + (t1 - t0) + "ms");
        if (cache != null)
            cacheCleanUp(ctxt, cache);
        ctxt.cleanup();
    }
}
Also used : Account(com.zimbra.cs.account.Account) DavException(com.zimbra.cs.dav.DavException) Upload(com.zimbra.cs.service.FileUploadServlet.Upload) ServletException(javax.servlet.ServletException) XmlParseException(com.zimbra.common.soap.XmlParseException) ServiceException(com.zimbra.common.service.ServiceException) IOException(java.io.IOException) AuthTokenException(com.zimbra.cs.account.AuthTokenException) DavException(com.zimbra.cs.dav.DavException) MailServiceException(com.zimbra.cs.mailbox.MailServiceException) ServiceException(com.zimbra.common.service.ServiceException) MailServiceException(com.zimbra.cs.mailbox.MailServiceException) AuthTokenException(com.zimbra.cs.account.AuthTokenException) AuthToken(com.zimbra.cs.account.AuthToken) MailServiceException(com.zimbra.cs.mailbox.MailServiceException) DavContext(com.zimbra.cs.dav.DavContext)

Example 69 with AuthToken

use of com.zimbra.cs.account.AuthToken in project zm-mailbox by Zimbra.

the class Auth method needTwoFactorAuth.

private Element needTwoFactorAuth(Account account, TwoFactorAuth auth, ZimbraSoapContext zsc) throws ServiceException {
    /* two cases here:
         * 1) the user needs to provide a two-factor code.
         *    in this case, the server returns a two-factor auth token in the response header that the client
         *    must send back, along with the code, in order to finish the authentication process.
         * 2) the user needs to set up two-factor auth.
         *    this can happen if it's required for the account but the user hasn't received a secret yet.
         */
    if (!auth.twoFactorAuthEnabled()) {
        throw AccountServiceException.TWO_FACTOR_SETUP_REQUIRED();
    } else {
        Element response = zsc.createElement(AccountConstants.AUTH_RESPONSE);
        AuthToken twoFactorToken = AuthProvider.getAuthToken(account, Usage.TWO_FACTOR_AUTH);
        response.addUniqueElement(AccountConstants.E_TWO_FACTOR_AUTH_REQUIRED).setText("true");
        response.addAttribute(AccountConstants.E_LIFETIME, twoFactorToken.getExpires() - System.currentTimeMillis(), Element.Disposition.CONTENT);
        twoFactorToken.encodeAuthResp(response, false);
        response.addUniqueElement(AccountConstants.E_TRUSTED_DEVICES_ENABLED).setText(account.isFeatureTrustedDevicesEnabled() ? "true" : "false");
        return response;
    }
}
Also used : Element(com.zimbra.common.soap.Element) AuthToken(com.zimbra.cs.account.AuthToken)

Example 70 with AuthToken

use of com.zimbra.cs.account.AuthToken in project zm-mailbox by Zimbra.

the class GetDomainInfo method handle.

@Override
public Element handle(Element request, Map<String, Object> context) throws ServiceException {
    ZimbraSoapContext lc = getZimbraSoapContext(context);
    Provisioning prov = Provisioning.getInstance();
    AuthToken at = lc.getAuthToken();
    boolean hasAuth = at != null;
    boolean applyConfig = request.getAttributeBool(AdminConstants.A_APPLY_CONFIG, true);
    Element d = request.getElement(AdminConstants.E_DOMAIN);
    String key = d.getAttribute(AdminConstants.A_BY);
    String value = d.getText();
    Key.DomainBy domainBy = Key.DomainBy.fromString(key);
    Domain domain = prov.getDomain(domainBy, value, true);
    Element response = lc.createElement(AdminConstants.GET_DOMAIN_INFO_RESPONSE);
    if (domain == null && domainBy != Key.DomainBy.name && domainBy != Key.DomainBy.virtualHostname) {
        // domain not found, and we don't have info for walking up sub domains
        // return attributes on global config
        toXML(response, prov.getConfig(), applyConfig, hasAuth);
    } else {
        if (domain == null) {
            if (domainBy == Key.DomainBy.virtualHostname)
                domain = prov.getDomain(Key.DomainBy.name, value, true);
            if (domain == null)
                domain = findDomain(prov, value);
        }
        if (domain != null)
            toXML(response, domain, applyConfig, hasAuth);
        else
            toXML(response, prov.getConfig(), applyConfig, hasAuth);
    }
    return response;
}
Also used : ZimbraSoapContext(com.zimbra.soap.ZimbraSoapContext) Element(com.zimbra.common.soap.Element) AuthToken(com.zimbra.cs.account.AuthToken) Domain(com.zimbra.cs.account.Domain) ZAttrProvisioning(com.zimbra.common.account.ZAttrProvisioning) Provisioning(com.zimbra.cs.account.Provisioning) Key(com.zimbra.common.account.Key)

Aggregations

AuthToken (com.zimbra.cs.account.AuthToken)98 ServiceException (com.zimbra.common.service.ServiceException)46 Account (com.zimbra.cs.account.Account)44 ZimbraAuthToken (com.zimbra.cs.account.ZimbraAuthToken)27 AuthTokenException (com.zimbra.cs.account.AuthTokenException)26 Element (com.zimbra.common.soap.Element)24 Provisioning (com.zimbra.cs.account.Provisioning)23 ZMailbox (com.zimbra.client.ZMailbox)19 ZAuthToken (com.zimbra.common.auth.ZAuthToken)18 IOException (java.io.IOException)14 Server (com.zimbra.cs.account.Server)12 ZimbraSoapContext (com.zimbra.soap.ZimbraSoapContext)12 HttpClient (org.apache.commons.httpclient.HttpClient)12 HashMap (java.util.HashMap)11 GetMethod (org.apache.commons.httpclient.methods.GetMethod)11 Test (org.junit.Test)11 SoapHttpTransport (com.zimbra.common.soap.SoapHttpTransport)10 ServletException (javax.servlet.ServletException)10 AuthFailedServiceException (com.zimbra.cs.account.AccountServiceException.AuthFailedServiceException)8 MailServiceException (com.zimbra.cs.mailbox.MailServiceException)8