Search in sources :

Example 1 with AuthTokenException

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

the class AuthProvider method getAuthToken.

public static AuthToken getAuthToken(Element authTokenElem, Account acct) throws AuthTokenException {
    AuthToken at = null;
    List<AuthProvider> providers = getProviders();
    AuthTokenException authTokenExp = null;
    for (AuthProvider ap : providers) {
        try {
            at = ap.authToken(authTokenElem, acct);
            if (at == null) {
                authTokenExp = new AuthTokenException("auth provider " + ap.getName() + " returned null");
            } else {
                return at;
            }
        } catch (AuthProviderException e) {
            // if there is no auth data for this provider, log and continue with next provider
            if (e.canIgnore()) {
                logger().debug(ap.getName() + ":" + e.getMessage());
            } else {
                authTokenExp = new AuthTokenException("auth provider error", e);
            }
        } catch (AuthTokenException e) {
            //log and store exception reference
            authTokenExp = e;
            logger().debug("getAuthToken error: provider=" + ap.getName() + ", err=" + e.getMessage(), e);
        }
    }
    //If multiple auth providers caused AuthTokenException, then last exception is rethrown from here.
    if (null != authTokenExp) {
        throw authTokenExp;
    }
    // there is no auth data for any of the enabled providers
    return null;
}
Also used : AuthTokenException(com.zimbra.cs.account.AuthTokenException) AuthToken(com.zimbra.cs.account.AuthToken)

Example 2 with AuthTokenException

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

the class AuthProvider method getAuthToken.

/**
     * The static getAuthToken methods go through all the providers, trying them in order
     * until one returns an AuthToken.
     *
     * If any provider in the chain throws AuthTokenException,
     * it will be stored and re-thrown to caller at the end.
     *
     * If more than one provider throws AuthTokenException then exception reported
     * by last provider will be thrown to caller.
     *
     * If AuthProviderException is thrown by provider then-
     *    - For AuthProviderException that is ignorable(AuthProviderException.NO_AUTH_TOKEN, AuthProviderException.NOT_SUPPORTED),
     *      it will be logged and next provider will be tried.
     *    - For AuthProviderExceptions that is not ignorable, AuthTokenException is generated and stored,
     *      thrown at the end if all provider fails.
     *
     * Return null when all providers fails to get AuthToken and no exception thrown by any provider.
     */
/**
     * @param req http request
     * @return an AuthToken object, or null if auth data is not present for any of the enabled providers
     * @throws ServiceException
     */
public static AuthToken getAuthToken(HttpServletRequest req, boolean isAdminReq) throws AuthTokenException {
    AuthToken at = null;
    List<AuthProvider> providers = getProviders();
    AuthTokenException authTokenExp = null;
    for (AuthProvider ap : providers) {
        try {
            at = ap.authToken(req, isAdminReq);
            if (at == null) {
                authTokenExp = new AuthTokenException("auth provider " + ap.getName() + " returned null");
            } else {
                return at;
            }
        } catch (AuthProviderException e) {
            // if there is no auth data for this provider, log and continue with next provider
            if (e.canIgnore()) {
                logger().debug(ap.getName() + ":" + e.getMessage());
            } else {
                authTokenExp = new AuthTokenException("auth provider error", e);
            }
        } catch (AuthTokenException e) {
            //log and store exception reference
            authTokenExp = e;
            logger().debug("getAuthToken error: provider=" + ap.getName() + ", err=" + e.getMessage(), e);
        }
    }
    //If multiple auth providers caused AuthTokenException, then last exception is rethrown from here.
    if (null != authTokenExp) {
        throw authTokenExp;
    }
    // there is no auth data for any of the enabled providers
    return null;
}
Also used : AuthTokenException(com.zimbra.cs.account.AuthTokenException) AuthToken(com.zimbra.cs.account.AuthToken)

Example 3 with AuthTokenException

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

the class ProxyServlet method doProxy.

