1
0
mirror of https://github.com/AR2000AR/openComputers_codes.git synced 2025-09-08 22:51:14 +02:00

initial commit

This commit is contained in:
2020-08-23 21:24:49 +02:00
commit 6e2582d69f
5 changed files with 427 additions and 0 deletions

43
bank_api/bank_api Normal file
View File

@@ -0,0 +1,43 @@
NAME
bank_api - provide method to communicate with a bank server
SYNOPSIS
local bank = require("bank_api")
DESCIPTION
This API allow easy communication with the bank server
Data structure
cbData : see man libCB
rawCBdata : see man libCB
Method list
getCredit(cbData):int,int
makeTransaction(uuid_cible,cbData,amount):int
setModemTimeout(t)
Returned values
The first returned value is a status code
0 = OK
1 = NO_ACCOUNT
2 = ERROR_ACCOUNT
3 = ERROR_CB
4 = ERROR_AMOUNT
-1 = timeout
-2 = wrong message
The second returned value is optional
CONFIGURATION
FILES
/usr/lib/bank_api.lua
the library
/etc/bank/api/conf.cfg
the config file location
SEE ALSO
libCB
AUTHOR
AR2000

142
bank_api/bank_api.lua Normal file
View File

@@ -0,0 +1,142 @@
--Bank API by AR2000AR=(AR2000)======
--public api used to comunicate with the bank server.
--=====================================
--LOAD LIB
local event = require("event")
local serialization = require("serialization")
--INIT CONST
local BANK_PORT = 351
local CONF_DIR = "/etc/bank/api/"
local MODEM_TIMEDOUT = -1
--INIT COMPONENT
local modem = require("component").modem
--INIT VAR
local bank_addr = "ecdc8d43-5e73-4a9c-ba43-051716c71dc8" --fetched from conf file
local timeout = 5
local bank = {} --table returned by require
--protocole commands constants
local PROTOCOLE_GET_CREDIT = "GET_CREDIT"
local PROTOCOLE_MAKE_TRANSACTION = "MAKE_TRANSACTION"
local PROTOCOLE_NEW_ACCOUNT = "NEW_ACCOUNT"
local PROTOCOLE_NEW_CB = "NEW_CB"
--protocole status constants
local PROTOCOLE_OK = 0
local PROTOCOLE_NO_ACCOUNT = 1
local PROTOCOLE_ERROR_ACCOUNT = 2
local PROTOCOLE_ERROR_CB = 3
local PROTOCOLE_ERROR_AMOUNT = 4
local PROTOCOLE_DENIED = 4
local PROTOCOLE_ERROR_RECEIVING_ACCOUNT = 5
local PROTOCOLE_ERROR_UNKNOWN = 999
--=====================================
local function reciveMessage() --recive a message from the modem component
local _,_,from,port,_,status,command,message = event.pull(timeout,"modem_message")
if(not status) then status = MODEM_TIMEDOUT end
if(not command) then command = "" end
if(not message) then message = "" end
return status,command,serialization.unserialize(message)
end
--send a request to the server
-- @param requestType:string
-- @param requestData:table
-- @return status:int,command:string,message:table
local function sendRequest(requestType,requestData) --format and send a request to the server
modem.open(BANK_PORT)
modem.send(bank_addr,BANK_PORT,requestType,serialization.serialize(requestData))
local status,command,message = reciveMessage()
modem.close(BANK_PORT)
return status,command,message
end
--get the account solde
-- @param uuid_cible:string
-- @param cbData:table
-- @param amount:init
-- @return int
-- -1 : timeout
-- -2 : wrong message
-- 0 : ok
-- 1 : no account
-- 2 : account error
-- 3 : cb error
-- @return solde
function bank.getCredit(cbData)
local status,command,message = sendRequest(PROTOCOLE_GET_CREDIT,{cbData=cbData})
if(status) then
if(command == PROTOCOLE_GET_CREDIT) then
if(status==PROTOCOLE_OK) then return 0, message.solde
elseif(status==PROTOCOLE_NO_ACCOUNT) then return 1, nil
elseif(status==PROTOCOLE_ERROR_ACCOUNT) then return 2, nil
elseif(status==PROTOCOLE_ERROR_CB) then return 3, nil
end
else
return -2 --wrong message
end
else
return MODEM_TIMEDOUT --timeout
end
end
-- send credit to uuid_cible
-- @param uuid_cible:string
-- @param cbData:table
-- @param amount:init
-- @return int
-- -1 : timeout
-- -2 : wrong message
-- 0 : ok
-- 1 : no account
-- 2 : account error
-- 3 : cb error
-- 4 : amount error
function bank.makeTransaction(uuid_cible,cbData,amount)
local status,command,msg = sendRequest(PROTOCOLE_MAKE_TRANSACTION,{dst=uuid_cible,cbData=cbData,amount=amount})
if(command == PROTOCOLE_MAKE_TRANSACTION) then
return status
elseif(status) then
return -2 --wrong message
else
return MODEM_TIMEDOUT --timeout
end
end
function bank.createAccount(secret)
local status,command,msg = sendRequest(PROTOCOLE_NEW_ACCOUNT,{secret=secret})
if(command == PROTOCOLE_NEW_ACCOUNT) then
if(status == PROTOCOLE_OK) then
return status,msg.uuid
else
return status
end
elseif(status)then
return -2
else
return MODEM_TIMEDOUT
end
end
function bank.requestNewCBdata(secret,accountUUID,cbUUID)
local status,command,msg = sendRequest(PROTOCOLE_NEW_CB,{secret=secret,uuid=accountUUID,cbUUID=cbUUID})
if(command == PROTOCOLE_NEW_CB) then
if(status == PROTOCOLE_OK) then
return status, msg.pin, msg.rawCBdata
else
return status
end
elseif(status)then
return -2
else
return MODEM_TIMEDOUT
end
end
--set the modem timeout (in s)
-- @param t:int
function bank.setModemTimeout(t)
timeout = t
end
return bank

