Search in sources :

Example 21 with AuthToken

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

the class WebClientServiceUtil method sendServiceRequestToOneRandomUiNode.

/**
     * send service request to one random ui node, keep trying until succeeds.
     * @param serviceUrl the url that should be matched and handled by ServiceServlet in ZimbraWebClient
     *        reqHeaders the map of req/rsp attributes that need to be set by the UI node
     * @return response from ui node in String
     * @throws ServiceException
     */
public static String sendServiceRequestToOneRandomUiNode(String serviceUrl, Map<String, String> reqHeaders) throws ServiceException {
    List<Server> servers = Provisioning.getInstance().getAllServers(Provisioning.SERVICE_WEBCLIENT);
    if (servers == null || servers.isEmpty()) {
        servers.add(Provisioning.getInstance().getLocalServer());
    }
    HttpClient client = ZimbraHttpConnectionManager.getExternalHttpConnMgr().newHttpClient();
    HttpProxyUtil.configureProxy(client);
    AuthToken authToken = AuthProvider.getAdminAuthToken();
    ZimbraLog.misc.debug("got admin auth token");
    String resp = "";
    for (Server server : servers) {
        if (isServerAtLeast8dot5(server)) {
            HttpMethod method = null;
            try {
                method = new GetMethod(URLUtil.getServiceURL(server, serviceUrl, false));
                ZimbraLog.misc.debug("connecting to ui node %s", server.getName());
                method.addRequestHeader(PARAM_AUTHTOKEN, authToken.getEncoded());
                // Add all the req headers passed to this function as well
                for (Map.Entry<String, String> entry : reqHeaders.entrySet()) {
                    method.addRequestHeader(entry.getKey(), entry.getValue());
                    ZimbraLog.misc.debug("adding request header %s=%s", entry.getKey(), entry.getValue());
                }
                int result = HttpClientUtil.executeMethod(client, method);
                ZimbraLog.misc.debug("resp: %d", result);
                resp = method.getResponseBodyAsString();
                ZimbraLog.misc.debug("got response from ui node: %s", resp);
                //try ui nodes one by one until one succeeds.
                break;
            } catch (IOException e) {
                ZimbraLog.misc.warn("failed to get response from ui node", e);
            } catch (AuthTokenException e) {
                ZimbraLog.misc.warn("failed to get authToken", e);
            } finally {
                if (method != null) {
                    method.releaseConnection();
                }
            }
        }
    }
    if (authToken != null && authToken.isRegistered()) {
        try {
            authToken.deRegister();
            ZimbraLog.misc.debug("de-registered auth token, isRegistered?%s", authToken.isRegistered());
        } catch (AuthTokenException e) {
            ZimbraLog.misc.warn("failed to de-register authToken", e);
        }
    }
    return resp;
}
Also used : Server(com.zimbra.cs.account.Server) HttpClient(org.apache.commons.httpclient.HttpClient) AuthTokenException(com.zimbra.cs.account.AuthTokenException) GetMethod(org.apache.commons.httpclient.methods.GetMethod) AuthToken(com.zimbra.cs.account.AuthToken) IOException(java.io.IOException) Map(java.util.Map) HttpMethod(org.apache.commons.httpclient.HttpMethod)

Example 22 with AuthToken

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

the class PreAuthServlet method doGet.

