+++ /dev/null
-include $(TOPDIR)/rules.mk
-
-PKG_NAME:=cjdns-master
-PKG_VERSION:=2014-10-25-e2b673698e471dbc82b4e9dbc04cb9e16f1f06a6
-PKG_RELEASE:=4
-
-PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
-PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
-PKG_SOURCE_URL:=https://github.com/cjdelisle/cjdns.git
-PKG_SOURCE_PROTO:=git
-PKG_SOURCE_VERSION:=e2b673698e471dbc82b4e9dbc04cb9e16f1f06a6
-PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)
-PKG_BUILD_DEPENDS:=libssp
-
-include $(INCLUDE_DIR)/package.mk
-
-define Package/cjdns-master
- SECTION:=net
- CATEGORY:=Network
- SUBMENU:=Routing and Redirection
- TITLE:=Experimental self configuring routing protocol.
- DEPENDS:=+kmod-tun +kmod-ipv6 +libnl +libpthread +librt +@SSP_SUPPORT +libssp
-endef
-
-define Package/cjdns-master/description
- Cjdns is a networking protocol, a system of digital rules for
- message exchange between computers. The philosophy behind cjdns
- is that networks should be easy to set up, protocols should
- scale up smoothly and security should be ubiquitous.
-endef
-
-define Build/Configure
-endef
-
-## NEON
-#define Build/Compile
-# CROSS="true" \
-# CFLAGS="-O2 -march=armv7-a -mtune=cortex-a8 -mfpu=neon -ftree-vectorize -ffast-math -mfloat-abi=hard -marm -Wno-error=maybe-uninitialized" \
-# NO_PIE="true" \
-# Seccomp_NO="true" \
-# CC="$(TARGET_CC)" \
-# ARCH="$(ARCH)" \
-# LDFLAGS="$(CFLAGS) -lssp" \
-# $(PKG_BUILD_DIR)/do
-#endef
-
-# regular
-define Build/Compile
- CROSS="true" \
- CFLAGS="$(TARGET_CFLAGS)" \
- NO_PIE="true" \
- Seccomp_NO="true" \
- CC="$(TARGET_CC)" \
- ARCH="$(ARCH)" \
- LDFLAGS="$(TARGET_LDFLAGS) -lssp" \
- $(PKG_BUILD_DIR)/do
-endef
-
-define Package/cjdns-master/install
- $(INSTALL_DIR) $(1)/usr/sbin
- $(INSTALL_BIN) $(PKG_BUILD_DIR)/cjdroute $(1)/usr/sbin/cjdroute
- $(INSTALL_BIN) $(PKG_BUILD_DIR)/cjdroute $(1)/usr/sbin/cjdroute.master
- $(INSTALL_BIN) $(PKG_BUILD_DIR)/privatetopublic $(1)/usr/sbin/
- $(INSTALL_BIN) $(PKG_BUILD_DIR)/publictoip6 $(1)/usr/sbin/
-
- $(INSTALL_DIR) $(1)/usr/lib/python2.7
- cp -rv $(PKG_BUILD_DIR)/contrib/python/cjdnsadmin $(1)/usr/lib/python2.7/
-
- $(INSTALL_DIR) $(1)/usr/bin
- $(INSTALL_BIN) $(PKG_BUILD_DIR)/contrib/python/cexec $(1)/usr/bin/
- $(INSTALL_BIN) $(PKG_BUILD_DIR)/contrib/python/cjdnsa $(1)/usr/bin/
- $(INSTALL_BIN) $(PKG_BUILD_DIR)/contrib/python/cjdnslog $(1)/usr/bin/
- $(INSTALL_BIN) $(PKG_BUILD_DIR)/contrib/python/dumptable $(1)/usr/bin/
- $(INSTALL_BIN) $(PKG_BUILD_DIR)/contrib/python/findnodes $(1)/usr/bin/
- $(INSTALL_BIN) $(PKG_BUILD_DIR)/contrib/python/ip6topk $(1)/usr/bin/
- $(INSTALL_BIN) $(PKG_BUILD_DIR)/contrib/python/peerStats $(1)/usr/bin/
- $(INSTALL_BIN) $(PKG_BUILD_DIR)/contrib/python/pingAll.py $(1)/usr/bin/
- $(INSTALL_BIN) $(PKG_BUILD_DIR)/contrib/python/pktoip6 $(1)/usr/bin/
- $(INSTALL_BIN) $(PKG_BUILD_DIR)/contrib/python/sessionStats $(1)/usr/bin/
- $(INSTALL_BIN) $(PKG_BUILD_DIR)/contrib/python/trashroutes $(1)/usr/bin/
-
- $(INSTALL_DIR) $(1)/etc/init.d
- $(INSTALL_BIN) ./files/cjdns.init $(1)/etc/init.d/cjdns
-endef
-
-$(eval $(call BuildPackage,cjdns-master))
+++ /dev/null
-#!/bin/sh /etc/rc.common
-# cjdns
-
-START=93
-STOP=07
-EXTRA_COMMANDS="status"
-
-start() {
- ( /usr/sbin/cjdroute < /box/cjdroute.conf &> /dev/null ) &
-}
-
-stop() {
- killall cjdroute
-}
-
-status() {
- if [[ $(ps | grep cjdroute | wc -l) -gt 1 ]]; then
- echo running
- else
- echo stopped
- fi
-}
-
-restart() {
- stop
- start
-}
-
+++ /dev/null
-diff --git a/node_build/dependencies/libuv/gyp_uv.py b/node_build/dependencies/libuv/gyp_uv.py
-index 4ba6916..d9f871b 100755
---- a/node_build/dependencies/libuv/gyp_uv.py
-+++ b/node_build/dependencies/libuv/gyp_uv.py
-@@ -20,7 +20,7 @@ except ImportError:
-
-
- def host_arch():
-- machine = platform.machine()
-+ machine = os.environ.get('ARCH', platform.machine())
- if machine == 'i386': return 'ia32'
- if machine == 'x86_64': return 'x64'
- if machine.startswith('arm'): return 'arm'
+++ /dev/null
-diff --git a/node_build/make.js b/node_build/make.js
-index 522c185..9bd81d5 100644
---- a/node_build/make.js
-+++ b/node_build/make.js
-@@ -297,6 +297,8 @@ Builder.configure({
- 'BUILDTYPE=Release',
- 'CC=' + builder.config.gcc,
- 'CXX=' + builder.config.gcc,
-+ 'LINK=' + builder.config.gcc,
-+ 'LDFLAGS=' + builder.config.ldflags,
- 'V=1'
- ];
-
+++ /dev/null
-include $(TOPDIR)/rules.mk
-
-PKG_NAME:=cjdns-v6
-PKG_VERSION:=2015-02-02-1d51ddc5d036244c5eb231d635e649bb5d325445
-PKG_RELEASE:=3
-
-PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
-PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
-PKG_SOURCE_URL:=https://github.com/cjdelisle/cjdns.git
-PKG_SOURCE_PROTO:=git
-PKG_SOURCE_VERSION:=1d51ddc5d036244c5eb231d635e649bb5d325445
-PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)
-PKG_BUILD_DEPENDS:=libssp
-
-include $(INCLUDE_DIR)/package.mk
-
-define Package/cjdns-v6
- SECTION:=net
- CATEGORY:=Network
- SUBMENU:=Routing and Redirection
- TITLE:=Experimental self configuring routing protocol.
- DEPENDS:=+kmod-tun +kmod-ipv6 +libnl +libpthread +librt +@SSP_SUPPORT +libssp
-endef
-
-define Package/cjdns-v6/description
- Cjdns is a networking protocol, a system of digital rules for
- message exchange between computers. The philosophy behind cjdns
- is that networks should be easy to set up, protocols should
- scale up smoothly and security should be ubiquitous.
-endef
-
-define Build/Configure
-endef
-
-## NEON
-#define Build/Compile
-# CROSS="true" \
-# CFLAGS="-O2 -march=armv7-a -mtune=cortex-a8 -mfpu=neon -ftree-vectorize -ffast-math -mfloat-abi=hard -marm -Wno-error=maybe-uninitialized" \
-# NO_PIE="true" \
-# Seccomp_NO="true" \
-# CC="$(TARGET_CC)" \
-# ARCH="$(ARCH)" \
-# LDFLAGS="$(CFLAGS) -lssp" \
-# $(PKG_BUILD_DIR)/do
-#endef
-
-# regular
-define Build/Compile
- CROSS="true" \
- CFLAGS="$(TARGET_CFLAGS) -Wno-error=maybe-uninitialized" \
- NO_PIE="true" \
- Seccomp_NO="true" \
- CC="$(TARGET_CC)" \
- ARCH="$(ARCH)" \
- LDFLAGS="$(TARGET_LDFLAGS) -lssp" \
- LINK="$(TARGET_CC)" \
- $(PKG_BUILD_DIR)/do
-endef
-
-define Package/cjdns-v6/install
- $(INSTALL_DIR) $(1)/usr/sbin
- $(INSTALL_BIN) $(PKG_BUILD_DIR)/cjdroute $(1)/usr/sbin/cjdroute.v6
-endef
-
-$(eval $(call BuildPackage,cjdns-v6))
+++ /dev/null
-diff --git a/node_build/dependencies/libuv/gyp_uv.py b/node_build/dependencies/libuv/gyp_uv.py
-index 4ba6916..d9f871b 100755
---- a/node_build/dependencies/libuv/gyp_uv.py
-+++ b/node_build/dependencies/libuv/gyp_uv.py
-@@ -20,7 +20,7 @@ except ImportError:
-
-
- def host_arch():
-- machine = platform.machine()
-+ machine = os.environ.get('ARCH', platform.machine())
- if machine == 'i386': return 'ia32'
- if machine == 'x86_64': return 'x64'
- if machine.startswith('arm'): return 'arm'
--- /dev/null
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=cjdns
+PKG_VERSION:=0.16
+PKG_RELEASE:=9
+
+PKG_SOURCE_URL:=https://github.com/cjdelisle/cjdns.git
+PKG_SOURCE_PROTO:=git
+PKG_SOURCE_VERSION:=2138a1f6a94fc009958cde7b002c077a1eee929a
+PKG_LICENSE:=GPL-3.0
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_SOURCE_VERSION).tar.bz2
+PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_SOURCE_VERSION)
+PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_SOURCE_VERSION)
+
+include $(INCLUDE_DIR)/package.mk
+
+
+define Package/cjdns
+ SECTION:=net
+ CATEGORY:=Network
+ SUBMENU:=Routing and Redirection
+ TITLE:=Encrypted near-zero-conf mesh routing protocol
+ URL:=https://github.com/hyperboria/cjdns
+ MAINTAINER:=Lars Gierth <larsg@systemli.org>
+ DEPENDS:=+kmod-tun +kmod-ipv6 +libnl-tiny +libpthread +librt \
+ +libuci-lua +lua-bencode +dkjson +luasocket +lua-sha2
+endef
+
+define Package/cjdns/description
+ Cjdns implements an encrypted IPv6 network using public-key cryptography \
+ for address allocation and a distributed hash table for routing. \
+ This provides near-zero-configuration networking, and prevents many \
+ of the security and scalability issues that plague existing networks.
+endef
+
+define Build/Configure
+endef
+
+ifneq ($(CONFIG_KERNEL_SECCOMP_FILTER),y)
+PKG_DO_VARS:=Seccomp_NO=1
+endif
+
+define Build/Compile
+ CROSS="true" \
+ CC="$(TARGET_CC)" \
+ CFLAGS="$(TARGET_CFLAGS)" \
+ LDFLAGS="$(TARGET_LDFLAGS)" \
+ SYSTEM="linux" \
+ TARGET_ARCH="$(CONFIG_ARCH)" \
+ UCLIBC=1 \
+ SSP_SUPPORT="$(CONFIG_SSP_SUPPORT)" \
+ $(PKG_DO_VARS) \
+ $(PKG_BUILD_DIR)/do
+endef
+
+define Package/cjdns/install
+ $(INSTALL_DIR) \
+ $(1)/usr/sbin \
+ $(1)/usr/bin \
+ $(1)/etc/config \
+ $(1)/etc/init.d \
+ $(1)/etc/uci-defaults \
+ $(1)/usr/lib/lua/cjdns
+
+ $(INSTALL_BIN) \
+ ./files/cjdrouteconf \
+ $(1)/usr/bin
+
+ $(INSTALL_BIN) \
+ $(PKG_BUILD_DIR)/cjdroute \
+ $(1)/usr/sbin
+
+ $(INSTALL_BIN) \
+ $(PKG_BUILD_DIR)/publictoip6 \
+ $(1)/usr/bin
+
+ $(INSTALL_BIN) \
+ ./files/cjdns.init \
+ $(1)/etc/init.d/cjdns
+
+ $(INSTALL_BIN) \
+ ./files/cjdns.defaults \
+ $(1)/etc/uci-defaults/cjdns
+
+ $(CP) \
+ ./lua/cjdns/* \
+ $(1)/usr/lib/lua/cjdns
+endef
+
+define Package/cjdns/postinst
+#!/bin/sh
+if [ -z $${IPKG_INSTROOT} ] ; then
+ ( . /etc/uci-defaults/cjdns ) && rm -f /etc/uci-defaults/cjdns
+ # TODO: we should have an 'Enable' button instead
+ /etc/init.d/cjdns enabled || /etc/init.d/cjdns enable
+ exit 0
+fi
+endef
+
+$(eval $(call BuildPackage,cjdns))
--- /dev/null
+#!/bin/sh
+
+# if there is an existing config, our work is already done
+uci get cjdns.cjdns.ipv6 >/dev/null 2>&1
+if [ $? -ne 0 ]; then
+
+ # register commit handler
+ uci -q batch <<-EOF >/dev/null
+ delete ucitrack.@cjdns[-1]
+ add ucitrack cjdns
+ set ucitrack.@cjdns[-1].init=cjdns
+ commit ucitrack
+EOF
+
+ # generate configuration
+ touch /etc/config/cjdns
+ cjdroute --genconf | cjdroute --cleanconf | cjdrouteconf set
+
+ # make sure config is present (might fail for any reason)
+ uci get cjdns.cjdns.ipv6 >/dev/null 2>&1
+ if [ $? -ne 0]; then
+ exit 1
+ fi
+
+ # enable auto-peering on ethernet
+ uci show network.lan | grep type=bridge >/dev/null 2>&1
+ if [ $? -eq 0 ]; then
+ # most routers will set up an ethernet bridge for the lan
+ ifname="br-lan"
+ else
+ # docker containers don't have permission to create bridges by default,
+ # so we bind to the underlying interface instead (likely eth0)
+ ifname=`uci get network.lan.ifname`
+ fi
+ uci -q batch <<-EOF >/dev/null
+ add cjdns eth_interface
+ set cjdns.@eth_interface[-1].beacon=2
+ set cjdns.@eth_interface[-1].bind=$ifname
+EOF
+
+ # set the tun interface name
+ uci set cjdns.cjdns.tun_device=tuncjdns
+
+ # create the network interface
+ uci -q batch <<-EOF >/dev/null
+ set network.cjdns=interface
+ set network.cjdns.ifname=tuncjdns
+ set network.cjdns.proto=none
+EOF
+
+ # firewall rules by @dangowrt -- thanks <3
+
+ # create the firewall zone
+ uci -q batch <<-EOF >/dev/null
+ add firewall zone
+ set firewall.@zone[-1].name=cjdns
+ add_list firewall.@zone[-1].network=cjdns
+ set firewall.@zone[-1].input=REJECT
+ set firewall.@zone[-1].output=ACCEPT
+ set firewall.@zone[-1].forward=REJECT
+ set firewall.@zone[-1].conntrack=1
+ set firewall.@zone[-1].family=ipv6
+EOF
+
+ # allow ICMP from cjdns zone, e.g. ping6
+ uci -q batch <<-EOF >/dev/null
+ add firewall rule
+ set firewall.@rule[-1].name='Allow-ICMPv6-cjdns'
+ set firewall.@rule[-1].src=cjdns
+ set firewall.@rule[-1].proto=icmp
+ add_list firewall.@rule[-1].icmp_type=echo-request
+ add_list firewall.@rule[-1].icmp_type=echo-reply
+ add_list firewall.@rule[-1].icmp_type=destination-unreachable
+ add_list firewall.@rule[-1].icmp_type=packet-too-big
+ add_list firewall.@rule[-1].icmp_type=time-exceeded
+ add_list firewall.@rule[-1].icmp_type=bad-header
+ add_list firewall.@rule[-1].icmp_type=unknown-header-type
+ set firewall.@rule[-1].limit='1000/sec'
+ set firewall.@rule[-1].family=ipv6
+ set firewall.@rule[-1].target=ACCEPT
+EOF
+
+ # allow SSH from cjdns zone, needs to be explicitly enabled
+ uci -q batch <<-EOF >/dev/null
+ add firewall rule
+ set firewall.@rule[-1].enabled=0
+ set firewall.@rule[-1].name='Allow-SSH-cjdns'
+ set firewall.@rule[-1].src=cjdns
+ set firewall.@rule[-1].proto=tcp
+ set firewall.@rule[-1].dest_port=22
+ set firewall.@rule[-1].target=ACCEPT
+EOF
+
+ # allow LuCI access from cjdns zone, needs to be explicitly enabled
+ uci -q batch <<-EOF >/dev/null
+ add firewall rule
+ set firewall.@rule[-1].enabled=0
+ set firewall.@rule[-1].name='Allow-HTTP-cjdns'
+ set firewall.@rule[-1].src=cjdns
+ set firewall.@rule[-1].proto=tcp
+ set firewall.@rule[-1].dest_port=80
+ set firewall.@rule[-1].target=ACCEPT
+EOF
+
+ # allow UDP peering from wan zone, if it exists
+ uci show network.wan >/dev/null 2>&1
+ if [ $? -eq 0 ]; then
+ peeringPort=`uci get cjdns.@udp_interface[0].port`
+ uci -q batch <<-EOF >/dev/null
+ add firewall rule
+ set firewall.@rule[-1].name='Allow-cjdns-wan'
+ set firewall.@rule[-1].src=wan
+ set firewall.@rule[-1].proto=udp
+ set firewall.@rule[-1].dest_port=$peeringPort
+ set firewall.@rule[-1].target=ACCEPT
+EOF
+ fi
+
+ uci commit cjdns
+ uci commit firewall
+ uci commit network
+
+fi
+
+exit 0
--- /dev/null
+#!/bin/sh /etc/rc.common
+
+START=90
+STOP=85
+
+USE_PROCD=1
+
+start_service()
+{
+ [ -f /etc/uci-defaults/cjdns ] && ( . /etc/uci-defaults/cjdns )
+
+ procd_open_instance
+ procd_set_param respawn
+ procd_set_param command /bin/ash -c "cjdrouteconf get | tee /tmp/etc/cjdroute.conf | cjdroute --nobg | logger -t cjdns"
+ procd_close_instance
+}
+
+stop_service()
+{
+ killall cjdroute
+}
+
+reload_service()
+{
+ # cat /tmp/etc/cjdroute.conf | cjdrouteconf reload
+ restart
+}
+
+service_triggers()
+{
+ procd_add_reload_trigger cjdns
+}
--- /dev/null
+#!/usr/bin/env lua
+
+dkjson = require("dkjson")
+cjdns = require("cjdns")
+require("cjdns/uci")
+
+function help()
+ print("JSON interface to /etc/config/cjdns\n\nExamples: \
+ cjdrouteconf get > /tmp/etc/cjdroute.conf \
+ cat /tmp/etc/cjdroute.conf | cjdrouteconf set \
+ uci changes \
+ cjdrouteconf get | cjdroute")
+end
+
+if arg[1] == "get" then
+ local json = dkjson.encode(cjdns.uci.get(), { indent = true })
+ print(json)
+elseif arg[1] == "set" then
+ local json = io.stdin:read("*a")
+ local obj, pos, err = dkjson.decode(json, 1, nil)
+
+ if obj then
+ cjdns.uci.set(obj)
+ else
+ print("dkjson: " .. err .. " (try cjdroute --cleanconf)")
+ os.exit(1)
+ end
+else
+ help()
+end
--- /dev/null
+-- Cjdns admin module for Lua
+-- Written by Philip Horger
+
+common = require 'cjdns/common'
+
+AdminInterface = {}
+AdminInterface.__index = AdminInterface
+common.AdminInterface = AdminInterface
+
+function AdminInterface.new(properties)
+ properties = properties or {}
+
+ properties.host = properties.host or "127.0.0.1"
+ properties.port = properties.port or 11234
+ properties.password = properties.password or nil
+ properties.config = properties.config or common.ConfigFile.new("/etc/cjdroute.conf", false)
+ properties.timeout = properties.timeout or 2
+
+ properties.udp = common.UDPInterface.new(properties)
+
+ return setmetatable(properties, AdminInterface)
+end
+
+function AdminInterface:send(object)
+ local bencoded, err = bencode.encode(object)
+ if err then
+ return nil, err
+ end
+
+ local sock_obj = assert(socket.udp())
+ sock_obj:settimeout(self.timeout)
+
+ local _, err = sock_obj:sendto(bencoded, self.host, self.port)
+ if err then
+ return nil, err
+ end
+
+ return sock_obj
+end
+
+function AdminInterface:recv(sock_obj)
+ local retrieved, err = sock_obj:receive()
+ if not retrieved then
+ return nil, "ai:recv > " .. err
+ end
+ local bencoded, err = bencode.decode(retrieved)
+ if bencoded then
+ return bencoded
+ else
+ return nil, "ai:recv > " .. err
+ end
+end
+
+function AdminInterface:call(request)
+ local sock_obj, err = self:send(request)
+ if err then
+ return nil, "ai:call > " .. err
+ end
+
+ return self:recv(sock_obj)
+end
+
+function AdminInterface:getCookie()
+ local cookie_response, err = self:call({ q = "cookie" })
+ if not cookie_response then
+ return nil, "ai:getCookie > " .. err
+ end
+ return cookie_response.cookie
+end
+
+function AdminInterface:auth(request)
+ local funcname = request.q
+ local args = {}
+ for k, v in pairs(request) do
+ args[k] = v
+ end
+
+ -- Step 1: Get cookie
+ local cookie, err = self:getCookie()
+ if err then
+ return nil, err
+ end
+
+ -- Step 2: Calculate hash1 (password + cookie)
+ local plaintext1 = self.password .. cookie
+ local hash1 = sha2.sha256hex(plaintext1)
+
+ -- Step 3: Calculate hash2 (intermediate stage request)
+ local request = {
+ q = "auth",
+ aq = funcname,
+ args = args,
+ hash = hash1,
+ cookie = cookie
+ }
+ local plaintext2, err = bencode.encode(request)
+ if err then
+ return nil, err
+ end
+ local hash2 = sha2.sha256hex(plaintext2)
+
+ -- Step 4: Update hash in request, then ship it out
+ request.hash = hash2
+ return self:call(request)
+end
--- /dev/null
+-- Cjdns admin module for Lua
+-- Written by Philip Horger
+
+-- This table is preserved over multiple imports, and collects
+-- submodules import-by-import via init.lua.
+
+return {}
--- /dev/null
+-- Cjdns admin module for Lua
+-- Written by Philip Horger
+
+bencode = require "bencode" -- https://bitbucket.org/wilhelmy/lua-bencode/
+dkjson = require "dkjson" -- http://dkolf.de/src/dkjson-lua.fsl/home
+socket = require "socket" -- http://w3.impa.br/~diego/software/luasocket/
+sha2 = require "sha2" -- https://code.google.com/p/sha2/
+
+require "cjdns/admin"
+require "cjdns/udp"
+
+return require "cjdns/common"
--- /dev/null
+common = require("cjdns/common")
+uci = require("uci")
+
+UCI = {}
+common.uci = UCI
+
+--- Return the configuration defaults as a table suitable for JSON output
+--
+-- Mostly taken from cjdroute --genconf
+-- @return table with configuration defaults
+function UCI.defaults()
+ return {
+ security = { { exemptAngel = 1, setuser = "nobody" } },
+ router = {
+ ipTunnel = { outgoingConnections = {}, allowedConnections = {} },
+ interface = { type = "TUNInterface" }
+ },
+ interfaces = { UDPInterface = {}, ETHInterface = {} },
+ authorizedPasswords = {},
+ logging = { logTo = "stdout" }
+ }
+end
+
+--- Return the cjdns configuration as a table suitable for JSON output
+--
+-- Iterates over cjdns, eth_interface, udp_interface, eth_peer, udp_peer,
+-- and password sections. Doesn't include IPTunnel related options yet.
+-- @return table with cjdns configuration
+function UCI.get()
+ local obj = UCI.defaults()
+
+ local cursor = uci.cursor()
+
+ local config = cursor:get_all("cjdns", "cjdns")
+ if not config then return obj end
+
+ obj.ipv6 = config.ipv6
+ obj.publicKey = config.public_key
+ obj.privateKey = config.private_key
+ obj.admin = {
+ bind = config.admin_address .. ":" .. config.admin_port,
+ password = config.admin_password }
+
+ if config.tun_device and string.len(config.tun_device) > 0 then
+ obj.router.interface.tunDevice = config.tun_device
+ end
+
+ cursor:foreach("cjdns", "iptunnel_outgoing", function(outgoing)
+ table.insert(obj.router.ipTunnel.outgoingConnections, outgoing.public_key)
+ end)
+
+ cursor:foreach("cjdns", "iptunnel_allowed", function(allowed)
+ entry = { publicKey = allowed.public_key }
+ if allowed.ipv4 then
+ entry["ip4Address"] = allowed.ipv4
+ end
+ if allowed.ipv6 then
+ entry["ip6Address"] = allowed.ipv6
+ end
+ table.insert(obj.router.ipTunnel.allowedConnections, entry)
+ end)
+
+ cursor:foreach("cjdns", "eth_interface", function(eth_interface)
+ table.insert(obj.interfaces.ETHInterface, {
+ bind = eth_interface.bind,
+ beacon = tonumber(eth_interface.beacon),
+ connectTo = {}
+ })
+ end)
+
+ cursor:foreach("cjdns", "udp_interface", function(udp_interface)
+ table.insert(obj.interfaces.UDPInterface, {
+ bind = udp_interface.address .. ":" .. udp_interface.port,
+ connectTo = {}
+ })
+ end)
+
+ cursor:foreach("cjdns", "eth_peer", function(eth_peer)
+ if not eth_peer.address == "" then
+ local i = tonumber(eth_peer.interface)
+ obj.interfaces.ETHInterface[i].connectTo[eth_peer.address] = {
+ publicKey = eth_peer.public_key,
+ password = eth_peer.password
+ }
+ end
+ end)
+
+ cursor:foreach("cjdns", "udp_peer", function(udp_peer)
+ local bind = udp_peer.address .. ":" .. udp_peer.port
+ local i = tonumber(udp_peer.interface)
+ obj.interfaces.UDPInterface[i].connectTo[bind] = {
+ user = udp_peer.user,
+ publicKey = udp_peer.public_key,
+ password = udp_peer.password
+ }
+ end)
+
+ cursor:foreach("cjdns", "password", function(password)
+ table.insert(obj.authorizedPasswords, {
+ password = password.password,
+ user = password.user,
+ contact = password.contact
+ })
+ end)
+
+ return obj
+end
+
+--- Parse and save updated configuration from JSON input
+--
+-- Transforms general settings, ETHInterface, UDPInterface, connectTo, and
+-- authorizedPasswords fields into UCI sections, and replaces the UCI config's
+-- contents with them.
+-- @param table JSON input
+-- @return Boolean whether saving succeeded
+function UCI.set(obj)
+ local cursor = uci.cursor()
+
+ for i, section in pairs(cursor:get_all("cjdns")) do
+ cursor:delete("cjdns", section[".name"])
+ end
+
+ local admin_address, admin_port = string.match(obj.admin.bind, "^(.*):(.*)$")
+ UCI.cursor_section(cursor, "cjdns", "cjdns", "cjdns", {
+ ipv6 = obj.ipv6,
+ public_key = obj.publicKey,
+ private_key = obj.privateKey,
+ admin_password = obj.admin.password,
+ admin_address = admin_address,
+ admin_port = admin_port,
+ })
+
+ if obj.router.interface.tunDevice then
+ UCI.cursor_section(cursor, "cjdns", "cjdns", "cjdns", {
+ tun_device = tostring(obj.router.interface.tunDevice)
+ })
+ end
+
+ if obj.router.ipTunnel.outgoingConnections then
+ for i,public_key in pairs(obj.router.ipTunnel.outgoingConnections) do
+ UCI.cursor_section(cursor, "cjdns", "iptunnel_outgoing", nil, {
+ public_key = public_key
+ })
+ end
+ end
+
+ if obj.router.ipTunnel.allowedConnections then
+ for i,allowed in pairs(obj.router.ipTunnel.allowedConnections) do
+ entry = { public_key = allowed.publicKey }
+ if allowed.ip4Address then
+ entry["ipv4"] = allowed.ip4Address
+ end
+ if allowed.ip6Address then
+ entry["ipv6"] = allowed.ip6Address
+ end
+
+ UCI.cursor_section(cursor, "cjdns", "iptunnel_allowed", nil, entry)
+ end
+ end
+
+ if obj.interfaces.ETHInterface then
+ for i,interface in pairs(obj.interfaces.ETHInterface) do
+ UCI.cursor_section(cursor, "cjdns", "eth_interface", nil, {
+ bind = interface.bind,
+ beacon = tostring(interface.beacon)
+ })
+
+ if interface.connectTo then
+ for peer_address,peer in pairs(interface.connectTo) do
+ UCI.cursor_section(cursor, "cjdns", "eth_peer", nil, {
+ interface = i,
+ address = peer_address,
+ public_key = peer.publicKey,
+ password = peer.password
+ })
+ end
+ end
+ end
+ end
+
+ if obj.interfaces.UDPInterface then
+ for i,interface in pairs(obj.interfaces.UDPInterface) do
+ local address, port = string.match(interface.bind, "^(.*):(.*)$")
+ UCI.cursor_section(cursor, "cjdns", "udp_interface", nil, {
+ address = address,
+ port = port
+ })
+
+ if interface.connectTo then
+ for peer_bind,peer in pairs(interface.connectTo) do
+ local peer_address, peer_port = string.match(peer_bind, "^(.*):(.*)$")
+ UCI.cursor_section(cursor, "cjdns", "udp_peer", nil, {
+ interface = i,
+ address = peer_address,
+ port = peer_port,
+ user = peer.user,
+ public_key = peer.publicKey,
+ password = peer.password
+ })
+ end
+ end
+ end
+ end
+
+ if obj.authorizedPasswords then
+ for i,password in pairs(obj.authorizedPasswords) do
+ local user = password.user
+ if not user or string.len(user) == 0 then
+ user = "user-" .. UCI.random_string(6)
+ end
+
+ UCI.cursor_section(cursor, "cjdns", "password", nil, {
+ password = password.password,
+ user = user,
+ contact = password.contact
+ })
+ end
+ end
+
+ return cursor:save("cjdns")
+end
+
+--- Simple backport of Cursor:section from luci.model.uci
+--
+-- Backport reason: we don't wanna depend on LuCI.
+-- @param Cursor the UCI cursor to operate on
+-- @param string name of the config
+-- @param string type of the section
+-- @param string name of the section (optional)
+-- @param table config values
+function UCI.cursor_section(cursor, config, type, section, values)
+ if section then
+ cursor:set(config, section, type)
+ else
+ section = cursor:add("cjdns", type)
+ end
+
+ for k,v in pairs(values) do
+ cursor:set(config, section, k, v)
+ end
+end
+
+function UCI.makeInterface()
+ local cursor = uci.cursor()
+
+ local config = cursor:get_all("cjdns", "cjdns")
+ if not config then return nil end
+
+ return common.AdminInterface.new({
+ host = config.admin_address,
+ port = config.admin_port,
+ password = config.admin_password,
+ config = UCI.get(),
+ timeout = 2
+ })
+end
+
+function UCI.random_string(length)
+ -- tr -cd 'A-Za-z0-9' < /dev/urandom
+ local urandom = io.popen("tr -cd 'A-Za-z0-9' 2> /dev/null < /dev/urandom", "r")
+ local string = urandom:read(length)
+ urandom:close()
+ return string
+end
--- /dev/null
+-- Cjdns admin module for Lua
+-- Written by Philip Horger
+
+common = require 'cjdns/common'
+
+UDPInterface = {}
+UDPInterface.__index = UDPInterface
+common.UDPInterface = UDPInterface
+
+function UDPInterface.new(ai, config, ptype)
+ properties = {
+ ai = ai,
+ config = config or ai.config,
+ ptype = ptype or "ai"
+ }
+
+ return setmetatable(properties, UDPInterface)
+end
+
+function UDPInterface:call(name, args)
+ local func = self[name .. "_" .. self.ptype]
+ return func(self, unpack(args))
+end
+
+function UDPInterface:newBind(...)
+ return self:call("newBind", arg)
+end
+
+function UDPInterface:beginConnection(...)
+ return self:call("beginConnection", arg)
+end
+
+function UDPInterface:newBind_ai(address)
+ local response, err = self.ai:auth({
+ q = "UDPInterface_new",
+ bindAddress = address
+ })
+ if not response then
+ return nil, err
+ elseif response.error ~= "none" then
+ return nil, response.error
+ elseif response.interfaceNumber then
+ return response.interfaceNumber
+ else
+ return nil, "bad response format"
+ end
+end
+
+function UDPInterface:newBind_config(address)
+ local udpif = self.config.contents.interfaces.UDPInterface
+ local new_interface = {
+ bind = address,
+ connectTo = {}
+ }
+ table.insert(udpif, new_interface)
+ return (#udpif - 1), new_interface
+end
+
+function UDPInterface:newBind_perm(...)
+ return
+ self:newBind_config(unpack(arg)),
+ self:newBind_ai(unpack(arg))
+end
+
+function UDPInterface:beginConnection_ai(pubkey, addr, password, interface)
+ local request = {
+ q = "UDPInterface_beginConnection",
+ publicKey = pubkey,
+ address = addr,
+ password = password
+ }
+ if interface then
+ request.interfaceNumber = interface
+ end
+
+ local response, err = self.ai:auth(request)
+ if not response then
+ return nil, err
+ elseif response.error == "none" then
+ -- Unfortunately, no real success indicator either.
+ return "No error"
+ else
+ return nil, response.error
+ end
+end
+
+function UDPInterface:beginConnection_config(pubkey, addr, password, interface)
+ local udpif = self.config.contents.interfaces.UDPInterface
+ local connections = udpif[(interface or 0) + 1].connectTo
+ local this_conn = {
+ password = password,
+ publicKey = pubkey
+ }
+ connections[addr] = this_conn
+ return this_conn -- allows adding metadata fields afterwards
+end
+
+function UDPInterface:beginConnection_perm(...)
+ return
+ self:beginConnection_config(unpack(arg)),
+ self:beginConnection_ai(unpack(arg))
+end
--- /dev/null
+Index: cjdns-649e26c7d61ccc66c20e87e1e3d381f9ef0cfcb0/crypto/random/seed/LinuxRandomUuidSysctlRandomSeed.c
+===================================================================
+--- cjdns-649e26c7d61ccc66c20e87e1e3d381f9ef0cfcb0.orig/crypto/random/seed/LinuxRandomUuidSysctlRandomSeed.c
++++ cjdns-649e26c7d61ccc66c20e87e1e3d381f9ef0cfcb0/crypto/random/seed/LinuxRandomUuidSysctlRandomSeed.c
+@@ -18,6 +18,8 @@
+ #include "util/Hex.h"
+
+ #include <unistd.h>
++
++#ifdef __GLIBC__
+ #include <sys/sysctl.h>
+
+ static int getUUID(uint64_t output[2])
+@@ -42,6 +44,15 @@ static int get(struct RandomSeed* random
+ return 0;
+ }
+
++#else
++
++static int get(struct RandomSeed* randomSeed, uint64_t output[8])
++{
++ return -1;
++}
++
++#endif
++
+ struct RandomSeed* LinuxRandomUuidSysctlRandomSeed_new(struct Allocator* alloc)
+ {
+ return Allocator_clone(alloc, (&(struct RandomSeed) {
+++ /dev/null
-include $(TOPDIR)/rules.mk
-
-PKG_NAME:=owncloud
-PKG_VERSION:=8.0.0
-PKG_RELEASE:=2
-
-PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
-PKG_SOURCE_URL:=https://download.owncloud.org/community/
-PKG_MD5SUM:=d2c1366be0756c24e1f5cfc02f80269f
-PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)
-CC="$(TARGET_CC)"
-
-include $(INCLUDE_DIR)/package.mk
-
-define Package/owncloud
- SECTION:=admin
- CATEGORY:=Enigmabox
- TITLE:=ownCloud - self hosted cloud
- DEPENDS:=hypesites
- SUBMENU:=Hypesite apps
-endef
-
-define Package/owncloud/description
- Access your data from all your devices, on an open platform you can extend and modify.
-endef
-
-define Build/Configure
-endef
-
-define Build/Compile
-endef
-
-define Package/owncloud/install
- $(INSTALL_DIR) $(1)/www/htdocs/owncloud
- $(CP) -rv $(BUILD_DIR)/owncloud/* $(1)/www/htdocs/owncloud/
-
- # hypesite config
- $(INSTALL_DIR) $(1)/etc/lighttpd/hypesites.d
- $(INSTALL_DATA) ./files/owncloud.conf $(1)/etc/lighttpd/hypesites.d/owncloud.conf
-endef
-
-$(eval $(call BuildPackage,owncloud))
+++ /dev/null
-
-#TODO: also doesn't work yet
-$HTTP["url"] =~ "^/owncloud/data/" {
- url.access-deny = ("")
-}
-
-$HTTP["url"] =~ "^/owncloud/" {
-
- # max post request: 1M
- server.max-request-size = 1024
-
- # docroot
- server.document-root = "/www/htdocs"
-
- # activate directory listing
- dir-listing.activate = "disable"
-
- # php
- cgi.assign = ( ".php" => "/usr/bin/php-cgi" )
- #TODO: manage /etc/lighttpd/lighttpd.conf with cfengine
-
-# # fastcgi: not yet; white page in files :(
-# fastcgi.server = (
-# ".php" =>
-# ((
-# "host" => "127.0.0.1",
-# "port" => 1026,
-# "check-local" => "disable",
-# "docroot" => "/www/htdocs"
-# ))
-# )
-
-}
-