View File

@@ -0,0 +1,127 @@
local dataCard = require("component").data
local fs = require("filesystem")
local io = require("io")
local os = require("os")
local serialization = require("serialization")
local shell = require("shell")
local CONF_DIR = "/etc/bank/server/"
local CONF_FILE_NAME = "conf.cfg"
local AES_IV = dataCard.md5("bank")
local keyFile = CONF_DIR.."key" --default value
local aesKeyFile = CONF_DIR.."aes" --default value
local accountDir = "/srv/bank/" --default value
local PROTOCOLE_NO_ACCOUNT = 1
local PROTOCOLE_ERROR_ACCOUNT = 2
local function getKey(public)
print("-> getKey")
local ext = ".priv"
local type = "ec-private"
if(public) then
ext=".pub"
type = "ec-public"
end
local file = io.open(keyFile..ext,"r")
local key = dataCard.deserializeKey(dataCard.decode64(file:read("*a")),type)
file:close()
print("<- getKey")
return key
end
local function getAES()
local file = io.open(aesKeyFile,"r")
local res = file:read("*a")
file:close()
return dataCard.decode64(res)
end
local function loadAccount(accountUUID)
print("-> loadAccount")
local account = {}
if(fs.exists(accountDir..accountUUID)) then
local file = io.open(accountDir..accountUUID,"r")
local rawData = file:read("*a") --read the entire file
file:close()
rawData = dataCard.decode64(rawData)
local clearData = dataCard.decrypt(rawData,getAES(),AES_IV) --decrypt the data
print("clear data : "..clearData)
clearData = serialization.unserialize(clearData) --get the table form the decrypted string
if(dataCard.ecdsa(clearData.solde..accountUUID,getKey(true),dataCard.decode64(clearData.sig))) then --check the data signature to prevent manual edition of the file
print("<- loadAccount sig ok")
return clearData,clearData;
else
print("<- loadAccount sig err")
return PROTOCOLE_ERROR_ACCOUNT,clearData --signature invalide
end
else
print("<- loadAccount no account")
return PROTOCOLE_NO_ACCOUNT --account not found
end
end
-- write the account file
-- @param accountUUID:string
-- @param solde:int
local function writeAccount(accountUUID,solde)
print("-> writeAccount")
local account = {solde=solde,uuid=accountUUID}
account.sig = dataCard.encode64(dataCard.ecdsa(solde..accountUUID,getKey(false))) --encode sig to make saving it easier
local fileContent = serialization.serialize(account) --convert the table into a string
fileContent = dataCard.encrypt(fileContent,getAES(),AES_IV) --encrypt the data
fileContent = dataCard.encode64(fileContent) --encode the encrypted data to make saving and reading it easier
io.open(accountDir..accountUUID,"w"):write(fileContent):close() --save the data
print("<- writeAccount ")
end
-- handle account edition (check if the account exists and add amount to it's solde)
-- @param uuid:string
-- @param amount:ini
-- @return boolean
local function editAccount(accountUUID,amount)
local account = loadAccount(accountUUID)
if(account == PROTOCOLE_NO_ACCOUNT or account == PROTOCOLE_ERROR_ACCOUNT) then --check for errors with the account
return false --give up
else
writeAccount(account.uuid,account.solde + amount)
return true
end
end
--MAIN=================================
if(fs.exists(CONF_DIR..CONF_FILE_NAME))then --read the config file
local file=io.open(CONF_DIR..CONF_FILE_NAME,"r")
local confTable = serialization.unserialize(file:read("*a"))
file:close()
if(confTable.accountDir)then accountDir = confTable.accountDir end
if(confTable.aesKeyFile)then aesKeyFile = confTable.aesKeyFile end
if(confTable.keyFile)then keyFile = confTable.keyFile end
else
io.stream(2):write("NO CONFIG FILE FOUND IN "..CONF_DIR)
os.exit()
end
local args,opts = shell.parse(...)
if(args[1]=="get") then
ac=loadAccount(args[2])
if(type(ac)=="number")then
print("err:"..ac)
else
print(ac.solde)
end
elseif(args[1]=="set") then
writeAccount(args[2],tonumber(args[3]))
print("done")
elseif(args[1]=='test') then
_,clearData = loadAccount(args[2])
local b,c = 0,0
b=dataCard.ecdsa(clearData.solde..args[2],getKey(true),dataCard.decode64(clearData.sig))
c=dataCard.encode64(dataCard.ecdsa(clearData.solde..args[2],getKey(false)))
print(b)
print("saved: "..clearData.sig)
print("calc : "..c)
else
print("accountEdit <get/set> <uuid> [ammount]")
end

37
libCB/libCB Normal file
View File

@@ -0,0 +1,37 @@
NAME
libCB - provide a way to use credit card
SYNOPSIS
local libCB = require("libCB")
DESCIPTION
Use this lib to access a credit card. A credit card is a special unmanaged floppy disk
Data structure
cbData:table
uudi, --account uuid
cbUUID, --card uuid
sig --card signature made form uuid & card's drive component's uuid
rawCBdata:table
uudi, --account uuid
sig --card signature made form uuid & card's drive component's uuid
pink_check
Method list
getCB(cbDrive,pin):cbData
cbDrive:uuid > the drive component address of the cb
pin:str > user pin code
Returned values
cbData
FILE
/usr/lib/libCB.lua
the library
SEE ALSO
bank_api
AUTHOR
AR2000

78
libCB/libCB.lua Normal file
View File

@@ -0,0 +1,78 @@
--libCB by AR2000AR=(AR2000)==========
--manage credit card (unmanaged floppy)
--=====================================
local cb = {} --table returned by require
local data = require("component").data --data component used for cryptocraphic stuf
local serialization = require("serialization") --data serialization and unserialization
--read the credit card data and return it
-- @param cbDrive:proxy the floppy's component
local function readCB(cbDrive)
local i = 1
--get the data from the card
--the card is in unmanaged mode (binary) and the data is writen at the start of
--the floppy disk
local rawData = cbDrive.readSector(1):gsub("\0","") --clean null byte after the data
local cbData = serialization.unserialize(rawData)
cbData.cbUUID = cbDrive.address
return cbData
end
function cb.getCB(cbDrive,pin)
local res = readCB(cbDrive)
res.uuid = data.decrypt(data.decode64(res.uuid),data.md5(res.cbUUID),data.md5(pin))
local pin_check = false
pin_check = data.decrypt(data.decode64(res.pin_check),data.md5(res.cbUUID),data.md5(pin)) == "PIN"
if(pin_check) then
return res
else
return false
end
end
-- check if the cb is valide
-- @param cbData:table (see man libCB for more info about cbData)
-- @param publicKey:userdata
-- @return boolean
function cb.checkCBdata(cbData,publicKey)
return data.ecdsa(cbData.uuid..cbData.cbUUID..cbData.pin_check,publicKey,data.decode64(cbData.sig))
end
-- generate a random 4 digit pin
-- @return string
local function randomPin()
local pin = ""..math.random(9999)
while (#pin < 4) do
pin = "0"..pin
end
return pin
end
-- create a new rawCBdata
-- @param uuid:string account uuid
-- @param cbUUID:string new cb's uuid
-- @param privateKey:userdata key used to sign the cb
-- @retrun rawCBdata:table
-- @return pin:string
function cb.createNew(uuid,cbUUID,privateKey)
local pin = randomPin()
local aesKey = data.md5(cbUUID)
local aesIV = data.md5(pin)
local newCB = {}
newCB.uuid = data.encode64(data.encrypt(uuid,aesKey,aesIV))
newCB.pin_check = data.encode64(data.encrypt("PIN",aesKey,aesIV))
newCB.sig = data.ecdsa(uuid..cbUUID..newCB.pin_check,privateKey)
newCB.sig = data.encode64(newCB.sig)
return newCB,pin
end
-- write rawCBdata to a unmanaged floppy
-- @param rawCBdata:table the table provided by cb.createNew(...)
-- @param cbDrive:proxy the floppy's component proxy
function cb.writeCB(rawCBdata,cbDrive)
local buffer = serialization.serialize(rawCBdata)
cbDrive.writeSector(1,buffer)
cbDrive.setLabel("CB")
end
return cb --return the table containing all the public functions