Search in sources :

Example 1 with ZimbraAuthToken

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

the class AttributeMigration method clearConfigCacheOnAllServers.

public static void clearConfigCacheOnAllServers(boolean includeLocal, boolean registerTokenInPrevStore) {
    ExecutorService executor = newCachedThreadPool(newDaemonThreadFactory("ClearEphemeralConfigCache"));
    List<Server> servers = null;
    List<Server> imapServers = null;
    try {
        servers = Provisioning.getInstance().getAllMailClientServers();
    } catch (ServiceException e) {
        ZimbraLog.account.warn("cannot fetch list of servers");
        return;
    }
    try {
        imapServers = Provisioning.getIMAPDaemonServersForLocalServer();
    } catch (ServiceException e) {
        ZimbraLog.account.warn("cannot fetch list of imapd servers");
    }
    for (Server server : servers) {
        try {
            if (server.isLocalServer() && !includeLocal) {
                // don't need to flush cache on this server
                continue;
            }
        } catch (ServiceException e2) {
            ZimbraLog.ephemeral.warn("error determining if server %s is local server", server.getServiceHostname());
        }
        executor.submit(new Runnable() {

            @Override
            public void run() {
                SoapProvisioning soapProv = new SoapProvisioning();
                try {
                    String adminUrl = URLUtil.getAdminURL(server, AdminConstants.ADMIN_SERVICE_URI, true);
                    soapProv.soapSetURI(adminUrl);
                } catch (ServiceException e1) {
                    ZimbraLog.ephemeral.warn("could not get admin URL for server %s during ephemeral backend change", e1);
                    return;
                }
                try {
                    soapProv.soapZimbraAdminAuthenticate();
                    // don't flush imap daemon cache via FlushCache forwarding, since it will be done below
                    soapProv.flushCache(CacheEntryType.config.name(), null, false, false);
                    ZimbraLog.ephemeral.debug("sent FlushCache request to server %s", server.getServiceHostname());
                } catch (ServiceException e) {
                    ZimbraLog.ephemeral.warn("cannot send FlushCache request to server %s", server.getServiceHostname(), e);
                }
            }
        });
    }
    /* To flush the cache on imapd servers via the X-ZIMBRA-FLUSHCACHE command, in some cases, the auth token needs to be registered
         * with the previous ephemeral backend. This is because the imapd server may still be using the previous backend.
         */
    EphemeralStore.Factory previousEphemeralFactory = null;
    if (imapServers != null && imapServers.size() > 0) {
        if (registerTokenInPrevStore) {
            try {
                previousEphemeralFactory = EphemeralStore.getNewFactory(BackendType.previous);
            } catch (ServiceException e) {
                ZimbraLog.ephemeral.warn("could not instantiate previous EphemeralStore; imapd servers may not recognize auth token", e);
            }
        }
        final EphemeralStore previousEphemeralStore;
        if (previousEphemeralFactory != null) {
            previousEphemeralStore = registerTokenInPrevStore ? previousEphemeralFactory.getStore() : null;
        } else {
            previousEphemeralStore = null;
        }
        for (Server server : imapServers) {
            executor.submit(new Runnable() {

                @Override
                public void run() {
                    try {
                        ZimbraAuthToken token = (ZimbraAuthToken) AuthProvider.getAdminAuthToken();
                        if (registerTokenInPrevStore && previousEphemeralStore != null) {
                            token.registerWithEphemeralStore(previousEphemeralStore);
                        }
                        FlushCache.flushCacheOnImapDaemon(server, "config", null, LC.zimbra_ldap_user.value(), token);
                        ZimbraLog.ephemeral.debug("sent X-ZIMBRA-FLUSHCACHE IMAP request to imapd server %s", server.getServiceHostname());
                    } catch (ServiceException e) {
                        ZimbraLog.ephemeral.error("cannot send X-ZIMBRA-FLUSHCACHE IMAP request to imapd server %s", server.getServiceHostname(), e);
                    }
                }
            });
        }
    }
    executor.shutdown();
    try {
        executor.awaitTermination(10, TimeUnit.SECONDS);
    } catch (InterruptedException e) {
    }
}
Also used : Server(com.zimbra.cs.account.Server) ServiceException(com.zimbra.common.service.ServiceException) SoapProvisioning(com.zimbra.cs.account.soap.SoapProvisioning) ZimbraAuthToken(com.zimbra.cs.account.ZimbraAuthToken) ExecutorService(java.util.concurrent.ExecutorService) EphemeralStore(com.zimbra.cs.ephemeral.EphemeralStore)

Example 2 with ZimbraAuthToken

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

the class ContactBackupThread method createBackup.

private void createBackup(OperationContext octxt, Mailbox mbox, Account account, Folder folder, Date startTime) {
    Date date = new Date();
    SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT);
    StringBuilder filename = new StringBuilder();
    filename.append(FILE_NAME).append("-").append(sdf.format(date));
    InputStream is = null;
    ZimbraAuthToken token = null;
    try {
        token = new ZimbraAuthToken(account);
        ZMailbox.Options zoptions = new ZMailbox.Options(token.toZAuthToken(), AccountUtil.getSoapUri(account));
        zoptions.setNoSession(true);
        zoptions.setTargetAccount(account.getId());
        zoptions.setTargetAccountBy(AccountBy.id);
        ZMailbox zmbx = ZMailbox.getMailbox(zoptions);
        is = zmbx.getRESTResource(CONTACT_RES_URL);
        ParsedDocument pd = new ParsedDocument(is, filename.toString(), CT_TYPE, startTime.getTime(), OPERATION, FILE_DESC + startTime.toString());
        Document doc = mbox.createDocument(octxt, folder.getId(), pd, MailItem.Type.DOCUMENT, 0);
        ZimbraLog.contactbackup.debug("contact backup created size %d bytes", doc.getSize());
    } catch (UnsupportedOperationException | IOException | ServiceException exception) {
        success = false;
        ZimbraLog.contactbackup.warn("contact export failed, continuing to next mailbox");
        ZimbraLog.contactbackup.debug(exception);
    } catch (OutOfMemoryError e) {
        Zimbra.halt("OutOfMemoryError while creating contact backup", e);
    } finally {
        if (is != null) {
            try {
                is.close();
            } catch (IOException ioe) {
                ZimbraLog.contactbackup.debug("IOExcepion occured while closing stream", ioe);
            }
        }
        if (token != null) {
            try {
                token.deRegister();
            } catch (AuthTokenException e) {
                ZimbraLog.contactbackup.warn("failed to deregister token");
                ZimbraLog.contactbackup.debug(e);
            }
        }
    }
}
Also used : FolderOptions(com.zimbra.cs.mailbox.Folder.FolderOptions) InputStream(java.io.InputStream) ZimbraAuthToken(com.zimbra.cs.account.ZimbraAuthToken) IOException(java.io.IOException) ParsedDocument(com.zimbra.cs.mime.ParsedDocument) Date(java.util.Date) ZMailbox(com.zimbra.client.ZMailbox) ParsedDocument(com.zimbra.cs.mime.ParsedDocument) ServiceException(com.zimbra.common.service.ServiceException) AuthTokenException(com.zimbra.cs.account.AuthTokenException) SimpleDateFormat(java.text.SimpleDateFormat)

Example 3 with ZimbraAuthToken

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

the class CsrfUtilTest method testIsValidCsrfTokenForAccountWithMultipleTokens.

@Test
public final void testIsValidCsrfTokenForAccountWithMultipleTokens() {
    try {
        Account acct = Provisioning.getInstance().getAccountByName("test@zimbra.com");
        AuthToken authToken = new ZimbraAuthToken(acct);
        String csrfToken1 = CsrfUtil.generateCsrfToken(acct.getId(), AUTH_TOKEN_EXPR, CSRFTOKEN_SALT, authToken);
        boolean validToken = CsrfUtil.isValidCsrfToken(csrfToken1, authToken);
        assertTrue(validToken);
    } catch (ServiceException e) {
        fail("Should not throw exception.");
    }
}
Also used : Account(com.zimbra.cs.account.Account) ServiceException(com.zimbra.common.service.ServiceException) ZimbraAuthToken(com.zimbra.cs.account.ZimbraAuthToken) ZimbraAuthToken(com.zimbra.cs.account.ZimbraAuthToken) AuthToken(com.zimbra.cs.account.AuthToken) Test(org.junit.Test)