@Override
public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    ZimbraLog.clearContext();
    try {
        Provisioning prov = Provisioning.getInstance();
        Server server = prov.getLocalServer();
        String referMode = server.getAttr(Provisioning.A_zimbraMailReferMode, "wronghost");
        boolean isRedirect = getOptionalParam(req, PARAM_ISREDIRECT, "0").equals("1");
        String rawAuthToken = getOptionalParam(req, PARAM_AUTHTOKEN, null);
        AuthToken authToken = null;
        if (rawAuthToken != null) {
            authToken = AuthProvider.getAuthToken(rawAuthToken);
            if (authToken == null) {
                throw new AuthTokenException("unable to get auth token from " + PARAM_AUTHTOKEN);
            } else if (authToken.isExpired()) {
                throw new AuthTokenException("auth token expired");
            } else if (!authToken.isRegistered()) {
                throw new AuthTokenException("authtoken is invalid");
            }
        }
        if (rawAuthToken != null) {
            if (!authToken.isRegistered()) {
                throw new AuthTokenException("authtoken is not registered");
            }
            if (authToken.isExpired()) {
                throw new AuthTokenException("authtoken is expired registered");
            }
            // we've got an auth token in the request:
            // See if we need a redirect to the correct server
            boolean isAdmin = authToken != null && AuthToken.isAnyAdmin(authToken);
            Account acct = prov.get(AccountBy.id, authToken.getAccountId(), authToken);
            if (isAdmin || !needReferral(acct, referMode, isRedirect)) {
                //authtoken in get request is for one time use only. Deregister and generate new one.
                if (authToken instanceof ZimbraAuthToken) {
                    ZimbraAuthToken oneTimeToken = (ZimbraAuthToken) authToken;
                    ZimbraAuthToken newZimbraAuthToken = null;
                    try {
                        newZimbraAuthToken = oneTimeToken.clone();
                    } catch (CloneNotSupportedException e) {
                        throw new ServletException(e);
                    }
                    newZimbraAuthToken.resetTokenId();
                    oneTimeToken.deRegister();
                    authToken = newZimbraAuthToken;
                    ZimbraLog.account.debug("Deregistered the one time preauth token and issuing new one to the user.");
                }
                // no need to redirect to the correct server, just send them off to do business
                setCookieAndRedirect(req, resp, authToken);
            } else {
                // redirect to the correct server with the incoming auth token
                // we no longer send the auth token we generate over when we redirect to the correct server,
                // but customer can be sending a token in their preauth URL, in this case, just
                // send over the auth token as is.
                redirectToCorrectServer(req, resp, acct, rawAuthToken);
            }
        } else {
            // no auth token in the request URL.  See if we should redirect this request
            // to the correct server, or should do the preauth locally.
            String preAuth = getRequiredParam(req, resp, PARAM_PREAUTH);
            String account = getRequiredParam(req, resp, PARAM_ACCOUNT);
            String accountBy = getOptionalParam(req, PARAM_BY, AccountBy.name.name());
            AccountBy by = AccountBy.fromString(accountBy);
            boolean admin = getOptionalParam(req, PARAM_ADMIN, "0").equals("1") && isAdminRequest(req);
            long timestamp = Long.parseLong(getRequiredParam(req, resp, PARAM_TIMESTAMP));
            long expires = Long.parseLong(getRequiredParam(req, resp, PARAM_EXPIRES));
            Account acct = null;
            acct = prov.get(by, account, authToken);
            Map<String, Object> authCtxt = new HashMap<String, Object>();
            authCtxt.put(AuthContext.AC_ORIGINATING_CLIENT_IP, ZimbraServlet.getOrigIp(req));
            authCtxt.put(AuthContext.AC_REMOTE_IP, ZimbraServlet.getClientIp(req));
            authCtxt.put(AuthContext.AC_ACCOUNT_NAME_PASSEDIN, account);
            authCtxt.put(AuthContext.AC_USER_AGENT, req.getHeader("User-Agent"));
            boolean acctAutoProvisioned = false;
            if (acct == null) {
                //
                if (by == AccountBy.name && !admin) {
                    try {
                        EmailAddress email = new EmailAddress(account, false);
                        String domainName = email.getDomain();
                        Domain domain = domainName == null ? null : prov.get(Key.DomainBy.name, domainName);
                        prov.preAuthAccount(domain, account, accountBy, timestamp, expires, preAuth, authCtxt);
                        acct = prov.autoProvAccountLazy(domain, account, null, AutoProvAuthMech.PREAUTH);
                        if (acct != null) {
                            acctAutoProvisioned = true;
                        }
                    } catch (AuthFailedServiceException e) {
                        ZimbraLog.account.debug("auth failed, unable to auto provisioing acct " + account, e);
                    } catch (ServiceException e) {
                        ZimbraLog.account.info("unable to auto provisioing acct " + account, e);
                    }
                }
            }
            if (acct == null) {
                throw AuthFailedServiceException.AUTH_FAILED(account, account, "account not found");
            }
            String accountStatus = acct.getAccountStatus(prov);
            if (!Provisioning.ACCOUNT_STATUS_ACTIVE.equalsIgnoreCase(accountStatus)) {
                if (Provisioning.ACCOUNT_STATUS_MAINTENANCE.equalsIgnoreCase(accountStatus)) {
                    throw AccountServiceException.MAINTENANCE_MODE();
                } else {
                    throw AccountServiceException.ACCOUNT_INACTIVE(acct.getName());
                }
            }
            if (admin) {
                boolean isDomainAdminAccount = acct.getBooleanAttr(Provisioning.A_zimbraIsDomainAdminAccount, false);
                boolean isAdminAccount = acct.getBooleanAttr(Provisioning.A_zimbraIsAdminAccount, false);
                boolean isDelegatedAdminAccount = acct.getBooleanAttr(Provisioning.A_zimbraIsDelegatedAdminAccount, false);
                boolean ok = (isDomainAdminAccount || isAdminAccount || isDelegatedAdminAccount);
                if (!ok)
                    throw ServiceException.PERM_DENIED("not an admin account");
            }
            if (admin || !needReferral(acct, referMode, isRedirect)) {
                // do preauth locally
                if (!acctAutoProvisioned) {
                    prov.preAuthAccount(acct, account, accountBy, timestamp, expires, preAuth, admin, authCtxt);
                }
                AuthToken at;
                if (admin)
                    at = (expires == 0) ? AuthProvider.getAuthToken(acct, admin) : AuthProvider.getAuthToken(acct, expires, admin, null);
                else
                    at = (expires == 0) ? AuthProvider.getAuthToken(acct) : AuthProvider.getAuthToken(acct, expires);
                setCookieAndRedirect(req, resp, at);
            } else {
                // redirect to the correct server.
                // Note: we do not send over the generated auth token (the auth token param passed to
                // redirectToCorrectServer is null).
                redirectToCorrectServer(req, resp, acct, null);
            }
        }
    } catch (ServiceException e) {
        resp.sendError(HttpServletResponse.SC_BAD_REQUEST, e.getMessage());
    } catch (AuthTokenException e) {
        resp.sendError(HttpServletResponse.SC_BAD_REQUEST, e.getMessage());
    }
}
Also used : Account(com.zimbra.cs.account.Account) Server(com.zimbra.cs.account.Server) AuthFailedServiceException(com.zimbra.cs.account.AccountServiceException.AuthFailedServiceException) HashMap(java.util.HashMap) ZimbraAuthToken(com.zimbra.cs.account.ZimbraAuthToken) Provisioning(com.zimbra.cs.account.Provisioning) EmailAddress(com.zimbra.cs.account.names.NameUtil.EmailAddress) AccountBy(com.zimbra.common.account.Key.AccountBy) ServletException(javax.servlet.ServletException) AccountServiceException(com.zimbra.cs.account.AccountServiceException) ServiceException(com.zimbra.common.service.ServiceException) AuthFailedServiceException(com.zimbra.cs.account.AccountServiceException.AuthFailedServiceException) AuthTokenException(com.zimbra.cs.account.AuthTokenException) ZimbraAuthToken(com.zimbra.cs.account.ZimbraAuthToken) AuthToken(com.zimbra.cs.account.AuthToken) Domain(com.zimbra.cs.account.Domain)