private void doProxy(HttpServletRequest req, HttpServletResponse resp) throws IOException {
    ZimbraLog.clearContext();
    boolean isAdmin = isAdminRequest(req);
    AuthToken authToken = isAdmin ? getAdminAuthTokenFromCookie(req, resp, true) : getAuthTokenFromCookie(req, resp, true);
    if (authToken == null) {
        String zAuthToken = req.getParameter(QP_ZAUTHTOKEN);
        if (zAuthToken != null) {
            try {
                authToken = AuthProvider.getAuthToken(zAuthToken);
                if (authToken.isExpired()) {
                    resp.sendError(HttpServletResponse.SC_UNAUTHORIZED, "authtoken expired");
                    return;
                }
                if (!authToken.isRegistered()) {
                    resp.sendError(HttpServletResponse.SC_UNAUTHORIZED, "authtoken is invalid");
                    return;
                }
                if (isAdmin && !authToken.isAdmin()) {
                    resp.sendError(HttpServletResponse.SC_UNAUTHORIZED, "permission denied");
                    return;
                }
            } catch (AuthTokenException e) {
                resp.sendError(HttpServletResponse.SC_UNAUTHORIZED, "unable to parse authtoken");
                return;
            }
        }
    }
    if (authToken == null) {
        resp.sendError(HttpServletResponse.SC_UNAUTHORIZED, "no authtoken cookie");
        return;
    }
    // get the posted body before the server read and parse them.
    byte[] body = copyPostedData(req);
    // sanity check
    String target = req.getParameter(TARGET_PARAM);
    if (target == null) {
        resp.sendError(HttpServletResponse.SC_BAD_REQUEST);
        return;
    }
    // check for permission
    URL url = new URL(target);
    if (!isAdmin && !checkPermissionOnTarget(url, authToken)) {
        resp.sendError(HttpServletResponse.SC_FORBIDDEN);
        return;
    }
    // determine whether to return the target inline or store it as an upload
    String uploadParam = req.getParameter(UPLOAD_PARAM);
    boolean asUpload = uploadParam != null && (uploadParam.equals("1") || uploadParam.equalsIgnoreCase("true"));
    HttpMethod method = null;
    try {
        HttpClient client = ZimbraHttpConnectionManager.getExternalHttpConnMgr().newHttpClient();
        HttpProxyUtil.configureProxy(client);
        String reqMethod = req.getMethod();
        if (reqMethod.equalsIgnoreCase("GET")) {
            method = new GetMethod(target);
        } else if (reqMethod.equalsIgnoreCase("POST")) {
            PostMethod post = new PostMethod(target);
            if (body != null)
                post.setRequestEntity(new ByteArrayRequestEntity(body, req.getContentType()));
            method = post;
        } else if (reqMethod.equalsIgnoreCase("PUT")) {
            PutMethod put = new PutMethod(target);
            if (body != null)
                put.setRequestEntity(new ByteArrayRequestEntity(body, req.getContentType()));
            method = put;
        } else if (reqMethod.equalsIgnoreCase("DELETE")) {
            method = new DeleteMethod(target);
        } else {
            ZimbraLog.zimlet.info("unsupported request method: " + reqMethod);
            resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
            return;
        }
        // handle basic auth
        String auth, user, pass;
        auth = req.getParameter(AUTH_PARAM);
        user = req.getParameter(USER_PARAM);
        pass = req.getParameter(PASS_PARAM);
        if (auth != null && user != null && pass != null) {
            if (!auth.equals(AUTH_BASIC)) {
                ZimbraLog.zimlet.info("unsupported auth type: " + auth);
                resp.sendError(HttpServletResponse.SC_BAD_REQUEST);
                return;
            }
            HttpState state = new HttpState();
            state.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(user, pass));
            client.setState(state);
            method.setDoAuthentication(true);
        }
        Enumeration headers = req.getHeaderNames();
        while (headers.hasMoreElements()) {
            String hdr = (String) headers.nextElement();
            ZimbraLog.zimlet.debug("incoming: " + hdr + ": " + req.getHeader(hdr));
            if (canProxyHeader(hdr)) {
                ZimbraLog.zimlet.debug("outgoing: " + hdr + ": " + req.getHeader(hdr));
                if (hdr.equalsIgnoreCase("x-host"))
                    method.getParams().setVirtualHost(req.getHeader(hdr));
                else
                    method.addRequestHeader(hdr, req.getHeader(hdr));
            }
        }
        try {
            if (!(reqMethod.equalsIgnoreCase("POST") || reqMethod.equalsIgnoreCase("PUT"))) {
                method.setFollowRedirects(true);
            }
            HttpClientUtil.executeMethod(client, method);
        } catch (HttpException ex) {
            ZimbraLog.zimlet.info("exception while proxying " + target, ex);
            resp.sendError(HttpServletResponse.SC_NOT_FOUND);
            return;
        }
        int status = method.getStatusLine() == null ? HttpServletResponse.SC_INTERNAL_SERVER_ERROR : method.getStatusCode();
        // workaround for Alexa Thumbnails paid web service, which doesn't bother to return a content-type line
        Header ctHeader = method.getResponseHeader("Content-Type");
        String contentType = ctHeader == null || ctHeader.getValue() == null ? DEFAULT_CTYPE : ctHeader.getValue();
        InputStream targetResponseBody = method.getResponseBodyAsStream();
        if (asUpload) {
            String filename = req.getParameter(FILENAME_PARAM);
            if (filename == null || filename.equals(""))
                filename = new ContentType(contentType).getParameter("name");
            if ((filename == null || filename.equals("")) && method.getResponseHeader("Content-Disposition") != null)
                filename = new ContentDisposition(method.getResponseHeader("Content-Disposition").getValue()).getParameter("filename");
            if (filename == null || filename.equals(""))
                filename = "unknown";
            List<Upload> uploads = null;
            if (targetResponseBody != null) {
                try {
                    Upload up = FileUploadServlet.saveUpload(targetResponseBody, filename, contentType, authToken.getAccountId());
                    uploads = Arrays.asList(up);
                } catch (ServiceException e) {
                    if (e.getCode().equals(MailServiceException.UPLOAD_REJECTED))
                        status = HttpServletResponse.SC_REQUEST_ENTITY_TOO_LARGE;
                    else
                        status = HttpServletResponse.SC_INTERNAL_SERVER_ERROR;
                }
            }
            resp.setStatus(status);
            FileUploadServlet.sendResponse(resp, status, req.getParameter(FORMAT_PARAM), null, uploads, null);
        } else {
            resp.setStatus(status);
            resp.setContentType(contentType);
            for (Header h : method.getResponseHeaders()) if (canProxyHeader(h.getName()))
                resp.addHeader(h.getName(), h.getValue());
            if (targetResponseBody != null)
                ByteUtil.copy(targetResponseBody, true, resp.getOutputStream(), true);
        }
    } finally {
        if (method != null)
            method.releaseConnection();
    }
}
Also used : ContentType(com.zimbra.common.mime.ContentType) PostMethod(org.apache.commons.httpclient.methods.PostMethod) HttpState(org.apache.commons.httpclient.HttpState) Upload(com.zimbra.cs.service.FileUploadServlet.Upload) URL(java.net.URL) HttpException(org.apache.commons.httpclient.HttpException) DeleteMethod(org.apache.commons.httpclient.methods.DeleteMethod) Enumeration(java.util.Enumeration) InputStream(java.io.InputStream) UsernamePasswordCredentials(org.apache.commons.httpclient.UsernamePasswordCredentials) Header(org.apache.commons.httpclient.Header) ContentDisposition(com.zimbra.common.mime.ContentDisposition) ServiceException(com.zimbra.common.service.ServiceException) MailServiceException(com.zimbra.cs.mailbox.MailServiceException) AuthTokenException(com.zimbra.cs.account.AuthTokenException) HttpClient(org.apache.commons.httpclient.HttpClient) GetMethod(org.apache.commons.httpclient.methods.GetMethod) AuthToken(com.zimbra.cs.account.AuthToken) PutMethod(org.apache.commons.httpclient.methods.PutMethod) HttpMethod(org.apache.commons.httpclient.HttpMethod) ByteArrayRequestEntity(org.apache.commons.httpclient.methods.ByteArrayRequestEntity)

