diff options
-rw-r--r-- | .gitignore | 2 | ||||
-rw-r--r-- | html/index.html | 27 | ||||
-rw-r--r-- | html/mail.html | 47 | ||||
-rw-r--r-- | index.ts | 91 | ||||
-rw-r--r-- | json/user.example.json | 11 | ||||
-rw-r--r-- | json/user.json | 9 | ||||
-rw-r--r-- | package.json | 6 | ||||
-rw-r--r-- | readme.md | 2 |
8 files changed, 169 insertions, 26 deletions
@@ -4,4 +4,4 @@ node_modules/ certs/ -/pass.json
\ No newline at end of file +json/user.json
\ No newline at end of file diff --git a/html/index.html b/html/index.html index 2765855..f28a971 100644 --- a/html/index.html +++ b/html/index.html @@ -96,6 +96,28 @@ return (promise) } let pub = '' + function setCookie(name, value, days) { + var expires = ""; + if (days) { + var date = new Date(); + date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000)); + expires = "; expires=" + date.toUTCString(); + } + document.cookie = name + "=" + (value || "") + expires + "; path=/"; + } + function getCookie(name) { + var nameEQ = name + "="; + var ca = document.cookie.split(';'); + for (var i = 0; i < ca.length; i++) { + var c = ca[i]; + while (c.charAt(0) == ' ') c = c.substring(1, c.length); + if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length, c.length); + } + return null; + } + function eraseCookie(name) { + document.cookie = name + '=; Path=/; Expires=Thu, 01 Jan 1970 00:00:01 GMT;'; + } function submit() { //{body:{json:boolean,enc:boolean,data:string,sid:keyof keyring}} var xhr = new XMLHttpRequest(); @@ -107,6 +129,11 @@ if (JSON.parse(xhr.responseText).html) { document.body.innerHTML = dec } + if (JSON.parse(xhr.responseText).json && JSON.parse(xhr.responseText).type == 'key') { + let decc = new TextDecoder().decode(dec) + //console.log(JSON.parse(decc)) + setCookie('login_key', JSON.parse(decc).login_key, 7) + } } } let user = document.getElementById('user').value diff --git a/html/mail.html b/html/mail.html index 7320400..db26593 100644 --- a/html/mail.html +++ b/html/mail.html @@ -3,12 +3,45 @@ <head> <title>mail</title> <script src="/src/bundle.js"></script> + <style> + .split { + height: 100%; + width: 50%; + position: fixed; + z-index: 1; + top: 0; + overflow-x: hidden; + padding-top: 20px; + } + </style> </head> <body onload="load()"> <script> const sid = makeid(20) window.sid = sid + function setCookie(name, value, days) { + var expires = ""; + if (days) { + var date = new Date(); + date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000)); + expires = "; expires=" + date.toUTCString(); + } + document.cookie = name + "=" + (value || "") + expires + "; path=/"; + } + function getCookie(name) { + var nameEQ = name + "="; + var ca = document.cookie.split(';'); + for (var i = 0; i < ca.length; i++) { + var c = ca[i]; + while (c.charAt(0) == ' ') c = c.substring(1, c.length); + if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length, c.length); + } + return null; + } + function eraseCookie(name) { + document.cookie = name + '=; Path=/; Expires=Thu, 01 Jan 1970 00:00:01 GMT;'; + } function makeid(length) { var result = ''; var characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; @@ -63,13 +96,18 @@ let emails = [] function update() { //console.log('hi') - sendenc('/get', { 'user': 'root', 'pass': 'password' }).then(res => { + sendenc('/get', { 'user': 'root', 'pass': 'password', 'requested': 0, 'login_key': getCookie('login_key') }).then(res => { res = JSON.parse(res) console.log('parsed') emails = res.reverse() }) } let mypriv, mypub, pub, kekw + let preview = -1 + async function lm(index) { + console.log() + document.getElementById('view').innerHTML = emails[index]['body[1]'] + } async function load() { kekw = await nodersa({ b: 512 }) @@ -87,7 +125,7 @@ c = '#395B64' } evo = !evo - ret += '<div style="color:#A5C9CA;border-radius:10px;max-width:50%;min-width:400px;padding:20px;background-color:' + c + ';">' + ret += '<div onclick="lm(' + emails.indexOf(email) + ')" style="color:#A5C9CA;border-radius:10px;max-width:40%;min-width:400px;padding:20px;background-color:' + c + ';">' ret += '<tt><b><font size="4">sub:' + email.envelope.subject + '</font></b></br>frm:' + email.envelope.from[0].address + '</br><sub style="color:#E7F6F2;">' + email.envelope.date + '</sub></tt></br></div><div style="height:2px;"></div>' } @@ -97,6 +135,11 @@ //<button onclick="update()">update mail</button> </script> <div id="emails"></div> + <div id="box" class="split" style="background-color:red;right:0;margin:40px;"> + <div id="view"> + fneoutvbnoruitnvorntvo</br>uitnvorntvo</br>uitnvorntvo</br>uitnvorntvo</br>uitnvorntvo</br>uitnvorntvo</br>uitnvorntvo</br>uitnvorntvo</br>uitnvorntvo</br>uitnvorntvo</br>uitnvorntvo</br>uitnvorntvo</br>uitnvorntvo</br>uitnvorntvo</br>uitnvorntvo</br>uitnvorntvo</br>uitnvorntvo</br>uitnvorntvo</br>uitnvorntvo</br>uitnvorntvo</br>uitnvorntvo</br>uitnvorntvo</br>uitnvorntvo</br>uitnvorntvo</br>uitnvorntvo</br>uitnvorntvo</br>uitnvorntvo</br>uitnvorntvo</br>uitnvorntvo</br>uitnvorntvo</br>uitnvorntvo</br>uitnvorntvo</br>uitnvorntvo</br>uitnvorntvo</br>uitnvorntvo</br>uitnvorntvo</br>uitnvorntvo</br>uitnvorntvo</br>uitnvorntvo</br>uitnvorntvo</br>uitnvorntvo</br>uitnvorntvo</br>uitnvorntvo</br>uitnvorntvo</br>uitnvorntvo</br>uitnvorntvo</br>uitnvorntvo</br>uitnvorntvo</br>uitnvorntvo</br>uitnvorntvo</br>uitnvorntvo</br>uitnvorntvo</br>uitnvorntvo</br>uitnvorntvo</br>uitnvorntvo</br>uitnvorntvo</br>uitnvorntvo</br>uitnvorntvo</br>uitnvorntvo</br>uitnvorntvo</br>uitnvorntvo</br>uitnvorntvo</br>uitnvorntvo</br>uitnvorntvo</br>uitnvorntvo</br>uitnvorntvo</br>uitnvorntvo</br>uitnvorntvo</br>uitnvorntvo</br>uitnvorntvo</br>uitnvorntvo</br>uitnvorntvo</br>uitnvorntvo</br>uitnvorntvo</br>uitnvorntvo</br>uitnvorntvo</br>uitnvorntvo</br>uitnvorntvo</br>uitnvorntvo</br>uitnvorntvo</br>uitnvorntvo</br>uitnvorntvo</br>uitnvorntvo</br>uitnvorntvo</br>uitnvorntvo</br>uitnvorntvo</br>uitnvorntvo</br>uitnvorntvo</br>uitnvorntvo</br>uitnvorntvo</br>uitnvorntvo</br>uitnvorntvo</br>uitnvorntvo</br>uitnvorntvo</br>uitnvorntvo</br> + </div> + </div> </body> @@ -1,4 +1,4 @@ -import { readFileSync } from "fs" +import { readFileSync, writeFileSync } from "fs" var privateKey = readFileSync('certs/selfsigned.key', 'utf8'); var certificate = readFileSync('certs/selfsigned.crt', 'utf8'); var http = require('http'); @@ -12,10 +12,35 @@ app.use(bodyParser.urlencoded({ extended: false })); app.use(bodyParser.json()); const NodeRSA = require('node-rsa'); var ip = require("ip") +var crypt = require('crypto'); + +const IV = "5183666c72eec9e4"; //!not really sure what this is lol +//TODO: learn what IV is +var encrypt = ((val:any,ENC_KEY:any) => { + let cipher = crypt.createCipheriv('aes-256-cbc', ENC_KEY, IV); + let encrypted = cipher.update(val, 'utf8', 'base64'); + encrypted += cipher.final('base64'); + return encrypted; +}); +var decrypt = ((encrypted:any,ENC_KEY:any) => { + try{ + let decipher = crypt.createDecipheriv('aes-256-cbc', ENC_KEY, IV); + let decrypted = decipher.update(encrypted, 'base64', 'utf8'); + return (decrypted + decipher.final('utf8')); + } catch(err){ + return('false') + } +}); +// function log(m:any){ var date = new Date; console.log('['+date.getHours()+':'+date.getMinutes()+':'+date.getSeconds()+'] ' + m.toString()) } +function d(){ + var date = new Date; + return(date.getHours()+''+date.getMinutes()+''+date.getSeconds()) + +} interface keyring{ [sid: string]: { mypub:string, @@ -26,24 +51,37 @@ interface keyring{ let keyring = {} as keyring let key:any; var ImapClient = require('emailjs-imap-client').default -let pass = JSON.parse(readFileSync('pass.json').toString()).pass +//let pass = JSON.parse(readFileSync('pass.json').toString()).pass app.post('/mail/get',(req:any,res:any)=>{ - var client = new ImapClient('disroot.org', 993, { + const key = new NodeRSA({b: 1024}) + + key.importKey(keyring[req.body.sid].mypriv,'pkcs1-private') + let dec:any = JSON.parse((atob(key.decrypt(req.body.data,'base64','base64')))) + //console.log(key) + //console.log(dec.data.login_key) + let users = JSON.parse(readFileSync('json/user.json').toString()) + let logkey,mail + for(let user of users){ + //console.log(user,dec) + if(user.name==dec.data.user){ + logkey = (decrypt(user.login_key,dec.data.login_key)) + mail =JSON.parse(decrypt(user.mail,logkey)).emails[parseInt(dec.data.requested)] + } + } + //console.log(JSON.parse(decrypt(users[0].mail,logkey)).emails) + var client = new ImapClient(mail.host, parseInt(mail.port), { auth: { - user: 'grantsquires', - pass: pass + user: mail.address, + pass: mail.creds } }); client.connect().then(()=>{ //['uid', 'flags','envelope'] for just header stuff //['uid', 'flags','envelope','body'] //body 0 is plani, 1 is html - client.listMessages('INBOX', '1:*', ['uid', 'flags','envelope','bodystructure'/*,'body[1]'*/]).then((messages:any) => { - //console.log(messages[2]['body[]']) + client.listMessages('INBOX', '1:*', ['uid', 'flags','envelope','bodystructure','body[1]' ]).then((messages:any) => { const skey = new NodeRSA() - console.log(keyring[req.body.sid]) - //res.send(JSON.stringify({'data':'hello'})) skey.importKey(keyring[req.body.sid].theirpub,'pkcs8-public') res.send(JSON.stringify({data:skey.encrypt(JSON.stringify(messages),'base64'),enc:true,html:true})) client.close() @@ -58,10 +96,13 @@ app.get('/mail', (req:any, res:any) => { var httpServer = http.createServer(app); var credentials = {key: privateKey, cert: certificate}; var httpsServer = https.createServer(credentials, app); -httpServer.listen(80,'0.0.0.0', () => { +app.listen(8080,()=>{ + log(`kanna is local http://${ip.address()}:8080`) +}) +httpServer.listen(80, () => { log(`kanna is on http://${ip.address()} click on me click on me! :3`) }) -httpsServer.listen(443,'0.0.0.0', () => { +httpsServer.listen(443, () => { log(`kanna is secure now too!! https://${ip.address()}`) }) //end @@ -89,7 +130,7 @@ app.post('/pub.key', async (req:{body:{json:boolean,sid:keyof keyring,pub:string mypub:key.exportKey('pkcs8-public'), theirpub:req.body.pub} res.send(key.exportKey('pkcs8-public')) - console.log(keyring) + //console.log(keyring) } }) @@ -102,12 +143,34 @@ app.post('/login/submit', async (req:{body:{json:boolean,enc:boolean,data:string let users = JSON.parse(readFileSync('json/user.json').toString()) for(let user of users){ let use=user as typeof users - if(user.name==dec.user&&user.pass==dec.pass){ + let hash = crypt.createHash('md5').update(dec.pass).digest('hex'); + if(user.name==dec.user&&hash==decrypt(user.hash,hash)){ + const skey = new NodeRSA() skey.importKey(keyring[req.body.sid].theirpub,'pkcs8-public') - res.send(JSON.stringify({data:skey.encrypt('<h1>hello!</h1>','base64'),enc:true,html:true})) + let logkey = crypt.createHash('md5').update(crypt.randomBytes(64).toString('hex')).digest('hex') + res.send(JSON.stringify({data:skey.encrypt(JSON.stringify({login_key:logkey}),'base64'),enc:true,html:false,json:true,type:'key'})) + users[users.indexOf(user)].login_key = encrypt(hash,logkey) + console.log(users[users.indexOf(user)].login_key,logkey,hash) + //console.log(users) + writeFileSync('./json/user.json',JSON.stringify(users)) } } }) +/*let l = (encrypt(JSON.stringify({ + 'emails':[{ + 'address':'[email protected]', + 'host':'disroot.org', + 'port':'993', + 'creds':pass, + 'salt':crypt.randomBytes(64).toString('hex') + }], //how much salt do you want? 'all of it' + 'salt':[ + d(),crypt.randomBytes(64).toString('hex'),crypt.randomBytes(64).toString('base64'),d() + ], + 'storage':'./storage/'+user.name, + + }),hash)) +*/ diff --git a/json/user.example.json b/json/user.example.json new file mode 100644 index 0000000..be82a4d --- /dev/null +++ b/json/user.example.json @@ -0,0 +1,11 @@ +[ + { + "name": "root", + "hash": "OTVYg/fHYeVbtyrusPl8fV+zQcp1ImjzbP+3Cy+3lk14fl2icYhzlULKtbTpOx4E", + "sudo": true, + "last_login": "", + "alias": "root", + "login_key": "", + "mail": "" + } +] diff --git a/json/user.json b/json/user.json index 318838a..6065bf3 100644 --- a/json/user.json +++ b/json/user.json @@ -1,8 +1 @@ -[{ - "name":"root", - "pass":"password", - "sudo":true, - "last_login":"", - "alias":"root", - "login_key":"" -}]
\ No newline at end of file +[{"name":"root","hash":"OTVYg/fHYeVbtyrusPl8fV+zQcp1ImjzbP+3Cy+3lk14fl2icYhzlULKtbTpOx4E","sudo":true,"last_login":"","alias":"root","login_key":"Q67f8ylkefiCao2ykXV/wDJvgeNLuVK+7FzRdiWK/Ap4gPZzV8L3hndX3PgU3YeW","mail":"X2vLkGESm6Q8owhEH5RR99g9Fb5ukZ5f0+ZbjF/oFLhF+uoAnRRjXxrzUYwFR8b688xG2zKWUx30xEoRkvB24HkDLXf6BW3kB+dWtIltdROnyNlZIyZIfPaZJ6z+XNz53xPFj6MwIwfbexQFLVz8sVzdRaKr27qvYQrI+ubrwK8nRvrErbTTMzjjsVwiqvvNWGs5L4i8VThvQ9iyVfH+ZLpeabd/CfesbntqWtzt86dBU5Z7ZS2Is5klHqnjk1zUUTXEfegqsQYXFXkb0EykfP1adfLrxmd5s/4QIGIRDBPIGYAqzSvXC1wyRkDKZwL/qmde/0rSqeSZej1JazAYQXwLxez/c80buTHaJGvlGT8dt3IpSYHGBbKG8SYAixqSChiJOodT1hcc00YVLWu+pFSWsCgCBkTjteVbI0OEOQG4O9hr+7ccTA465TYpsFRoN1WyB+s5psTADmYahuFV+OIq6etCNh4qi/Y7cN9rk3sbBZeLQr7LrROXwpeAx7aUiT/m7O1yjuNgsdjYexk/6tr54qLmE8H1+qFPq3kj4j0VjKiC+8SLaW7QkCjnra7ZXuFlYmZ8+uH0cSZLz4/Ok79gaXIeYhfqMl4J8fSElMnLurbF22fVE2NcVUyL1H6ixwpcJJ/qXrCxchBR9OdjfVhbrhD9bwbJ5jE1di9mz0grwa28E9hiKN4Wbw2QPQmU"}]
\ No newline at end of file diff --git a/package.json b/package.json index 23375d7..32dba1c 100644 --- a/package.json +++ b/package.json @@ -18,11 +18,15 @@ }, "homepage": "https://github.com/squiresgrant/kanna-site#readme", "dependencies": { + "bcrypt": "^5.1.0", + "bcryptjs": "^2.4.3", "body-parser": "^1.20.0", "express": "^4.18.1", "fs": "^0.0.1-security", "ip": "^1.1.8", - "node-rsa": "^1.1.1" + "md5": "^2.3.0", + "node-rsa": "^1.1.1", + "openpgp": "^5.5.0" }, "devDependencies": { "emailjs-imap-client": "^3.1.0" @@ -29,3 +29,5 @@ visit the [main git](https://git.disroot.org/grantsquires/kanna-site) or the [gi - [ ] learning how mail works - [ ] imap cli + +FeMail (iron mail) |