Refactor the not-yet-working AimeDB impl

This commit is contained in:
Tau 2018-11-26 00:37:48 -05:00
parent 92e002cbfc
commit b50f6dc5e6
2 changed files with 134 additions and 59 deletions

130
src/aimedb.js Normal file
View File

@ -0,0 +1,130 @@
const crypto = require('crypto')
const { Transform, pipeline } = require('stream')
const K = Buffer.from('Copyright(C)SEGA', 'utf8')
class Decoder extends Transform {
constructor(options) {
super({
readableObjectMode: true,
...options,
})
this.state = Buffer.alloc(0)
}
_transform(chunk, encoding, callback) {
this.state = Buffer.concat([ this.state, chunk ])
if (this.state.length < 8) {
return
}
const magic = this.state.readUInt16LE(0)
if (magic != 0xA13E) {
return callback(new Error(`Invalid magic (decimal ${magic})`))
}
const len = this.state.readUInt16LE(6)
if (this.state.length < len) {
return
}
console.log('Aimedb: Recv', this.state)
const cmd = this.state.readUInt16LE(4)
const payload = this.state.slice(8, len)
this.state = this.state.slice(len)
return callback(null, { cmd, payload })
}
}
class Encoder extends Transform {
constructor(options) {
super({
writableObjectMode: true,
...options
})
}
_transform(chunk, encoding, callback) {
const { cmd, payload } = chunk
// Message size must be rounded up to a multiple of 16
const len = 8 + payload.length
const buf = Buffer.alloc((len + 15) & ~15)
buf.writeUInt16LE(0xA13E, 0) // Magic?
buf.writeUInt16LE(0x3087, 2) // ???
buf.writeUInt16LE(cmd, 4)
buf.writeUInt16LE(buf.length, 6)
payload.copy(buf, 8)
console.log('Aimedb: Send', buf)
callback(null, buf)
}
}
async function dispatch(socket) {
console.log('Aimedb: Connection opened')
const input = pipeline(
socket,
crypto
.createDecipheriv('aes-128-ecb', K, null)
.setAutoPadding(false),
new Decoder(),
)
const output = new Encoder()
pipeline(
output,
crypto
.createCipheriv('aes-128-ecb', K, null)
.setAutoPadding(false),
socket,
)
try {
for await (const req of input) {
let payload
switch (req.cmd) {
case 0x0064:
console.log('Aimedb: Hello')
payload = Buffer.alloc(24)
payload.writeInt16LE(0x0001, 0)
output.write({ cmd: 0x0065, payload })
break
case 0x0066:
console.log('Aimedb: Goodbye')
break
default:
console.log('Aimedb: Unknown command', req.cmd)
break
}
}
} catch (e) {
console.log('Aimedb: Connection error:\n', e)
}
console.log('Aimedb: Connection closed')
socket.end()
}
module.exports = dispatch

View File

@ -1,10 +1,11 @@
const fs = require('fs')
const https = require('https')
const http = require('http')
const fs = require('fs')
const net = require('net')
const aimedb = require('./aimedb')
const billing = require('./billing')
const startup = require('./startup')
const crypto = require('crypto')
const title = require('./title')
const tls = {
@ -12,63 +13,7 @@ const tls = {
key: fs.readFileSync('pki/server.key'),
}
function encodeAimeBody(buf) {
const keyBuf = Buffer.from('Copyright(C)SEGA', 'utf8')
const ivBuf = Buffer.from('0x00', 'hex')
let cipher = crypto.createCipheriv('aes-128-ecb', keyBuf, ivBuf)
cipher.setAutoPadding(false)
crypted = Buffer.concat([cipher.update(buf), cipher.final()])
return crypted
}
function decodeAimeBody(buf) {
const keyBuf = Buffer.from('Copyright(C)SEGA', 'utf8')
const ivBuf = Buffer.from('0x00', 'hex')
let decipher = crypto.createDecipheriv('aes-128-ecb', keyBuf, ivBuf)
decipher.setAutoPadding(false)
decrypted = Buffer.concat([decipher.update(buf), decipher.final()])
return decrypted
}
function parseMessage(buf) {
switch(buf[4].toString(16)) {
case "64":
var newBuffer = new Buffer.from([0x3e, 0xa1, 0x87, 0x30, 0x65, 0x00, 0x20, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00]);
console.log(newBuffer)
return newBuffer
break;
case "66":
var newBuffer = new Buffer.from([0x3e, 0xa1, 0x87, 0x30, 0x67, 0x00, 0x20, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00]);
console.log(newBuffer)
return newBuffer
break;
default:
console.log("No case for "+buf[4].toString(16))
return null
}
}
const server = net.createServer((c) => {
// 'connection' listener
console.log('client connected');
c.on('end', () => {
console.log('client disconnected');
});
c.on('error', (err) => { throw err; });
c.on('data', (data) => {
decode = decodeAimeBody(data);
encode = encodeAimeBody(decodeAimeBody(data)).toString('hex')+'\r\n'
console.log('Decode: '+decode.toString('hex'))
c.write(encodeAimeBody(parseMessage(decode)))
});
c.pipe(c);
});
server.on('error', (err) => {
throw err;
});
server.listen(22345, () => {
console.log('server bound');
});
net.createServer(aimedb).listen(22345)
http.createServer(startup).listen(80)
https.createServer(tls, billing).listen(8443)
http.createServer(title).listen(9000)