Example 4 with AuthTokenException

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

the class CsrfUtil method generateCsrfToken.

/**
     * @param sessionId
     * @param i
     * @return
     * @throws AuthTokenException
     * @throws ServiceException
     * @throws InvalidAlgorithmParameterException
     */
public static String generateCsrfToken(String accountId, long authTokenExpiration, int tokenSalt, AuthToken at) throws ServiceException {
    try {
        String crumb = at.getCrumb();
        String tokenData = getExistingCsrfTokenForThisAuthToken(at, crumb);
        if (tokenData == null) {
            StringBuilder encodedBuff = new StringBuilder(64);
            BlobMetaData.encodeMetaData(C_ID, accountId, encodedBuff);
            BlobMetaData.encodeMetaData(C_EXP, Long.toString(authTokenExpiration), encodedBuff);
            BlobMetaData.encodeMetaData(C_SALT_ID, tokenSalt, encodedBuff);
            tokenData = new String(Hex.encodeHex(encodedBuff.toString().getBytes()));
        }
        CsrfTokenKey key = getCurrentKey();
        String hmac = TokenUtil.getHmac(tokenData, key.getKey());
        String encoded = key.getVersion() + "_" + hmac;
        storeTokenData(tokenData, at, authTokenExpiration, crumb);
        return encoded;
    } catch (AuthTokenException e) {
        throw ServiceException.FAILURE("Error generating Auth Token, " + e.getMessage(), e);
    }
}
Also used : AuthTokenException(com.zimbra.cs.account.AuthTokenException) CsrfTokenKey(com.zimbra.cs.account.CsrfTokenKey)

