Compare commits
4 Commits
071ef7bc02
...
909511f54a
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
909511f54a | ||
|
|
383d1a5c34 | ||
|
|
1bcc8212e9 | ||
|
|
271a17cd16 |
10
wap/mac-check/Dockerfile
Normal file
10
wap/mac-check/Dockerfile
Normal file
@@ -0,0 +1,10 @@
|
||||
FROM node:12.18.1
|
||||
ENV NODE_ENV=production
|
||||
|
||||
COPY "src" "/app"
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
RUN npm install --production
|
||||
|
||||
CMD [ "node", "app.js" ]
|
||||
37
wap/mac-check/README.md
Normal file
37
wap/mac-check/README.md
Normal file
@@ -0,0 +1,37 @@
|
||||
# **mac-check**
|
||||
|
||||
## Úvod
|
||||
|
||||
API na zjištovaní zda je mac addressa přiřazená k vyrobci, po případě k jakému vyrobci
|
||||
|
||||
Aplikace běží na Node.JS
|
||||
|
||||
Demo Url: [mac-check.starraria.eu](https://mac-check.starraria.eu)
|
||||
|
||||
## API
|
||||
|
||||
### GET /api
|
||||
|
||||
### GET /api/range/:macaddress
|
||||
|
||||
Vratí mac adresu s výrobcem pokud byl nalezen, jinak vratí chybu.
|
||||
|
||||
`:macaddress` >> Aspoň první polovina Mac Adresy
|
||||
|
||||
**Query Parameters**
|
||||
|| Required | Default Value | Description |
|
||||
|--|--|--|--|
|
||||
| `format` | `no` | `json` | Specifikuje jaký formát má být použit při odpovědi. Možnosti jsou: `json`,`xml`,`csv` |
|
||||
|
||||
## Quick start (On linux)
|
||||
```bash
|
||||
git clone https://github.com/Dzejkobik007/skolavdf.git
|
||||
mv skolavdf/wap/mac-check ./
|
||||
rm -rf skolavdf
|
||||
cd mac-check/
|
||||
docker-compose up -d --build
|
||||
```
|
||||
|
||||
## Requirements
|
||||
- docker
|
||||
- docker-compose
|
||||
11
wap/mac-check/docker-compose.yml
Normal file
11
wap/mac-check/docker-compose.yml
Normal file
@@ -0,0 +1,11 @@
|
||||
version: '3'
|
||||
|
||||
services:
|
||||
node:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile
|
||||
container_name: mac-check
|
||||
restart: always
|
||||
ports:
|
||||
- 80:80
|
||||
121
wap/mac-check/src/app.js
Normal file
121
wap/mac-check/src/app.js
Normal file
@@ -0,0 +1,121 @@
|
||||
const csv = require('fast-csv');
|
||||
const sha256 = require('simple-sha256')
|
||||
const xml = require('object-to-xml');
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const { response, json } = require('express');
|
||||
const express = require('express');
|
||||
const e = require('express');
|
||||
const app = express();
|
||||
const port = 80;
|
||||
const secret = "123456";
|
||||
|
||||
let ready = false;
|
||||
app.use(express.static('public'));
|
||||
|
||||
|
||||
function loadOrg(filename, options) {
|
||||
console.log("Loading records....");
|
||||
let orgdata = {};
|
||||
fs.createReadStream(path.resolve(__dirname, filename))
|
||||
.pipe(csv.parse(options))
|
||||
.on('error', error => console.error(error))
|
||||
.on('data', row => {orgdata[`${row[0]}`] = row[1]})
|
||||
.on('end', rowCount => {console.log(`Loaded ${rowCount} records`); ready = true });
|
||||
return orgdata;
|
||||
}
|
||||
|
||||
function error(ans, req, res) {
|
||||
if (req.query.format == "xml"){
|
||||
res.set('Content-Type', 'text/xml');
|
||||
res.send(xml({ xml: ans}));
|
||||
} else if (req.query.format == "csv") {
|
||||
res.send(ans.error);
|
||||
} else {
|
||||
res.json(ans);
|
||||
}
|
||||
}
|
||||
|
||||
app.get('/api/range/:mac', (req, res) => {
|
||||
|
||||
// console.log(req);
|
||||
allowed = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F"];
|
||||
mac = req.params.mac.toUpperCase();
|
||||
newmac = "";
|
||||
|
||||
if(mac.length < 6) {
|
||||
res.status(400);
|
||||
ans = { error: 'Mac address too short', code: 400 };
|
||||
error(ans, req, res);
|
||||
return;
|
||||
}
|
||||
|
||||
for (var i = 0; i < 6; i++) {
|
||||
if (allowed.includes(mac.charAt(i))) {
|
||||
newmac = newmac + mac.charAt(i);
|
||||
} else {
|
||||
res.status(400);
|
||||
ans = { error: 'Invalid mac', code: 400 };
|
||||
error(ans, req, res);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
while(!ready) {};
|
||||
|
||||
if(orgdata[mac] !== undefined) {
|
||||
|
||||
result = {"range":mac,"organization":orgdata[mac]};
|
||||
console.log(JSON.stringify(result));
|
||||
const resulthash = sha256.sync(result+secret);
|
||||
if (req.query.format == "xml"){
|
||||
res.set('Content-Type', 'text/xml');
|
||||
res.send(xml({xml: {result: result, code:200, hash:resulthash}},));
|
||||
} else if (req.query.format == "csv") {
|
||||
res.set('Content-Type', 'text/csv');
|
||||
res.send(result.mac+","+result.organization);
|
||||
} else {
|
||||
res.json({result: result, code:200, hash:resulthash});
|
||||
}
|
||||
} else {
|
||||
res.status(404);
|
||||
ans = {error:"Range not found", code: 404};
|
||||
error(ans, req, res);
|
||||
return;
|
||||
}
|
||||
})
|
||||
|
||||
app.use(function (req, res, next) {
|
||||
res.status(404);
|
||||
console.log(req.query);
|
||||
ans = { error: 'Not found', code: 404 }
|
||||
if (req.query.format == "xml"){
|
||||
res.set('Content-Type', 'text/xml');
|
||||
res.send(xml({xml: ans}));
|
||||
} else if (req.query.format == "csv") {
|
||||
res.send(ans.error);
|
||||
} else if (req.query.format == "json") {
|
||||
res.json(ans);
|
||||
}
|
||||
|
||||
// respond with html page
|
||||
if (req.accepts('html') && !req.url.startsWith("/api")) {
|
||||
res.send('<h1>Page not found</h1>');
|
||||
return;
|
||||
}
|
||||
|
||||
// respond with json
|
||||
if (req.accepts('json')) {
|
||||
res.json({ error: 'Not found', code: 404 });
|
||||
return;
|
||||
}
|
||||
|
||||
// default to plain-text. send()
|
||||
res.send('404');
|
||||
});
|
||||
|
||||
const orgdata = loadOrg("oui-fix.csv");
|
||||
|
||||
app.listen(port, () => {
|
||||
console.log(`App listening on port ${port}`);
|
||||
})
|
||||
33192
wap/mac-check/src/oui-fix.csv
Normal file
33192
wap/mac-check/src/oui-fix.csv
Normal file
File diff suppressed because it is too large
Load Diff
8
wap/mac-check/src/package.json
Normal file
8
wap/mac-check/src/package.json
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"dependencies": {
|
||||
"express": "^4.18.2",
|
||||
"fast-csv": "^4.3.6",
|
||||
"object-to-xml": "^2.0.0",
|
||||
"simple-sha256": "^1.1.0"
|
||||
}
|
||||
}
|
||||
77
wap/mac-check/src/public/bars-scale-light.svg
Normal file
77
wap/mac-check/src/public/bars-scale-light.svg
Normal file
@@ -0,0 +1,77 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
version="1.1"
|
||||
id="svg14"
|
||||
sodipodi:docname="bars-scale-light.svg"
|
||||
inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<defs
|
||||
id="defs18" />
|
||||
<sodipodi:namedview
|
||||
id="namedview16"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1"
|
||||
showgrid="false"
|
||||
inkscape:zoom="24.833333"
|
||||
inkscape:cx="12.020134"
|
||||
inkscape:cy="12"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1015"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg14" />
|
||||
<style
|
||||
id="style2">.spinner_jCIR{animation:spinner_B8Vq .9s linear infinite;animation-delay:-.9s}.spinner_upm8{animation-delay:-.8s}.spinner_2eL5{animation-delay:-.7s}.spinner_Rp9l{animation-delay:-.6s}.spinner_dy3W{animation-delay:-.5s}@keyframes spinner_B8Vq{0%,66.66%{animation-timing-function:cubic-bezier(0.36,.61,.3,.98);y:6px;height:12px}33.33%{animation-timing-function:cubic-bezier(0.36,.61,.3,.98);y:1px;height:22px}}</style>
|
||||
<rect
|
||||
class="spinner_jCIR"
|
||||
x="1"
|
||||
y="6"
|
||||
width="2.8"
|
||||
height="12"
|
||||
id="rect4"
|
||||
style="fill:#ffffff" />
|
||||
<rect
|
||||
class="spinner_jCIR spinner_upm8"
|
||||
x="5.8"
|
||||
y="6"
|
||||
width="2.8"
|
||||
height="12"
|
||||
id="rect6"
|
||||
style="fill:#ffffff" />
|
||||
<rect
|
||||
class="spinner_jCIR spinner_2eL5"
|
||||
x="10.6"
|
||||
y="6"
|
||||
width="2.8"
|
||||
height="12"
|
||||
id="rect8"
|
||||
style="fill:#ffffff" />
|
||||
<rect
|
||||
class="spinner_jCIR spinner_Rp9l"
|
||||
x="15.4"
|
||||
y="6"
|
||||
width="2.8"
|
||||
height="12"
|
||||
id="rect10"
|
||||
style="fill:#ffffff" />
|
||||
<rect
|
||||
class="spinner_jCIR spinner_dy3W"
|
||||
x="20.2"
|
||||
y="6"
|
||||
width="2.8"
|
||||
height="12"
|
||||
id="rect12"
|
||||
style="fill:#ffffff" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.2 KiB |
21
wap/mac-check/src/public/css/style.css
Normal file
21
wap/mac-check/src/public/css/style.css
Normal file
@@ -0,0 +1,21 @@
|
||||
html, body {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
border: none;
|
||||
background-color: #181a1b;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.box {
|
||||
display: block;
|
||||
width: 300px;
|
||||
margin-top: 200px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
text-align: center;
|
||||
}
|
||||
.box * {
|
||||
display: block;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}/*# sourceMappingURL=style.css.map */
|
||||
1
wap/mac-check/src/public/css/style.css.map
Normal file
1
wap/mac-check/src/public/css/style.css.map
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"sources":["style.scss","style.css"],"names":[],"mappings":"AAAA;EACI,UAAA;EACA,SAAA;EACA,YAAA;EACA,yBAAA;EACA,YAAA;ACCJ;;ADEA;EACI,cAAA;EACA,YAAA;EACA,iBAAA;EACA,iBAAA;EACA,kBAAA;EACA,kBAAA;ACCJ;ADAI;EACI,cAAA;EACA,iBAAA;EACA,kBAAA;ACER","file":"style.css"}
|
||||
21
wap/mac-check/src/public/css/style.scss
Normal file
21
wap/mac-check/src/public/css/style.scss
Normal file
@@ -0,0 +1,21 @@
|
||||
html, body {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
border: none;
|
||||
background-color: #181a1b;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.box {
|
||||
display: block;
|
||||
width: 300px;
|
||||
margin-top: 200px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
text-align: center;
|
||||
* {
|
||||
display: block;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
}
|
||||
77
wap/mac-check/src/public/index.html
Normal file
77
wap/mac-check/src/public/index.html
Normal file
@@ -0,0 +1,77 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Document</title>
|
||||
<link rel="stylesheet" href="/css/style.css">
|
||||
<script src="/js/hash.js"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="box">
|
||||
<p class="manufacturer">Please write first half of a mac address</p>
|
||||
<input type="text" autocomplete="off" maxlength="17" pattern="[a-fA-F0-9-]+" oninput="macformat(this);"
|
||||
required>
|
||||
</div>
|
||||
</body>
|
||||
<script>
|
||||
const secret = "1234567";
|
||||
|
||||
function macformat(input) {
|
||||
str = input.value.toUpperCase();
|
||||
allowed = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F", ":"];
|
||||
newstr = "";
|
||||
for (var i = 0; i < str.length; i++) {
|
||||
if (allowed.includes(str.charAt(i))) {
|
||||
if ((i + 1) % 3) {
|
||||
newstr = newstr + str.charAt(i).replace(':', '');
|
||||
} else {
|
||||
newstr = newstr + ":";
|
||||
newstr = newstr + str.charAt(i).replace(':', '');
|
||||
}
|
||||
}
|
||||
}
|
||||
input.value = newstr;
|
||||
if (newstr.length < 8) {
|
||||
document.getElementsByClassName("manufacturer")[0].innerHTML = "Please write first half of a mac address";
|
||||
} else if (newstr.length == 8) {
|
||||
updateOrg(input, newstr.replaceAll(':', ''));
|
||||
}
|
||||
}
|
||||
|
||||
function updateOrg(input, macrange) {
|
||||
man = document.getElementsByClassName("manufacturer")[0];
|
||||
man.innerHTML = '<img src="bars-scale-light.svg" alt="">';
|
||||
fetch('/api/range/' + macrange)
|
||||
.then(
|
||||
response => response.json()
|
||||
).then(jsonResponse => {
|
||||
console.log(jsonResponse);
|
||||
|
||||
if (jsonResponse.code == 404) {
|
||||
man.innerHTML = 'Unknown';
|
||||
} else if (jsonResponse.code == 200) {
|
||||
|
||||
man.innerHTML = jsonResponse.result.organization;
|
||||
|
||||
// Hash check not working, idk why
|
||||
// sha256(jsonResponse.result + secret).then(value => {
|
||||
// console.log(value);
|
||||
// if (value == jsonResponse.hash) {
|
||||
// man.innerHTML = jsonResponse.result.organization;
|
||||
// }else {
|
||||
// man.innerHTML = 'Insecure';
|
||||
// }
|
||||
// })
|
||||
|
||||
} else {
|
||||
man.innerHTML = 'Error';
|
||||
}
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
</html>
|
||||
38
wap/mac-check/src/public/js/hash.js
Normal file
38
wap/mac-check/src/public/js/hash.js
Normal file
@@ -0,0 +1,38 @@
|
||||
module.exports = sha256
|
||||
module.exports.sync = sha256sync
|
||||
|
||||
const crypto = globalThis.crypto || globalThis.msCrypto
|
||||
const subtle = crypto.subtle || crypto.webkitSubtle
|
||||
|
||||
function sha256sync (buf) {
|
||||
throw new Error('No support for sha256.sync() in the browser, use sha256()')
|
||||
}
|
||||
|
||||
async function sha256 (buf) {
|
||||
if (typeof buf === 'string') buf = strToBuf(buf)
|
||||
|
||||
// Browsers throw if they lack support for an algorithm.
|
||||
// Promise will be rejected on non-secure origins. (http://goo.gl/lq4gCo)
|
||||
const hash = subtle.digest({ name: 'sha-256' }, buf)
|
||||
return hex(new Uint8Array(hash))
|
||||
}
|
||||
|
||||
function strToBuf (str) {
|
||||
const len = str.length
|
||||
const buf = new Uint8Array(len)
|
||||
for (let i = 0; i < len; i++) {
|
||||
buf[i] = str.charCodeAt(i)
|
||||
}
|
||||
return buf
|
||||
}
|
||||
|
||||
function hex (buf) {
|
||||
const len = buf.length
|
||||
const chars = []
|
||||
for (let i = 0; i < len; i++) {
|
||||
const byte = buf[i]
|
||||
chars.push((byte >>> 4).toString(16))
|
||||
chars.push((byte & 0x0f).toString(16))
|
||||
}
|
||||
return chars.join('')
|
||||
}
|
||||
Reference in New Issue
Block a user