You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
287 lines
10 KiB
287 lines
10 KiB
var path = require('path')
|
|
var fs = require('fs')
|
|
var ecstatic = require('ecstatic')
|
|
const express = require('express')
|
|
const app = express()
|
|
var tar = require('tar')
|
|
const archiver = require('archiver');
|
|
var skqlib = require('./skq_modules/skq-lib')
|
|
|
|
// GLOBAL CONFIG
|
|
process['CONFIG'] = JSON.parse(fs.readFileSync(path.join(__dirname, 'config','skqitam-server-config.json'), 'utf8'))
|
|
process['CONFIG']['GLOBAL']['RUN_DIR'] = __dirname
|
|
process['CONFIG']['LOCAL']= skqlib.it_am_init()
|
|
|
|
// console.log(JSON.stringify(process['CONFIG'], null, 2))
|
|
|
|
// Generate Client Archive
|
|
console.log ('INFO: Generating: ' + path.join(__dirname, 'download', 'skqitam-client.tgz'))
|
|
tar.c(
|
|
{
|
|
gzip: true,
|
|
file: path.join(__dirname, 'download', 'skqitam-client.tgz')
|
|
},
|
|
[path.join('skqitam-client')]
|
|
)
|
|
// .then(_ => { .. tarball has been created .. })
|
|
|
|
// https://www.npmjs.com/package/archiver
|
|
console.log ('INFO: Generating: ' + path.join(__dirname, 'download', 'skqitam-client.zip'))
|
|
const ziparch = fs.createWriteStream(path.join(__dirname, 'download', 'skqitam-client.zip'))
|
|
const archive = archiver('zip', {
|
|
zlib: { level: 9 } // Sets the compression level.
|
|
})
|
|
|
|
archive.on('warning', function(err) {
|
|
if (err.code === 'ENOENT') {
|
|
// log warning
|
|
} else {
|
|
// throw error
|
|
throw err;
|
|
}
|
|
})
|
|
|
|
archive.pipe(ziparch)
|
|
archive.directory('skqitam-client/', true);
|
|
archive.finalize()
|
|
|
|
// Windows 7 Installers
|
|
try {
|
|
fs.mkdirSync(path.join(__dirname, 'download', 'win7-x64-installer'), { recursive: true })
|
|
|
|
let skqitam_setup_win7_bat = 'PowerShell.exe -ExecutionPolicy Unrestricted -command "%homedrive%%homepath%\\Downloads\\skqitam-client-win7-installer\\skqitam-setup-win7.ps1 http://' + process['CONFIG']['LOCAL']['HOST']['NETWORK']['IP_ADDR']['IPv4'][0] + ':' + process['CONFIG']['GLOBAL']['WEBUI_PORT']
|
|
|
|
try {
|
|
fs.copyFileSync(path.join(__dirname, 'download', 'skqitam-setup-win7.ps1'), path.join(__dirname, 'download', 'win7-x64-installer', 'skqitam-setup-win7.ps1'))
|
|
try {
|
|
fs.writeFileSync(path.join(__dirname, 'download', 'win7-x64-installer', 'skqitam-setup-win7.bat'), skqitam_setup_win7_bat, 'utf8')
|
|
// fs.copyFileSync(path.join(__dirname, 'download', 'skqitam-setup-win7.bat'), path.join(__dirname, 'download', 'win7-x64-installer', 'skqitam-setup-win7.bat'))
|
|
|
|
console.log ('INFO: Generating: ' + path.join(__dirname, 'download', 'skqitam-client-win7-installer.zip') + "\n")
|
|
const w7x64_ziparch = fs.createWriteStream(path.join(__dirname, 'download', 'skqitam-client-win7-installer.zip'))
|
|
const w7x64_archive = archiver('zip', {
|
|
zlib: { level: 9 } // Sets the compression level.
|
|
})
|
|
|
|
w7x64_archive.on('warning', function(err) {
|
|
if (err.code === 'ENOENT') {
|
|
// log warning
|
|
} else {
|
|
// throw error
|
|
throw err;
|
|
}
|
|
})
|
|
|
|
w7x64_archive.pipe(w7x64_ziparch)
|
|
// w7x64_archive.directory(path.join('download', 'win7-x64-installer'), 'win7-x64-installer');
|
|
w7x64_archive.directory(path.join('download', 'win7-x64-installer'), false);
|
|
w7x64_archive.finalize()
|
|
} catch (e) {
|
|
console.log ('ERROR: Could not copy: '+ path.join(__dirname, 'download', 'skqitam-setup-win7.bat'))
|
|
process.exit(1)
|
|
}
|
|
} catch (e) {
|
|
console.log ('ERROR: Could not copy: '+ path.join(__dirname, 'download', 'skqitam-setup-win7.ps1'))
|
|
process.exit(1)
|
|
}
|
|
} catch (e) {
|
|
console.log ('ERROR: Could not make directory: '+ path.join(__dirname, 'download', 'win7-x64-installer'))
|
|
process.exit(1)
|
|
}
|
|
|
|
|
|
// BEGIN DEV TEST FUNCTIONS - Disable for security purpose before deploying
|
|
|
|
app.use('/api/config', function(req, res) {
|
|
res.writeHead(200, {'Content-Type': 'application/json'})
|
|
res.end(JSON.stringify(process['CONFIG'], null, 2))
|
|
})
|
|
|
|
// END DEV TEST FUNCTIONS - Disable for security purpose before deploying
|
|
|
|
|
|
// API
|
|
// Web Config
|
|
app.use('/api/webconfig', function(req, res) {
|
|
res.writeHead(200, {'Content-Type': 'application/json'})
|
|
res.end(JSON.stringify(process['CONFIG']['LOCAL']['WEB'], null, 2))
|
|
})
|
|
|
|
|
|
// ITAM Data Uploads
|
|
app.use('/api/upload', function(req, res) {
|
|
let status = true
|
|
let now = skqlib.tell_time()
|
|
|
|
// console.log (req)
|
|
// console.log(req.headers)
|
|
|
|
if (req.query['ITAM_DATA']) {
|
|
// console.log(req.query['ITAM_DATA'])
|
|
try {
|
|
itam_data = JSON.parse(req.query['ITAM_DATA'])
|
|
// console.log(JSON.stringify(itam_data, null, 2))
|
|
|
|
// Log Dir
|
|
let log_dir = path.join(process['CONFIG']['LOCAL']['ITAM']['ITAM_DATA_DIR'], 'logs')
|
|
try {
|
|
|
|
fs.mkdirSync(log_dir, { recursive: true })
|
|
|
|
let log = {}
|
|
log['SERVER_UTC_TIMESTAMP'] = now['UTC']['ISO8601']
|
|
log['EVENT'] = 'CLIENT UPLOAD'
|
|
log['CLIENT_UTC_TIMESTAMP'] = itam_data['ITAM']['TIMESTAMP']
|
|
log['ITAM_ID'] = itam_data['ITAM']['ID']
|
|
log['HOSTNAME'] = itam_data['ITAM']['HOSTNAME']
|
|
let log_file = path.join(process['CONFIG']['LOCAL']['ITAM']['ITAM_DATA_DIR'], 'logs', now['UTC']['YYYY-MM-DD'] + '_itam-server.log')
|
|
try {
|
|
fs.appendFileSync(log_file, JSON.stringify(log) + "\n", 'utf8')
|
|
console.log (JSON.stringify(log))
|
|
} catch (err) {
|
|
console.log ("ERROR: Cannot LOG event to " + log_file)
|
|
}
|
|
|
|
} catch (err) {
|
|
console.log ("ERROR: Cannot make log dir: " + log_dir)
|
|
console.log (err)
|
|
status = false
|
|
}
|
|
|
|
// Data Dir
|
|
let sprgx = RegExp(/\s+/g)
|
|
data_dir = path.join(process['CONFIG']['LOCAL']['ITAM']['ITAM_DATA_DIR'], 'hosts', String(itam_data['ITAM']['HOSTNAME']).replace(sprgx, '_') + '_' + itam_data['ITAM']['ID'], 'raw')
|
|
try {
|
|
fs.mkdirSync(data_dir, { recursive: true })
|
|
|
|
let raw_data_file = path.join(data_dir, now['UTC']['ISO8601'] + '_' + String(itam_data['ITAM']['HOSTNAME']).replace(sprgx, '_') + '_' + itam_data['ITAM']['ID'] + '.json')
|
|
try {
|
|
fs.writeFileSync(raw_data_file, JSON.stringify(itam_data, null, 2), 'utf8')
|
|
|
|
itam_parse_data(itam_data)
|
|
|
|
// Host Map
|
|
let host_id_map_file = path.join(process['CONFIG']['LOCAL']['ITAM']['ITAM_DATA_DIR'], 'host-id-map.json')
|
|
|
|
try {
|
|
let host_id_map = JSON.parse(fs.readFileSync(host_id_map_file, 'utf8'))
|
|
host_id_map[itam_data['ITAM']['HOSTNAME']] = itam_data['ITAM']['ID']
|
|
|
|
try {
|
|
fs.writeFileSync(host_id_map_file, JSON.stringify(host_id_map, null, 2), 'utf8')
|
|
|
|
} catch (err) {
|
|
console.log ("ERROR: Cannot Write Host ID Map File " + host_id_map_file)
|
|
status = false
|
|
process.exit(1)
|
|
}
|
|
// fs.writeFileSync(raw_data_file, JSON.stringify(itam_data, null, 2), 'utf8')
|
|
} catch (err) {
|
|
console.log ("ERROR: Cannot Read Host ID Map File " + host_id_map_file)
|
|
status = false
|
|
process.exit(1)
|
|
}
|
|
|
|
} catch (err) {
|
|
console.log ("ERROR: Cannot Write Data File " + raw_data_file)
|
|
status = false
|
|
process.exit(1)
|
|
}
|
|
|
|
} catch (err) {
|
|
console.log ("ERROR: Cannot make data dir: " + data_dir)
|
|
console.log (err)
|
|
status = false
|
|
}
|
|
|
|
} catch (err) {
|
|
console.log ("ERROR: Cannot PARSE Client JSON Upload")
|
|
console.log (err)
|
|
status = false
|
|
}
|
|
|
|
} else {
|
|
console.log ("ERROR: Missing client ITAM_DATA Upload")
|
|
status = false
|
|
}
|
|
|
|
// res.writeHead(200, {'Content-Type': 'application/javascript'})
|
|
|
|
res.status(200)
|
|
res.send(status)
|
|
})
|
|
|
|
// Data
|
|
app.use('/api/data', express.static(path.join(__dirname, 'itam-data'), { index: false }))
|
|
|
|
// Downloads
|
|
app.use('/download', express.static(path.join(__dirname, 'download'), { index: false }))
|
|
// app.use('/download', ecstatic({
|
|
// root: path.join(__dirname, 'download'),
|
|
// showdir: true,
|
|
// // baseDir: '/download'
|
|
// }));
|
|
app.use('/download/nodejs', express.static(path.join(__dirname, 'nodejs'), { index: false }))
|
|
|
|
// WebUI Admin
|
|
app.use('/admin', express.static(path.join(__dirname, process['CONFIG']['GLOBAL']['WEBUI_ADMIN']['WEB_ROOT_DIR'])))
|
|
|
|
// WebUI Root
|
|
app.use('/', express.static(path.join(__dirname, process['CONFIG']['GLOBAL']['WEBUI_ROOT']['WEB_ROOT_DIR'])))
|
|
|
|
// 404 Errors
|
|
app.use(function (req, res, next) {
|
|
res.status(404).send("404 Page not found: " + req.url )
|
|
var remote_ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress
|
|
remote_ip = remote_ip.replace(/^\:\:ffff\:/, '') // IPv4 part only
|
|
console.log('ERR ' + res.statusCode + ' ' + req.method + ' ' + remote_ip + ' [' + req.headers['user-agent'] + '] ' + ' ' + req.url)
|
|
})
|
|
|
|
// Starting Express Web Service
|
|
app.listen(process['CONFIG']['GLOBAL']['WEBUI_PORT'], function () {
|
|
console.log ("Sikuliaq Cyber Asset Manager Server")
|
|
console.log (" - Version: v" + process['CONFIG']['LOCAL']['PACKAGE']['version'] + ' ' + process['CONFIG']['LOCAL']['PACKAGE']['version_date'])
|
|
console.log (" - Copyright (C) 2021 University of Alaska Fairbanks - College of Fisheries and Ocean Sciences - R/V Sikuliaq")
|
|
console.log (" - Author: John Haverlack (jehaverlack@alaska.edu)\n")
|
|
console.log ("Status: STARTED")
|
|
|
|
console.log (" Node.JS: v" + process['CONFIG']['LOCAL']['PROC']['VERSIONS']['node'])
|
|
for (i in process['CONFIG']['LOCAL']['HOST']['NETWORK']['IP_ADDR']['IPv4']) {
|
|
console.log (" WebUI: http://" + process['CONFIG']['LOCAL']['HOST']['NETWORK']['IP_ADDR']['IPv4'][i] + ':' + process['CONFIG']['GLOBAL']['WEBUI_PORT'])
|
|
}
|
|
for (i in process['CONFIG']['LOCAL']['HOST']['NETWORK']['IP_ADDR']['IPv6']) {
|
|
console.log (" WebUI: http://[" + process['CONFIG']['LOCAL']['HOST']['NETWORK']['IP_ADDR']['IPv6'][i] + ']:' + process['CONFIG']['GLOBAL']['WEBUI_PORT'])
|
|
}
|
|
console.log ("\nNOTE: Be sure to open port " + process['CONFIG']['GLOBAL']['WEBUI_PORT'] + " to the above IP's\n on server and network firewalls.")
|
|
|
|
})
|
|
|
|
|
|
// -------------------------------- Functions --------------------------
|
|
function itam_parse_data(data) {
|
|
|
|
console.log(JSON.stringify(data['ITAM'], null, 2))
|
|
let itam_index = {}
|
|
|
|
try {
|
|
let itam_index = JSON.parse(fs.readFileSync(path.join(__dirname, process['CONFIG']['GLOBAL']['ITAM_INDEX']), 'utf8'))
|
|
|
|
} catch (e) {
|
|
|
|
|
|
}
|
|
|
|
// Host Index Update
|
|
|
|
// Hardware Statistics
|
|
|
|
// OS Statistics
|
|
|
|
// Software Statistics
|
|
|
|
// Appendix-D Hardware
|
|
|
|
// Appendix-D Software
|
|
|
|
|
|
}
|