parent
7d44dfe2a5
commit
793a810ceb
@ -0,0 +1,245 @@ |
||||
const http = require('http') |
||||
const https = require('https') |
||||
const express = require('express') |
||||
const fs = require('fs') |
||||
const url = require('url') |
||||
const crypto = require('crypto') |
||||
|
||||
const app = express() |
||||
|
||||
process.on('uncaughtException', (error, origin) => { |
||||
console.log('----- Uncaught exception -----') |
||||
console.log(error) |
||||
console.log('----- Exception origin -----') |
||||
console.log(origin) |
||||
}) |
||||
|
||||
process.on('unhandledRejection', (reason, promise) => { |
||||
console.log('----- Unhandled Rejection at -----') |
||||
console.log(promise) |
||||
console.log('----- Reason -----') |
||||
console.log(reason) |
||||
}) |
||||
|
||||
|
||||
if(!fs.existsSync('repo')) fs.mkdirSync('repo') |
||||
if(!fs.existsSync('repo/admin')) fs.mkdirSync('repo/admin') |
||||
if(!fs.existsSync('repo/admin/deposit')) fs.mkdirSync('repo/admin/deposit') |
||||
if(!fs.existsSync('repo/admin/pub')) fs.mkdirSync('repo/admin/pub') |
||||
if(!fs.existsSync('repo/admin/notices')) fs.mkdirSync('repo/admin/notices') |
||||
if(!fs.existsSync('repo/admin/notices/trusted')) fs.mkdirSync('repo/admin/notices/trusted') |
||||
if(!fs.existsSync('repo/admin/notices/purgatory')) fs.mkdirSync('repo/admin/notices/purgatory') |
||||
if(!fs.existsSync('repo/admin/notices/banlist')) fs.writeFileSync('repo/admin/notices/banlist', '') |
||||
if(!fs.existsSync('repo/admin/notices/ipbanlist')) fs.writeFileSync('repo/admin/notices/ipbanlist', '') |
||||
if(!fs.existsSync('repo/admin/notices/trustlist')) fs.writeFileSync('repo/admin/notices/trustlist', '') |
||||
|
||||
function inList(str, strlistx){ |
||||
var arr = strlistx.toString().split('\n') |
||||
|
||||
for(var i = 0; i < arr.length; i++){ |
||||
if(str === arr[i]){ |
||||
return 1 |
||||
} |
||||
} |
||||
|
||||
return 0 |
||||
|
||||
} |
||||
|
||||
app.get('/postmailping', (request, response) => { |
||||
response.writeHead(200) |
||||
response.end("postmailpong") |
||||
}) |
||||
|
||||
app.get('/getinfo', (request, response) => { |
||||
|
||||
//common pub files to use: "bio" - user's bio (text)
|
||||
// "name" - user's complete (user)name, supports spaces and symbols
|
||||
// "pgp" - user's public pgp key (armored)
|
||||
// "pfp" - user's profile picture (in a PNG format)
|
||||
// "at" - alternate addresses in JSON (email, phone, social media, etc)
|
||||
// "status" - user's current status
|
||||
// "site" - website
|
||||
// "reusme" - resume
|
||||
|
||||
var reqfile = "repo/" + request.query.user + "/pub/" + request.query.file |
||||
|
||||
if(fs.existsSync(reqfile)){ |
||||
response.download(reqfile) |
||||
}else{ |
||||
response.writeHead(404) |
||||
response.end() |
||||
} |
||||
}) |
||||
|
||||
app.get('/sendnotice', (request, response) => { |
||||
|
||||
var noticeIsValid = false |
||||
|
||||
if(request.query.user === null || request.query.sender === null || request.query.token === null || request.query.id === null){ |
||||
response.writeHead(404) |
||||
response.end() |
||||
} |
||||
if(request.query.user.length > 256 || request.query.sender.length > 256 || request.query.token.length > 256 || request.query.id.length > 256){ |
||||
response.writeHead(404) |
||||
response.end() |
||||
} |
||||
|
||||
var notice = { |
||||
'user': request.query.user, |
||||
'sender': request.query.sender, |
||||
'token': request.query.token, |
||||
'id': request.query.id |
||||
} |
||||
|
||||
var userFolder = "repo/" + notice.user + "/" |
||||
var purgatoryDir = userFolder + "/notices/purgatory/" + notice.sender |
||||
var trustedDir = userFolder + "/notices/trusted/" |
||||
var senderUser = notice.sender.split(':')[0] |
||||
var senderHost = notice.sender.split(':')[1] |
||||
var confReqArgs = "/checkrepo?user=" + senderUser + "&id=" + notice.id + "&token=" + notice.token |
||||
|
||||
var confirmationReqOpts = { //request for sender server to confirm authenticity
|
||||
hostname: senderHost, |
||||
port: 27050, |
||||
path: confReqArgs, |
||||
method: 'GET', |
||||
rejectUnauthorized: false, |
||||
requestCert: true, |
||||
agent: false |
||||
} |
||||
|
||||
var trustlist = fs.readFileSync(userFolder + "/notices/trustlist") |
||||
var banlist = fs.readFileSync(userFolder + "/notices/banlist") |
||||
var ipbanlist = fs.readFileSync(userFolder + "/notices/ipbanlist") |
||||
|
||||
var confirmationReq = http.get(confirmationReqOpts, (confirmationRes) => { |
||||
|
||||
//Contact presumed sender's server to certify authenticity of message
|
||||
|
||||
confirmationRes.on('data', function(chunk){ |
||||
var d = chunk + "\0" |
||||
if(d === "yes!\0"){ |
||||
console.log("VALID NOTICE" + JSON.stringify(notice)) |
||||
|
||||
//if sender confirmed authenticity of mail
|
||||
noticeIsValid = true |
||||
|
||||
}else{ |
||||
console.log("INVALID NOTICE" + JSON.stringify(notice)) |
||||
noticeIsValid = false |
||||
response.writeHead(404) |
||||
response.end() |
||||
return |
||||
} |
||||
|
||||
if(noticeIsValid){ |
||||
if(inList(notice.sender, banlist) || inList(senderHost, ipbanlist)){ |
||||
|
||||
//IF BANNED
|
||||
|
||||
response.writeHead(200) |
||||
response.end("ban") |
||||
console.log("USER BANNED, NOTICE NOT RECEIVED") |
||||
return //return false confirm, but do not store noticefile
|
||||
} |
||||
|
||||
if(!inList(notice.sender, trustlist)){
|
||||
|
||||
//if not in the trust list
|
||||
|
||||
if(!fs.existsSync(purgatoryDir)) |
||||
fs.mkdirSync(purgatoryDir) |
||||
|
||||
var noticeAmm = fs.readdirSync(purgatoryDir).length |
||||
|
||||
if(noticeAmm > 5){ //if more than 5 mails sent by user end up in purgatory
|
||||
response.writeHead(200) |
||||
response.end('purglim') |
||||
console.log("PURGATORY LIMIT REACHED FOR " + notice.sender) |
||||
return //return false, but do not store noticefile
|
||||
} |
||||
|
||||
var fileName = purgatoryDir + "/" + Math.floor(new Date() / 1000) + "~" + notice.sender |
||||
|
||||
fs.writeFileSync(fileName, JSON.stringify(notice)) |
||||
|
||||
response.writeHead(200) |
||||
response.end("ok") |
||||
return |
||||
} |
||||
|
||||
if(inList(notice.sender, trustlist)){ |
||||
|
||||
//IF TRUSTED
|
||||
|
||||
if(!fs.existsSync(trustedDir)) |
||||
fs.mkdirSync(trustedDir) |
||||
|
||||
var filename = trustedDir + "/" + Math.floor(new Date() / 1000) + "~" + notice.sender |
||||
|
||||
fs.writeFileSync(filename, JSON.stringify(notice)) |
||||
|
||||
response.writeHead(200) |
||||
response.end("ok") |
||||
return |
||||
|
||||
} |
||||
} |
||||
}) |
||||
}) |
||||
|
||||
console.log("---") |
||||
}) |
||||
|
||||
app.get('/checkrepo', (request, response) => { |
||||
var fileName = "repo/" + request.query.user + "/deposit/" + request.query.id |
||||
var token = request.query.token |
||||
|
||||
if(fs.existsSync(fileName)){ |
||||
var authlist = fs.readFileSync(fileName + "/auth") |
||||
if(inList(token, authlist)){ |
||||
response.writeHead(200) |
||||
response.end('yes!') |
||||
return |
||||
} |
||||
} |
||||
|
||||
response.writeHead(200) |
||||
response.end('no') |
||||
return |
||||
}) |
||||
|
||||
app.get('/get', (request, response) => { |
||||
var fileName = "repo/" + request.query.user + "/deposit/" + request.query.id |
||||
var token = request.query.token |
||||
|
||||
if(fs.existsSync(fileName)){ |
||||
var authlist = fs.readFileSync(fileName + "/auth") |
||||
var actFileNameStr = fs.readFileSync(fileName + "/meta") |
||||
var actFileName = JSON.parse(actFileNameStr).filename |
||||
var persistStatus = JSON.parse(actFileNameStr).persist |
||||
if(inList(token, authlist)){ |
||||
console.log("serving file " + actFileName + "\n") |
||||
response.download(fileName + "/" + actFileName) |
||||
if(persistStatus !== 'true'){ |
||||
var newAuthlist = authlist.toString().replace(token + '\n', '') |
||||
fs.writeFileSync(fileName + "/auth", newAuthlist) |
||||
|
||||
if(newAuthlist.replace('\n', '') === "") |
||||
console.log("FILE " + request.query.id + " HAS BEEN DELIVERED TO EVERYONE") |
||||
|
||||
} |
||||
|
||||
return |
||||
} |
||||
} |
||||
|
||||
response.writeHead(200) |
||||
response.end('no') |
||||
return |
||||
}) |
||||
|
||||
|
||||
const server = http.createServer(app) |
||||
server.listen(27050) |
||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,20 @@ |
||||
{ |
||||
"name": "postmail", |
||||
"version": "1.0.0", |
||||
"description": "Notice-Based Simple Email Protocol", |
||||
"main": "app.js", |
||||
"scripts": { |
||||
"test": "echo \"Error: no test specified\" && exit 1" |
||||
}, |
||||
"author": "Puly4", |
||||
"license": "0BSD", |
||||
"dependencies": { |
||||
"crypto": "^1.0.1", |
||||
"express": "^4.18.2", |
||||
"express-session": "^1.17.3", |
||||
"fs": "^0.0.1-security", |
||||
"http": "^0.0.1-security", |
||||
"https": "^1.0.0", |
||||
"url": "^0.11.0" |
||||
} |
||||
} |
||||
@ -0,0 +1,35 @@ |
||||
#!/bin/bash |
||||
|
||||
USERNAMEx="" |
||||
|
||||
read -p "User LOGIN: " USERNAMEx |
||||
|
||||
DEPOSIT="repo/$USERNAMEx/deposit/" |
||||
|
||||
for file in $(ls $DEPOSIT) |
||||
do |
||||
echo -ne "\n\n\n\n" |
||||
echo "---> Checking $file" |
||||
cat $DEPOSIT$file/meta | jq '.filename' |
||||
cat $DEPOSIT$file/meta | jq '.time' -r | date -d - |
||||
cat $DEPOSIT$file/meta | jq '.description' |
||||
echo -ne '\n' |
||||
|
||||
if [[ $(cat $DEPOSIT$file/auth) == '' ]]; |
||||
then |
||||
echo " :: FILE HAS BEEN SENT TO EVERYONE!" |
||||
ans="" |
||||
read -p " Delete File? [rm -rf $DEPOSIT$file] (y/n)" ans |
||||
if [[ $ans == 'y' ]]; |
||||
then |
||||
rm -rf $DEPOSIT$file |
||||
fi |
||||
else |
||||
echo " :: File still pending - Needs to be received by ::" |
||||
for line in $(cat $DEPOSIT$file/auth) |
||||
do |
||||
PERSON=$(echo $line | cut -d ':' -f 1-2) |
||||
echo " -> $PERSON" |
||||
done |
||||
fi |
||||
done |
||||
@ -0,0 +1,47 @@ |
||||
#!/bin/bash |
||||
|
||||
USERNAMEx="" |
||||
|
||||
read -p "Username LOGIN: " USERNAMEx |
||||
|
||||
NOTICEFOLDER="repo/${USERNAMEx}/notices/trusted/" |
||||
|
||||
MAILFOLDER="repo/${USERNAMEx}/mail/new/" |
||||
|
||||
for file in $(ls ${NOTICEFOLDER}) |
||||
do |
||||
mkdir ${MAILFOLDER}$file |
||||
mv ${NOTICEFOLDER}$file ${MAILFOLDER}$file/$file |
||||
NOTICEFILE="${MAILFOLDER}$file/$file" |
||||
MSGID=$(cat $NOTICEFILE | jq '.id' -r) |
||||
SENDERstr=$(cat $NOTICEFILE | jq '.sender' -r) |
||||
TOKEN=$(cat $NOTICEFILE | jq '.token' -r) |
||||
USERu=$(echo $SENDERstr | cut -d ':' -f 1) |
||||
SRVu=$(echo $SENDERstr | cut -d ':' -f 2) |
||||
|
||||
echo -ne "\n\n---> NEW MAIL BY $SENDER" |
||||
|
||||
#MAKE FETCH REQ |
||||
|
||||
curl -q http://$SRVu:27050/get\?id\=${MSGID}\&user\=${USERu}\&token\=${TOKEN} > ${MAILFOLDER}$file/index.pmail |
||||
echo "-> curl http://$SRVu:27050/get\?id\=${MSGID}\&user\=${USERu}\&token\=${TOKEN}" |
||||
|
||||
PMAILFILE="${MAILFOLDER}$file/index.pmail" |
||||
|
||||
MAILTITLE=$(cat $PMAILFILE | jq '.title' -r) |
||||
|
||||
echo -ne $MAILTITLE > ${MAILFOLDER}$file/MESSAGE |
||||
echo -ne "\n----------------------\n" >> ${MAILFOLDER}$file/MESSAGE |
||||
echo -ne "(${SENDERstr})\n\n" >> ${MAILFOLDER}$file/MESSAGE |
||||
|
||||
TEXTID=$(cat $PMAILFILE | jq '.message' -r) |
||||
|
||||
curl -q http://$SRVu:27050/get\?id\=${TEXTID}\&user\=${USERu}\&token\=${TOKEN} >> ${MAILFOLDER}$file/MESSAGE |
||||
echo "-> curl http://$SRVu:27050/get\?id\=${TEXTID}\&user\=${USERu}\&token\=${TOKEN}" |
||||
echo "MESSAGE DOWNLOADED SUCCESFULLY" |
||||
ATTS=$(cat ${MAILFOLDER}$file/index.pmail | jq '.attachements') |
||||
echo $ATTS > ${MAILFOLDER}$file/ATTACHEMENTS |
||||
|
||||
echo -ne "---------------RECEIVED MESSAGE SUCESFULLY----------------\n\n\n\n\n\n\n\n\n\n" |
||||
less ${MAILFOLDER}$file/MESSAGE |
||||
done |
||||
@ -0,0 +1,62 @@ |
||||
#!/bin/bash |
||||
|
||||
INDEXFILE="" |
||||
ATTACHMENTS="" |
||||
|
||||
TITLE="" |
||||
USERNAMEx="" |
||||
SRVx="" |
||||
DESTu="" |
||||
read -p "Username LOGIN: " USERNAMEx |
||||
read -p "Server LOGIN: " SRVx |
||||
read -p "Send to (user:server.tld) -> " DESTu |
||||
|
||||
USERu=$(echo $DESTu | cut -f 1 -d ':') |
||||
SRVu=$(echo $DESTu | cut -f 2 -d ':') |
||||
echo "Generating Token..." |
||||
TOKEN=$(cat /dev/urandom | head -c 100 | sha256sum | head -c 20) |
||||
|
||||
TOKEN="${USERu}:${SRVu}:${TOKEN}" |
||||
|
||||
read -p "Mail Title: " TITLE |
||||
|
||||
echo "Write Mail Body Here" > buf.txt |
||||
nano buf.txt |
||||
mv buf.txt message |
||||
|
||||
MESSAGE="$(bash pmailcli.upload.sh $USERNAMEx ./message $TOKEN)" |
||||
|
||||
ATTACHEMENTS="{" |
||||
|
||||
|
||||
for file in $@ |
||||
do |
||||
echo $file |
||||
item="$(bash pmailcli.upload.sh $USERNAMEx $file $TOKEN)" |
||||
ATTACHEMENTS="$ATTACHEMENTS$item," |
||||
done |
||||
|
||||
ATTACHEMENTS=${ATTACHEMENTS::-1} |
||||
ATTACHEMENTS="$ATTACHEMENTS}" |
||||
|
||||
if [[ $ATTACHEMENTS == "}" ]]; |
||||
then |
||||
ATTACHEMENTS='""' |
||||
fi |
||||
|
||||
INDEXFILE="{\"title\":\"$TITLE\",$MESSAGE,\"attachements\":$ATTACHEMENTS}" |
||||
|
||||
echo $INDEXFILE > index.pmail |
||||
|
||||
|
||||
bash pmailcli.upload.sh $USERNAMEx index.pmail $TOKEN |
||||
MSGID=$(sha256sum index.pmail | cut -d ' ' -f 1) |
||||
rm index.pmail |
||||
rm message |
||||
|
||||
|
||||
echo -ne "\n\n\n+++++ RECEIVER'S CONCLUSION +++++\n\n --> " |
||||
curl http://$SRVu:27050/sendnotice\?id\=${MSGID}\&token\=${TOKEN}\&user\=${USERu}\&sender\=${USERNAMEx}:${SRVx} |
||||
echo -ne "\n\n+++++ END +++++\n\n" |
||||
echo "curl http://$SRVu:27050/sendnotice\?id\=${MSGID}\&token\=${TOKEN}\&user\=${USERu}\&sender\=${USERNAMEx}:${SRVx}" |
||||
|
||||
@ -0,0 +1,12 @@ |
||||
#!/bin/bash |
||||
USER="" |
||||
read -p "Username: " USER |
||||
install -d repo/$USER/deposit |
||||
install -d repo/$USER/pub |
||||
install -d repo/$USER/notices/trusted |
||||
install -d repo/$USER/notices/purgatory |
||||
install -d repo/$USER/mail/new |
||||
install -d repo/$USER/mail/old |
||||
touch repo/$USER/notices/banlist |
||||
touch repo/$USER/notices/ipbanlist |
||||
touch repo/$USER/notices/trustlist |
||||
@ -0,0 +1,10 @@ |
||||
#!/bin/bash |
||||
|
||||
USER="" |
||||
ME="" |
||||
|
||||
read -p "User LOGIN: " ME |
||||
read -p "User to TrustList (user:srv.tld) -> " USER |
||||
|
||||
echo $USER >> repo/$ME/notices/trustlist |
||||
mv repo/$ME/notices/purgatory/$USER/* repo/$ME/notices/trusted/. |
||||
@ -0,0 +1,17 @@ |
||||
#!/bin/bash |
||||
|
||||
CHECKSUM=$(sha256sum $2 | cut -f 1 -d " ") |
||||
FILENAME=$(basename $2) |
||||
DESC="" |
||||
TIME=$(date +%s) |
||||
|
||||
read -p "Short file description ($FILENAME): " DESC |
||||
|
||||
mkdir repo/$1/deposit/$CHECKSUM |
||||
cp $2 repo/$1/deposit/$CHECKSUM/$FILENAME |
||||
|
||||
echo "{\"filename\":\"$FILENAME\",\"persist\":\"false\",\"description\":\"$DESC\",\"time\":\"$TIME\"}" > repo/$1/deposit/$CHECKSUM/meta |
||||
|
||||
echo $3 >> repo/$1/deposit/$CHECKSUM/auth |
||||
|
||||
echo "\"$FILENAME\":\"$CHECKSUM\"" |
||||
Binary file not shown.
Loading…
Reference in new issue