Example 5 with AuthTokenException

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

the class CsrfUtil method isCsrfTokenCreated.

/**
     * @param authToken
     * @return
     */
public static boolean isCsrfTokenCreated(AuthToken authToken) {
    boolean csrfTokenCreated = false;
    ZimbraLog.misc.debug("isCsrfTokenCreated()");
    try {
        Account account = getAccount(authToken, Boolean.TRUE);
        if (account != null) {
            String crumb = authToken.getCrumb();
            csrfTokenCreated = account.hasCsrfTokenData(crumb);
        }
    } catch (ServiceException | AuthTokenException e) {
        ZimbraLog.ephemeral.info("Error fetching CSRF token data" + e.getMessage());
    }
    return csrfTokenCreated;
}
Also used : Account(com.zimbra.cs.account.Account) ServiceException(com.zimbra.common.service.ServiceException) AuthTokenException(com.zimbra.cs.account.AuthTokenException)

Aggregations

AuthTokenException (com.zimbra.cs.account.AuthTokenException)37 AuthToken (com.zimbra.cs.account.AuthToken)25 ServiceException (com.zimbra.common.service.ServiceException)24 Account (com.zimbra.cs.account.Account)20 Provisioning (com.zimbra.cs.account.Provisioning)8 ZimbraAuthToken (com.zimbra.cs.account.ZimbraAuthToken)7 IOException (java.io.IOException)7 HttpClient (org.apache.commons.httpclient.HttpClient)7 GetMethod (org.apache.commons.httpclient.methods.GetMethod)7 ZimbraSoapContext (com.zimbra.soap.ZimbraSoapContext)6 ServletException (javax.servlet.ServletException)6 Element (com.zimbra.common.soap.Element)5 Server (com.zimbra.cs.account.Server)5 HttpMethod (org.apache.commons.httpclient.HttpMethod)5 Domain (com.zimbra.cs.account.Domain)4 GuestAccount (com.zimbra.cs.account.GuestAccount)4 HashMap (java.util.HashMap)4 HttpServletRequest (javax.servlet.http.HttpServletRequest)4 ZMailbox (com.zimbra.client.ZMailbox)3 AccountBy (com.zimbra.common.account.Key.AccountBy)3