From 86a9794d9b9826deae000af750f5ff8500c11415 Mon Sep 17 00:00:00 2001 From: George Date: Sat, 16 May 2020 07:15:33 -0400 Subject: [PATCH] Add upstream build scripts and contrib files --- Dockerfile | 1 + Makefile | 31 --- README.md | 2 +- build | 77 ++++++ clean | 2 + contrib/ansible/genkeys.go | 134 +++++++++++ contrib/apparmor/usr.bin.yggdrasil | 25 ++ contrib/busybox-init/S42yggdrasil | 77 ++++++ contrib/config/yggdrasilconf.go | 97 ++++++++ contrib/deb/generate.sh | 127 ++++++++++ contrib/docker/Dockerfile | 26 ++ contrib/docker/entrypoint.sh | 13 + contrib/freebsd/yggdrasil | 72 ++++++ contrib/logo/ygg-neilalexander.svg | 157 ++++++++++++ contrib/macos/create-pkg.sh | 122 ++++++++++ contrib/macos/yggdrasil.plist | 24 ++ contrib/msi/build-msi.sh | 224 ++++++++++++++++++ contrib/openrc/yggdrasil | 55 +++++ contrib/semver/name.sh | 22 ++ contrib/semver/version.sh | 46 ++++ .../systemd/yggdrasil-default-config.service | 13 + contrib/systemd/yggdrasil.service | 21 ++ contrib/yggdrasil-brute-simple/LICENSE | 150 ++++++++++++ contrib/yggdrasil-brute-simple/Makefile | 12 + contrib/yggdrasil-brute-simple/README.md | 8 + contrib/yggdrasil-brute-simple/util.c | 62 +++++ .../yggdrasil-brute-multi-curve25519.c | 105 ++++++++ .../yggdrasil-brute-multi-ed25519.c | 106 +++++++++ .../yggdrasil-brute-simple/yggdrasil-brute.h | 12 + 29 files changed, 1791 insertions(+), 32 deletions(-) create mode 100644 Dockerfile delete mode 100644 Makefile create mode 100755 build create mode 100755 clean create mode 100644 contrib/ansible/genkeys.go create mode 100644 contrib/apparmor/usr.bin.yggdrasil create mode 100755 contrib/busybox-init/S42yggdrasil create mode 100644 contrib/config/yggdrasilconf.go create mode 100644 contrib/deb/generate.sh create mode 100644 contrib/docker/Dockerfile create mode 100755 contrib/docker/entrypoint.sh create mode 100644 contrib/freebsd/yggdrasil create mode 100644 contrib/logo/ygg-neilalexander.svg create mode 100755 contrib/macos/create-pkg.sh create mode 100644 contrib/macos/yggdrasil.plist create mode 100644 contrib/msi/build-msi.sh create mode 100755 contrib/openrc/yggdrasil create mode 100644 contrib/semver/name.sh create mode 100644 contrib/semver/version.sh create mode 100644 contrib/systemd/yggdrasil-default-config.service create mode 100644 contrib/systemd/yggdrasil.service create mode 100644 contrib/yggdrasil-brute-simple/LICENSE create mode 100644 contrib/yggdrasil-brute-simple/Makefile create mode 100644 contrib/yggdrasil-brute-simple/README.md create mode 100644 contrib/yggdrasil-brute-simple/util.c create mode 100644 contrib/yggdrasil-brute-simple/yggdrasil-brute-multi-curve25519.c create mode 100644 contrib/yggdrasil-brute-simple/yggdrasil-brute-multi-ed25519.c create mode 100644 contrib/yggdrasil-brute-simple/yggdrasil-brute.h diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..4cac86d --- /dev/null +++ b/Dockerfile @@ -0,0 +1 @@ +contrib/docker/Dockerfile diff --git a/Makefile b/Makefile deleted file mode 100644 index 4179bba..0000000 --- a/Makefile +++ /dev/null @@ -1,31 +0,0 @@ -GOARCH := $(GOARCH) -GOOS := $(GOOS) -FLAGS := -ldflags "-s -w" -PEER_LIST ?= "assets/peers.txt" -peers.go := "src/autopeering/peers.go" - -all: peers_asset - GOARCH=$$GOARCH GOOS=$$GOOS go build $(FLAGS) ./cmd/yggdrasil - GOARCH=$$GOARCH GOOS=$$GOOS go build $(FLAGS) ./cmd/yggdrasilctl - -clean: - $(RM) yggdrasil yggdrasil.exe yggdrasilctl yggdrasilctl.exe - -peers_asset: - echo "package autopeering\n" > $(peers.go) - echo -n "var HighCapPeers = []string{" >> $(peers.go) - for line in `grep -E "^h" $(PEER_LIST) | cut -d "," -f2 | head -n -1` - do - echo "\t\"$$line\"," >> $(peers.go) - done - echo "\t\"`grep -E "^h" $(PEER_LIST) | cut -d "," -f2 | tail -n 1`\"}" >> $(peers.go) - echo -n "var LowCapPeers = []string{" >> $(peers.go) - for line in `grep -E "^l" $(PEER_LIST) | cut -d "," -f2 | head -n -1` - do - echo "\t\"$$line\"," >> $(peers.go) - done - echo "\t\"`grep -E "^l" $(PEER_LIST) | cut -d "," -f2 | tail -n 1`\"}" >> $(peers.go) - -.PHONY: peers_asset all clean -.SILENT: peers_asset -.ONESHELL: peers_asset diff --git a/README.md b/README.md index 009a874..7fe6d24 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ experimental features which the original client lacks. 1. Install Go 2. Clone this repository -3. Run `make` +3. Run `./build` ## Information diff --git a/build b/build new file mode 100755 index 0000000..387ebd9 --- /dev/null +++ b/build @@ -0,0 +1,77 @@ +#!/bin/sh + +set -ef + +PKGSRC=${PKGSRC:-github.com/yggdrasil-network/yggdrasil-go/src/version} +PKGNAME=${PKGNAME:-$(sh contrib/semver/name.sh)} +PKGVER=${PKGVER:-$(sh contrib/semver/version.sh --bare)} + +LDFLAGS="-X $PKGSRC.buildName=$PKGNAME -X $PKGSRC.buildVersion=$PKGVER" +ARGS="-v" +PEER_LIST="assets/peers.txt" + +# Create peers.go "asset" file +make_peers_go() { + PEERS_GO_FILE="src/autopeering/peers.go" + echo "package autopeering\nvar HighCapPeers = []string{\n" >$PEERS_GO_FILE + grep "^h" $PEER_LIST | cut -d "," -f2 | while IFS= read -r line + do + echo "\t\"$line\"," >> $PEERS_GO_FILE + done + sed -i -e "$ s/,/}/" $PEERS_GO_FILE + + echo -n "var LowCapPeers = []string{" >> $PEERS_GO_FILE + grep "^l" $PEER_LIST | cut -d "," -f2 | while IFS= read -r line + do + echo "\t\"$line\"," >> $PEERS_GO_FILE + done + sed -i -e "$ s/,/}/" $PEERS_GO_FILE +} + +make_peers_go + +while getopts "uaitc:l:dro:p" option +do + case "$option" + in + u) UPX=true;; + i) IOS=true;; + a) ANDROID=true;; + t) TABLES=true;; + c) GCFLAGS="$GCFLAGS $OPTARG";; + l) LDFLAGS="$LDFLAGS $OPTARG";; + d) ARGS="$ARGS -tags debug" DEBUG=true;; + r) ARGS="$ARGS -race";; + o) ARGS="$ARGS -o $OPTARG";; + p) ARGS="$ARGS -buildmode=pie";; + esac +done + +if [ -z $TABLES ] && [ -z $DEBUG ]; then + LDFLAGS="$LDFLAGS -s -w" +fi + +if [ $IOS ]; then + echo "Building framework for iOS" + gomobile bind -target ios -tags mobile -ldflags="$LDFLAGS $STRIP" -gcflags="$GCFLAGS" \ + github.com/yggdrasil-network/yggdrasil-go/src/yggdrasil \ + github.com/yggdrasil-network/yggdrasil-go/src/config \ + github.com/yggdrasil-network/yggdrasil-extras/src/mobile \ + github.com/yggdrasil-network/yggdrasil-extras/src/dummy +elif [ $ANDROID ]; then + echo "Building aar for Android" + gomobile bind -target android -tags mobile -ldflags="$LDFLAGS $STRIP" -gcflags="$GCFLAGS" \ + github.com/yggdrasil-network/yggdrasil-go/src/yggdrasil \ + github.com/yggdrasil-network/yggdrasil-go/src/config \ + github.com/yggdrasil-network/yggdrasil-extras/src/mobile \ + github.com/yggdrasil-network/yggdrasil-extras/src/dummy +else + for CMD in yggdrasil yggdrasilctl ; do + echo "Building: $CMD" + go build $ARGS -ldflags="$LDFLAGS" -gcflags="$GCFLAGS" ./cmd/$CMD + + if [ $UPX ]; then + upx --brute $CMD + fi + done +fi diff --git a/clean b/clean new file mode 100755 index 0000000..a103676 --- /dev/null +++ b/clean @@ -0,0 +1,2 @@ +#!/bin/sh +git clean -dxf diff --git a/contrib/ansible/genkeys.go b/contrib/ansible/genkeys.go new file mode 100644 index 0000000..681431b --- /dev/null +++ b/contrib/ansible/genkeys.go @@ -0,0 +1,134 @@ +/* + +This file generates crypto keys for [ansible-yggdrasil](https://github.com/jcgruenhage/ansible-yggdrasil/) + +*/ +package main + +import ( + "encoding/hex" + "flag" + "fmt" + "net" + "os" + + "github.com/cheggaaa/pb/v3" + "github.com/yggdrasil-network/yggdrasil-go/src/address" + "github.com/yggdrasil-network/yggdrasil-go/src/crypto" +) + +var numHosts = flag.Int("hosts", 1, "number of host vars to generate") +var keyTries = flag.Int("tries", 1000, "number of tries before taking the best keys") + +type keySet struct { + priv []byte + pub []byte + id []byte + ip string +} + +func main() { + flag.Parse() + + bar := pb.StartNew(*keyTries*2 + *numHosts) + + if *numHosts > *keyTries { + println("Can't generate less keys than hosts.") + return + } + + var encryptionKeys []keySet + for i := 0; i < *numHosts+1; i++ { + encryptionKeys = append(encryptionKeys, newBoxKey()) + bar.Increment() + } + encryptionKeys = sortKeySetArray(encryptionKeys) + for i := 0; i < *keyTries-*numHosts-1; i++ { + encryptionKeys[0] = newBoxKey() + encryptionKeys = bubbleUpTo(encryptionKeys, 0) + bar.Increment() + } + + var signatureKeys []keySet + for i := 0; i < *numHosts+1; i++ { + signatureKeys = append(signatureKeys, newSigKey()) + bar.Increment() + } + signatureKeys = sortKeySetArray(signatureKeys) + for i := 0; i < *keyTries-*numHosts-1; i++ { + signatureKeys[0] = newSigKey() + signatureKeys = bubbleUpTo(signatureKeys, 0) + bar.Increment() + } + + os.MkdirAll("host_vars", 0755) + + for i := 1; i <= *numHosts; i++ { + os.MkdirAll(fmt.Sprintf("host_vars/%x", i), 0755) + file, err := os.Create(fmt.Sprintf("host_vars/%x/vars", i)) + if err != nil { + return + } + defer file.Close() + file.WriteString(fmt.Sprintf("yggdrasil_encryption_public_key: %v\n", hex.EncodeToString(encryptionKeys[i].pub))) + file.WriteString("yggdrasil_encryption_private_key: \"{{ vault_yggdrasil_encryption_private_key }}\"\n") + file.WriteString(fmt.Sprintf("yggdrasil_signing_public_key: %v\n", hex.EncodeToString(signatureKeys[i].pub))) + file.WriteString("yggdrasil_signing_private_key: \"{{ vault_yggdrasil_signing_private_key }}\"\n") + file.WriteString(fmt.Sprintf("ansible_host: %v\n", encryptionKeys[i].ip)) + + file, err = os.Create(fmt.Sprintf("host_vars/%x/vault", i)) + if err != nil { + return + } + defer file.Close() + file.WriteString(fmt.Sprintf("vault_yggdrasil_encryption_private_key: %v\n", hex.EncodeToString(encryptionKeys[i].priv))) + file.WriteString(fmt.Sprintf("vault_yggdrasil_signing_private_key: %v\n", hex.EncodeToString(signatureKeys[i].priv))) + bar.Increment() + } + bar.Finish() +} + +func newBoxKey() keySet { + pub, priv := crypto.NewBoxKeys() + id := crypto.GetNodeID(pub) + ip := net.IP(address.AddrForNodeID(id)[:]).String() + return keySet{priv[:], pub[:], id[:], ip} +} + +func newSigKey() keySet { + pub, priv := crypto.NewSigKeys() + id := crypto.GetTreeID(pub) + return keySet{priv[:], pub[:], id[:], ""} +} + +func isBetter(oldID, newID []byte) bool { + for idx := range oldID { + if newID[idx] > oldID[idx] { + return true + } + if newID[idx] < oldID[idx] { + return false + } + } + return false +} + +func sortKeySetArray(sets []keySet) []keySet { + for i := 0; i < len(sets); i++ { + sets = bubbleUpTo(sets, i) + } + return sets +} + +func bubbleUpTo(sets []keySet, num int) []keySet { + for i := 0; i < len(sets)-num-1; i++ { + if isBetter(sets[i+1].id, sets[i].id) { + var tmp = sets[i] + sets[i] = sets[i+1] + sets[i+1] = tmp + } else { + break + } + } + return sets +} diff --git a/contrib/apparmor/usr.bin.yggdrasil b/contrib/apparmor/usr.bin.yggdrasil new file mode 100644 index 0000000..3dea142 --- /dev/null +++ b/contrib/apparmor/usr.bin.yggdrasil @@ -0,0 +1,25 @@ +# Last Modified: Tue Mar 10 16:38:14 2020 +#include + +/usr/bin/yggdrasil { + #include + + capability net_admin, + capability net_raw, + + network inet stream, + network inet dgram, + network inet6 dgram, + network inet6 stream, + network netlink raw, + + /lib/@{multiarch}/ld-*.so mr, + /proc/sys/net/core/somaxconn r, + owner /sys/kernel/mm/transparent_hugepage/hpage_pmd_size r, + /dev/net/tun rw, + + /usr/bin/yggdrasil mr, + /etc/yggdrasil.conf rw, + /run/yggdrasil.sock rw, + +} diff --git a/contrib/busybox-init/S42yggdrasil b/contrib/busybox-init/S42yggdrasil new file mode 100755 index 0000000..862efc2 --- /dev/null +++ b/contrib/busybox-init/S42yggdrasil @@ -0,0 +1,77 @@ +#!/bin/sh + +CONFFILE="/etc/yggdrasil.conf" + +genconf() { + /usr/bin/yggdrasil -genconf > "$1" + return $? +} + +probetun() { + modprobe tun + return $? +} + +start() { + if [ ! -f "$CONFFILE" ]; then + printf 'Generating configuration file: ' + if genconf "$CONFFILE"; then + echo "OK" + else + echo "FAIL" + return 1 + fi + fi + + if [ ! -e /dev/net/tun ]; then + printf 'Inserting TUN module: ' + if probetun; then + echo "OK" + else + echo "FAIL" + return 1 + fi + fi + + printf 'Starting yggdrasil: ' + if start-stop-daemon -S -q -b -x /usr/bin/yggdrasil \ + -- -useconffile "$CONFFILE"; then + echo "OK" + else + echo "FAIL" + fi +} + +stop() { + printf "Stopping yggdrasil: " + if start-stop-daemon -K -q -x /usr/bin/yggdrasil; then + echo "OK" + else + echo "FAIL" + fi +} + +reload() { + printf "Reloading yggdrasil: " + if start-stop-daemon -K -q -s HUP -x /usr/bin/yggdrasil; then + echo "OK" + else + echo "FAIL" + start + fi +} + +restart() { + stop + start +} + +case "$1" in + start|stop|restart|reload) + "$1";; + *) + echo "Usage: $0 {start|stop|restart|reload}" + exit 1 +esac + +exit 0 diff --git a/contrib/config/yggdrasilconf.go b/contrib/config/yggdrasilconf.go new file mode 100644 index 0000000..ad55e16 --- /dev/null +++ b/contrib/config/yggdrasilconf.go @@ -0,0 +1,97 @@ +package main + +/* +This is a small utility that is designed to accompany the vyatta-yggdrasil +package. It takes a HJSON configuration file, makes changes to it based on +the command line arguments, and then spits out an updated file. +*/ + +import ( + "bytes" + "encoding/json" + "flag" + "fmt" + "io/ioutil" + "strconv" + + "github.com/hjson/hjson-go" + "golang.org/x/text/encoding/unicode" + + "github.com/yggdrasil-network/yggdrasil-go/src/config" +) + +type nodeConfig = config.NodeConfig + +func main() { + useconffile := flag.String("useconffile", "/etc/yggdrasil.conf", "update config at specified file path") + flag.Parse() + cfg := nodeConfig{} + var config []byte + var err error + config, err = ioutil.ReadFile(*useconffile) + if err != nil { + panic(err) + } + if bytes.Compare(config[0:2], []byte{0xFF, 0xFE}) == 0 || + bytes.Compare(config[0:2], []byte{0xFE, 0xFF}) == 0 { + utf := unicode.UTF16(unicode.BigEndian, unicode.UseBOM) + decoder := utf.NewDecoder() + config, err = decoder.Bytes(config) + if err != nil { + panic(err) + } + } + var dat map[string]interface{} + if err := hjson.Unmarshal(config, &dat); err != nil { + panic(err) + } + confJson, err := json.Marshal(dat) + if err != nil { + panic(err) + } + json.Unmarshal(confJson, &cfg) + switch flag.Arg(0) { + case "setMTU": + cfg.IfMTU, err = strconv.Atoi(flag.Arg(1)) + if err != nil { + cfg.IfMTU = 1280 + } + if mtu, _ := strconv.Atoi(flag.Arg(1)); mtu < 1280 { + cfg.IfMTU = 1280 + } + case "setIfName": + cfg.IfName = flag.Arg(1) + case "setListen": + cfg.Listen = flag.Arg(1) + case "setAdminListen": + cfg.AdminListen = flag.Arg(1) + case "setIfTapMode": + if flag.Arg(1) == "true" { + cfg.IfTAPMode = true + } else { + cfg.IfTAPMode = false + } + case "addPeer": + found := false + for _, v := range cfg.Peers { + if v == flag.Arg(1) { + found = true + } + } + if !found { + cfg.Peers = append(cfg.Peers, flag.Arg(1)) + } + case "removePeer": + for k, v := range cfg.Peers { + if v == flag.Arg(1) { + cfg.Peers = append(cfg.Peers[:k], cfg.Peers[k+1:]...) + } + } + } + bs, err := hjson.Marshal(cfg) + if err != nil { + panic(err) + } + fmt.Println(string(bs)) + return +} diff --git a/contrib/deb/generate.sh b/contrib/deb/generate.sh new file mode 100644 index 0000000..1f3186a --- /dev/null +++ b/contrib/deb/generate.sh @@ -0,0 +1,127 @@ +#!/bin/sh + +# This is a lazy script to create a .deb for Debian/Ubuntu. It installs +# yggdrasil and enables it in systemd. You can give it the PKGARCH= argument +# i.e. PKGARCH=i386 sh contrib/deb/generate.sh + +if [ `pwd` != `git rev-parse --show-toplevel` ] +then + echo "You should run this script from the top-level directory of the git repo" + exit 1 +fi + +PKGBRANCH=$(basename `git name-rev --name-only HEAD`) +PKGNAME=$(sh contrib/semver/name.sh) +PKGVERSION=$(sh contrib/semver/version.sh --bare) +PKGARCH=${PKGARCH-amd64} +PKGFILE=$PKGNAME-$PKGVERSION-$PKGARCH.deb +PKGREPLACES=yggdrasil + +if [ $PKGBRANCH = "master" ]; then + PKGREPLACES=yggdrasil-develop +fi + +if [ $PKGARCH = "amd64" ]; then GOARCH=amd64 GOOS=linux ./build +elif [ $PKGARCH = "i386" ]; then GOARCH=386 GOOS=linux ./build +elif [ $PKGARCH = "mipsel" ]; then GOARCH=mipsle GOOS=linux ./build +elif [ $PKGARCH = "mips" ]; then GOARCH=mips64 GOOS=linux ./build +elif [ $PKGARCH = "armhf" ]; then GOARCH=arm GOOS=linux GOARM=6 ./build +elif [ $PKGARCH = "arm64" ]; then GOARCH=arm64 GOOS=linux ./build +elif [ $PKGARCH = "armel" ]; then GOARCH=arm GOOS=linux GOARM=5 ./build +else + echo "Specify PKGARCH=amd64,i386,mips,mipsel,armhf,arm64,armel" + exit 1 +fi + +echo "Building $PKGFILE" + +mkdir -p /tmp/$PKGNAME/ +mkdir -p /tmp/$PKGNAME/debian/ +mkdir -p /tmp/$PKGNAME/usr/bin/ +mkdir -p /tmp/$PKGNAME/etc/systemd/system/ + +cat > /tmp/$PKGNAME/debian/changelog << EOF +Please see https://github.com/yggdrasil-network/yggdrasil-go/ +EOF +echo 9 > /tmp/$PKGNAME/debian/compat +cat > /tmp/$PKGNAME/debian/control << EOF +Package: $PKGNAME +Version: $PKGVERSION +Section: contrib/net +Priority: extra +Architecture: $PKGARCH +Replaces: $PKGREPLACES +Conflicts: $PKGREPLACES +Maintainer: Neil Alexander +Description: Yggdrasil Network + Yggdrasil is an early-stage implementation of a fully end-to-end encrypted IPv6 + network. It is lightweight, self-arranging, supported on multiple platforms and + allows pretty much any IPv6-capable application to communicate securely with + other Yggdrasil nodes. +EOF +cat > /tmp/$PKGNAME/debian/copyright << EOF +Please see https://github.com/yggdrasil-network/yggdrasil-go/ +EOF +cat > /tmp/$PKGNAME/debian/docs << EOF +Please see https://github.com/yggdrasil-network/yggdrasil-go/ +EOF +cat > /tmp/$PKGNAME/debian/install << EOF +usr/bin/yggdrasil usr/bin +usr/bin/yggdrasilctl usr/bin +etc/systemd/system/*.service etc/systemd/system +EOF +cat > /tmp/$PKGNAME/debian/postinst << EOF +#!/bin/sh + +if ! getent group yggdrasil 2>&1 > /dev/null; then + groupadd --system --force yggdrasil || echo "Failed to create group 'yggdrasil' - please create it manually and reinstall" +fi + +if [ -f /etc/yggdrasil.conf ]; +then + mkdir -p /var/backups + echo "Backing up configuration file to /var/backups/yggdrasil.conf.`date +%Y%m%d`" + cp /etc/yggdrasil.conf /var/backups/yggdrasil.conf.`date +%Y%m%d` + echo "Normalising and updating /etc/yggdrasil.conf" + /usr/bin/yggdrasil -useconffile /var/backups/yggdrasil.conf.`date +%Y%m%d` -normaliseconf > /etc/yggdrasil.conf + chgrp yggdrasil /etc/yggdrasil.conf + + if command -v systemctl >/dev/null; then + systemctl daemon-reload >/dev/null || true + systemctl enable yggdrasil || true + systemctl start yggdrasil || true + fi +else + echo "Generating initial configuration file /etc/yggdrasil.conf" + echo "Please familiarise yourself with this file before starting Yggdrasil" + /usr/bin/yggdrasil -genconf > /etc/yggdrasil.conf + chgrp yggdrasil /etc/yggdrasil.conf +fi +EOF +cat > /tmp/$PKGNAME/debian/prerm << EOF +#!/bin/sh +if command -v systemctl >/dev/null; then + if systemctl is-active --quiet yggdrasil; then + systemctl stop yggdrasil || true + fi + systemctl disable yggdrasil || true +fi +EOF + +cp yggdrasil /tmp/$PKGNAME/usr/bin/ +cp yggdrasilctl /tmp/$PKGNAME/usr/bin/ +cp contrib/systemd/*.service /tmp/$PKGNAME/etc/systemd/system/ + +tar -czvf /tmp/$PKGNAME/data.tar.gz -C /tmp/$PKGNAME/ \ + usr/bin/yggdrasil usr/bin/yggdrasilctl \ + etc/systemd/system/yggdrasil.service \ + etc/systemd/system/yggdrasil-default-config.service +tar -czvf /tmp/$PKGNAME/control.tar.gz -C /tmp/$PKGNAME/debian . +echo 2.0 > /tmp/$PKGNAME/debian-binary + +ar -r $PKGFILE \ + /tmp/$PKGNAME/debian-binary \ + /tmp/$PKGNAME/control.tar.gz \ + /tmp/$PKGNAME/data.tar.gz + +rm -rf /tmp/$PKGNAME diff --git a/contrib/docker/Dockerfile b/contrib/docker/Dockerfile new file mode 100644 index 0000000..fd2ae98 --- /dev/null +++ b/contrib/docker/Dockerfile @@ -0,0 +1,26 @@ +FROM docker.io/golang:alpine as builder + +COPY . /src +WORKDIR /src + +ENV CGO_ENABLED=0 + +RUN apk add git && ./build && go build -o /src/genkeys cmd/genkeys/main.go + +FROM docker.io/alpine +LABEL maintainer="Christer Waren/CWINFO " + +COPY --from=builder /src/yggdrasil /usr/bin/yggdrasil +COPY --from=builder /src/yggdrasilctl /usr/bin/yggdrasilctl +COPY --from=builder /src/genkeys /usr/bin/genkeys +COPY contrib/docker/entrypoint.sh /usr/bin/entrypoint.sh + +# RUN addgroup -g 1000 -S yggdrasil-network \ +# && adduser -u 1000 -S -g 1000 --home /etc/yggdrasil-network yggdrasil-network +# +# USER yggdrasil-network +# TODO: Make running unprivileged work + +VOLUME [ "/etc/yggdrasil-network" ] + +ENTRYPOINT [ "/usr/bin/entrypoint.sh" ] diff --git a/contrib/docker/entrypoint.sh b/contrib/docker/entrypoint.sh new file mode 100755 index 0000000..26c685a --- /dev/null +++ b/contrib/docker/entrypoint.sh @@ -0,0 +1,13 @@ +#!/usr/bin/env sh + +set -e + +CONF_DIR="/etc/yggdrasil-network" + +if [ ! -f "$CONF_DIR/config.conf" ]; then + echo "generate $CONF_DIR/config.conf" + yggdrasil --genconf > "$CONF_DIR/config.conf" +fi + +yggdrasil --useconf < "$CONF_DIR/config.conf" +exit $? diff --git a/contrib/freebsd/yggdrasil b/contrib/freebsd/yggdrasil new file mode 100644 index 0000000..58482fc --- /dev/null +++ b/contrib/freebsd/yggdrasil @@ -0,0 +1,72 @@ +#!/bin/sh +# +# Put the yggdrasil and yggdrasilctl binaries into /usr/local/bin +# Then copy this script into /etc/rc.d/yggdrasil +# Finally, run: +# 1. chmod +x /etc/rc.d/yggdrasil /usr/local/bin/{yggdrasil,yggdrasilctl} +# 2. echo "yggdrasil_enable=yes" >> /etc/rc.d +# 3. service yggdrasil start +# +# PROVIDE: yggdrasil +# REQUIRE: networking +# KEYWORD: + +. /etc/rc.subr + +name="yggdrasil" +rcvar="yggdrasil_enable" + +start_cmd="${name}_start" +stop_cmd="${name}_stop" + +pidfile="/var/run/yggdrasil/${name}.pid" +command="/usr/sbin/daemon" +command_args="-P ${pidfile} -r -f ${yggdrasil_command}" + +yggdrasil_start() +{ + test ! -x /usr/local/bin/yggdrasil && ( + logger -s -t yggdrasil "Warning: /usr/local/bin/yggdrasil is missing or not executable" + logger -s -t yggdrasil "Copy the yggdrasil binary into /usr/local/bin and then chmod +x /usr/local/bin/yggdrasil" + return 1 + ) + + test ! -f /etc/yggdrasil.conf && ( + logger -s -t yggdrasil "Generating new configuration file into /etc/yggdrasil.conf" + /usr/local/bin/yggdrasil -genconf > /etc/yggdrasil.conf + ) + + tap_path="$(cat /etc/yggdrasil.conf | egrep -o '/dev/tap[0-9]{1,2}$')" + tap_name="$(echo -n ${tap_path} | tr -d '/dev/')" + + /sbin/ifconfig ${tap_name} >/dev/null 2>&1 || ( + logger -s -t yggdrasil "Creating ${tap_name} adapter" + /sbin/ifconfig ${tap_name} create || logger -s -t yggdrasil "Failed to create ${tap_name} adapter" + ) + + test ! -d /var/run/yggdrasil && mkdir -p /var/run/yggdrasil + + logger -s -t yggdrasil "Starting yggdrasil" + ${command} ${command_args} /usr/local/bin/yggdrasil -useconffile /etc/yggdrasil.conf \ + 1>/var/log/yggdrasil.stdout.log \ + 2>/var/log/yggdrasil.stderr.log & +} + +yggdrasil_stop() +{ + logger -s -t yggdrasil "Stopping yggdrasil" + test -f /var/run/yggdrasil/${name}.pid && kill -TERM $(cat /var/run/yggdrasil/${name}.pid) + + tap_path="$(cat /etc/yggdrasil.conf | grep /dev/tap | egrep -o '/dev/.*$')" + tap_name="$(echo -n ${tap_path} | tr -d '/dev/')" + + /sbin/ifconfig ${tap_name} >/dev/null 2>&1 && ( + logger -s -t yggdrasil "Destroying ${tap_name} adapter" + /sbin/ifconfig ${tap_name} destroy || logger -s -t yggdrasil "Failed to destroy ${tap_name} adapter" + ) +} + +load_rc_config $name +: ${yggdrasil_enable:=no} + +run_rc_command "$1" diff --git a/contrib/logo/ygg-neilalexander.svg b/contrib/logo/ygg-neilalexander.svg new file mode 100644 index 0000000..d222200 --- /dev/null +++ b/contrib/logo/ygg-neilalexander.svg @@ -0,0 +1,157 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/contrib/macos/create-pkg.sh b/contrib/macos/create-pkg.sh new file mode 100755 index 0000000..cc9a74f --- /dev/null +++ b/contrib/macos/create-pkg.sh @@ -0,0 +1,122 @@ +#!/bin/sh + +# Check if xar and mkbom are available +command -v xar >/dev/null 2>&1 || ( + echo "Building xar" + sudo apt-get install libxml2-dev libssl1.0-dev zlib1g-dev -y + mkdir -p /tmp/xar && cd /tmp/xar + git clone https://github.com/mackyle/xar && cd xar/xar + (sh autogen.sh && make && sudo make install) || (echo "Failed to build xar"; exit 1) +) +command -v mkbom >/dev/null 2>&1 || ( + echo "Building mkbom" + mkdir -p /tmp/mkbom && cd /tmp/mkbom + git clone https://github.com/hogliux/bomutils && cd bomutils + sudo make install || (echo "Failed to build mkbom"; exit 1) +) + +# Check if we can find the files we need - they should +# exist if you are running this script from the root of +# the yggdrasil-go repo and you have ran ./build +test -f yggdrasil || (echo "yggdrasil binary not found"; exit 1) +test -f yggdrasilctl || (echo "yggdrasilctl binary not found"; exit 1) +test -f contrib/macos/yggdrasil.plist || (echo "contrib/macos/yggdrasil.plist not found"; exit 1) +test -f contrib/semver/version.sh || (echo "contrib/semver/version.sh not found"; exit 1) + +# Delete the pkgbuild folder if it already exists +test -d pkgbuild && rm -rf pkgbuild + +# Create our folder structure +mkdir -p pkgbuild/scripts +mkdir -p pkgbuild/flat/base.pkg +mkdir -p pkgbuild/flat/Resources/en.lproj +mkdir -p pkgbuild/root/usr/local/bin +mkdir -p pkgbuild/root/Library/LaunchDaemons + +# Copy package contents into the pkgbuild root +cp yggdrasil pkgbuild/root/usr/local/bin +cp yggdrasilctl pkgbuild/root/usr/local/bin +cp contrib/macos/yggdrasil.plist pkgbuild/root/Library/LaunchDaemons + +# Create the postinstall script +cat > pkgbuild/scripts/postinstall << EOF +#!/bin/sh + +# Normalise the config if it exists, generate it if it doesn't +if [ -f /etc/yggdrasil.conf ]; +then + mkdir -p /Library/Preferences/Yggdrasil + echo "Backing up configuration file to /Library/Preferences/Yggdrasil/yggdrasil.conf.`date +%Y%m%d`" + cp /etc/yggdrasil.conf /Library/Preferences/Yggdrasil/yggdrasil.conf.`date +%Y%m%d` + echo "Normalising /etc/yggdrasil.conf" + /usr/local/bin/yggdrasil -useconffile /Library/Preferences/Yggdrasil/yggdrasil.conf.`date +%Y%m%d` -normaliseconf > /etc/yggdrasil.conf +else + /usr/local/bin/yggdrasil -genconf > /etc/yggdrasil.conf +fi + +# Unload existing Yggdrasil launchd service, if possible +test -f /Library/LaunchDaemons/yggdrasil.plist && (launchctl unload /Library/LaunchDaemons/yggdrasil.plist || true) + +# Load Yggdrasil launchd service and start Yggdrasil +launchctl load /Library/LaunchDaemons/yggdrasil.plist +EOF + +# Set execution permissions +chmod +x pkgbuild/scripts/postinstall +chmod +x pkgbuild/root/usr/local/bin/yggdrasil +chmod +x pkgbuild/root/usr/local/bin/yggdrasilctl + +# Pack payload and scripts +( cd pkgbuild/scripts && find . | cpio -o --format odc --owner 0:80 | gzip -c ) > pkgbuild/flat/base.pkg/Scripts +( cd pkgbuild/root && find . | cpio -o --format odc --owner 0:80 | gzip -c ) > pkgbuild/flat/base.pkg/Payload + +# Work out metadata for the package info +PKGNAME=$(sh contrib/semver/name.sh) +PKGVERSION=$(sh contrib/semver/version.sh --bare) +PKGARCH=${PKGARCH-amd64} +PAYLOADSIZE=$(( $(wc -c pkgbuild/flat/base.pkg/Payload | awk '{ print $1 }') / 1024 )) + +# Create the PackageInfo file +cat > pkgbuild/flat/base.pkg/PackageInfo << EOF + + + + + + +EOF + +# Create the BOM +( cd pkgbuild && mkbom root flat/base.pkg/Bom ) + +# Create the Distribution file +cat > pkgbuild/flat/Distribution << EOF + + + Yggdrasil (${PKGNAME}-${PKGVERSION}) + + + + + + + + + + + #base.pkg + +EOF + +# Finally pack the .pkg +( cd pkgbuild/flat && xar --compression none -cf "../../${PKGNAME}-${PKGVERSION}-macos-${PKGARCH}.pkg" * ) diff --git a/contrib/macos/yggdrasil.plist b/contrib/macos/yggdrasil.plist new file mode 100644 index 0000000..c436d4b --- /dev/null +++ b/contrib/macos/yggdrasil.plist @@ -0,0 +1,24 @@ + + + + + Label + yggdrasil + ProgramArguments + + sh + -c + /usr/local/bin/yggdrasil -useconffile /etc/yggdrasil.conf + + KeepAlive + + RunAtLoad + + ProcessType + Interactive + StandardOutPath + /tmp/yggdrasil.stdout.log + StandardErrorPath + /tmp/yggdrasil.stderr.log + + diff --git a/contrib/msi/build-msi.sh b/contrib/msi/build-msi.sh new file mode 100644 index 0000000..421481c --- /dev/null +++ b/contrib/msi/build-msi.sh @@ -0,0 +1,224 @@ +#!/bin/sh + +# This script generates an MSI file for Yggdrasil for a given architecture. It +# needs to run on Windows within MSYS2 and Go 1.13 or later must be installed on +# the system and within the PATH. This is ran currently by Appveyor (see +# appveyor.yml in the repository root) for both x86 and x64. +# +# Author: Neil Alexander + +# Get arch from command line if given +PKGARCH=$1 +if [ "${PKGARCH}" == "" ]; +then + echo "tell me the architecture: x86 or x64" + exit 1 +fi + +# Get the rest of the repository history. This is needed within Appveyor because +# otherwise we don't get all of the branch histories and therefore the semver +# scripts don't work properly. +if [ "${APPVEYOR_PULL_REQUEST_HEAD_REPO_BRANCH}" != "" ]; +then + git fetch --all + git checkout ${APPVEYOR_PULL_REQUEST_HEAD_REPO_BRANCH} +elif [ "${APPVEYOR_REPO_BRANCH}" != "" ]; +then + git fetch --all + git checkout ${APPVEYOR_REPO_BRANCH} +fi + +# Install prerequisites within MSYS2 +pacman -S --needed --noconfirm unzip git curl + +# Download the wix tools! +if [ ! -d wixbin ]; +then + curl -LO https://github.com/wixtoolset/wix3/releases/download/wix3112rtm/wix311-binaries.zip + if [ `md5sum wix311-binaries.zip | cut -f 1 -d " "` != "47a506f8ab6666ee3cc502fb07d0ee2a" ]; + then + echo "wix package didn't match expected checksum" + exit 1 + fi + mkdir -p wixbin + unzip -o wix311-binaries.zip -d wixbin || ( + echo "failed to unzip WiX" + exit 1 + ) +fi + +# Build Yggdrasil! +[ "${PKGARCH}" == "x64" ] && GOOS=windows GOARCH=amd64 CGO_ENABLED=0 ./build +[ "${PKGARCH}" == "x86" ] && GOOS=windows GOARCH=386 CGO_ENABLED=0 ./build + +# Create the postinstall script +cat > updateconfig.bat << EOF +if not exist %ALLUSERSPROFILE%\\Yggdrasil ( + mkdir %ALLUSERSPROFILE%\\Yggdrasil +) +if not exist %ALLUSERSPROFILE%\\Yggdrasil\\yggdrasil.conf ( + if exist yggdrasil.exe ( + yggdrasil.exe -genconf > %ALLUSERSPROFILE%\\Yggdrasil\\yggdrasil.conf + ) +) +EOF + +# Work out metadata for the package info +PKGNAME=$(sh contrib/semver/name.sh) +PKGVERSION=$(sh contrib/semver/version.sh --bare) +PKGVERSIONMS=$(echo $PKGVERSION | tr - .) +[ "${PKGARCH}" == "x64" ] && \ + PKGGUID="77757838-1a23-40a5-a720-c3b43e0260cc" PKGINSTFOLDER="ProgramFiles64Folder" || \ + PKGGUID="54a3294e-a441-4322-aefb-3bb40dd022bb" PKGINSTFOLDER="ProgramFilesFolder" + +# Download the Wintun driver +if [ $PKGARCH = "x64" ]; then + PKGMSMNAME=wintun-x64.msm + curl -o ${PKGMSMNAME} https://www.wintun.net/builds/wintun-amd64-0.7.msm || (echo "couldn't get wintun"; exit 1) +elif [ $PKGARCH = "x86" ]; then + PKGMSMNAME=wintun-x86.msm + curl -o ${PKGMSMNAME} https://www.wintun.net/builds/wintun-x86-0.7.msm || (echo "couldn't get wintun"; exit 1) +else + echo "wasn't sure which architecture to get wintun for" + exit 1 +fi + +if [ $PKGNAME != "master" ]; then + PKGDISPLAYNAME="Yggdrasil Network (${PKGNAME} branch)" +else + PKGDISPLAYNAME="Yggdrasil Network" +fi + +# Generate the wix.xml file +cat > wix.xml << EOF + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + UPGRADINGPRODUCTCODE + + + + + + + + + NOT Installed AND NOT REMOVE + + + + + +EOF + +# Generate the MSI +CANDLEFLAGS="-nologo" +LIGHTFLAGS="-nologo -spdb -sice:ICE71 -sice:ICE61" +wixbin/candle $CANDLEFLAGS -out ${PKGNAME}-${PKGVERSION}-${PKGARCH}.wixobj -arch ${PKGARCH} wix.xml && \ +wixbin/light $LIGHTFLAGS -ext WixUtilExtension.dll -out ${PKGNAME}-${PKGVERSION}-${PKGARCH}.msi ${PKGNAME}-${PKGVERSION}-${PKGARCH}.wixobj diff --git a/contrib/openrc/yggdrasil b/contrib/openrc/yggdrasil new file mode 100755 index 0000000..4a2e0a1 --- /dev/null +++ b/contrib/openrc/yggdrasil @@ -0,0 +1,55 @@ +#!/sbin/openrc-run + +description="An experiment in scalable routing as an encrypted IPv6 overlay network." + +CONFFILE="/etc/yggdrasil.conf" +pidfile="/run/${RC_SVCNAME}.pid" + +command="/usr/bin/yggdrasil" +extra_started_commands="reload" + +depend() { + use net dns logger +} + +start_pre() { + if [ ! -f "${CONFFILE}" ]; then + ebegin "Generating new configuration file into ${CONFFILE}" + if ! eval ${command} -genconf > ${CONFFILE}; then + eerror "Failed to generate configuration file" + exit 1 + fi + fi + + if [ ! -e /dev/net/tun ]; then + ebegin "Inserting TUN module" + if ! modprobe tun; then + eerror "Failed to insert TUN kernel module" + exit 1 + fi + fi +} + +start() { + ebegin "Starting ${RC_SVCNAME}" + start-stop-daemon --start --quiet \ + --pidfile "${pidfile}" \ + --make-pidfile \ + --background \ + --stdout /var/log/yggdrasil.stdout.log \ + --stderr /var/log/yggdrasil.stderr.log \ + --exec "${command}" -- -useconffile "${CONFFILE}" + eend $? +} + +reload() { + ebegin "Reloading ${RC_SVCNAME}" + start-stop-daemon --signal HUP --pidfile "${pidfile}" + eend $? +} + +stop() { + ebegin "Stopping ${RC_SVCNAME}" + start-stop-daemon --stop --pidfile "${pidfile}" --exec "${command}" + eend $? +} diff --git a/contrib/semver/name.sh b/contrib/semver/name.sh new file mode 100644 index 0000000..308e07b --- /dev/null +++ b/contrib/semver/name.sh @@ -0,0 +1,22 @@ +#!/bin/sh + +# Get the current branch name +BRANCH=$(git symbolic-ref --short HEAD 2>/dev/null) + +# Complain if the git history is not available +if [ $? != 0 ] || [ -z "$BRANCH" ]; then + printf "yggdrasil" + exit 0 +fi + +# Remove "/" characters from the branch name if present +BRANCH=$(echo $BRANCH | tr -d "/") + +# Check if the branch name is not master +if [ "$BRANCH" = "master" ]; then + printf "yggdrasil" + exit 0 +fi + +# If it is something other than master, append it +printf "yggdrasil-%s" "$BRANCH" diff --git a/contrib/semver/version.sh b/contrib/semver/version.sh new file mode 100644 index 0000000..db96e33 --- /dev/null +++ b/contrib/semver/version.sh @@ -0,0 +1,46 @@ +#!/bin/sh + +# Get the last tag +TAG=$(git describe --abbrev=0 --tags --match="v[0-9]*\.[0-9]*\.[0-9]*" 2>/dev/null) + +# Did getting the tag succeed? +if [ $? != 0 ] || [ -z "$TAG" ]; then + printf -- "unknown" + exit 0 +fi + +# Get the current branch +BRANCH=$(git symbolic-ref -q HEAD --short 2>/dev/null) + +# Did getting the branch succeed? +if [ $? != 0 ] || [ -z "$BRANCH" ]; then + BRANCH="master" +fi + +# Split out into major, minor and patch numbers +MAJOR=$(echo $TAG | cut -c 2- | cut -d "." -f 1) +MINOR=$(echo $TAG | cut -c 2- | cut -d "." -f 2) +PATCH=$(echo $TAG | cut -c 2- | cut -d "." -f 3) + +# Output in the desired format +if [ $((PATCH)) -eq 0 ]; then + printf '%s%d.%d' "$PREPEND" "$((MAJOR))" "$((MINOR))" +else + printf '%s%d.%d.%d' "$PREPEND" "$((MAJOR))" "$((MINOR))" "$((PATCH))" +fi + +# Add the build tag on non-master branches +if [ "$BRANCH" != "master" ]; then + BUILD=$(git rev-list --count $TAG..HEAD 2>/dev/null) + + # Did getting the count of commits since the tag succeed? + if [ $? != 0 ] || [ -z "$BUILD" ]; then + printf -- "-unknown" + exit 0 + fi + + # Is the build greater than zero? + if [ $((BUILD)) -gt 0 ]; then + printf -- "-%04d" "$((BUILD))" + fi +fi diff --git a/contrib/systemd/yggdrasil-default-config.service b/contrib/systemd/yggdrasil-default-config.service new file mode 100644 index 0000000..e9fe45b --- /dev/null +++ b/contrib/systemd/yggdrasil-default-config.service @@ -0,0 +1,13 @@ +[Unit] +Description=yggdrasil default config generator +ConditionPathExists=|!/etc/yggdrasil.conf +ConditionFileNotEmpty=|!/etc/yggdrasil.conf +Wants=local-fs.target +After=local-fs.target + +[Service] +Type=oneshot +Group=yggdrasil +StandardOutput=file:/etc/yggdrasil.conf +ExecStart=/usr/bin/yggdrasil -genconf +ExecStartPost=/usr/bin/chmod 0640 /etc/yggdrasil.conf diff --git a/contrib/systemd/yggdrasil.service b/contrib/systemd/yggdrasil.service new file mode 100644 index 0000000..3002e61 --- /dev/null +++ b/contrib/systemd/yggdrasil.service @@ -0,0 +1,21 @@ +[Unit] +Description=yggdrasil +Wants=network.target +Wants=yggdrasil-default-config.service +After=network.target +After=yggdrasil-default-config.service + +[Service] +Group=yggdrasil +ProtectHome=true +ProtectSystem=true +SyslogIdentifier=yggdrasil +CapabilityBoundingSet=CAP_NET_ADMIN CAP_NET_RAW +ExecStartPre=+-/sbin/modprobe tun +ExecStart=/usr/bin/yggdrasil -useconffile /etc/yggdrasil.conf +ExecReload=/bin/kill -HUP $MAINPID +Restart=always +TimeoutStopSec=5 + +[Install] +WantedBy=multi-user.target diff --git a/contrib/yggdrasil-brute-simple/LICENSE b/contrib/yggdrasil-brute-simple/LICENSE new file mode 100644 index 0000000..2d61b40 --- /dev/null +++ b/contrib/yggdrasil-brute-simple/LICENSE @@ -0,0 +1,150 @@ +This software is released into the public domain. As such, it can be +used under the Unlicense or CC0 public domain dedications. + + + +The Unlicense + +This is free and unencumbered software released into the public domain. + +Anyone is free to copy, modify, publish, use, compile, sell, or +distribute this software, either in source code form or as a compiled +binary, for any purpose, commercial or non-commercial, and by any +means. + +In jurisdictions that recognize copyright laws, the author or authors +of this software dedicate any and all copyright interest in the +software to the public domain. We make this dedication for the benefit +of the public at large and to the detriment of our heirs and +successors. We intend this dedication to be an overt act of +relinquishment in perpetuity of all present and future rights to this +software under copyright law. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +For more information, please refer to + + + +CC0 1.0 Universal + +Statement of Purpose + +The laws of most jurisdictions throughout the world automatically confer +exclusive Copyright and Related Rights (defined below) upon the creator and +subsequent owner(s) (each and all, an "owner") of an original work of +authorship and/or a database (each, a "Work"). + +Certain owners wish to permanently relinquish those rights to a Work for the +purpose of contributing to a commons of creative, cultural and scientific +works ("Commons") that the public can reliably and without fear of later +claims of infringement build upon, modify, incorporate in other works, reuse +and redistribute as freely as possible in any form whatsoever and for any +purposes, including without limitation commercial purposes. These owners may +contribute to the Commons to promote the ideal of a free culture and the +further production of creative, cultural and scientific works, or to gain +reputation or greater distribution for their Work in part through the use and +efforts of others. + +For these and/or other purposes and motivations, and without any expectation +of additional consideration or compensation, the person associating CC0 with a +Work (the "Affirmer"), to the extent that he or she is an owner of Copyright +and Related Rights in the Work, voluntarily elects to apply CC0 to the Work +and publicly distribute the Work under its terms, with knowledge of his or her +Copyright and Related Rights in the Work and the meaning and intended legal +effect of CC0 on those rights. + +1. Copyright and Related Rights. A Work made available under CC0 may be +protected by copyright and related or neighboring rights ("Copyright and +Related Rights"). Copyright and Related Rights include, but are not limited +to, the following: + + i. the right to reproduce, adapt, distribute, perform, display, communicate, + and translate a Work; + + ii. moral rights retained by the original author(s) and/or performer(s); + + iii. publicity and privacy rights pertaining to a person's image or likeness + depicted in a Work; + + iv. rights protecting against unfair competition in regards to a Work, + subject to the limitations in paragraph 4(a), below; + + v. rights protecting the extraction, dissemination, use and reuse of data in + a Work; + + vi. database rights (such as those arising under Directive 96/9/EC of the + European Parliament and of the Council of 11 March 1996 on the legal + protection of databases, and under any national implementation thereof, + including any amended or successor version of such directive); and + + vii. other similar, equivalent or corresponding rights throughout the world + based on applicable law or treaty, and any national implementations thereof. + +2. Waiver. To the greatest extent permitted by, but not in contravention of, +applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and +unconditionally waives, abandons, and surrenders all of Affirmer's Copyright +and Related Rights and associated claims and causes of action, whether now +known or unknown (including existing as well as future claims and causes of +action), in the Work (i) in all territories worldwide, (ii) for the maximum +duration provided by applicable law or treaty (including future time +extensions), (iii) in any current or future medium and for any number of +copies, and (iv) for any purpose whatsoever, including without limitation +commercial, advertising or promotional purposes (the "Waiver"). Affirmer makes +the Waiver for the benefit of each member of the public at large and to the +detriment of Affirmer's heirs and successors, fully intending that such Waiver +shall not be subject to revocation, rescission, cancellation, termination, or +any other legal or equitable action to disrupt the quiet enjoyment of the Work +by the public as contemplated by Affirmer's express Statement of Purpose. + +3. Public License Fallback. Should any part of the Waiver for any reason be +judged legally invalid or ineffective under applicable law, then the Waiver +shall be preserved to the maximum extent permitted taking into account +Affirmer's express Statement of Purpose. In addition, to the extent the Waiver +is so judged Affirmer hereby grants to each affected person a royalty-free, +non transferable, non sublicensable, non exclusive, irrevocable and +unconditional license to exercise Affirmer's Copyright and Related Rights in +the Work (i) in all territories worldwide, (ii) for the maximum duration +provided by applicable law or treaty (including future time extensions), (iii) +in any current or future medium and for any number of copies, and (iv) for any +purpose whatsoever, including without limitation commercial, advertising or +promotional purposes (the "License"). The License shall be deemed effective as +of the date CC0 was applied by Affirmer to the Work. Should any part of the +License for any reason be judged legally invalid or ineffective under +applicable law, such partial invalidity or ineffectiveness shall not +invalidate the remainder of the License, and in such case Affirmer hereby +affirms that he or she will not (i) exercise any of his or her remaining +Copyright and Related Rights in the Work or (ii) assert any associated claims +and causes of action with respect to the Work, in either case contrary to +Affirmer's express Statement of Purpose. + +4. Limitations and Disclaimers. + + a. No trademark or patent rights held by Affirmer are waived, abandoned, + surrendered, licensed or otherwise affected by this document. + + b. Affirmer offers the Work as-is and makes no representations or warranties + of any kind concerning the Work, express, implied, statutory or otherwise, + including without limitation warranties of title, merchantability, fitness + for a particular purpose, non infringement, or the absence of latent or + other defects, accuracy, or the present or absence of errors, whether or not + discoverable, all to the greatest extent permissible under applicable law. + + c. Affirmer disclaims responsibility for clearing rights of other persons + that may apply to the Work or any use thereof, including without limitation + any person's Copyright and Related Rights in the Work. Further, Affirmer + disclaims responsibility for obtaining any necessary consents, permissions + or other rights required for any use of the Work. + + d. Affirmer understands and acknowledges that Creative Commons is not a + party to this document and has no duty or obligation with respect to this + CC0 or use of the Work. + +For more information, please see + diff --git a/contrib/yggdrasil-brute-simple/Makefile b/contrib/yggdrasil-brute-simple/Makefile new file mode 100644 index 0000000..aa2adc8 --- /dev/null +++ b/contrib/yggdrasil-brute-simple/Makefile @@ -0,0 +1,12 @@ +.PHONY: all + +all: util yggdrasil-brute-multi-curve25519 yggdrasil-brute-multi-ed25519 + +util: util.c + gcc -Wall -std=c89 -O3 -c -o util.o util.c + +yggdrasil-brute-multi-ed25519: yggdrasil-brute-multi-ed25519.c util.o + gcc -Wall -std=c89 -O3 -o yggdrasil-brute-multi-ed25519 -lsodium yggdrasil-brute-multi-ed25519.c util.o + +yggdrasil-brute-multi-curve25519: yggdrasil-brute-multi-curve25519.c util.o + gcc -Wall -std=c89 -O3 -o yggdrasil-brute-multi-curve25519 -lsodium yggdrasil-brute-multi-curve25519.c util.o diff --git a/contrib/yggdrasil-brute-simple/README.md b/contrib/yggdrasil-brute-simple/README.md new file mode 100644 index 0000000..f7b6876 --- /dev/null +++ b/contrib/yggdrasil-brute-simple/README.md @@ -0,0 +1,8 @@ +# yggdrasil-brute-simple + +Simple program for finding curve25519 and ed25519 public keys whose sha512 hash has many leading ones. +Because ed25519 private keys consist of a seed that is hashed to find the secret part of the keypair, +this program is near optimal for finding ed25519 keypairs. Curve25519 key generation, on the other hand, +could be further optimized with elliptic curve magic. + +Depends on libsodium. diff --git a/contrib/yggdrasil-brute-simple/util.c b/contrib/yggdrasil-brute-simple/util.c new file mode 100644 index 0000000..fd17e49 --- /dev/null +++ b/contrib/yggdrasil-brute-simple/util.c @@ -0,0 +1,62 @@ +#include "yggdrasil-brute.h" + +int find_where(unsigned char hash[64], unsigned char besthashlist[NUMKEYS][64]) { + /* Where to insert hash into sorted hashlist */ + int j; + int where = -1; + for (j = 0; j < NUMKEYS; ++j) { + if (memcmp(hash, besthashlist[j], 64) > 0) ++where; + else break; + } + return where; +} + +void insert_64(unsigned char itemlist[NUMKEYS][64], unsigned char item[64], int where) { + int j; + for (j = 0; j < where; ++j) { + memcpy(itemlist[j], itemlist[j+1], 64); + } + memcpy(itemlist[where], item, 64); +} + +void insert_32(unsigned char itemlist[NUMKEYS][32], unsigned char item[32], int where) { + int j; + for (j = 0; j < where; ++j) { + memcpy(itemlist[j], itemlist[j+1], 32); + } + memcpy(itemlist[where], item, 32); +} + +void make_addr(unsigned char addr[32], unsigned char hash[64]) { + /* Public key hash to yggdrasil ipv6 address */ + int i; + int offset; + unsigned char mask; + unsigned char c; + int ones = 0; + unsigned char br = 0; /* false */ + for (i = 0; i < 64 && !br; ++i) { + mask = 128; + c = hash[i]; + while (mask) { + if (c & mask) { + ++ones; + } else { + br = 1; /* true */ + break; + } + mask >>= 1; + } + } + + addr[0] = 2; + addr[1] = ones; + + offset = ones + 1; + for (i = 0; i < 14; ++i) { + c = hash[offset/8] << (offset%8); + c |= hash[offset/8 + 1] >> (8 - offset%8); + addr[i + 2] = c; + offset += 8; + } +} diff --git a/contrib/yggdrasil-brute-simple/yggdrasil-brute-multi-curve25519.c b/contrib/yggdrasil-brute-simple/yggdrasil-brute-multi-curve25519.c new file mode 100644 index 0000000..a592f38 --- /dev/null +++ b/contrib/yggdrasil-brute-simple/yggdrasil-brute-multi-curve25519.c @@ -0,0 +1,105 @@ +/* +sk: 32 random bytes +sk[0] &= 248; +sk[31] &= 127; +sk[31] |= 64; + +increment sk +pk = curve25519_scalarmult_base(mysecret) +hash = sha512(pk) + +if besthash: + bestsk = sk + besthash = hash +*/ + +#include "yggdrasil-brute.h" + + +void seed(unsigned char sk[32]) { + randombytes_buf(sk, 32); + sk[0] &= 248; + sk[31] &= 127; + sk[31] |= 64; +} + + +int main(int argc, char **argv) { + int i; + int j; + unsigned char addr[16]; + time_t starttime; + time_t requestedtime; + + unsigned char bestsklist[NUMKEYS][32]; + unsigned char bestpklist[NUMKEYS][32]; + unsigned char besthashlist[NUMKEYS][64]; + + unsigned char sk[32]; + unsigned char pk[32]; + unsigned char hash[64]; + + unsigned int runs = 0; + int where; + + if (argc != 2) { + fprintf(stderr, "usage: ./yggdrasil-brute-multi-curve25519 \n"); + return 1; + } + + if (sodium_init() < 0) { + /* panic! the library couldn't be initialized, it is not safe to use */ + printf("sodium init failed!\n"); + return 1; + } + + starttime = time(NULL); + requestedtime = atoi(argv[1]); + + if (requestedtime < 0) requestedtime = 0; + fprintf(stderr, "Searching for yggdrasil curve25519 keys (this will take slightly longer than %ld seconds)\n", requestedtime); + + sodium_memzero(bestsklist, NUMKEYS * 32); + sodium_memzero(bestpklist, NUMKEYS * 32); + sodium_memzero(besthashlist, NUMKEYS * 64); + seed(sk); + + do { + /* generate pubkey, hash, compare, increment secret. + * this loop should take 4 seconds on modern hardware */ + for (i = 0; i < (1 << 16); ++i) { + ++runs; + if (crypto_scalarmult_curve25519_base(pk, sk) != 0) { + printf("scalarmult to create pub failed!\n"); + return 1; + } + crypto_hash_sha512(hash, pk, 32); + + where = find_where(hash, besthashlist); + if (where >= 0) { + insert_32(bestsklist, sk, where); + insert_32(bestpklist, pk, where); + insert_64(besthashlist, hash, where); + + seed(sk); + } + for (j = 1; j < 31; ++j) if (++sk[j]) break; + } + } while (time(NULL) - starttime < requestedtime || runs < NUMKEYS); + + fprintf(stderr, "--------------addr-------------- -----------------------------secret----------------------------- -----------------------------public-----------------------------\n"); + for (i = 0; i < NUMKEYS; ++i) { + make_addr(addr, besthashlist[i]); + for (j = 0; j < 16; ++j) printf("%02x", addr[j]); + printf(" "); + for (j = 0; j < 32; ++j) printf("%02x", bestsklist[i][j]); + printf(" "); + for (j = 0; j < 32; ++j) printf("%02x", bestpklist[i][j]); + printf("\n"); + } + + sodium_memzero(bestsklist, NUMKEYS * 32); + sodium_memzero(sk, 32); + + return 0; +} diff --git a/contrib/yggdrasil-brute-simple/yggdrasil-brute-multi-ed25519.c b/contrib/yggdrasil-brute-simple/yggdrasil-brute-multi-ed25519.c new file mode 100644 index 0000000..02218e5 --- /dev/null +++ b/contrib/yggdrasil-brute-simple/yggdrasil-brute-multi-ed25519.c @@ -0,0 +1,106 @@ +/* +seed: 32 random bytes +sk: sha512(seed) +sk[0] &= 248 +sk[31] &= 127 +sk[31] |= 64 + +pk: scalarmult_ed25519_base(sk) + + +increment seed +generate sk +generate pk +hash = sha512(mypub) + +if besthash: + bestseed = seed + bestseckey = sk + bestpubkey = pk + besthash = hash +*/ + +#include "yggdrasil-brute.h" + + +int main(int argc, char **argv) { + int i; + int j; + time_t starttime; + time_t requestedtime; + + unsigned char bestsklist[NUMKEYS][64]; /* sk contains pk */ + unsigned char besthashlist[NUMKEYS][64]; + + unsigned char seed[32]; + unsigned char sk[64]; + unsigned char pk[32]; + unsigned char hash[64]; + + unsigned int runs = 0; + int where; + + if (argc != 2) { + fprintf(stderr, "usage: ./yggdrasil-brute-multi-curve25519 \n"); + return 1; + } + + if (sodium_init() < 0) { + /* panic! the library couldn't be initialized, it is not safe to use */ + printf("sodium init failed!\n"); + return 1; + } + + starttime = time(NULL); + requestedtime = atoi(argv[1]); + + if (requestedtime < 0) requestedtime = 0; + fprintf(stderr, "Searching for yggdrasil ed25519 keys (this will take slightly longer than %ld seconds)\n", requestedtime); + + sodium_memzero(bestsklist, NUMKEYS * 64); + sodium_memzero(besthashlist, NUMKEYS * 64); + randombytes_buf(seed, 32); + + do { + /* generate pubkey, hash, compare, increment secret. + * this loop should take 4 seconds on modern hardware */ + for (i = 0; i < (1 << 17); ++i) { + ++runs; + crypto_hash_sha512(sk, seed, 32); + + if (crypto_scalarmult_ed25519_base(pk, sk) != 0) { + printf("scalarmult to create pub failed!\n"); + return 1; + } + memcpy(sk + 32, pk, 32); + + crypto_hash_sha512(hash, pk, 32); + + /* insert into local list of good key */ + where = find_where(hash, besthashlist); + if (where >= 0) { + insert_64(bestsklist, sk, where); + insert_64(besthashlist, hash, where); + randombytes_buf(seed, 32); + } + for (j = 1; j < 31; ++j) if (++seed[j]) break; + } + } while (time(NULL) - starttime < requestedtime || runs < NUMKEYS); + + fprintf(stderr, "!! Secret key is seed concatenated with public !!\n"); + fprintf(stderr, "---hash--- ------------------------------seed------------------------------ -----------------------------public-----------------------------\n"); + for (i = 0; i < NUMKEYS; ++i) { + for (j = 0; j < 5; ++j) printf("%02x", besthashlist[i][j]); + printf(" "); + for (j = 0; j < 32; ++j) printf("%02x", bestsklist[i][j]); + printf(" "); + for (j = 32; j < 64; ++j) printf("%02x", bestsklist[i][j]); + printf("\n"); + } + + sodium_memzero(bestsklist, NUMKEYS * 64); + sodium_memzero(sk, 64); + sodium_memzero(seed, 32); + + return 0; +} diff --git a/contrib/yggdrasil-brute-simple/yggdrasil-brute.h b/contrib/yggdrasil-brute-simple/yggdrasil-brute.h new file mode 100644 index 0000000..8e39e0f --- /dev/null +++ b/contrib/yggdrasil-brute-simple/yggdrasil-brute.h @@ -0,0 +1,12 @@ +#include +#include /* printf */ +#include /* memcpy */ +#include /* atoi */ +#include /* time */ + + +#define NUMKEYS 10 +void make_addr(unsigned char addr[32], unsigned char hash[64]); +int find_where(unsigned char hash[64], unsigned char besthashlist[NUMKEYS][64]); +void insert_64(unsigned char itemlist[NUMKEYS][64], unsigned char item[64], int where); +void insert_32(unsigned char itemlist[NUMKEYS][32], unsigned char item[32], int where);