Skip to content

Instantly share code, notes, and snippets.

@hackervera
Created July 27, 2010 23:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hackervera/493049 to your computer and use it in GitHub Desktop.
Save hackervera/493049 to your computer and use it in GitHub Desktop.
var http = require('http');
var fs = require('fs');
var config_file = fs.readFileSync('ritalin.config','ascii');
var config = JSON.parse(config_file);
var crypto = require('crypto');
var sys = require('sys');
var spawn = require('child_process').spawn;
var url = require('url');
var Buffer = require('buffer').Buffer;
var redis = require('redis-client').createClient();
var expires = new Date();
expires.setDate(expires.getDate() - 100000);
expires = expires.toUTCString();
var when = new Date();
when.setDate(when.getDate() + 14);
when.toUTCString();
var b64 = require('base64');
var Session = new Object;
if (config.bot == 1)
{
var irc = require('irc');
var client = new irc.Client(config.bot_server,config.bot_name,
{
channels: [config.bot_channel],
});
client.on("error", function(error)
{
console.log(lookUp(error));
console.log(error.stack);
});
}
var dgram = require('dgram');
var udp = dgram.createSocket('udp4');
function hitAPI(host,path,data,port,method){
var web_client = http.createClient(port,"http://" + host);
var request = web_client.request(method,path, {'host': host});
request.write(data);
request.end();
console.log(sys.inspect(request));
request.on('response', function(response){
response.on('data', function(data){
console.log(data);
});
});
}
function sendLocation(){
var d = new Date();
//console.log(ISODateString(d));
var date = ISODateString(d);
var packet = fs.readFileSync("packet","ascii");
hitAPI("tyler-postbin.appspot.com","/1grwu0e",packet,80,"POST");
}
udp.on('error', function(message)
{
console.log(message);
});
udp.bind(config.udp_port);
udp.on('message', function(message,rinfo)
{
message = JSON.parse(message);
var signature = message.signature;
var text = message.text;
var name = message.name;
var publicKey;
var web_client = http.createClient(config.port,config.domain)
var getKey = web_client.request("/keys/" + name,{'host': 'rital.in'})
getKey.end();
getKey.on('response', function(response)
{
response.on('data', function(data)
{
console.log(data);
publicKey = data;
var verified = crypto.createVerify('RSA-SHA256').update(text).verify(publicKey,signature,'hex');
if (verified && client)
{
client.say(config.bot_channel, name + " " + "sent '" + text + "' [ http://" + config.domain + ":" + config.port + "/keys/" + name + " ]");
}
});
});
});
function newKey(user)
{
var key = spawn('openssl', ['req', '-nodes', '-newkey', 'rsa:1024', '-x509', '-keyout', 'keys/' + user + '.pem', '-out', 'keys/' + user + '-pub.pem', '-days', '1095', '-batch']);
key.stdout.on('data', function(data){
console.log(data);
});
key.stderr.on('data', function(data){
console.log(data);
});
}
function ISODateString(d){
function pad(n){return n<10 ? '0'+n : n}
return d.getUTCFullYear()+'-'
+ pad(d.getUTCMonth()+1)+'-'
+ pad(d.getUTCDate())+'T'
+ pad(d.getUTCHours())+':'
+ pad(d.getUTCMinutes())+':'
+ pad(d.getUTCSeconds())+'Z'
}
function randomString() {
var chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz";
var string_length = 32;
var randomstring = '';
for (var i=0; i<string_length; i++) {
var rnum = Math.floor(Math.random() * chars.length);
randomstring += chars.substring(rnum,rnum+1);
}
return randomstring;
}
console.log(randomString());
http.createServer(function (req, res) {
function writeOut(obj){
status = obj.status || 200;
headers = obj.headers || new Object;
if (!headers['content-type']){
headers['content-type'] = "text/html";
}
data = obj.data;
console.log(sys.inspect(headers));
res.writeHead(status, headers);
res.end(data);
}
try {
var path = req.url.substr(1);
var key = /^\/key\/(.*)/.exec(req.url);
var login = /.*\/login.*/.exec(req.url);
key = key || 0;
var incoming = /^\/incoming.*/.exec(req.url);
incoming = incoming || 0;
login = login || 0
var params = url.parse(req.url,true).query;
var resource = url.parse(req.url,true).pathname;
var name = req.headers.cookie
name = /name=(\w+)/.exec(req.headers.cookie)
if (name){ name = name[1] };
appname = /^\/apps\/(.*)/.exec(req.url);
appname = appname || 0;
auth = /^\/oauth\/authorize/;
switch(resource)
{
case "/":
{
console.log(sys.inspect(req));
if (req.headers.cookie){
res.writeHead(302, {'Location': '/main' });
res.end('set cookie');
}
else {
res.writeHead(200, {'Content-Type': 'text/html'});
index = fs.readFileSync("public/index.html");
if (params && params.error){
index = index.toString().replace(/ERROR/,
"<div style='color:red;border-stlye:solid;border-color:red;border-width:3px;'>Username or Password incorrect<br><br></div>");
}else {
index = index.toString().replace(/ERROR/,"");
}
res.end(index);
}
break;
}
case "/login":{
name = params.user;
pass = params.pass;
redis.get("ritalin:" + name + ":password", function(err,password){
if (password && password.toString() == pass) {
console.log("login good");
res.writeHead(302, {'Location':'/main', 'set-cookie':'name=' + name + '; expires=' + when } );
res.end('');
}
else {
writeOut({status:302,headers:{"Location":"/?error=1"}});
}
});
break;
}
case "/main":{
if (!req.headers.cookie){
res.writeHead(302, {'Location': '/' });
res.end('');
} else {
main = fs.readFileSync('public/main.html');
//newKey(name);
main = main.toString().replace(/NAME/g,name);
res.writeHead(200, {'Content-Type': 'text/html' });
res.end(main);
}
break;
}
case "/logout":{
res.writeHead(302, {'Content-Type': 'text/plain', 'set-cookie':'name=tyler;expires=' + expires, 'Location': '/'});
res.end('');
}
case "/oauth/authorize":
if (!params) {
writeOut({status:401,data:"no params in request!"});
break;
}
console.log("requesting auth");
redirect = params['redirect_uri'];
scope = params.scope;
client_id = params['client_id'];
code = randomString();
if (req.headers.cookie){
writeOut({data:"Hello " + name + ". Grant access to " + client_id + "? <a href='" + redirect + "?code=" + code + "'>YES</a>"});
} else {
//writeOut({ status:302, headers: { 'Location':redirect + '?scope=' + scope + '&code=' + code} });
writeOut({data:"TODO"}); //TODO
}
break;
case "/oauth/token":
if (!params) {
writeOut({status:401,data:"no params in request!"});
break;
}
access_token = randomString();
refresh_token = randomString();
if (params['grant_type'] == "password"){
//console.log(sys.inspect(req));
auth_pieces = req.headers['authorization'].split(" ");
if (auth_pieces[0] == "Basic"){
id_secret = b64.decode(new Buffer(auth_pieces[1])).split(":");
redis.get("ritalin:apptoken:" + id_secret[0], function(err,appsecret){
try {
if (appsecret.toString() == id_secret[1]){
redis.get("ritalin:" + params.username + ":password", function(err, password){
console.log(sys.inspect(params.password) + " " + sys.inspect(password.toString('ascii')));
if (params.password == password.toString('ascii')){
redis.set("ritalin:" + params.username + ":access_token",access_token);
output = { access_token:access_token,expires_in:3600 };
output = JSON.stringify(output);
writeOut({data:output,headers:{"content-type":"application/json"}});
}
});
}
} catch (e) {
writeOut({data:"That clientid does not exist!\n"});
}
});
} else {
writeOut({data:"Sorry thats not the right auth method",status:401});
}
}else {
output = { access_token:access_token,refresh_token:refresh_token };
output = JSON.stringify(output);
writeOut({data:output});
}
break;
case "/json":
test = JSON.stringify({"test":"json"});
writeOut({data:test});
break;
case appname[0]:
redis.get("ritalin:apptoken:" + appname[1], function(error, token){
console.log(token);
output = "App Id:<br> <b>" + appname[1] + "</b><br><br>" +
"App Secret:<br> <b>" + token + "</b><br><br><a href='/apps'>Back to apps</a>";
writeOut({data:output});
});
break;
case "/apps":
if (req.headers.cookie){
redis.smembers("ritalin:apps:" + name,function(error,value){
for (i=0; i < value.length; i++){
value[i] = "<a href='/apps/" + value[i] + "'>" + value[i] + "</a>"
}
output = fs.readFileSync("public/apps.html","ascii");
output = output.replace(/APPS/g,value);
writeOut({data:output});
});
} else {
writeOut({headers: {'Location':'/'}, status:302});
}
break;
case key[0]:
{
path = config.install_path + '/keys/' + key[1] + '-pub.pem'
publicKey = fs.readFileSync(path,'ascii');
console.log(path);
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end(publicKey);
break;
}
case incoming[0]:
{
packet = JSON.parse(params.body);
domain = packet.domain;
name = packet.name;
text = packet.text;
signature = packet.signature;
var web_client = http.createClient(80,domain)
var getKey = web_client.request("/key/" + name,{'host': domain})
var verified;
getKey.end();
getKey.on('response', function(response)
{
response.on('data', function(data)
{
console.log(data);
publicKey = data;
verified = crypto.createVerify('RSA-SHA256').update(text).verify(publicKey,signature,'hex');
console.log(verified);
if (verified == 1){
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end("You sent: " + params.body + "\n\nMessage verified");
}
else {
res.writeHead(401, {'Content-Type': 'text/plain'});
res.end("Verification failed");
}
});
});
break;
}
default: res.writeHead(404, {'Content-Type': 'text/plain'}); res.end("File doesn't exist");break;
}
} catch(e)
{
res.writeHead(500, {'Content-Type': 'text/plain'}); res.end("There has been an error: " + e.message);
}
}).listen(config.port, "0.0.0.0");
console.log('Server running at http://' + config.domain + ':' + config.port + '/');
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment