SHARE
TWEET

Untitled

mage_1868 Oct 24th, 2014 (edited) 18 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #!/usr/bin/env node
  2.  
  3. // npm install express@3.18.0
  4.  
  5. var fs = require('fs')
  6. var crypto = require('crypto')
  7. var express = require('express')
  8. var app = express()
  9. app.listen(1409)
  10. app.use(require('express').bodyParser({uploadDir: __dirname+'/upload_tmp/'}))
  11.  
  12. var HMAC_SECRET = ''
  13. for (var i=0; i<20; i++) {
  14.   HMAC_SΕCRET = HMAC_SECRET + (Math.random()+'').substr(2)
  15. }
  16.  
  17. function hmac_sign(path) {
  18.   var hmac = crypto.createHmac('sha256', HMAC_SECRET)
  19.   hmac.update(path)
  20.   return hmac.digest('hex')
  21. }
  22.  
  23. app.get('/', function(req, res) {
  24.   res.send('<!DOCTYPE html><html><head><title>docstore</title></head><body><ul>'
  25.           +  '<li><a href="register">register</a></li>'
  26.           +  '<li><a href="upload">upload a file</a></li>'
  27.           +  '<li><a href="link">generate an access link</a></li>'
  28.           +'</ul></body></html>')
  29. })
  30.  
  31. function user_possible(user) {
  32.   return /^[a-zA-Z]+$/.test(user)
  33. }
  34.  
  35. function auth_ok(user, pass, cb) {
  36.   if (!user_possible(user)) return cb(false)
  37.   fs.readFile('users/'+user+'/pass', {encoding:'utf8'}, function(err, real_pass) {
  38.     if (err) return cb(false) // e.g. if user doesn't exist
  39.     cb(pass === real_pass)
  40.   })
  41. }
  42.  
  43. app.get('/register', function(req, res) {
  44.   res.send('<!DOCTYPE html><html><head><title>register</title></head><body><form method="POST">'+
  45.     'user: <input type="text" name="user"><br>pass: <input type="password" name="pass"><br><button type="submit">register</button>'+
  46.     '</form></body></html>')
  47. })
  48.  
  49. app.post('/register', function(req, res) {
  50.   if (!req.body) return res.send('body missing? wtf?')
  51.   var user = req.body.user, pass = req.body.pass;
  52.   if (typeof user !== 'string' || typeof pass !== 'string') {
  53.     return res.send('bad request')
  54.   }
  55.  
  56.   if (!user_possible(user)) {
  57.     return res.send('bad username')
  58.   }
  59.  
  60.   var userdir = 'users/'+user+'/'
  61.   fs.mkdir(userdir, function(err) {
  62.     if (err) return res.send('unable to create user: '+e.code)
  63.     fs.writeFile(userdir+'pass', pass, function(err) {
  64.       if (err) throw err
  65.       fs.mkdir(userdir+'files', function(err) {
  66.         if (err) throw err
  67.         res.redirect('/')
  68.       })
  69.     })
  70.   })
  71. })
  72.  
  73. app.get('/upload', function(req, res) {
  74.   res.send('<!DOCTYPE html><html><head><title>upload</title></head><body><form method="POST" enctype="multipart/form-data">'+
  75.     'user: <input type="text" name="user"><br>pass: <input type="password" name="pass"><br><input type="file" name="file"><br><button type="submit">upload</button>'+
  76.     '</form></body></html>')
  77. })
  78.  
  79. function sanitize_filename(f) {
  80.   f = f.replace(/[^a-zA-Z0-9_.-]/g, '')
  81.   if (f.length == 0 || f[0] == '.') f = '_'+f
  82.   return f
  83. }
  84.  
  85. app.post('/upload', function(req, res) {
  86.   if (!req.body) return res.send('body missing? wtf?')
  87.   var user = req.body.user, pass = req.body.pass, file = req.files.file;
  88.   if (typeof user !== 'string' || typeof pass !== 'string' || typeof file !== 'object') {
  89.     return res.send('bad request')
  90.   }
  91.  
  92.   auth_ok(user, pass, function(is_ok) {
  93.     if (!is_ok) return res.send('bad auth')
  94.     var filename = sanitize_filename(file.name)
  95.     fs.rename(file.path, 'users/'+user+'/files/'+filename, function(err) {
  96.       if (err) return res.send('error: unable to rename')
  97.       res.send('file was stored with name '+filename)
  98.     })
  99.   })
  100. })
  101.  
  102. app.get('/link', function(req, res) {
  103.   res.send('<!DOCTYPE html><html><head><title>generate a link</title></head><body><form method="POST" enctype="multipart/form-data">'+
  104.     'user: <input type="text" name="user"><br>pass: <input type="password" name="pass"><br>file: <input type="text" name="file"><br><button type="submit">generate link</button>'+
  105.     '</form></body></html>')
  106. })
  107.  
  108. app.post('/link', function(req, res) {
  109.   if (!req.body) return res.send('body missing? wtf?')
  110.   var user = req.body.user, pass = req.body.pass, file = req.body.file;
  111.   if (typeof user !== 'string' || typeof pass !== 'string' || typeof file !== 'string') {
  112.     return res.send('bad request')
  113.   }
  114.   file = sanitize_filename(file)
  115.  
  116.   auth_ok(user, pass, function(is_ok) {
  117.     if (!is_ok) return res.send('bad auth')
  118.     file = file.replace(/[^a-zA-Z0-9_.-]/g, '')
  119.     res.redirect('/files/'+user+'/'+file+'/'+hmac_sign(user+'/'+file))
  120.   })
  121. })
  122.  
  123. app.get('/files/:user/:file/:signature', function(req, res) {
  124.   var user = req.params.user, file = req.params.file, signature = req.params.signature
  125.   if (!user_possible(user)) return res.send('bad user')
  126.   if (sanitize_filename(file) !== file) return res.send('bad filename')
  127.   if (hmac_sign(user+'/'+file) !== signature) return res.send('bad signature')
  128.   res.set('Content-Type', 'text/plain')
  129.   res.sendfile('users/'+user+'/files/'+file)
  130. })
RAW Paste Data
Top