📄 imapconnection.java
字号:
} else if (id == OK) { // The capability list may be contained in the // response code. List code = response.getResponseCode(); int len = (code == null) ? 0 : code.size(); if (len > 0 && CAPABILITY.equals(code.get(0))) { for (int i = 1; i < len; i++) { String token = (String) code.get(i); if (!capabilities.contains(token)) { capabilities.add(token); } } } else { asyncResponses.add(response); } } else { asyncResponses.add(response); } } else { throw new IMAPException(id, response.getText()); } } } private void addTokens(List list, String text) { int start = 0; int end = text.indexOf(' '); String token; while (end != -1) { token = text.substring(start, end); if (!list.contains(token)) { list.add(token); } start = end + 1; end = text.indexOf(' ', start); } token = text.substring(start); if (token.length() > 0 && !list.contains(token)) { list.add(token); } } /** * Ping the server. * If a change in mailbox state is detected, a new mailbox status is * returned, otherwise this method returns null. */ public MailboxStatus noop() throws IOException { String tag = newTag(); sendCommand(tag, NOOP); boolean changed = false; MailboxStatus ms = new MailboxStatus(); Iterator asyncIterator = asyncResponses.iterator(); while (true) { IMAPResponse response; // Process any asynchronous responses first if (asyncIterator.hasNext()) { response = (IMAPResponse) asyncIterator.next(); asyncIterator.remove(); } else { response = readResponse(); } String id = response.getID(); if (response.isUntagged()) { changed = changed || updateMailboxStatus(ms, id, response); } else if (tag.equals(response.getTag())) { processAlerts(response); if (id == OK) { return changed ? ms : null; } else { throw new IMAPException(id, response.getText()); } } else { throw new IMAPException(id, response.getText()); } } } /** * Returns a configured SSLSocketFactory to use in creating new SSL * sockets. * @param tm an optional trust manager to use */ protected SSLSocketFactory getSSLSocketFactory(TrustManager tm) throws GeneralSecurityException { if (tm == null) { tm = new EmptyX509TrustManager(); } SSLContext context = SSLContext.getInstance("TLS"); TrustManager[] trust = new TrustManager[] { tm }; context.init(null, trust, null); return context.getSocketFactory(); } /** * Attempts to start TLS on the specified connection. * See RFC 2595 for details. * @return true if successful, false otherwise */ public boolean starttls() throws IOException { return starttls(new EmptyX509TrustManager()); } /** * Attempts to start TLS on the specified connection. * See RFC 2595 for details. * @param tm the custom trust manager to use * @return true if successful, false otherwise */ public boolean starttls(TrustManager tm) throws IOException { try { SSLSocketFactory factory = getSSLSocketFactory(tm); String hostname = socket.getInetAddress().getHostName(); int port = socket.getPort(); String tag = newTag(); sendCommand(tag, STARTTLS); while (true) { IMAPResponse response = readResponse(); if (response.isTagged() && tag.equals(response.getTag())) { processAlerts(response); String id = response.getID(); if (id == OK) { break; // negotiate TLS } else if (id == BAD) { return false; } } else { asyncResponses.add(response); } } SSLSocket ss = (SSLSocket) factory.createSocket(socket, hostname, port, true); String[] protocols = { "TLSv1", "SSLv3" }; ss.setEnabledProtocols(protocols); ss.setUseClientMode(true); ss.startHandshake(); InputStream in = ss.getInputStream(); in = new BufferedInputStream(in); this.in = new IMAPResponseTokenizer(in); OutputStream out = ss.getOutputStream(); out = new BufferedOutputStream(out); this.out = new CRLFOutputStream(out); return true; } catch (GeneralSecurityException e) { e.printStackTrace(); return false; } } /** * Login to the connection using the username and password method. * @param username the authentication principal * @param password the authentication credentials * @return true if authentication was successful, false otherwise */ public boolean login(String username, String password) throws IOException { return invokeSimpleCommand(LOGIN + ' ' + quote(username) + ' ' + quote(password)); } /** * Authenticates the connection using the specified SASL mechanism, * username, and password. * @param mechanism a SASL authentication mechanism, e.g. LOGIN, PLAIN, * CRAM-MD5, GSSAPI * @param username the authentication principal * @param password the authentication credentials * @return true if authentication was successful, false otherwise */ public boolean authenticate(String mechanism, String username, String password) throws IOException { try { String[] m = new String[] { mechanism }; CallbackHandler ch = new SaslCallbackHandler(username, password); // Avoid lengthy callback procedure for GNU Crypto HashMap p = new HashMap(); p.put("gnu.crypto.sasl.username", username); p.put("gnu.crypto.sasl.password", password); SaslClient sasl = Sasl.createSaslClient(m, null, "imap", socket.getInetAddress(). getHostName(), p, ch); if (sasl == null) { // Fall back to home-grown SASL clients if ("LOGIN".equalsIgnoreCase(mechanism)) { sasl = new SaslLogin(username, password); } else if ("PLAIN".equalsIgnoreCase(mechanism)) { sasl = new SaslPlain(username, password); } else if ("CRAM-MD5".equalsIgnoreCase(mechanism)) { sasl = new SaslCramMD5(username, password); } else { logger.log(IMAP_TRACE, mechanism + " not available"); return false; } } StringBuffer cmd = new StringBuffer(AUTHENTICATE); cmd.append(' '); cmd.append(mechanism); String tag = newTag(); sendCommand(tag, cmd.toString()); while (true) { IMAPResponse response = readResponse(); if (tag.equals(response.getTag())) { processAlerts(response); String id = response.getID(); if (id == OK) { String qop = (String) sasl.getNegotiatedProperty(Sasl.QOP); if ("auth-int".equalsIgnoreCase(qop) || "auth-conf".equalsIgnoreCase(qop)) { InputStream in = socket.getInputStream(); in = new BufferedInputStream(in); in = new SaslInputStream(sasl, in); this.in = new IMAPResponseTokenizer(in); OutputStream out = socket.getOutputStream(); out = new BufferedOutputStream(out); out = new SaslOutputStream(sasl, out); this.out = new CRLFOutputStream(out); } return true; } else if (id == NO) { return false; } else if (id == BAD) { throw new IMAPException(id, response.getText()); } } else if (response.isContinuation()) { try { byte[] c0 = response.getText().getBytes(US_ASCII); byte[] c1 = BASE64.decode(c0); // challenge byte[] r0 = sasl.evaluateChallenge(c1); byte[] r1 = BASE64.encode(r0); // response out.write(r1); out.writeln(); out.flush(); logger.log(IMAP_TRACE, "> " + new String(r1, US_ASCII)); } catch (SaslException e) { // Error in SASL challenge evaluation - cancel exchange out.write(0x2a); out.writeln(); out.flush(); logger.log(IMAP_TRACE, "> *"); } } else { asyncResponses.add(response); } } } catch (SaslException e) { logger.log(IMAP_TRACE, e.getMessage(), e); return false; // No provider for mechanism } catch (RuntimeException e) { logger.log(IMAP_TRACE, e.getMessage(), e); return false; // No javax.security.sasl classes } } /** * Logout this connection. * Underlying network resources will be freed. */ public void logout() throws IOException { String tag = newTag(); sendCommand(tag, LOGOUT); while (true) { IMAPResponse response = readResponse(); if (response.isTagged() && tag.equals(response.getTag())) { processAlerts(response); String id = response.getID(); if (id == OK) { socket.close(); return; } else { throw new IMAPException(id, response.getText()); } } else { asyncResponses.add(response); } } } /** * Selects the specified mailbox. * The mailbox is identified as read-write if writes are permitted. * @param mailbox the mailbox name * @return a MailboxStatus containing the state of the selected mailbox */ public MailboxStatus select(String mailbox) throws IOException { return selectImpl(mailbox, SELECT); } /** * Selects the specified mailbox. * The mailbox is identified as read-only. * @param mailbox the mailbox name * @return a MailboxStatus containing the state of the selected mailbox */ public MailboxStatus examine(String mailbox) throws IOException { return selectImpl(mailbox, EXAMINE); } protected MailboxStatus selectImpl(String mailbox, String command) throws IOException { String tag = newTag(); sendCommand(tag, command + ' ' + quote(UTF7imap.encode(mailbox))); MailboxStatus ms = new MailboxStatus(); while (true) { IMAPResponse response = readResponse(); String id = response.getID(); if (response.isUntagged()) { if (!updateMailboxStatus(ms, id, response)) { asyncResponses.add(response); } } else if (tag.equals(response.getTag())) { processAlerts(response); if (id == OK) { List rc = response.getResponseCode(); if (rc != null && rc.size() > 0 && rc.get(0) == READ_WRITE) { ms.readWrite = true; } return ms; } else { throw new IMAPException(id, response.getText()); } } else { throw new IMAPException(id, response.getText()); } } } protected boolean updateMailboxStatus(MailboxStatus ms, String id, IMAPResponse response) throws IOException { if (id == OK) { boolean changed = false; List rc = response.getResponseCode(); int len = (rc == null) ? 0 : rc.size(); for (int i = 0; i < len; i++)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -