Skip to content

Commit

Permalink
Initial Commit
Browse files Browse the repository at this point in the history
  • Loading branch information
mkg20001 committed Jun 18, 2017
0 parents commit 983afb7
Show file tree
Hide file tree
Showing 8 changed files with 316 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
*.pem
node_modules
27 changes: 27 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# ZeroNet JS
A JS version of ZeroNet

What works:
Well, nothing at the moment

WIP:
- The protocol

ToDo:
- Everything else

# Running
Just run `client.js` and it should connect to localhost:15411 and get the content.json of HelloZeroNet (that's all it does for now)

# Certificate
That will be useful later
```
openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -nodes -config cert.conf << .
.
```
80 changes: 80 additions & 0 deletions cert.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
[ req ]
default_bits = 2048
default_keyfile = server-key.pem
distinguished_name = subject
req_extensions = req_ext
x509_extensions = x509_ext
string_mask = utf8only

# The Subject DN can be formed using X501 or RFC 4514 (see RFC 4519 for a description).
# Its sort of a mashup. For example, RFC 4514 does not provide emailAddress.
[ subject ]
countryName = Country Name (2 letter code)
countryName_default = US

stateOrProvinceName = State or Province Name (full name)
stateOrProvinceName_default = NY

localityName = Locality Name (eg, city)
localityName_default = New York

organizationName = Organization Name (eg, company)
organizationName_default = Example, LLC

# Use a friendly name here because its presented to the user. The server's DNS
# names are placed in Subject Alternate Names. Plus, DNS names here is deprecated
# by both IETF and CA/Browser Forums. If you place a DNS name here, then you
# must include the DNS name in the SAN too (otherwise, Chrome and others that
# strictly follow the CA/Browser Baseline Requirements will fail).
commonName = Common Name (e.g. server FQDN or YOUR name)
commonName_default = Example Company

emailAddress = Email Address
emailAddress_default = test@example.com

# Section x509_ext is used when generating a self-signed certificate. I.e., openssl req -x509 ...
[ x509_ext ]

subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer

# You only need digitalSignature below. *If* you don't allow
# RSA Key transport (i.e., you use ephemeral cipher suites), then
# omit keyEncipherment because that's key transport.
basicConstraints = CA:FALSE
keyUsage = digitalSignature, keyEncipherment
subjectAltName = @alternate_names
nsComment = "OpenSSL Generated Certificate"

# RFC 5280, Section 4.2.1.12 makes EKU optional
# CA/Browser Baseline Requirements, Appendix (B)(3)(G) makes me confused
# In either case, you probably only need serverAuth.
# extendedKeyUsage = serverAuth, clientAuth

# Section req_ext is used when generating a certificate signing request. I.e., openssl req ...
[ req_ext ]

subjectKeyIdentifier = hash

basicConstraints = CA:FALSE
keyUsage = digitalSignature, keyEncipherment
subjectAltName = @alternate_names
nsComment = "OpenSSL Generated Certificate"

# RFC 5280, Section 4.2.1.12 makes EKU optional
# CA/Browser Baseline Requirements, Appendix (B)(3)(G) makes me confused
# In either case, you probably only need serverAuth.
# extendedKeyUsage = serverAuth, clientAuth

[ alternate_names ]

DNS.1 = localhost

# Add these if you need them. But usually you don't want them or
# need them in production. You may need them for development.
# DNS.5 = localhost
# DNS.6 = localhost.localdomain
# DNS.7 = 127.0.0.1

# IPv6 localhost
# DNS.8 = ::1
14 changes: 14 additions & 0 deletions client.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
const net = require('net')

const msgpack = require("msgpack")

const Protocol = require("./lib/protocol/")

const sock = net.connect({
host: "localhost",
port: 15441
}, err => {
if (err) console.error(err)
const client = new Protocol(sock)
client.getFile("1HeLLo4uzjaLetFx6NH3PMwFP3qbRbTf3D", "content.json", 100, console.log)
})
23 changes: 23 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
const tls = require('tls')
const net = require('net')

const msgpack = require("msgpack")

//new tls.TLSSocket()
const sock = net.connect({
host: "localhost",
port: 15441
}, err => {
if (err) console.error(err)
const s = new msgpack.Stream(sock)
s.on("msg", console.log)
sock.write(msgpack.pack({
"cmd": "getFile",
"req_id": 1,
"params": {
"site": "1HeLLo4uzjaLetFx6NH3PMwFP3qbRbTf3D",
"inner_path": "content.json",
"location": 0
}
}))
})
130 changes: 130 additions & 0 deletions lib/protocol/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
"use strict"

const msgpack = require("msgpack")

module.exports = function Protocol(stream) {
//Turns a stream into a zeronet protocol client
const msg = new msgpack.Stream(stream)
const self = this
let req_id = 0 //req_id
let cbs = {}

const buffer_size = 1024 * 512 //aka 512kb

function write(data) {
stream.write(msgpack.pack(data))
}

function request(cmd, params, cb) {
req_id++
cbs[req_id] = cb
write({
cmd,
params,
req_id
})
}

msg.on("msg", data => {
if (data.to) {
if (cbs[data.to]) {
cbs[data.to](data)
delete cbs[data.to]
}
} else if (data.cmd) {
console.log("got %s", data.cmd, data)
msg.emit(data.cmd, data)
}
})

function validate(def, param) {
//validate if "param" matches "def"
for (var p in def) {
switch (typeof def[p]) {
case "function":
if (!def[p](param[p])) throw new Error("Invalid value for key " + p + " (validation function)")
break;
case "string":
if (typeof param[p] != def[p]) throw new Error("Invalid value for key " + p + " (typeof)")
break;
}
}
}

function createProtocolFunction(name, params, ret) {
//name=the command
//params=the parameters with which to be called (object key => type/value/validation function)
//return=the parameters that we get as a response (object key => type/value/validation function)
const fnc = function PeerRequest() {
const a = [].slice.call(arguments, 0) //turn "arguments" into array
let i = 0
const reqData = {} //req data as object
Object.keys(params).forEach(key => {
reqData[key] = a[i]
i++
})

const cb = a[i] //final callback
if (typeof cb != "function") throw new Error("CB must be a function")

try {
validate(params, reqData)
request(name, reqData, data => {
if (data.error) {
let e = new Error(data.error)
e.raw = data.error
e.stack = "Error: " + data.error + "\n at PeerReqest(" + name + ")" + "\n at ZeroNet Protocol"
return cb(e)
} else {
const respData = {}
const cba = [null] //array as argument for cb, first is err
Object.keys(ret).forEach(key => {
respData[key] = data[key]
cba.push(data[key])
})
validate(ret, respData)
return cb.apply(data, cba) //and call the callback
}
})
} catch (e) {
return cb(e)
}
}
self[name] = fnc
}

//Peer requests (see: https://zeronet.readthedocs.io/en/latest/help_zeronet/network_protocol/)

createProtocolFunction("getFile", {
site: "string",
inner_path: "string",
location: "number"
}, {
body: Buffer,
location: "number",
size: "number"
})

createProtocolFunction("ping", {}, {
body: b => b == "pong"
})

createProtocolFunction("pex", {
site: "string",
peers: "string",
need: "number"
}, {
peers: "string"
})

createProtocolFunction("update", {
site: "string",
inner_path: "string",
body: "object"
}, {
ok: "string"
})

//self.registerHandler=(handler) => msg.on("")

}
17 changes: 17 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

23 changes: 23 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"name": "zeronet",
"version": "0.0.1",
"description": "ZeroNet JS",
"main": "index.js",
"directories": {
"lib": "lib"
},
"dependencies": {
"msgpack": "^1.0.2"
},
"devDependencies": {},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [
"zeronet",
"js",
"p2p"
],
"author": "Maciej Krüger <mkg20001@gmail.com>",
"license": "GPL-3.0"
}

0 comments on commit 983afb7

Please sign in to comment.