Example 23 with AuthToken

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

the class PublicICalServlet method doGetFreeBusy.

/**
     * 
     * http://localhost:7070/service/pubcal/freebusy.ifb?acct=user@host.com
     * 
     * @param req
     * @param resp
     * @throws IOException
     * @throws ServletException
     */
public final void doGetFreeBusy(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException {
    String acctName = req.getParameter(QP_ACCOUNT);
    String startStr = req.getParameter(QP_START_TIME);
    String endStr = req.getParameter(QP_END_TIME);
    resp.setContentType(MimeConstants.CT_TEXT_CALENDAR);
    if (checkBlankOrNull(resp, QP_ACCOUNT, acctName))
        return;
    long now = new Date().getTime();
    long rangeStart = now - Constants.MILLIS_PER_WEEK;
    long rangeEnd = now + (2 * Constants.MILLIS_PER_MONTH);
    if (startStr != null)
        rangeStart = Long.parseLong(startStr);
    if (endStr != null)
        rangeEnd = Long.parseLong(endStr);
    if (rangeEnd < rangeStart) {
        resp.sendError(HttpServletResponse.SC_BAD_REQUEST, "End time must be after Start time");
        return;
    }
    long days = (rangeEnd - rangeStart) / Constants.MILLIS_PER_DAY;
    long maxDays = LC.calendar_freebusy_max_days.longValueWithinRange(0, 36600);
    if (days > maxDays) {
        resp.sendError(HttpServletResponse.SC_BAD_REQUEST, "Requested range is too large (max " + maxDays + " days)");
        return;
    }
    String targetAccountId = null;
    try {
        Account targetAccount = Provisioning.getInstance().get(AccountBy.name, acctName);
        if (targetAccount != null)
            targetAccountId = targetAccount.getId();
    } catch (ServiceException e) {
    }
    AuthToken at = getAuthTokenFromCookie(req, resp, true);
    if (at == null) {
        String authTokenParam = req.getParameter(QP_AUTH_TOKEN);
        if (authTokenParam != null) {
            try {
                at = AuthProvider.getAuthToken(authTokenParam);
            } catch (AuthTokenException e) {
                sLog.warn("Auth error: " + e.getMessage(), e);
            }
        }
    }
    Account authAccount = null;
    ZimbraSoapContext zsc = null;
    if (at != null) {
        try {
            authAccount = Provisioning.getInstance().get(AccountBy.id, at.getAccountId(), at);
        } catch (ServiceException e) {
            sLog.warn("Auth error: " + e.getMessage(), e);
        }
        try {
            zsc = new ZimbraSoapContext(at, targetAccountId, SoapProtocol.SoapJS, SoapProtocol.SoapJS);
        } catch (ServiceException e) {
            sLog.error("Error initializing request context", e);
            resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Error initializing request context");
            return;
        }
    } else {
        authAccount = GuestAccount.ANONYMOUS_ACCT;
    }
    FreeBusyQuery fbQuery = new FreeBusyQuery(req, zsc, authAccount, rangeStart, rangeEnd, null);
    fbQuery.addEmailAddress(acctName, FreeBusyQuery.CALENDAR_FOLDER_ALL);
    Collection<FreeBusy> result = fbQuery.getResults();
    FreeBusy fb = null;
    if (result.size() > 0)
        fb = result.iterator().next();
    else
        fb = FreeBusy.emptyFreeBusy(acctName, rangeStart, rangeEnd);
    String url = req.getRequestURL() + "?" + req.getQueryString();
    String fbMsg = fb.toVCalendar(FreeBusy.Method.PUBLISH, acctName, null, url);
    resp.getOutputStream().write(fbMsg.getBytes());
}
Also used : GuestAccount(com.zimbra.cs.account.GuestAccount) Account(com.zimbra.cs.account.Account) ServiceException(com.zimbra.common.service.ServiceException) FreeBusy(com.zimbra.cs.fb.FreeBusy) ZimbraSoapContext(com.zimbra.soap.ZimbraSoapContext) AuthTokenException(com.zimbra.cs.account.AuthTokenException) FreeBusyQuery(com.zimbra.cs.fb.FreeBusyQuery) AuthToken(com.zimbra.cs.account.AuthToken) Date(java.util.Date)

Example 24 with AuthToken

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

the class SSOServlet method authorize.

protected AuthToken authorize(HttpServletRequest req, AuthContext.Protocol proto, ZimbraPrincipal principal, boolean isAdminRequest) throws ServiceException {
    Map<String, Object> authCtxt = new HashMap<String, Object>();
    authCtxt.put(AuthContext.AC_ORIGINATING_CLIENT_IP, ZimbraServlet.getOrigIp(req));
    authCtxt.put(AuthContext.AC_REMOTE_IP, ZimbraServlet.getClientIp(req));
    authCtxt.put(AuthContext.AC_ACCOUNT_NAME_PASSEDIN, principal.getName());
    authCtxt.put(AuthContext.AC_USER_AGENT, req.getHeader("User-Agent"));
    Provisioning prov = Provisioning.getInstance();
    Account acct = principal.getAccount();
    ZimbraLog.addAccountNameToContext(acct.getName());
    prov.ssoAuthAccount(acct, proto, authCtxt);
    if (isAdminRequest) {
        if (!AccessManager.getInstance().isAdequateAdminAccount(acct)) {
            throw ServiceException.PERM_DENIED("not an admin account");
        }
    }
    AuthToken authToken = AuthProvider.getAuthToken(acct, isAdminRequest);
    return authToken;
}
Also used : Account(com.zimbra.cs.account.Account) HashMap(java.util.HashMap) AuthToken(com.zimbra.cs.account.AuthToken) Provisioning(com.zimbra.cs.account.Provisioning)

Example 25 with AuthToken

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

the class SpnegoAuthServlet method doGet.

@Override
public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    ZimbraLog.clearContext();
    addRemoteIpToLoggingContext(req);
    addUAToLoggingContext(req);
    boolean isAdminRequest = false;
    boolean isFromZCO = false;
    try {
        isAdminRequest = isOnAdminPort(req);
        isFromZCO = isFromZCO(req);
        Principal principal = req.getUserPrincipal();
        if (principal == null) {
            throw AuthFailedServiceException.AUTH_FAILED("no principal");
        }
        if (!(principal instanceof ZimbraPrincipal)) {
            throw AuthFailedServiceException.AUTH_FAILED(principal.getName(), "not ZimbraPrincipal", (Throwable) null);
        }
        ZimbraPrincipal zimbraPrincipal = (ZimbraPrincipal) principal;
        AuthToken authToken = authorize(req, AuthContext.Protocol.spnego, zimbraPrincipal, isAdminRequest);
        if (isFromZCO) {
            setAuthTokenCookieAndReturn(req, resp, authToken);
        } else {
            setAuthTokenCookieAndRedirect(req, resp, zimbraPrincipal.getAccount(), authToken);
        }
    } catch (ServiceException e) {
        if (e instanceof AuthFailedServiceException) {
            AuthFailedServiceException afe = (AuthFailedServiceException) e;
            ZimbraLog.account.info("spnego auth failed: " + afe.getMessage() + afe.getReason(", %s"));
        } else {
            ZimbraLog.account.info("spnego auth failed: " + e.getMessage());
        }
        ZimbraLog.account.debug("spnego auth failed", e);
        if (isFromZCO) {
            resp.sendError(HttpServletResponse.SC_FORBIDDEN, e.getMessage());
        } else {
            try {
                redirectToErrorPage(req, resp, isAdminRequest, Provisioning.getInstance().getConfig().getSpnegoAuthErrorURL());
            } catch (ServiceException se) {
                ZimbraLog.account.info("failed to redirect to error page: " + se.getMessage());
                resp.sendError(HttpServletResponse.SC_FORBIDDEN, e.getMessage());
            }
        }
    }
}
Also used : AuthFailedServiceException(com.zimbra.cs.account.AccountServiceException.AuthFailedServiceException) ServiceException(com.zimbra.common.service.ServiceException) AuthFailedServiceException(com.zimbra.cs.account.AccountServiceException.AuthFailedServiceException) ZimbraPrincipal(com.zimbra.cs.service.authenticator.SSOAuthenticator.ZimbraPrincipal) AuthToken(com.zimbra.cs.account.AuthToken) ZimbraPrincipal(com.zimbra.cs.service.authenticator.SSOAuthenticator.ZimbraPrincipal) Principal(java.security.Principal)

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