// Copyright 2000-2005 the Contributors, as shown in the revision logs. // Licensed under the Apache Public Source License 2.0 ("the License"). // You may not use this file except in compliance with the License. package org.ibex.mail; import org.ibex.crypto.*; import org.ibex.mail.protocol.*; import org.ibex.util.*; import org.ibex.net.*; import org.ibex.js.*; import org.ibex.mail.target.*; import java.util.*; import java.net.*; import java.text.*; import java.io.*; import org.ibex.io.*; import org.ibex.io.Fountain; public class GMail extends Account { private GMailIMAP imap = new GMailIMAP(); private HTTP.Cookie.Jar jar = new HTTP.Cookie.Jar(); private String captcha = null; private String ctoken = null; private String email = null; private String password = null; private boolean invalid = false; private String[] labels = new String[0]; private String[] queries = new String[0]; private Summary[] summaries = new Summary[0]; // Constructor, Pooling /////////////////////////////////////////////////////////////////////////// public GMail(String email, String pass) throws IOException { super(email.substring(0, email.indexOf('@')), Address.parse(email)); this.email = email; this.password = pass; Log.warn(GMail.class, "logging in " + email); getCookies(); } public void close() { cache.remove(email, password); invalid = true; } private static Hash cache = new Hash(); static { HTTP.userAgent = "Mozilla/5.0 (compatible;)"; } public static GMail getGMail(String email, String pass) { try { GMail g = (GMail)cache.get(email, pass); if (g == null) cache.put(email, pass, g = new GMail(email, pass)); return g; } catch (Exception e) { Log.error(GMail.class, e); return null; } } // IMAP Interface ////////////////////////////////////////////////////////////////////////////// public IMAP.Server getIMAP() { return imap; } private class GMailIMAP implements IMAP.Server { private String query = "?search=inbox&start=0&view=tl"; private int validity = new Random().nextInt(); private IMAP.Client client; public void setClient(IMAP.Client client) { this.client = client; } public String[] capability() { return new String[] { }; } public Hashtable id(Hashtable clientId) { return null; } public void logout() { GMail.this.close(); } public void subscribe(String mailbox) { } public void unsubscribe(String mailbox) { } public void unselect() { summaries = new Summary[0]; } public void close() { summaries = new Summary[0]; } public void noop() { check(); } public void expunge() { } public void setFlags(Query q, int flags, boolean uid, boolean silent) { } public void removeFlags(Query q, int flags, boolean uid, boolean silent) { } public void addFlags(Query q, int flags, boolean uid, boolean silent) { } public void rename(String from, String to) { } public void delete(String m) { } public void create(String m) { String[] newqueries = new String[queries.length+1]; System.arraycopy(queries, 0, newqueries, 0, queries.length); newqueries[queries.length] = m; queries = newqueries; } public void append(String m, int flags, Date arrival, String body) { } public void copy(Query q, String to) { } public void check() { query(query); } public void select(String mailbox, boolean examineOnly) { String oldquery = query; if (mailbox.equalsIgnoreCase("inbox")) { query = "?search=inbox&start=0&view=tl"; if (!query.equals(oldquery)) check(); return; } for(int i=0; i\r\n" + "Hi there. Google is lame; please type in the word you see below and " + "click submit. You might have to click 'get mail' again after that.
" + "\r\n" + "
\r\n"+ " \r\n"+ " \r\n"+ " \r\n"+ " \r\n"+ " \r\n"+ "
\r\n"+ "\r\n"; try { captchaMessage = Message.newMessage(new Fountain.StringFountain(str)); } catch (Message.Malformed e) { Log.warn(this, e); throw new IOException(e.toString()); } */ } public synchronized Summary[] query(String query) { if (captcha != null) return new Summary[0]; try { Log.info(GMail.class, "query: " + query); JSArray ret = http(gmail + query, jar); Hashtable h = new Hashtable(); for(int i=0; i"); this.from = Address.parse(m.get(6).toString()+"<"+m.get(7).toString()+">"); this.subject = m.get(15).toString(); } } public JSArray http(String url, HTTP.Cookie.Jar jar) throws JSExn, IOException { Stream stream = new Stream(new HTTP(url).GET(null, jar)); boolean inscript = false; StringBuffer buf = new StringBuffer("var ret = []; var D = function(x){ret.push(x);};"); String s = null; while((s = stream.readln()) != null) { if (s.indexOf("") != -1) { inscript = false; continue; } if (inscript) buf.append(s); } buf.append("return ret;"); synchronized(GMail.class) { JS js = JSU.fromReader("google", 0, new StringReader(buf.toString())); return (JSArray)js.call(null, JSU.emptyArgs); } } // HTTP Listener for Captcha requests ////////////////////////////////////////////////////////////////////////////// public static void handleRequest(Connection conn) { String top = null; for(String s = conn.readln(); s != null && s.length() > 0; s = conn.readln()) { if (top == null) top = s; Log.warn(GMail.class, s); } if (top.startsWith("GET /Captcha")) { top = top.substring(top.indexOf('?')+1); top = top.substring(0, top.indexOf(' ')); StringTokenizer st = new StringTokenizer(top, "&"); Hash h = new Hash(); while(st.hasMoreTokens()) { String tok = st.nextToken(); h.put(URLDecoder.decode(tok.substring(0, tok.indexOf('='))), URLDecoder.decode(tok.substring(tok.indexOf('=')+1))); } ((GMail)cache.get((String)h.get("email"), (String)h.get("pass"))).setCaptcha(h); conn.println("HTTP/1.0 200 OK\r\n"); conn.println("Content-Type: text/plain\r\n"); conn.println("\r\n"); conn.println("\r\n"); } else { conn.println("HTTP/1.0 500 Error\r\n\r\n"); } conn.flush(); conn.close(); } public void setCaptcha(Hash h) { captcha = (String)h.get("captcha"); ctoken = (String)h.get("ctoken"); Log.warn(GMail.class, "captcha = " + captcha); Log.warn(GMail.class, "ctoken = " + ctoken); Log.warn(GMail.class, "initting..." + ctoken); try { getCookies(); Log.warn(GMail.class, " done..." + ctoken); } catch (Exception e) { Log.error(this, e); } } // Constants ////////////////////////////////////////////////////////////////////////////// public static final String login = "https://www.google.com/accounts/ServiceLoginBoxAuth"; public static final String gmail = "https://gmail.google.com/gmail"; }