Example 4 with ZimbraAuthToken

use of com.zimbra.cs.account.ZimbraAuthToken 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 provision acct " + account, e);
                    } catch (ServiceException e) {
                        ZimbraLog.account.info("unable to auto provision 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 5 with ZimbraAuthToken

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

the class TestPreAuthServlet method testShouldNotAllowPreAuthGetCookieReuse.

public void testShouldNotAllowPreAuthGetCookieReuse() throws Exception {
    Account account = TestUtil.getAccount("user1");
    AuthToken authToken = new ZimbraAuthToken(account);
    System.out.println(authToken.isRegistered());
    HttpClient client = HttpClientBuilder.create().build();
    Server localServer = Provisioning.getInstance().getLocalServer();
    String protoHostPort = "http://localhost:" + localServer.getIntAttr(Provisioning.A_zimbraMailPort, 0);
    String url = protoHostPort + PRE_AUTH_URL;
    // allow first request
    List<NameValuePair> nvp = new ArrayList<NameValuePair>();
    nvp.add(new BasicNameValuePair("isredirect", "1"));
    nvp.add(new BasicNameValuePair("authtoken", authToken.getEncoded()));
    HttpRequestBase method = new HttpGet(url + "?" + URLEncodedUtils.format(nvp, "utf-8"));
    HttpResponse response = HttpClientUtil.executeMethod(client, method);
    // reject second request
    method = new HttpGet(url + "?" + URLEncodedUtils.format(nvp, "utf-8"));
    response = HttpClientUtil.executeMethod(client, method);
    int respCode = response.getStatusLine().getStatusCode();
    Assert.assertEquals(400, respCode);
}
Also used : Account(com.zimbra.cs.account.Account) BasicNameValuePair(org.apache.http.message.BasicNameValuePair) NameValuePair(org.apache.http.NameValuePair) HttpRequestBase(org.apache.http.client.methods.HttpRequestBase) Server(com.zimbra.cs.account.Server) ZimbraAuthToken(com.zimbra.cs.account.ZimbraAuthToken) HttpGet(org.apache.http.client.methods.HttpGet) ArrayList(java.util.ArrayList) HttpResponse(org.apache.http.HttpResponse) HttpClient(org.apache.http.client.HttpClient) BasicNameValuePair(org.apache.http.message.BasicNameValuePair) ZimbraAuthToken(com.zimbra.cs.account.ZimbraAuthToken) AuthToken(com.zimbra.cs.account.AuthToken)

Aggregations

ZimbraAuthToken (com.zimbra.cs.account.ZimbraAuthToken)16 Account (com.zimbra.cs.account.Account)14 Test (org.junit.Test)9 ServiceException (com.zimbra.common.service.ServiceException)8 AuthToken (com.zimbra.cs.account.AuthToken)8 AuthTokenException (com.zimbra.cs.account.AuthTokenException)5 Server (com.zimbra.cs.account.Server)3 ZMailbox (com.zimbra.client.ZMailbox)2 IOException (java.io.IOException)2 InputStream (java.io.InputStream)2 AccountBy (com.zimbra.common.account.Key.AccountBy)1 ZAuthToken (com.zimbra.common.auth.ZAuthToken)1 Element (com.zimbra.common.soap.Element)1 JSONElement (com.zimbra.common.soap.Element.JSONElement)1 XMLElement (com.zimbra.common.soap.Element.XMLElement)1 SoapHttpTransport (com.zimbra.common.soap.SoapHttpTransport)1 AccountServiceException (com.zimbra.cs.account.AccountServiceException)1 AuthFailedServiceException (com.zimbra.cs.account.AccountServiceException.AuthFailedServiceException)1 Domain (com.zimbra.cs.account.Domain)1 Provisioning (com.zimbra.cs.account.Provisioning)1