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) {
}
}
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);
}
}
}
}
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.");
}
}
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());
}
}
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);
}
Aggregations