/** * Connect to Gmail without setting any session/cookie * * @return bool Connect to Gmail successfully or not */ function connectNoCookie() { $postdata = ""; $this->cookie_array = array(); if ($this->domain) { $postdata .= "&at=null"; $postdata .= "&continue=" . urlencode($this->GM_LNK_GMAIL); $postdata .= "&service=mail"; $postdata .= "&userName="******"&password="******"fixed"?!?; by Neerav; 1 Sept 2006 /* $postdata .= "<mpl=yj_blanco"; */ $postdata .= "<mpl=default"; // changed (was "<mpl=yj_blanco"); Neerav; 1 Nov 2007; $postdata .= "<mplcache=2"; $postdata .= "&continue=" . urlencode($this->GM_LNK_GMAIL); $postdata .= "&service=mail"; $postdata .= "&rm=false"; $postdata .= "&hl=en"; $postdata .= "&Email=" . urlencode($this->login); $postdata .= "&Passwd=" . urlencode($this->pwd); $postdata .= "&PersistentCookie=yes"; // Added by Neerav; 21 Dec 2007 $postdata .= "&rmShown=1"; $postdata .= "signIn=Sign+in"; // changed (was "&null=Sign+in"); Neerav; 1 Nov 2007; //$postdata .= "GALX="; // added but not used yet; Neerav; 1 Nov 2007; } // password debugging //Debugger::say(basename(__FILE__).": ".__LINE__.": ".print_r($this->pwd,true)); //Debugger::say(basename(__FILE__).": ".__LINE__.": ".print_r(urlencode($this->pwd),true)); //Debugger::say(basename(__FILE__).": ".__LINE__.": ".print_r(urlencode(urldecode($this->pwd)),true)); //Debugger::say(basename(__FILE__).": ".__LINE__.": ".print_r($postdata,true)); //exit; // Check for valid hosted domains; Added by Neerav; 10 June 2006 if ($this->domain) { if (preg_match("/(^yahoo\\.)|(^hotmail\\.)|(^(sayni)\\.net\$)|(^(live|msn|rediffmail|gmail|googlemail|mail)\\.com\$)/i", $this->domain) or strpos($this->domain, ".") === false) { $a = array("action" => "sign in", "status" => "failed", "message" => $this->domain . " cannot be used as a 'Gmail for your domain' (hosted) domain.", "login_error" => "invalid_domain"); array_unshift($this->return_status, $a); ///Debugger::say(basename(__FILE__).": ".__LINE__.": ".print_r($a,true)); return false; } // Domain test $this->gmail_data = GMailer::execute_curl($this->GM_LNK_LOGIN_REFER, "", 'get', "", 'nocookie', "", false, true); ///Debugger::say(basename(__FILE__).": ".__LINE__.": "."checked for valid GAFYD: ".print_r($this->gmail_data,true)); //exit; if (strpos($this->gmail_data, '<div class="x"> Sign in to your account at <h2>') > 0 or strpos($this->gmail_data, '<input type="hidden" name="continue" value="http://mail.google.com/hosted/' . $this->domain . '">') > 0 or strpos($this->gmail_data, 'SAMLRequest') !== false and strpos($this->gmail_data, urlencode(urlencode('http://mail.google.com/hosted/' . $this->domain))) !== false) { // domain exists ///Debugger::say(basename(__FILE__).": ".__LINE__.": "."hosted domain found"); } elseif (strpos($this->gmail_data, "Google Apps for Your Domain - Server error") > 0 or strpos($this->gmail_data, "<p>Sorry, you've reached a login page for a domain that isn't using Google Apps for Your Domain. Please check the web address and try again.</p>") > 0 or strpos($this->gmail_data, "<p>Sorry, you've reached a login page for a domain that isn't using Google Apps. Please check the web address and try again.</p>") > 0 or strpos($this->gmail_data, "<p>Domain does not exist</p>") > 0 or strpos($this->gmail_data, "Gmail for your domain - Server error") > 0) { // domain does not exist $a = array("action" => "sign in", "status" => "failed", "message" => "Gmail for your domain - Server error -- Domain does not exist", "login_error" => "domain_nonexist"); array_unshift($this->return_status, $a); ///Debugger::say(basename(__FILE__).": ".__LINE__.": hosted domain NOT found: ".print_r($a,true)); return false; } } // Added by Neerav; 8 July 2005 // Finally implemented 18 Oct 2006 // login challenge if (isset($this->logintoken) and $this->logintoken !== "") { $postdata .= "&logintoken=" . $this->logintoken; } if (isset($this->logincaptcha) and $this->logincaptcha !== "") { $postdata .= "&logincaptcha=" . $this->logincaptcha; } /* Let's begin the signin process */ // The GMAIL_LOGIN cookie is now required since 31 Aug 2006; by Neerav; 1 Sept 2006 $time = time(); $time_past = $time - rand(4, 20); // we fake that the user loaded the browser 4-20 seconds ago // create the cookie $this->cookie_array['GMAIL_LOGIN'] = array("name" => 'GMAIL_LOGIN', "value" => "T{$time_past}/{$time_past}/{$time}", "domain" => "manual", "path" => ""); $login_cookie = GMailer::gmail_cookie('GMAIL_LOGIN'); // added to use later for Gmail 2.0 accounts; Neerav; 1 Nov 2007 //echo 'login_cookie: '.$login_cookie; // Gmail's "user ping", sending word that this user is about to sign in. // added in case it's needed in the future; Neerav; 1 Sept 2006 // user pings are also done by non-GAFYD //if ($this->domain) { // $this->gmail_data = GMailer::execute_curl( // $this->GM_LNK_GMAIL."?gxlu=".urlencode($this->login)."&zx=".(time()-rand(2,6)).rand(100,999), // (($this->domain) ? $this->GM_LNK_LOGIN : $this->GM_LNK_LOGIN_REFER), // 'get', // "", // 'cookie', "$login_cookie" // ); // Debugger::say(basename(__FILE__).": ".__LINE__.": "."user ping result: ".print_r($this->gmail_data,true)); //} // double confirm the post data ///Debugger::say(basename(__FILE__).": ".__LINE__.": post data for signin: ".print_r($postdata,true)); //exit; $this->gmail_data = GMailer::execute_curl($this->GM_LNK_LOGIN, $this->domain ? $this->GM_LNK_LOGIN : $this->GM_LNK_LOGIN_REFER, 'post', $postdata, $this->domain ? 'nocookie' : 'cookie', $this->domain ? '' : "{$login_cookie}"); $a = array("action" => "connecting to Gmail (without cookie)", "status" => $this->gmail_data != "" ? "success" : "failed", "message" => $this->gmail_data != "" ? "connected to Gmail (without cookie)" : "no response", "login_error" => $this->gmail_data != "" ? "" : "no response"); array_unshift($this->return_status, $a); ///Debugger::say(basename(__FILE__).": ".__LINE__.": ".print_r($a,true)); ///Debugger::say(basename(__FILE__).": ".__LINE__.": "."user/pass phase: ".print_r($this->gmail_data,true)); //exit; if ($this->gmail_data == "") { return false; } /** from here we have to perform "cookie-handshaking"... (multiple redirects) **/ ///Debugger::say(basename(__FILE__).": ".__LINE__.": "."current cookie array: ".print_r($this->cookie_array,true)); $cookies = GMailer::get_cookies($this->gmail_data); ///Debugger::say(basename(__FILE__).": ".__LINE__.": "."user/pass phase cookies: ".print_r($this->cookie_array,true)); //exit; $this->logintoken = ""; $this->logincaptcha = ""; // hosted domains signin changed by Gmail; Neerav; 18 May 2007 if (strpos($this->gmail_data, $this->domain . "/?auth=") !== false or strpos($this->gmail_data, "&auth=") !== false) { // no error, already have the auth code and Location $cookies = ""; $auth_received = true; $second = $this->gmail_data; // skip the Auth phase ///Debugger::say(basename(__FILE__).": ".__LINE__.": "."hosted domain auth recieved: ".print_r($this->gmail_data,true)); // updated if condition for hosted domains; by Neerav; 8 June 2006 } elseif ((strpos($this->gmail_data, "errormsg_0_Passwd") > 0 or strpos($this->gmail_data, "errormsg_0_password") > 0) and strpos($this->gmail_data, "Username and password do not match") > 0) { $this->cookie_str = ""; $this->cookie_ik_str = ""; $this->cookie_array = array(); // Added appropriate error message; by Neerav; 8 July 2005 // Added error message for suggested username; by Neerav; 28 July 2006 if (preg_match("/Did you mean(.*?)\\?\\)/i", $this->gmail_data, $userpass_match)) { $suggest = trim($userpass_match[1]); $a = array("action" => "sign in", "status" => "failed", "message" => "Username and password do not match. (Did you mean " . $suggest . " ?)", "login_error" => "userpass_suggest", "login_suggest" => $suggest); } else { $a = array("action" => "sign in", "status" => "failed", "message" => "Username and password do not match. (You provided " . $this->login . ")", "login_error" => "userpass"); } array_unshift($this->return_status, $a); ///Debugger::say(basename(__FILE__).": ".__LINE__.": ".print_r($a,true)); return false; // Blank username or password; Added by Neerav; 8 June 2006 } elseif ((strpos($this->gmail_data, "errormsg_0_password") > 0 or strpos($this->gmail_data, "errormsg_0_userName") > 0 or strpos($this->gmail_data, "errormsg_0_username") > 0) and strpos($this->gmail_data, "Required field must not be blank") > 0) { $this->cookie_str = ""; $this->cookie_ik_str = ""; $this->cookie_array = array(); $a = array("action" => "sign in", "status" => "failed", "message" => "Required field must not be blank", "login_error" => "blank"); array_unshift($this->return_status, $a); ///Debugger::say(basename(__FILE__).": ".__LINE__.": ".print_r($a,true)); return false; // Added to support login challenge; by Neerav; 8 July 2005 } elseif (strpos($this->gmail_data, "errormsg_0_logincaptcha") > 0) { $this->cookie_str = ""; $this->cookie_ik_str = ""; $this->cookie_array = array(); ereg("id=\"logintoken\" value=\"([^\"]*)\" name=\"logintoken\"", $this->gmail_data, $matches); // Added appropriate error message; by Neerav; 8 July 2005 $a = array("action" => "sign in", "status" => "failed", "message" => "login challenge", "login_token" => $matches[1], "login_error" => "challenge"); array_unshift($this->return_status, $a); ///Debugger::say(basename(__FILE__).": ".__LINE__.": ".print_r($a,true)); return false; // Check if the Gmail URL has changed; Added by Neerav; 14 Sept 2005 } elseif (strpos($this->gmail_data, "Invalid request.")) { $this->cookie_str = ""; $this->cookie_ik_str = ""; $this->cookie_array = array(); $a = array("action" => "sign in", "status" => "failed", "message" => "Gmail: Invalid request. (libgmailer: Gmail seems to have changed the URL again.)", "login_error" => "URL"); array_unshift($this->return_status, $a); ///Debugger::say(basename(__FILE__).": ".__LINE__.": ".print_r($a,true)); return false; // Other custom Gmail error; Added by Neerav; 18 Jan 2007 } elseif (preg_match("@<div[^>]*errormsg_0_errMsg[^>]*>(.*)</div>@Uis", $this->gmail_data, $matches)) { $this->cookie_str = ""; $this->cookie_ik_str = ""; $this->cookie_array = array(); $a = array("action" => "sign in", "status" => "failed", "message" => $matches[1], "login_error" => "custom"); array_unshift($this->return_status, $a); return false; // Check for first time signin for hosted domain users; Added by Neerav; 25 Jan 2007 } elseif (strpos($this->gmail_data, 'action="SetupAccountAction"')) { $this->cookie_str = ""; $this->cookie_ik_str = ""; $this->cookie_array = array(); $a = array("action" => "sign in", "status" => "failed", "message" => "User needs to signin through a PC to setup the account.", "login_error" => "newly_created"); array_unshift($this->return_status, $a); return false; // Check for hosted domains that need to be set up; Addd by Neerav; 26 Jan 2007 // if condition changed (remove Location:); Neerav; 6 Nov 2007 } elseif ($this->domain and strpos($this->gmail_data, '/a/register?n=')) { $this->cookie_str = ""; $this->cookie_ik_str = ""; $this->cookie_array = array(); $a = array("action" => "sign in", "status" => "failed", "message" => "This Google Apps for Your Domain needs to be first set up.", "login_error" => "domain_setup"); array_unshift($this->return_status, $a); return false; // Check for a cookie as a way to check the Gmail URL; Added by Neerav; 14 Sept 2005 // For hosted domains, the cookie may be blank in some cases; changed by Neerav; 15 Mar 2007 } elseif (!$this->domain and $cookies == "" or $this->domain and strpos($this->gmail_data, "AuthEventSource=Internal&auth=") === false and $cookies == "") { $this->cookie_str = ""; $this->cookie_ik_str = ""; $this->cookie_array = array(); $a = array("action" => "sign in", "status" => "failed", "message" => "libgmailer: user/pass phase cookie not obtained. Gmail may be down.", "login_error" => "cookie"); array_unshift($this->return_status, $a); ///Debugger::say(basename(__FILE__).": ".__LINE__.": ".print_r($a,true)); return false; } $a = array("action" => "user/pass phase cookie", "status" => "success", "message" => "Received: " . $cookies); array_unshift($this->return_status, $a); ///Debugger::say(basename(__FILE__).": ".__LINE__.": ".print_r($a,true)); $this->cookie_array['TZ'] = array("name" => 'TZ', "value" => $this->timezone, "domain" => "manual", "path" => ""); $auth_received = false; $SID_received = GMailer::gmail_cookie('SID') !== "" ? true : false; $redirect_found = false; $redirect_HID = true; $redirect_url = ""; $redirect_count = 0; $refer = $this->domain ? $this->GM_LNK_LOGIN : $this->GM_LNK_LOGIN_REFER; while (true) { $redirect_count++; if ($redirect_HID and GMailer::gmail_cookie('HID') !== "") { $redirect_HID = false; $redirect_url = $this->GM_LNK_GMAIL . '?auth=' . str_replace("HID=", "", GMailer::gmail_cookie('HID')); /* // New redirection scheme for some accounts; Neerav; 22 Sept 2006 */ /* } elseif (preg_match("/url=['\"](http(s)?:\/\/([^'\"]*?))['\"]/s",$second,$matches)) { */ /* $redirect_url = ""; */ } elseif (strpos($this->gmail_data, "You cannot log into Gmail using your Google Account username and password.") !== false) { // using a Google Accounts login $a = array("action" => "sign in", "status" => "failed", "message" => "Sorry, this is not a valid Gmail login. You cannot log into Gmail using your Google Account username and password.", "login_error" => "google_account"); array_unshift($this->return_status, $a); ///Debugger::say(basename(__FILE__).": ".__LINE__.": ".print_r($a,true)); return false; } elseif (strpos($this->gmail_data, "500 Internal Server Error") !== false) { // internal server error $a = array("action" => "sign in", "status" => "failed", "message" => "Gmail Internal Server Error", "login_error" => "500"); array_unshift($this->return_status, $a); ///Debugger::say(basename(__FILE__).": ".__LINE__.": ".print_r($a,true)); return false; // Standard Location header } elseif (preg_match("/Location:\\s*((http(s)?:\\/\\/)?(.*?))\n/", $this->gmail_data, $matches)) { if (strpos($matches[1], "http") !== 0) { // relative url $redirect_url = "https://mail.google.com" . $matches[1]; } else { // fully qualified url $redirect_url = $matches[1]; } } elseif (preg_match("/<meta( http-equiv=\"refresh\")? content=\"0;\\s*url='?([^\"\\']*)'?\"/", $this->gmail_data, $matches)) { $redirect_url = str_replace("&", "&", $matches[2]); } if ($redirect_url != "") { if (strpos($redirect_url, "/accounts") !== false) { $use_cookie = GMailer::gmail_cookie("", "/accounts"); } else { $use_cookie = GMailer::gmail_cookie(); } $a = array("action" => "Redirection " . $redirect_count, "status" => "status", "message" => "Redirect to:\n" . $redirect_url); $a['cookie'] = "with cookie:\n" . $use_cookie; array_unshift($this->return_status, $a); ///Debugger::say(basename(__FILE__).": ".__LINE__.": ".print_r($a,true)); $this->gmail_data = GMailer::execute_curl($redirect_url, $refer, 'get', "", "cookie", $use_cookie); ///Debugger::say(basename(__FILE__).": ".__LINE__.": "."Redirection $redirect_count result:\n\n".print_r($this->gmail_data,true)); $cookies = GMailer::get_cookies($this->gmail_data); ///Debugger::say(basename(__FILE__).": ".__LINE__.": "."cookies after Redirection $redirect_count:\n".print_r($this->cookie_array,true)); $refer = $redirect_url; $redirect_url = ""; } else { break; } } if (strpos($this->gmail_data, "ui=2") !== false) { $this->GMAIL_GUI_VERSION = 2; } else { $this->GMAIL_GUI_VERSION = 1; } ///Debugger::say(basename(__FILE__).": ".__LINE__.": "."cookies (pre-clean): ".print_r($this->cookie_array,true)); // remove test cookie if (isset($this->cookie_array['dhc'])) { unset($this->cookie_array['dhc']); } // remove unnecessary GoogleAccountsLocale_session, if it still exists. if (isset($this->cookie_array['GoogleAccountsLocale_session'])) { unset($this->cookie_array['GoogleAccountsLocale_session']); } // remove cookies outside of the /mail path, we won't need them anymore foreach ($this->cookie_array as $name => $value) { if ($value['path'] == '/accounts') { unset($this->cookie_array["{$name}"]); } } ///Debugger::say(basename(__FILE__).": ".__LINE__.": "."final cookies (corrected/cleaned): ".print_r($this->cookie_array,true)); $this->cookie_str = GMailer::gmail_cookie("", "/accounts"); $a = array("action" => "final gmail cookie", "status" => "status", "message" => "Cookie:\n" . $this->cookie_str); array_unshift($this->return_status, $a); ///Debugger::say(basename(__FILE__).": ".__LINE__.": ".print_r($a,true)); return true; }