function handmadeimap_get_command_result($connection, $commandid) { global $g_resultlines; global $g_infolines; $g_infolines = array(); $insidequotes = false; $insideliteral = false; $chewingliteral = false; $literallength = 0; $outputline = ''; $previouschar = ''; while (!feof($connection)) { if (isset($g_resultlines[$commandid])) { return $g_resultlines[$commandid]; } while (!feof($connection)) { $outputchar = fgetc($connection); if ($outputchar === FALSE) { break; } if ($chewingliteral) { $literallength -= 1; if ($outputchar == '"') { $outputline .= '\\'; } if ($literallength < 1) { $chewingliteral = false; $outputline .= $outputchar; $outputline .= '"'; } else { if ($outputchar != chr(10) && $outputchar != chr(13)) { $outputline .= $outputchar; } } } else { if ($outputchar == '"') { $insidequotes = !$insidequotes; $outputline .= $outputchar; } else { if (!$insidequotes && $outputchar == '{') { $insideliteral = true; $literallength = 0; } else { if ($insideliteral && ctype_digit($outputchar)) { $literallength *= 10; $literallength += $outputchar; } else { if ($insideliteral && $outputchar == '}') { $literallength += 2; $chewingliteral = true; $outputline .= '"'; } else { if ($outputchar == chr(10) && $previouschar == chr(13)) { $outputline = trim($outputline); pete_log('handmadeimap', "Received '{$outputline}'"); $spacearray = explode(" ", $outputline); $resultid = $spacearray[0]; if ($resultid == '*') { $g_infolines[] = $outputline; } else { $g_resultlines[$resultid] = array('resultline' => $outputline, 'infolines' => $g_infolines); } $outputline = ''; $insidequotes = false; $insideliteral = false; $chewingliteral = false; $literallength = 0; } else { $outputline .= $outputchar; } } } } } } $previouschar = $outputchar; } time_nanosleep(0, 500000); } return null; }
function OutputDebug($message) { pete_log('handmadeimap', $message); }
function handle_gmail_oauth() { if (!isset($_SESSION['emailaddress'])) { if (!empty($_REQUEST['emailaddress'])) { $_SESSION['emailaddress'] = $_REQUEST['emailaddress']; } else { ?> <center> <form method="GET" action="index.php"> Gmail address: <input type="text" size="40" name="emailaddress" value="<?php echo $email; ?> "/> <input type="submit" value="Authorize"/> </form> </center> <?php return; } } $emailaddress = $_SESSION['emailaddress']; $oauthstate = get_gmail_oauth_state(); // If there's no oAuth state stored at all, then we need to initialize one with our request // information, ready to create a request URL. if (!isset($oauthstate)) { pete_log('oauth', "No OAuth state found"); $to = new GmailOAuth(GOOGLE_API_KEY_PUBLIC, GOOGLE_API_KEY_PRIVATE); // This call can be unreliable if the Gmail API servers are under a heavy load, so // retry it with an increasing amount of back-off if there's a problem. $maxretrycount = 1; $retrycount = 0; while ($retrycount < $maxretrycount) { $tok = $to->getRequestToken(); if (isset($tok['oauth_token']) && isset($tok['oauth_token_secret'])) { break; } $retrycount += 1; sleep($retrycount * 5); } $tokenpublic = $tok['oauth_token']; $tokenprivate = $tok['oauth_token_secret']; $state = 'start'; // Create a new set of information, initially just containing the keys we need to make // the request. $oauthstate = array('request_token' => $tokenpublic, 'request_token_secret' => $tokenprivate, 'access_token' => '', 'access_token_secret' => '', 'state' => $state); set_gmail_oauth_state($oauthstate); } // If there's an 'oauth_token' in the URL parameters passed into us, and we don't already // have access tokens stored, this is the user being returned from the authorization page. // Retrieve the access tokens and store them, and set the state to 'done'. if (isset($_REQUEST['oauth_token']) && $oauthstate['access_token'] == '') { error_log('$_REQUEST: ' . print_r($_REQUEST, true)); $urlaccesstoken = $_REQUEST['oauth_token']; pete_log('oauth', "Found access tokens in the URL - {$urlaccesstoken}"); $requesttoken = $oauthstate['request_token']; $requesttokensecret = $oauthstate['request_token_secret']; pete_log('oauth', "Creating API with {$requesttoken}, {$requesttokensecret}"); $to = new GmailOAuth(GOOGLE_API_KEY_PUBLIC, GOOGLE_API_KEY_PRIVATE, $requesttoken, $requesttokensecret); $tok = $to->getAccessToken(); $accesstoken = $tok['oauth_token']; $accesstokensecret = $tok['oauth_token_secret']; pete_log('oauth', "Calculated access tokens {$accesstoken}, {$accesstokensecret}"); $oauthstate['access_token'] = $accesstoken; $oauthstate['access_token_secret'] = $accesstokensecret; $oauthstate['state'] = 'done'; set_gmail_oauth_state($oauthstate); } $state = $oauthstate['state']; if ($state == 'start') { // This is either the first time the user has seen this page, or they've refreshed it before // they've authorized us to access their information. Either way, display a link they can // click that will take them to the authorization page. // In a real application, you'd probably have the page automatically redirect, since the // user has already entered their email address once for us already $tokenpublic = $oauthstate['request_token']; $to = new GmailOAuth(GOOGLE_API_KEY_PUBLIC, GOOGLE_API_KEY_PRIVATE); $requestlink = $to->getAuthorizeURL($tokenpublic, get_current_url()); ?> <center><h1>Click this link to authorize accessing messages from <?php echo htmlspecialchars($emailaddress); ?> </h1></center> <br><br> <center><a href="<?php echo $requestlink; ?> "><?php echo $requestlink; ?> </a></center> <?php } else { // We've been given some access tokens, so try and use them to make an API call, and // display the results. $accesstoken = $oauthstate['access_token']; $accesstokensecret = $oauthstate['access_token_secret']; $connection = gmail_login($emailaddress, $accesstoken, $accesstokensecret); $receivedmailbox = 'Inbox'; $received = fetch_senders_and_recipients($connection, $receivedmailbox, 500); $receivedfrom = $received['from']; $sentmailbox = '[Gmail]/Sent Mail'; $sent = fetch_senders_and_recipients($connection, $sentmailbox, 500); $sentto = $sent['to']; $sentfrom = $sent['from']; $rankedfriends = array(); foreach ($receivedfrom as $address => $receivedinfo) { if (!isset($sentto[$address])) { continue; } if (isset($sentfrom[$address])) { continue; } $sentinfo = $sentto[$address]; $senttocount = $sentinfo['count']; $receivedfromcount = $receivedinfo['count']; $score = min($senttocount, $receivedfromcount); if ($score < 1) { continue; } $display = $sentinfo['display']; $rankedfriends[] = array('address' => $address, 'display' => $display, 'score' => $score); } $sortfunction = create_function('$a, $b', 'if ($a["score"]<$b["score"]) return 1; else return -1;'); usort($rankedfriends, $sortfunction); print '<h3>Your friends ranked by how often you email each other</h3>'; print '<br>'; print "\n"; foreach ($rankedfriends as $friendinfo) { $address = $friendinfo['address']; $display = $friendinfo['display']; $score = $friendinfo['score']; print htmlspecialchars('<' . $address . '> "' . $display . '" - ' . $score); print '<br>'; print "\n"; } } }
function get_imap_info_for_address($address) { global $g_domainimapinfo; $domain = get_canonical_domain_from_email_address($address); $imapdomain = get_imap_domain_from_domain($domain); if ($imapdomain == null) { pete_log('accounts', 'No host found for ' . $address); return null; } pete_log('accounts', 'Host ' . $imapdomain . ' found for ' . $address); $result = $g_domainimapinfo[$imapdomain]; $result['username'] = $address; return $result; }
function handle_twitter_oauth() { $oauthstate = get_twitter_oauth_state(); // If there's no oAuth state stored at all, then we need to initialize one with our request // information, ready to create a request URL. if (!isset($oauthstate)) { pete_log('oauth', "No OAuth state found"); $to = new TwitterOAuth(TWITTER_API_KEY_PUBLIC, TWITTER_API_KEY_PRIVATE); // This call can be unreliable if the Twitter API servers are under a heavy load, so // retry it with an increasing amount of back-off if there's a problem. $maxretrycount = 10; $retrycount = 0; while ($retrycount < $maxretrycount) { $tok = $to->getRequestToken(); if (isset($tok['oauth_token']) && isset($tok['oauth_token_secret'])) { break; } $retrycount += 1; sleep($retrycount * 5); } $tokenpublic = $tok['oauth_token']; $tokenprivate = $tok['oauth_token_secret']; $state = 'start'; // Create a new set of information, initially just containing the keys we need to make // the request. $oauthstate = array('request_token' => $tokenpublic, 'request_token_secret' => $tokenprivate, 'access_token' => '', 'access_token_secret' => '', 'state' => $state); set_twitter_oauth_state($oauthstate); } // If there's an 'oauth_token' in the URL parameters passed into us, and we don't already // have access tokens stored, this is the user being returned from the authorization page. // Retrieve the access tokens and store them, and set the state to 'done'. if (isset($_REQUEST['oauth_token']) && $oauthstate['access_token'] == '') { $urlaccesstoken = $_REQUEST['oauth_token']; pete_log('oauth', "Found access tokens in the URL - {$urlaccesstoken}"); $requesttoken = $oauthstate['request_token']; $requesttokensecret = $oauthstate['request_token_secret']; pete_log('oauth', "Creating API with {$requesttoken}, {$requesttokensecret}"); $to = new TwitterOAuth(TWITTER_API_KEY_PUBLIC, TWITTER_API_KEY_PRIVATE, $requesttoken, $requesttokensecret); $tok = $to->getAccessToken(); $accesstoken = $tok['oauth_token']; $accesstokensecret = $tok['oauth_token_secret']; pete_log('oauth', "Calculated access tokens {$accesstoken}, {$accesstokensecret}"); $oauthstate['access_token'] = $accesstoken; $oauthstate['access_token_secret'] = $accesstokensecret; $oauthstate['state'] = 'done'; set_twitter_oauth_state($oauthstate); } $state = $oauthstate['state']; if ($state == 'start') { // This is either the first time the user has seen this page, or they've refreshed it before // they've authorized us to access their information. Either way, display a link they can // click that will take them to the authorization page. $tokenpublic = $oauthstate['request_token']; $to = new TwitterOAuth(TWITTER_API_KEY_PUBLIC, TWITTER_API_KEY_PRIVATE); $requestlink = $to->getAuthorizeURL($tokenpublic); ?> <center><h1>Click this link to authorize the example application to access your Twitter data</h1></center> <br><br> <center><a href="<?php echo $requestlink; ?> " target="_blank"><?php echo $requestlink; ?> </a></center> <?php } else { // We've been given some access tokens, so try and use them to make an API call, and // display the results. $accesstoken = $oauthstate['access_token']; $accesstokensecret = $oauthstate['access_token_secret']; $to = new TwitterOAuth(TWITTER_API_KEY_PUBLIC, TWITTER_API_KEY_PRIVATE, $accesstoken, $accesstokensecret); $content = twitter_api_call($to, 'twitter.com/account/verify_credentials.json', array(), 'GET'); if (empty($content)) { global $g_twitter_error_message; global $g_twitter_error_code; ?> <center><h1>Authorization failed</h1></center> <br><br> <center>Authorization tokens were returned, but when I tried an API call I received the following error:</center> <br><br> <center><?php echo htmlspecialchars($g_twitter_error_message); ?> :<?php echo htmlspecialchars($g_twitter_error_code); ?> </center> <?php } else { $accountinfo = json_decode($content, true); pete_log('oauth', print_r($accountinfo, true)); $twittername = $accountinfo['screen_name']; ?> <center><h1>Successfully authorized <?php echo htmlspecialchars($twittername); ?> </h1></center> <?php } } }
function handle_gmail_oauth() { if (!isset($_SESSION['emailaddress'])) { if (!empty($_REQUEST['emailaddress'])) { $_SESSION['emailaddress'] = $_REQUEST['emailaddress']; } else { ?> <center> <form method="GET" action="index.php"> Gmail address: <input type="text" size="40" name="emailaddress" value="<?php echo $email; ?> "/> <input type="submit" value="Authorize"/> </form> </center> <?php return; } } $emailaddress = $_SESSION['emailaddress']; $oauthstate = get_gmail_oauth_state(); // If there's no oAuth state stored at all, then we need to initialize one with our request // information, ready to create a request URL. if (!isset($oauthstate)) { pete_log('oauth', "No OAuth state found"); $to = new GmailOAuth(GOOGLE_API_KEY_PUBLIC, GOOGLE_API_KEY_PRIVATE); // This call can be unreliable if the Gmail API servers are under a heavy load, so // retry it with an increasing amount of back-off if there's a problem. $maxretrycount = 1; $retrycount = 0; while ($retrycount < $maxretrycount) { $tok = $to->getRequestToken(); if (isset($tok['oauth_token']) && isset($tok['oauth_token_secret'])) { break; } $retrycount += 1; sleep($retrycount * 5); } $tokenpublic = $tok['oauth_token']; $tokenprivate = $tok['oauth_token_secret']; $state = 'start'; // Create a new set of information, initially just containing the keys we need to make // the request. $oauthstate = array('request_token' => $tokenpublic, 'request_token_secret' => $tokenprivate, 'access_token' => '', 'access_token_secret' => '', 'state' => $state); set_gmail_oauth_state($oauthstate); } // If there's an 'oauth_token' in the URL parameters passed into us, and we don't already // have access tokens stored, this is the user being returned from the authorization page. // Retrieve the access tokens and store them, and set the state to 'done'. if (isset($_REQUEST['oauth_token']) && $oauthstate['access_token'] == '') { error_log('$_REQUEST: ' . print_r($_REQUEST, true)); $urlaccesstoken = $_REQUEST['oauth_token']; pete_log('oauth', "Found access tokens in the URL - {$urlaccesstoken}"); $requesttoken = $oauthstate['request_token']; $requesttokensecret = $oauthstate['request_token_secret']; pete_log('oauth', "Creating API with {$requesttoken}, {$requesttokensecret}"); $to = new GmailOAuth(GOOGLE_API_KEY_PUBLIC, GOOGLE_API_KEY_PRIVATE, $requesttoken, $requesttokensecret); $tok = $to->getAccessToken(); $accesstoken = $tok['oauth_token']; $accesstokensecret = $tok['oauth_token_secret']; pete_log('oauth', "Calculated access tokens {$accesstoken}, {$accesstokensecret}"); $oauthstate['access_token'] = $accesstoken; $oauthstate['access_token_secret'] = $accesstokensecret; $oauthstate['state'] = 'done'; set_gmail_oauth_state($oauthstate); } $state = $oauthstate['state']; if ($state == 'start') { // This is either the first time the user has seen this page, or they've refreshed it before // they've authorized us to access their information. Either way, display a link they can // click that will take them to the authorization page. // In a real application, you'd probably have the page automatically redirect, since the // user has already entered their email address once for us already $tokenpublic = $oauthstate['request_token']; $to = new GmailOAuth(GOOGLE_API_KEY_PUBLIC, GOOGLE_API_KEY_PRIVATE); $requestlink = $to->getAuthorizeURL($tokenpublic, get_current_url()); ?> <center><h1>Click this link to authorize accessing messages from <?php echo htmlspecialchars($emailaddress); ?> </h1></center> <br><br> <center><a href="<?php echo $requestlink; ?> "><?php echo $requestlink; ?> </a></center> <?php } else { // We've been given some access tokens, so try and use them to make an API call, and // display the results. $accesstoken = $oauthstate['access_token']; $accesstokensecret = $oauthstate['access_token_secret']; $to = new GmailOAuth(GOOGLE_API_KEY_PUBLIC, GOOGLE_API_KEY_PRIVATE, $accesstoken, $accesstokensecret); $loginstring = $to->getLoginString($emailaddress); $imapinfo = get_imap_info_for_address($emailaddress); if ($imapinfo == null) { die("Can't find info for {$emailaddress}\n"); } $host = $imapinfo['host']; $mailserver = 'ssl://' . $host; $port = $imapinfo['port']; $protocol = $imapinfo['protocol']; $connection = handmadeimap_open_connection($mailserver, $port); if ($connection == null) { die("Connection failed: " . handmadeimap_get_error() . "\n"); } handmadeimap_capability($connection); if (!handmadeimap_was_ok()) { die("CAPABILITY failed: " . handmadeimap_get_error() . "\n"); } handmadeimap_login_xoauth($connection, $loginstring); if (!handmadeimap_was_ok()) { die("LOGIN failed: " . handmadeimap_get_error() . "\n"); } $startindex = 1; $endindex = 10; $fetchresult = handmadeimap_fetch_envelopes($connection, $startindex, $endindex); if (!handmadeimap_was_ok()) { die("FETCH failed: " . handmadeimap_get_error() . "\n"); } $messagexml = envelopes_to_xml($fetchresult, 'received'); $output = htmlspecialchars($messagexml); $output = str_replace("\n", "<br>", $output); print $output; } }