summaryrefslogtreecommitdiffstats
path: root/ship
diff options
context:
space:
mode:
Diffstat (limited to 'ship')
-rw-r--r--ship/.gitignore1
-rw-r--r--ship/Makefile56
-rw-r--r--ship/README.markdown54
-rw-r--r--ship/TODO2
-rwxr-xr-xship/build210
-rw-r--r--ship/lib/_punani_db57
-rw-r--r--ship/lib/color7
-rw-r--r--ship/lib/core80
-rw-r--r--ship/lib/filehooker117
-rw-r--r--ship/lib/iso7
-rw-r--r--ship/lib/krebs16
-rw-r--r--ship/lib/network110
-rw-r--r--ship/lib/punani99
-rw-r--r--ship/lib/retiolum109
-rw-r--r--ship/lib/tahoe34
-rw-r--r--ship/lib/tor20
-rw-r--r--ship/lib/vim40
-rwxr-xr-xship/src/arch_autoinstall164
-rwxr-xr-xship/src/bootstrap_env_makefu171
-rw-r--r--ship/src/deploy-ssh-keys15
-rw-r--r--ship/src/filehooker_configure_ncdc15
-rw-r--r--ship/src/filehooker_configure_netshare7
-rwxr-xr-xship/src/filehooker_install143
-rw-r--r--ship/src/find-supers-tinc6
-rwxr-xr-xship/src/fix_dircolors13
-rw-r--r--ship/src/get_repo22
-rw-r--r--ship/src/install_tor_announce5
-rwxr-xr-xship/src/punani4
-rw-r--r--ship/src/refresh-super-keys5
-rw-r--r--ship/src/refresh-supers35
-rwxr-xr-xship/src/remaster_arch_shack_installstick104
-rwxr-xr-xship/src/retiolum292
-rw-r--r--ship/src/tahoe_install15
-rwxr-xr-xship/src/tor_publish_ssh14
-rw-r--r--ship/src/vim_sane_defaults11
-rwxr-xr-xship/t/docker/docker_remote_punani.sh5
-rw-r--r--ship/t/docker/punani/remote_punani11
-rw-r--r--ship/tmp/.placeholder0
38 files changed, 2076 insertions, 0 deletions
diff --git a/ship/.gitignore b/ship/.gitignore
new file mode 100644
index 00000000..89f9ac04
--- /dev/null
+++ b/ship/.gitignore
@@ -0,0 +1 @@
+out/
diff --git a/ship/Makefile b/ship/Makefile
new file mode 100644
index 00000000..4805613d
--- /dev/null
+++ b/ship/Makefile
@@ -0,0 +1,56 @@
+exesrcdir := src
+libsrcdir := lib
+tmpoutdir := tmp
+finoutdir := ../bin
+
+exesrcs := $(notdir $(wildcard $(exesrcdir)/*))
+exetmpouts := $(addprefix $(tmpoutdir)/,$(exesrcs))
+exefinouts := $(addprefix $(finoutdir)/,$(exesrcs))
+
+build := BUILD_PATH=$(libsrcdir) ./build
+
+.PHONY: all install clean distclean
+
+all: $(exetmpouts)
+
+install: $(exefinouts)
+
+clean:
+ rm -f $(exetmpouts)
+
+distclean: clean
+ rm -f $(exefinouts)
+
+define buildrule
+$(tmpoutdir)/$(1): $(exesrcdir)/$(1) $(shell $(build) deps $(exesrcdir)/$(1))
+ $(build) compile $$< $$@
+endef
+
+$(foreach exe, $(exesrcs), $(eval $(call buildrule,$(exe))))
+
+$(finoutdir)/%: $(tmpoutdir)/%
+ cp $< $@
+
+test:
+ @export PATH="$(CURDIR)/bin:$(PATH)"; \
+ tests="`find t -type f -executable`"; \
+ i=1; \
+ pids="";\
+ n=`echo "$$tests" | wc -l`; \
+ echo $$i..$$n; \
+ for exe in $$tests; do \
+ { \
+ ./$$exe; \
+ ret=$$?; \
+ case $$ret in 0) result=ok;; *) result='not ok';; esac; \
+ echo $$result $$i - $$exe; \
+ exit $$ret;\
+ } & \
+ pids="$${pids} $$!" \
+ i=$$(( i+1 )); \
+ done; \
+ ret=0;\
+ for pid in $$pids; do \
+ wait $$pid || ret=23;\
+ done; \
+ exit $$ret;
diff --git a/ship/README.markdown b/ship/README.markdown
new file mode 100644
index 00000000..a84f542c
--- /dev/null
+++ b/ship/README.markdown
@@ -0,0 +1,54 @@
+# ship - shellscript installation processor
+
+ This utility is used to build modular shell scripts using recursive macro
+ expansion.
+
+## Quickstart Guide
+
+ BUILD_PATH=libs ./build compile INPUTFILE OUTPUTFILE
+
+ If this doesn't make science to you, then prepend `debug=true` to get all
+ the intermediate files printed to stdout.
+
+## Make Interface
+
+ Put libraries into `lib`.
+ Put executables into `src`.
+
+ Build all executables from `src` into `tmp` with
+
+ make [all]
+
+ Build all executables from `src` into `tmp` and `//bin` with
+
+ make install
+
+ Undo `make [all]` with
+
+ make clean
+
+ Undo `make install` with
+
+ make distclean
+
+## Macro Development
+
+ To define a new macro, you have to add a function like
+
+ ## usage: BRE -> FUNCTION_NAME \1 [\2 ...]
+
+ where `BRE` is a basic regular expression, that has to match a whole
+ line. `FUNCTION_NAME` should be the name of a function that outputs
+ a `sed` script. `\1` refers to the line number, where the macro is
+ used and `\2 ...` are the backreferences into `BRE`. E.g.
+
+ ## usage: #@date \([.*]\) -> build_datemacro \1 \2
+ build_datemacro() {
+ printf '%da\\\n%s\n' "$1" "$(date +"$2")"
+ }
+
+ Like in this example, the line number `\1`, which gets mapped to `$1`,
+ is usually used to only change the line, where the macro got called.
+ The second argument gets passed as format specifier to `date`.
+
+ Further examples can be found in `./build`.
diff --git a/ship/TODO b/ship/TODO
new file mode 100644
index 00000000..7c2fe73f
--- /dev/null
+++ b/ship/TODO
@@ -0,0 +1,2 @@
+- refresh-supers: somehow test if a real tinc connection is possible to new
+ given supernodes
diff --git a/ship/build b/ship/build
new file mode 100755
index 00000000..0e8e1013
--- /dev/null
+++ b/ship/build
@@ -0,0 +1,210 @@
+#! /bin/sh
+set -euf
+
+## SYNOPSIS
+# [debug=true] build compile SRCFILE DSTFILE
+# [debug=true] build deps SRCFILE...
+build() {
+
+ ## Load macro definitions.
+ defmacro_pattern='## usage: \(.*\) -> \([^ ]\+\) \(.*\)'
+ script='s/^'"$defmacro_pattern"'$/\2_macro='"'"'\1'"'"'/p' \
+ setf defmacros '$(sed -n "$script" "$%s")' 0
+ eval "$defmacros"
+
+ ## Dispatch.
+ case "$1" in
+ compile) build_compile "$2" "$3";;
+ deps) shift; build_deps "$@";;
+ *) echo "build: $1: bad command" >&2; return 23;;
+ esac
+}
+
+###
+### macros
+###
+
+## usage: #@include \([0-9A-Za-z_]\+\) -> build_include \1 \2
+build_include() {
+ if buildcache_has "#@include:$2"; then
+ printf '%da\\\n##include %s: already done\n' $1 $2
+ else
+ buildcache_add "#@include:$2"
+ cat<<EOF
+$1a\\
+# begin $2
+$1r$(build_resolve $2)
+$1a\\
+# end $2
+EOF
+ fi
+}
+
+## usage: #@strict -> build_strict_mode \1
+build_strict_mode() { cat<<EOF
+$1a\\
+set -euf\\
+(set -o posix 2>/dev/null) && set -o posix || :
+EOF
+}
+
+## usage: #@info -> build_info \1
+build_info() {
+ gitinfo=$(git describe --always --dirty --abbrev=0 2>/dev/null || :)
+cat<<EOF
+$1a\\
+# this file was generated by //ship/build\\
+# build date: $(date -u --rfc-3339=s)\\
+# git describe: ${gitinfo:-not under version control}
+EOF
+}
+
+## usage: #@mainifyme\( \([A-Za-z_][A-Za-z0-9_]*\)\)\? -> build_mainifyme \1 \3
+build_mainifyme() {
+ mainifyme_name="${2:-main}"
+ cat<<EOF
+ $1a\\
+$mainifyme_name(){
+ \$a\\
+}\\
+$mainifyme_name "\$@"
+EOF
+}
+
+###
+### main subroutines
+###
+
+## usage: build_compile SRCFILE DSTFILE
+build_compile() {
+
+ script='s/^'"$defmacro_pattern"'$/\2_macro/p' \
+ setf macro_names '$(sed -n "$script" "$%s")' 0
+
+ setf unexpanded_macros_pattern \
+ '$(make_unexpanded_macros_pattern $%s)' macro_names
+
+ script='
+ s/^'"$defmacro_pattern"'$/s:^ *\\([0-9]\\+\\) \1$:\2 \3:/p
+ $a\
+t;s:^ *\\([0-9]\\+\\) .*:echo \\1p:
+ ' \
+ setf input_parser '$(sed -n "$script" "$%s")' 0
+
+ SRCFILE="$1" setf src '$(cat "$%s")' SRCFILE
+
+ buildcache_initialize "$2"
+
+ while echo "$src" | grep -q "$unexpanded_macros_pattern"; do
+ setf sedgen '$(echo "$%s" | nl -b a -s \ | sed "$%s")' src input_parser
+ setf sedscript '$(eval "$%s")' sedgen
+ setf src '$(echo "$%s" | sed -n "$%s")' src sedscript
+ done
+
+ buildcache_finalize
+
+ echo "$src" > "$2"
+ chmod +x "$2"
+}
+
+## usage: build_deps SRCFILE...
+# Print all the dependencies of SRCFILE... to stdout. (alphabetic order)
+build_deps() {
+ while test $# -gt 0; do
+ deps="$(
+ for f; do
+ for d in $(sed -n 's:^'"$build_include_macro"'$:\1:p' "$f"); do
+ build_resolve $d
+ done
+ done
+ )"
+ set -- $deps
+ if test $# -gt 0; then
+ echo "$deps"
+ fi
+ done | sort | uniq
+}
+
+###
+### misc utilities
+###
+
+## usage: build_resolve LIBNAME
+build_resolve() {
+ echo "$BUILD_PATH" | tr : \\n |
+ xargs -I: printf '%s/%s\n' : "$1" |
+ xargs -I: ls -d : 2>/dev/null |
+ head -n 1 |
+ grep . ||
+ {
+ echo "build resolve: $1: library not found" >&2
+ return 23
+ }
+}
+
+## usage: make_unexpanded_macros_pattern BUILD_DIRECTIVES...
+make_unexpanded_macros_pattern() {
+ echo "^\\($(
+ for macro; do
+ eval echo \"\$$macro\"
+ done |
+ tr \\n \| |
+ sed 's/|/\\|/'
+ )\\)$"
+}
+
+## usage: setf NAME FMT [ARG...]
+setf() {
+ value_script="$(shift; printf "$@")"
+
+ eval "$1=$value_script"
+
+ if is_debug_mode; then
+ eval 'echo "$1=\"$value_script\""'
+ eval 'echo "'"\$$1"'"' | nl -b a
+ fi >&2
+}
+
+## usage: is_debug_mode
+is_debug_mode() {
+ test "${debug-false}" = true
+}
+
+###
+### buildcache utilities
+###
+
+## usage: buildcache_initialize DESTFILE
+buildcache_initialize() {
+ buildcache="$1.buildcache"
+ cat /dev/null > "$buildcache"
+}
+
+## usage: buildcache_finalize
+buildcache_finalize() {
+ if is_debug_mode; then
+ rm "$buildcache"
+ fi
+}
+
+## usage: buildcache_has BRE
+# Check if buildcache contains a line matching BRE.
+buildcache_has() {
+ grep -q "^$1\$" "$buildcache"
+}
+
+## usage: buildcache_add LINE
+# Add LINE to buildcache.
+buildcache_add() {
+ echo "$1" >> "$buildcache"
+}
+
+
+
+###
+### main invocation
+###
+
+if echo "$0" | grep -q '^\(.*/\)\?build$'; then
+ build "$@"
+fi
diff --git a/ship/lib/_punani_db b/ship/lib/_punani_db
new file mode 100644
index 00000000..6f89029f
--- /dev/null
+++ b/ship/lib/_punani_db
@@ -0,0 +1,57 @@
+_punanidb_pacman_=
+_punanidb_yum_=
+_punanidb_aptget_=
+
+_punanidb_pacman_git=git
+_punanidb_yum_git=git
+_punanidb_aptget_git=git-core
+
+_punanidb_pacman_python2=python2
+_punanidb_yum_python2=python
+_punanidb_aptget_python2=python
+
+_punanidb_pacman_python3=python
+_punanidb_aptget_python3=python3
+
+_punanidb_pacman_pip2=python2-pip
+_punanidb_aptget_pip2=python-pip
+
+_punanidb_pacman_virtualenv=python-virtualenv
+_punanidb_aptget_virtualenv=python-virtualenv
+
+_punanidb_pacman_gpp=gcc
+_punanidb_aptget_gpp=gcc
+
+_punanidb_pacman_python2_dev=python2
+_punanidb_aptget_python2_dev=python-dev
+
+_punanidb_pacman_hostname=inetutils
+_punanidb_aptget_hostname=hostname
+
+_punanidb_pacman_hostname=inetutils
+_punanidb_aptget_hostname=hostname
+
+_punanidb_pacman_make=make
+_punanidb_yum_make=make
+_punanidb_aptget_make=make
+
+_punanidb_pacman_tinc=tinc
+_punanidb_yum_tinc=tinc
+_punanidb_aptget_tinc=tinc
+
+_punanidb_pacman_zsh=zsh
+_punanidb_yum_zsh=zsh
+_punanidb_aptget_zsh=zsh
+
+_punanidb_pacman_tor=tor
+_punanidb_yum_tor=tor
+_punanidb_aptget_tor=tor
+
+_punanidb_pacman_nano=nano
+_punanidb_yum_nano=nano
+_punanidb_aptget_nano=nano
+
+_punanidb_pacman_vim=vim
+_punanidb_yum_vim=vim-enhanced
+_punanidb_aptget_vim=vim
+
diff --git a/ship/lib/color b/ship/lib/color
new file mode 100644
index 00000000..cec2044e
--- /dev/null
+++ b/ship/lib/color
@@ -0,0 +1,7 @@
+# superseed logging with color
+green='\e[0;32m'
+red='\e[0;31m'
+nc='\e[0m'
+msg() { printf "$*\n" >&2; }
+info() { msg "$green$*$nc"; }
+error() { msg "$green$*$nc"; }
diff --git a/ship/lib/core b/ship/lib/core
new file mode 100644
index 00000000..0c321525
--- /dev/null
+++ b/ship/lib/core
@@ -0,0 +1,80 @@
+# logging
+msg() { echo "$*" >&2; }
+info() { msg "** $*"; }
+error() { msg "!! $*"; }
+## usage: die [REASON...]
+die() {
+ test $# -gt 0 && error "$*"
+ error 'Bailing out.'
+ exit 1
+}
+exists(){
+ type "$1" >/dev/null 2>/dev/null;
+}
+
+is_root(){
+ test $(id -u) -eq 0
+}
+
+defer(){
+ #close enough
+ trapstr="$1;${trapstr:-exit}"
+ trap "$trapstr" INT TERM EXIT KILL
+}
+
+esudo(){
+ # weaksauce esudo (expect sudo)
+ if ! is_root; then
+ # for the record:
+ # exec sudo -E "$0" "$@"
+ error "You are not root enough for this script"
+ exit 23 # go to hell
+ fi
+}
+
+get_hostname(){
+ # finds the current hostname
+ # if ENV HOSTN is set echo $HOSTN
+ # We try the following:
+ # $HOSTN
+ # $HOSTNAME
+ # hostname
+ # uci system.hostname
+ # /etc/hostname
+ # if everything fails, it returns 1 and prints 'unknown'
+
+ if [ -n "${HOSTN:-}" ] ; then printf "${HOSTN:-}"
+ elif [ -n "${HOSTNAME:-}" ] ;then printf "$HOSTNAME"
+ elif exists hostname ; then printf "$(hostname)"
+ elif exists uci ; then printf "$(uci get system.@system[0].hostname)"
+ elif [ -e /etc/hostname ] ;then printf "$(cat /etc/hostname)"
+ else printf "unknown"; return 1
+ fi
+ return 0
+}
+
+line_to_dot(){
+ while read line; do printf .; done;
+}
+
+get_os(){
+ # TODO: find all the release files
+ #if grep -q 'Linux' /etc/*release 2>/dev/null || grep -qe 'Linux' /etc/issue 2>/dev/null; then
+ if grep -q 'Linux' /etc/lsb-release 2>/dev/null || grep -q 'Linux' /etc/issue 2>/dev/null; then
+ echo 'linux'
+ elif test -e /etc/preferred-apps/google.xml; then
+ echo 'android'
+ elif test -e /etc/openwrt_release; then
+ echo 'openwrt'
+ elif uname -s | grep -qi 'darwin'; then
+ echo 'osx'
+ else
+ warn "Cannot determine your operating system, falling back to Linux"
+ echo 'linux'
+ fi
+}
+
+# user management
+has_user(){
+ egrep "^$1:" /etc/passwd >/dev/null
+}
diff --git a/ship/lib/filehooker b/ship/lib/filehooker
new file mode 100644
index 00000000..72be751a
--- /dev/null
+++ b/ship/lib/filehooker
@@ -0,0 +1,117 @@
+#@include core
+#@include network
+ncdc_user=${ncdc_user:-hooker}
+ncdc_bin=${ncdc_bin:-/usr/bin/ncdc}
+
+ncdc_config(){
+ # maybe we want to use the running ncdc process and communicate via tmux send-keys ?
+ (sleep 1;cat;printf "/quit\n") | sudo -u $ncdc_user "$ncdc_bin"
+}
+
+ncdc_configure_netshare(){
+ : "${1?provide path to share}"
+ rnd=`hexdump -n 2 -e '/2 "%u"' /dev/urandom`
+ rnd_name="${2:-share_$rnd}"
+ info "adding share"
+ (echo "/share $rnd_name $1") | ncdc_config
+}
+
+ncdc_configure_nick(){
+ nick=${1?nick must be provided}
+ info "configuring DC Nick: $nick"
+ echo "/nick $nick" | ncdc_config
+}
+ncdc_configure_hub(){
+ rnd=`hexdump -n 2 -e '/2 "%u"' /dev/urandom`
+ hubname="hub_$rnd"
+ hub=${1?adcs://localhost:2781}
+ info "configuring DC Hub: $hub, activating autconnect"
+ info "setting active as true"
+ (echo "/open ${hubname} ${hub}" ;
+ echo "/hset autoconnect true") | ncdc_config
+}
+
+ncdc_download(){
+install_dir="$(dirname "${ncdc_bin}")"
+info "installing ncdc to $install_dir"
+curl http://dev.yorhel.nl/download/ncdc-linux-x86_64-1.19.tar.gz | tar xz -C "$install_dir"
+}
+ncdc_install(){
+useradd -m $ncdc_user ||:
+}
+
+ncdc_autostart(){
+# only systemd
+# punani install tmux
+cat > /etc/systemd/system/ncdc@.service <<EOF
+[Unit]
+Description=ncdc
+Requires=network.target local-fs.target
+
+[Service]
+Type=oneshot
+RemainAfterExit=yes
+KillMode=none
+User=%I
+ExecStart=/usr/bin/tmux new-session -s dcpp -n ncdc -d ncdc
+ExecStop=/usr/bin/tmux send-keys -t dcpp:ncdc "/quit" C-m
+
+[Install]
+WantedBy=multi-user.target
+EOF
+systemctl enable ncdc@$ncdc_user
+}
+
+# 20gig in bytes
+min_netshare_size=${min_netshare_size:-20000000000}
+get_disksize(){
+fdisk -l ${1?provide disk} | grep '^Disk ' | cut -d\ -f 5
+}
+
+prepare_netshares(){
+ count=0
+ fdisk -l | grep '^Disk ' | egrep '(/dev/sd|/dev/hd)' | cut -d\ -f 2 | tr -d : | while read disk;do
+ size=$(get_disksize $disk)
+ if test "$size" -gt "$min_netshare_size";
+ then
+ info "using $disk with $size bytes"
+ dd if=/dev/zero of=$disk bs=1M count=1 >/dev/null
+ sleep 1
+ (printf "o\nn\np\n\n\n\nw\n\n") |fdisk $disk >/dev/null ||:
+ #partprobe $disk
+ mkfs.btrfs -f ${disk}1 >/dev/null
+ uuid="$(blkid ${disk}1 -o value | head -n 1)"
+ mountpoint="/media/vag${count}"
+ mkdir -p "$mountpoint"
+ echo "UUID=$uuid $mountpoint btrfs rw,relatime,space_cache 0 0" >> /etc/fstab
+ echo "$mountpoint"
+ : $((count++))
+ else
+ info "skipping $disk"
+ fi
+ done
+}
+install_tor_announce(){
+# systemd only
+info "writing tor_announce.service"
+cat > /etc/systemd/system/tor_announce.service<<EOF
+[Unit]
+Description=Announce Tor Hidden Address
+After=network.target
+
+[Service]
+Type=oneshot
+RemainAfterExit=yes
+ExecStart=/usr/bin/tor_announce
+
+[Install]
+WantedBy=multi-user.target
+EOF
+info "writing tor_announce to /usr/bin/tor_announce"
+printf '#!/bin/sh\nsleep 20\n' > /usr/bin/tor_announce
+http_get conf.krebsco.de/tor_publish_ssh >> /usr/bin/tor_announce
+chmod +x /usr/bin/tor_announce
+info "enable tor_announce"
+systemctl enable tor_announce
+#systemctl start tor_announce
+}
diff --git a/ship/lib/iso b/ship/lib/iso
new file mode 100644
index 00000000..0776d796
--- /dev/null
+++ b/ship/lib/iso
@@ -0,0 +1,7 @@
+get_volid(){
+ #returns the volume id of the iso given
+ # is needed for remastering the archlinux iso
+
+ #punani install genisoimage
+ isoinfo -d -i "${1?path to iso must be given}" | grep "^Volume id:" | cut -d: -f 2 |xargs
+}
diff --git a/ship/lib/krebs b/ship/lib/krebs
new file mode 100644
index 00000000..e47031d6
--- /dev/null
+++ b/ship/lib/krebs
@@ -0,0 +1,16 @@
+#@include core
+krebs_pubkeys="ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC7YrLdnXDRU2XEdZDu1BmgiT0Vaxplf3bfvSm+5o3g4AcR2yCv7h2D633c9uA0gq52EJ3V5m8B1ZcxqA0zqDptKwx+ZTMUGDls7StH5xpJyk9j5gf8DzyDLQPQG2IYszCH+8esKjo3BOFxfey8NaX+k6gvQsG3lyV0PjLvvIy4gDuMn6dPZfVAlwNYFOUNgwpku3W3A0d+UFyVjt3/sgZxM+8C3y6QE1gwT5/NfBbHM5vaEqjHcVq1ui+7a4iOXFGKkZDcd7EX6cQZSbCzZL7sZ0OmB1WpAsDCvIXfzX1YfNA0sso7ldSF6ZUGNgwEk1LootnQlCK/dfbM+i62SZ+1 tv@iiso
+ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCv9TTt4FkzT3jlQ0VS2tX/GpQO9Ef0wIQ+g96foe4qSniBwR667T1gIhURrod/p7N9oQcWRrNohjgmSBZRYA0kW6ZyqYJkLvRv54nXv6j/8Xq2nG/KVfDqL0kp8if+JGeFlQElpWJiAbGifYkopFy69QiLYU2ndR7aPbx+5qm/dcwPJ7K+n6dyePynCZadtcabm3PuBFUxGLdT9ImDXMOPfXxPMlN/3eb78byuEuHnhCIvIGLMBGx+8QTXvu7kHpZObvkbsF1xjVs9fDpwVLjh7GWdwf3BZ/agFlI24ffyqCPFnuaxUVyfUZeqf4twRsIZkTTB47lHDhYiVkyGe8gd root@pigstarter.de
+ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCl3RTOHd5DLiVeUbUr/GSiKoRWknXQnbkIf+uNiFO+XxiqZVojPlumQUVhasY8UzDzj9tSDruUKXpjut50FhIO5UFAgsBeMJyoZbgY/+R+QKU00Q19+IiUtxeFol/9dCO+F4o937MC0OpAC10LbOXN/9SYIXueYk3pJxIycXwUqhYmyEqtDdVh9Rx32LBVqlBoXRHpNGPLiswV2qNe0b5p919IGcslzf1XoUzfE3a3yjk/XbWh/59xnl4V7Oe7+iQheFxOT6rFA30WYwEygs5As//ZYtxvnn0gA02gOnXJsNjOW9irlxOUeP7IOU6Ye3WRKFRR0+7PS+w8IJLag2xb makefu@pornocauster
+ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC7df1RfMGNHPJe0iF6rD9DBs/4VujN6nNr7RbRCFk7HF/JzLXSn9Vcwk+3JefP4/d/bUo0h03rhQaRohDhBScrJidj2YacF6gmZOuTf3AMWprdz9D/1dDkN/ytwzGhADhqbHEWeomIllsa8Up4PvEeDcIHJGzYvuc0BbGqRk0XgxwqIrLAhdpTfEKaTbt7IzmUqEofxThTZ/4k020PKn2WDBWKQYGZJ9Ba2WzlKUXWx842ncW29oxC2faRz4M3eMPy0JMpBLkK9U3dccE75dgT/89/4ofVjM7+J3FOP3dgXzrtk+A5aN5a/veJUViQ9xdGxXvoa++iCr5q/BVRv0Bb sammy@muhbaasu.de
+ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDOIRWLC4ESCDxjyoJUqaUNC8ZDiE4UICZk3cbDptdtendTQvjSXz0RW6MWhJ+F6wWZntL1EibKn8djax1tzgcvNASCUEtGey/850IzBIrETs+WQDRjV2QqBKWxVaQPIFjw2V3vFSKKNxq01qznVBY510DIf4+0WR8b1ZPD/XbuyQLGYM3N7dP4JQSnnNAgtyutBKdomWfT18hW1lLjkP8h1IOiC03HxXTYX+nMUiLDff3D5GT5u3Ke2+VigXjz4Ue8rVsOg/zgqrwEAfx8o1q83uSB23oqUqWkqlxOC/4QY5kpdNqW/Iz89zHibp5ZceHd2ZSoGefv7UZM0lRIDHjJ retiolum@ire
+ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC3+2vSwiJoIpHpnkw4SslPrlR6/z43nZ7s1tGXkkNnVDB2uzxMaISNRjSk0GgXpDx4hLEi6074hSvv5JWbUuMyKr9n6GVVeYNCjsiPcRkL3d7zDwFwqyndhVeWgmpuylYx4XKIbTvpBVyG3CRT1+D4apVUgiDa9lVfjBk7/ESxBzt0dXtlJEzQBBoCo0C8jeeIpvZKbq1zeM9wvLsgFaT7fsSxrg5BEb/tQl6pbkykWFXbzzd91liEQaSqai7Ux2355ZXGANQBCTglKhdTcir0RuHNtQGrZHBxL9qVfJjJJNZg1b6UAhDanqE/HyOI3sp6LGBvpW5afLKOdj9ppQQN retiolum@nomic
+ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAp83zynhIueJJsWlSEykVSBrrgBFKq38+vT8bRfa+csqyjZBl2SQFuCPo+Qbh49mwchpZRshBa9jQEIGqmXxv/PYdfBFQuOFgyUq9ZcTZUXqeynicg/SyOYFW86iiqYralIAkuGPfQ4howLPVyjTZtWeEeeEttom6p6LMY5Aumjz2em0FG0n9rRFY2fBzrdYAgk9C0N6ojCs/Gzknk9SGntA96MDqHJ1HXWFMfmwOLCnxtE5TY30MqSmkrJb7Fsejwjoqoe9Y/mCaR0LpG2cStC1+37GbHJNH0caCMaQCX8qdfgMVbWTVeFWtV6aWOaRgwLrPDYn4cHWQJqTfhtPrNQ== death@uriel"
+
+authorized_keys_file="${authorized_keys:-$HOME/.ssh/authorized_keys}"
+deploy_krebs_pubkeys(){
+info "deploying pubkeys in $authorized_keys_file"
+mkdir -p "$(dirname "$authorized_keys_file")"
+printf "$krebs_pubkeys\n" >> "$authorized_keys_file"
+
+}
diff --git a/ship/lib/network b/ship/lib/network
new file mode 100644
index 00000000..6c8970a0
--- /dev/null
+++ b/ship/lib/network
@@ -0,0 +1,110 @@
+#@include core
+
+# TODO refactor this
+which_get_loader(){
+ if ! exists curl ; then
+ if ! exists wget ; then
+ warn "Please install curl or wget"
+ return 1
+ else
+ echo "wget -q -O-"
+ fi
+ else
+ echo "curl -L -s"
+ fi
+ return 0
+}
+
+which_head_loader(){
+ if ! exists curl ; then
+ if ! exists wget ; then
+ warn "Please install curl or wget"
+ return 1
+ else
+ echo "wget -O- --spider -S -q"
+ fi
+ else
+ echo "curl -L -I -s"
+ fi
+ return 0
+}
+
+http_get(){
+ eval "$(which_get_loader)" "${1?please provide url}"
+}
+http_head(){
+ eval "$(which_head_loader)" "${1?please provide url}" 2>&1
+}
+
+internet(){
+ secret=$(http_get http://krebsco.de/secret 2>/dev/null)
+ if [ "$secret" = "1337" ]; then
+ return 0
+ else
+ echo "cannot load secret or secret incorrect" >&2
+ return 1
+ fi
+}
+
+which_telnet(){
+ # find Telnet or similar and executes it at the end
+ # requires exist
+ # if env TELNET is set, will be trying to run this
+ # Tries the following things:
+ # telnet
+ # nc
+ # netcat
+ # busybox telnet
+ if [ -e "${TELNET:-does_not_exist}" ]; then
+ info "Will be using $TELNET as Telnet Client"
+ echo $TELNET
+ elif exists telnet ;then
+ command -v telnet
+ elif exists nc ;then
+ command -v nc
+ elif exists netcat;then
+ command -v netcat
+ elif exists busybox;then
+ echo `command -v busybox` telnet
+ else
+ die 'Cannot find telnet binary, please install either telnet-client or busybox or netcat or provided TELNET environment.'
+ fi
+}
+
+run_telnet(){
+ host="$1"
+ port="$2"
+ $(which_telnet) "$host" "$port"
+}
+port_open(){
+ # $1 - host
+ # $2 - port
+ # nc -zw 2 $1 $2
+ echo | run_telnet "$1" "$2" & pid=$!
+ { sleep 5; kill $pid;} & wid=$!
+ wait $pid
+ RET=$?
+ kill $wid >/dev/null 2>&1
+ return $RET
+}
+
+send_irc(){
+ ## reads from stdin, writes to IRC
+ ##
+ ## requires func: exists() anytelnet()
+ if [ -z "${HOSTN:-}" ]; then
+ HOSTN="$(get_hostname)"
+ info "no HOSTN given, using $HOSTN instead"
+ fi
+ IRCCHANNEL=${IRCCHANNEL:-"#krebs_incoming"}
+ IRCSERVER=${IRCSERVER:-"irc.freenode.net"}
+ IRCPORT=${IRCPORT:-6667}
+ NICK="${HOSTN}_$(head /dev/urandom | tr -dc "0123456789" | head -c3)"
+ info "starting irc connect as $NICK"
+ ( echo "NICK $NICK";
+ echo "USER $NICK $IRCSERVER bla : $NICK";
+ echo "JOIN $IRCCHANNEL";
+ sleep 23;
+ while read line; do echo "PRIVMSG $IRCCHANNEL :$line";sleep 1;done
+ sleep 5; ) | run_telnet $IRCSERVER $IRCPORT 2>/dev/null
+}
diff --git a/ship/lib/punani b/ship/lib/punani
new file mode 100644
index 00000000..4338d19d
--- /dev/null
+++ b/ship/lib/punani
@@ -0,0 +1,99 @@
+#@include core
+#@include _punani_db
+
+## usage: punani_has PACKAGE
+punani_has() {
+ eval "_punani_${PACKER}_has \"\$1\""
+}
+
+## usage: punani_owner PACKAGE
+punani_owner() {
+ eval "_punani_${PACKER}_owner \"\$1\""
+}
+
+## usage: punani_install PACKAGE
+punani_install() {
+ eval "_punani_${PACKER}_install \"\$1\""
+}
+
+## usage: punani_remove PACKAGE
+punani_remove() {
+ eval "_punani_${PACKER}_remove \"\$1\""
+}
+
+## usage: _punani_resolve_package PKGNAME
+_punani_resolve_package(){
+ eval "set -u; echo \"\${_punanidb_${PACKER}_$1}\"" 2>/dev/null
+}
+
+## usage: _punani_select_packer
+_punani_select_packer() {
+ for p in ${_punani_known_packers:-null}; do
+ exists $p && info "using $p" && PACKER=`echo $p | tr -d -` && break
+ done
+}
+_punani_known_packers='pacman apt-get yum brew'
+_punani_pacman_install(){ pacman --noconfirm -S --needed "$@" ;}
+_punani_pacman_remove(){ pacman --noconfirm -Rcs "$@" ;}
+_punani_pacman_has(){ pacman -Q "$1" >/dev/null;}
+_punani_pacman_owner() { pacman -Qo "$1"; }
+_punani_aptget_install(){ apt-get -y install "$@" ;}
+_punani_aptget_remove(){ apt-get -y remove "$@" ;}
+_punani_aptget_has() { dpkg -s "$1" | grep -q "Status: install";}
+_punani_aptget_owner() { dpkg-query -S "$1" | cut -d: -f1;}
+_punani_yum_install(){ yum -y install "$@" ;}
+_punani_yum_remove(){ yum -y remove "$@" ;}
+_punani_yum_has() { rpm -qa --qf "%{NAME}\n"| egrep "^${1}\$" >/dev/null ;}
+_punani_yum_owner(){ rpm -qf "$1" ;}
+_punani_brew_install(){ brew install "$@"; }
+_punani_brew_remove(){ brew remove "$@";}
+# TODO _punani_brew_has
+
+punani(){
+ # punani UI
+ _punani_usage='punani {install,remove,has,owner} PACKAGE...'
+ _punani_select_packer || die 'no package manager found; no punani for you!'
+
+ ACTION="$1"; shift
+
+ if test $# = 0; then
+ error 'no PACKAGE specified.'
+ die "usage: $_punani_usage"
+ fi
+
+ for PKG; do
+ RES="`_punani_resolve_package $PKG`" ||
+ die "could not resolve '$PKG'; no punani for you!"
+
+ case "$ACTION" in
+ install)
+ if punani_has $RES; then
+ info "$RES already installed, skipping"
+ else
+ punani_install $RES || die "cannot install $RES with $PACKER"
+ fi
+ ;;
+ remove)
+ if ! punani_has $RES; then
+ info "$RES not installed, skipping"
+ else
+ punani_remove $RES || die "cannot install $RES with $PACKER"
+ fi
+ ;;
+ has)
+ if punani_has $RES; then
+ info "$RES is installed"
+ else
+ info "$RES is not installed"
+ exit 1
+ fi
+ ;;
+ owner)
+ punani_owner $RES
+ ;;
+ *)
+ error "bad action: $ACTION"
+ die "usage: $_punani_usage"
+ esac
+ done
+}
diff --git a/ship/lib/retiolum b/ship/lib/retiolum
new file mode 100644
index 00000000..eba2775e
--- /dev/null
+++ b/ship/lib/retiolum
@@ -0,0 +1,109 @@
+#!/bin/sh
+# retiolum host functions
+#@include core
+#@include network
+tinc_path=${tinc_path:-/etc/tinc}
+netname=${netname:-retiolum}
+hosts_dir=${hosts_dir:-$tinc_path/$netname/hosts}
+supernode_urls="http://euer.krebsco.de/retiolum/supernodes.tar.gz"
+reload_tinc(){
+ info "reloading tinc configuration"
+ pkill -HUP tincd || tinc -n $netname reload;
+}
+
+refresh_supernode_keys(){
+ for url in $supernode_urls;do
+ info "Trying $url to retrieve supernodes"
+ if http_get "$url" \
+ | tar xvz -C $hosts_dir | xargs -n1 echo "refreshed:" ;then
+ info "refreshed supernode keys"
+ return 0
+ else
+ error "$url unusable for retrieving supernode host files"
+ fi
+ done && return 1
+}
+port_open(){
+ # $1 - host
+ # $2 - port
+ # nc -zw 2 $1 $2
+ echo | run_telnet "$1" "$2" & pid=$!
+ { sleep 5; kill $pid;} & wid=$!
+ wait $pid
+ RET=$?
+ kill $wid >/dev/null 2>&1
+ return $RET
+}
+find_supernodes(){
+ cd $hosts_dir
+ set +f
+ for name in `
+ grep '^[ ]*Address[ ]*=' * |
+ cut -d: -f1 | sort | uniq
+ `; do
+ if eval "`sed -n '
+ s/[ ]\+//g
+ s/^\(Address\|Port\)=\(.*\)/\1="\${\1+\$\1\n}\2"/p
+ ' $name`"; then
+ port=${Port-655}
+ for host in $Address; do
+ if port_open $host $port 2>/dev/null; then
+ echo "$name [('$host', $port)]"
+ fi &
+ done
+ wait
+ fi &
+ done
+ wait
+ cd - >/dev/null
+}
+
+find_active_nodes(){
+ # TODO this function currently only supports a single address for a host
+ cd $hosts_dir
+ # posix grep does not support [[:space:]]
+ set +f
+ for name in `
+ grep '^[ ]*Address[ ]*=' * |
+ cut -d: -f1 | sort | uniq
+ `; do
+ if eval "`sed -n '
+ s/[ ]\+//g
+ s/^\(Address\|Port\)=\(.*\)/\1="\${\1+\$\1\n}\2"/p
+ ' $name`"; then
+ port=${Port-655}
+ for host in $Address; do
+ if port_open $host $port 2>/dev/null; then
+ echo "$name [('$host', $port)]"
+ fi &
+ done
+ wait
+ fi &
+ done
+ wait
+ cd - >/dev/null
+}
+
+check_free_v4(){
+ myipv4=${1-10.243.0.-1}
+ v4num=${myipv4##*.}
+ printf "Retard check: "
+ if [ "$v4num" -gt 0 -a "$v4num" -lt "256" ];
+ then
+ info "No retard detected\n"
+ cd $hosts_dir
+ info "Check if ip is still free: "
+ for i in `ls -1`; do
+ if grep -q -e $myipv4\$ $i ;then
+ error "Host IP already taken by $i! "
+ return 1
+ fi
+ done
+ info "Passed\n"
+ return 0
+ else
+ error "you are made of stupid. bailing out\n"
+ return 1
+ fi
+ cd - >/dev/null
+}
diff --git a/ship/lib/tahoe b/ship/lib/tahoe
new file mode 100644
index 00000000..6960b3e7
--- /dev/null
+++ b/ship/lib/tahoe
@@ -0,0 +1,34 @@
+#@include core
+#@include network
+#@include punani
+
+tahoe_home=/home/tahoe
+tahoe_dir=$tahoe_home/.tahoe
+tahoe_init(){
+ # installs dependencies, user and a virtual environment for the tahoe user
+ punani install gpp pip2 python2_dev python2 virtualenv
+ has_user tahoe || useradd -r -m -b $tahoe_home -s /bin/false
+ cd $tahoe_home
+ virtualenv --no-site-packages -p "`type -p python2.7`"
+ . bin/activate
+ pip install twisted pyasn1
+ pip install allmydata-tahoe
+ chown tahoe -R $tahoe_home
+}
+tahoe_create_node(){
+ # requires tahoe_init
+ sudo -u tahoe create-node $tahoe_dir
+ sudo -u tahoe cat > $tahoe_dir/tahoe.cfg <<EOF
+[node]
+nickname = $(get_hostname)
+web.port =
+web.static = public_html
+
+[client]
+introducer.furl = $(http_get http://pigstarter/tahoe/introducer.furl)
+helper.furl = $(http_get http://pigstarter/tahoe/helper.furl)
+[storage]
+enabled = true
+reserved_space = 1G
+EOF
+}
diff --git a/ship/lib/tor b/ship/lib/tor
new file mode 100644
index 00000000..0911e92a
--- /dev/null
+++ b/ship/lib/tor
@@ -0,0 +1,20 @@
+# can be set via env:
+# torrc - path to torrc (default: /etc/tor/torrc )
+# hidden_service_dir - path to hidden service (default: /var/lib/tor/hidden_service/ )
+
+
+torrc=${torrc:-/etc/tor/torrc}
+hidden_service_dir=${hidden_service_dir:-/var/lib/tor/hidden_service/}
+
+configure_hidden_service(){
+ mkdir -p "$hidden_service_dir"
+ if ! grep -q '^HiddenService' "$torrc" ;then
+ info "adding hidden service to $torrc"
+ cat >> "$torrc" << EOF
+HiddenServiceDir ${hidden_service_dir}
+HiddenServicePort 22 127.0.0.1:22
+EOF
+ else
+ info "HiddenServiceDir or Port already in $torrc, skipping!"
+ fi
+}
diff --git a/ship/lib/vim b/ship/lib/vim
new file mode 100644
index 00000000..f75f3d0e
--- /dev/null
+++ b/ship/lib/vim
@@ -0,0 +1,40 @@
+# configure vim
+
+vimrc=$HOME/.vimrc
+
+vim_conf_sane_defaults(){
+ # TODO - make stuff more modular?
+ cat >>$vimrc<<EOF
+set nocompatible
+filetype plugin indent on
+syntax on
+set vb
+set foldenable
+set foldmethod=syntax
+set ignorecase
+set incsearch
+set showmatch
+set matchtime=3
+set hlsearch
+set backupdir=~/.vim/backup
+set directory=~/.vim/backup
+inoremap <F1> <ESC>
+nnoremap <F1> <ESC>
+vnoremap <F1> <ESC>
+set wildignore=*.o,*.obj,*.bak,*.exe,*.os
+cmap w!! w !sudo tee > /dev/null %
+colorscheme darkblue
+set background=dark
+set number
+set mouse=
+set shiftwidth=2
+set tabstop=2
+set et
+set sw=2
+set smarttab
+set autoindent
+set backspace=indent,eol,start
+set nocp
+EOF
+ mkdir -p $HOME/.vim/backup
+}
diff --git a/ship/src/arch_autoinstall b/ship/src/arch_autoinstall
new file mode 100755
index 00000000..c9b6c4d4
--- /dev/null
+++ b/ship/src/arch_autoinstall
@@ -0,0 +1,164 @@
+#/bin/sh
+#@strict
+#@include core
+#@include color
+#@include network
+#@include tor
+pass=shackit
+shack_printer_ip=10.42.0.135
+extra_pkg="xorg vim xfce4 feh chromium zsh sudo git flashplugin alsa-oss alsa-lib alsa-utils grub-bios slim ntp tor network-manager-applet networkmanager openssh cups cups-filters"
+
+info "writing stdout to /tmp/install.log"
+defer 'pkill tail'
+
+installer_disk(){
+ find /dev/disk/by-label/ -name ARCH_\* 2>/dev/null | xargs readlink
+}
+
+find_rootdisk(){
+ for i in sd vd hd;do
+ for j in a b;do
+ dsk="/dev/$i$j"
+ test "$(installer_disk)" == "$dsk" && continue
+ test -e "$dsk" && echo "$dsk" && return
+ done
+ done
+}
+
+rootdisk=$(find_rootdisk)
+test "$rootdisk" || die "cannot find your root disk"
+
+info "Your rootdisk is $rootdisk"
+sleep 3
+
+umount /mnt/boot ||:
+umount /mnt ||:
+info "starting partitioning"
+(printf "o\nn\np\n\n\n+256M\n\a\nn\np\n\n\n\nw\n\n") |fdisk $rootdisk||:
+info "done partitioning"
+sleep 1
+info "generating filesystem on /boot"
+mkfs.ext2 ${rootdisk}1
+info "Done"
+sleep 1
+info "starting LVM magic"
+vgchange -an ||:
+vgremove -f pool0 ||:
+pvcreate ${rootdisk}2
+vgcreate -ff pool0 ${rootdisk}2
+lvcreate -l 100%free -n root pool0
+info "finished creating LVM"
+sleep 1
+info "generating filesystems on the LVM"
+mkfs.ext4 /dev/mapper/pool0-root
+info "finished generating filesystems"
+sleep 1
+info "mounting"
+mount /dev/mapper/pool0-root /mnt
+mkdir /mnt/boot
+mount ${rootdisk}1 /mnt/boot
+
+info "finished mounting!"
+sleep 1
+info "installing!"
+
+info "Setting http proxy"
+if http_head heidi.shack:3142 &>/dev/null; then
+ http_proxy=heidi.shack:3142
+ info "Heidi is reachable, will use this box as proxy"
+else
+ http_proxy=''
+ info "Will not use any proxy"
+fi
+info "Installing the following packages: $extra_pkg"
+if [ -n "${user_pkg:-}" ] ;then
+ info "User chooses additional packages: $user_pkg"
+else
+ info "No additional packages set by user (\$user_pkg unset)"
+fi
+http_proxy=${http_proxy} pacstrap /mnt base base-devel $extra_pkg ${user_pkg:-}
+info "installation done"
+sleep 1
+info "generating configs"
+genfstab -U -p /mnt > /mnt/etc/fstab
+
+info "beginning chroot!"
+arch-chroot /mnt << EOF
+
+msg() { printf "\$*\n" >&2; }
+info() { msg "$green\$*$nc"; }
+error() { msg "$green\$*$nc"; }
+
+info "generating locales"
+ln -s /usr/share/zoneinfo/Europe/Berlin /etc/localtime
+echo "LANG=en_US.UTF-8" >> /etc/locale.conf
+echo "en_US.UTF-8 UTF-8" >> /etc/locale.gen
+locale-gen
+echo "shackbook$RANDOM" > /etc/hostname
+sed -i 's/block/& lvm2/g' /etc/mkinitcpio.conf
+info "Done! "
+mkinitcpio -p linux
+info "setting root password"
+printf "${pass}\n${pass}\n" | (passwd )
+info "adding user"
+useradd -d /home/shack -m -G audio,video,wheel -s /usr/bin/zsh shack
+printf "${pass}\n${pass}\n" | (passwd shack)
+
+info "editing sudoers"
+printf "root ALL=(ALL) ALL\n%s ALL=(ALL) ALL\n" %wheel >> /etc/sudoers
+info "configuring slim"
+printf "default_user\tshack\nfocus_password\tyes\nauto_login\tyes\n" >> /etc/slim.conf
+info "configuring .xinitrc"
+printf "exec startxfce4\n" >> /home/shack/.xinitrc
+
+for i in slim NetworkManager ntpd tor cups; do
+ info "enabling \$i"
+ systemctl enable \$i
+done
+
+### CUPS
+mkdir -p /etc/cups
+cat >>/etc/cups/printers.conf<<EOT
+<Printer HP_LaserJet_5000_Series>
+Info Shack Printer HP 5000
+Location lounge
+MakeModel HP LaserJet Series PCL 6 CUPS
+DeviceURI socket://$shack_printer_ip
+State Idle
+StateTime 1387400063
+Type 8400964
+Accepting Yes
+Shared No
+JobSheets none none
+QuotaPeriod 0
+PageLimit 0
+KLimit 0
+OpPolicy default
+ErrorPolicy stop-printer
+</Printer>
+EOT
+
+info "installing grub"
+grub-install ${rootdisk} 2>/dev/null
+echo "GRUB_DISABLE_LINUX_UUID=true" >> /etc/default/grub
+grub-mkconfig > /boot/grub/grub.cfg 2>/dev/null
+
+info "installing oh-my-zsh"
+curl -L https://github.com/robbyrussell/oh-my-zsh/raw/master/tools/install.sh | sudo -u shack sh
+sed -i 's/robbyrussell/afowler/g' /home/shack/.zshrc
+info "fixing chrome for incognito use"
+sed -i 's/Exec=chromium/Exec=chromium --incognito/g' /usr/share/applications/chromium.desktop
+exit
+EOF
+
+info "configuring tor"
+torrc=/mnt/etc/tor/torrc
+hidden_service_dir=/var/lib/tor/hidden_service/
+configure_hidden_service
+#TODO publish tor address after reboot
+#info "publishing hidden service address"
+#cat $hidden_service_dir/hostname | send_irc
+
+
+info "We're all done, simply reboot!"
+reboot
diff --git a/ship/src/bootstrap_env_makefu b/ship/src/bootstrap_env_makefu
new file mode 100755
index 00000000..e61f4e99
--- /dev/null
+++ b/ship/src/bootstrap_env_makefu
@@ -0,0 +1,171 @@
+#!/bin/sh
+# TODO: modularize zsh configuration and vim configuration
+#@info
+#@strict
+#@include core
+#@include punani
+#@include vim
+
+# vim +python
+_punanidb_pacman_vim_python=gvim
+_punanidb_yum_vim_python=vim-enhanced
+_punanidb_aptget_vim_python=vim
+
+# TODO pull out youcompleteme into a vim function
+# cmake ,make,g++,python-dev for youcompleteme
+_punanidb_pacman_cmake=cmake
+_punanidb_yum_cmake=cmake
+_punanidb_aptget_cmake=cmake
+#@mainifyme
+
+info "Configuring environment for $(id -un)"
+cd $(readlink -f $(dirname $0))
+info "Using punani to install git vim and zsh"
+punani install git vim_python zsh gpp cmake make python2_dev || die "cannot install some shit"
+
+info "writing dotfiles"
+# deploying zshrc
+# TODO modularize zshrc
+cat > $HOME/.zshrc <<EOF
+# Path to your oh-my-zsh configuration.
+export ZSH=\$HOME/.oh-my-zsh
+
+# Look in ~/.oh-my-zsh/themes/
+export ZSH_THEME="gallifrey"
+
+# Comment this out to disable weekly auto-update checks
+export DISABLE_AUTO_UPDATE="true"
+
+plugins=(git ssh-agent)
+. \$ZSH/oh-my-zsh.sh
+test -e \$HOME/.aliases && source \$HOME/.aliases
+
+# Customize to your needs...
+export PATH=/usr/sbin:/krebs/bin:\$HOME/bin:\$PATH:/sbin
+HISTFILE=~/.histfile
+HISTSIZE=9000001
+SAVEHIST=9000001
+
+export EDITOR=vim
+
+export JAVA_HOME=\$JAVA_HOME:/opt/java/jre
+
+GREP_COLOR="1;33"
+alias grep='grep --color=auto'
+alias vi=vim
+
+export MANPATH=\$MANPATH:\$HOME/man
+
+if [ -f "\$HOME/.dircolors" ] ; then
+ eval \$(dircolors -b "\$HOME/.dircolors")
+ export LS_COLORS
+fi
+
+which fortune >/dev/null && fortune -a
+which task >/dev/null && task
+echo "--"
+test -r ~/TODO && cat ~/TODO
+
+setopt menu_complete
+unsetopt correct_all
+export PYTHONSTARTUP=~/.pythonrc
+EOF
+info 'deploying pythonrc'
+cat > $HOME/.pythonrc <<EOF
+import rlcompleter, readline
+readline.parse_and_bind('tab:complete')
+EOF
+info "deploying vim config"
+if [ -e $HOME/.vim ] ; then
+ oldvim=$HOME/.vim.`date +%Y%M%d`
+ info "Backing up old vim folder to $oldvim"
+ mv -v $HOME/.vim $oldvim
+fi
+
+mkdir -p $HOME/.vim
+
+# TODO modilarize vimconfig
+
+cat > $HOME/.vim/vimrc <<EOF
+filetype off
+set rtp+=~/.vim/bundle/vundle
+call vundle#rc()
+" TODO refactor this
+Bundle 'gmarik/vundle'
+Bundle 'SudoEdit.vim'
+Bundle 'snipMate'
+Bundle 'tpope/vim-fugitive'
+Bundle 'Valloric/YouCompleteMe'
+Bundle 'scrooloose/syntastic'
+Bundle 'sjl/gundo.vim'
+
+nnoremap <F5> :GundoToggle<CR>
+set undodir=~/.vim/undo
+set undofile
+"maximum number of changes that can be undone
+set undolevels=1000000
+"maximum number lines to save for undo on a buffer reload
+set undoreload=10000000
+
+set pastetoggle=<F2>
+set showmode
+filetype plugin indent on
+
+
+filetype plugin indent on
+
+let g:snips_author = 'Bob Ross <root@syntax-fehler.de>'
+let g:makefu_author = 'makefu'
+
+" pasting
+nnoremap <F2> :set invpaste paste?<CR>
+set pastetoggle=<F2>
+set showmode
+
+" save on focus lost
+au FocusLost * :wa
+
+set spelllang=en
+
+set textwidth=9001
+autocmd BufRead *.json set filetype=json
+EOF
+if [ -e $HOME/.vimrc ] ; then
+ oldvim=$HOME/.vimrc.`date +%Y%M%d`
+ info "Backing up old vimrc file to $oldvim"
+ mv -v $HOME/.vimrc $oldvim
+fi
+info "Symlinking .vimrc to .vim/vimrc"
+ln -vs $HOME/.vim/vimrc $HOME/.vimrc
+vim_conf_sane_defaults
+
+#install all the vim stuff with the help of vundle
+cd $HOME/.vim
+mkdir -p bundle undo backup
+info "Fetching vim-vundle"
+git clone https://github.com/gmarik/vundle.git bundle/vundle > /dev/null && \
+ info "Vim Vundle deployed"
+info "Installing Vundle Bundles"
+vim "+:BundleInstall" "+:qall"
+
+info "building youcompleteme libs"
+cd $HOME/.vim/bundle/YouCompleteMe
+./install.sh
+cd -
+
+info "configuring zsh"
+if exists zsh; then
+ if [ "$SHELL" != "`which zsh`" ] ;then
+ info "setting zsh as new shell,please enter your user password"
+ chsh -s `which zsh`
+ else
+ info "zsh already set as default shell"
+ fi
+ if [ ! -d ~/.oh-my-zsh ] ; then
+ git clone https://github.com/robbyrussell/oh-my-zsh.git ~/.oh-my-zsh > /dev/null && info "oh-my-zsh deployed"
+ else
+ info "oh-my-zsh already installed"
+ fi
+else
+ error "cannot find zsh :("
+fi
diff --git a/ship/src/deploy-ssh-keys b/ship/src/deploy-ssh-keys
new file mode 100644
index 00000000..7eedb2cb
--- /dev/null
+++ b/ship/src/deploy-ssh-keys
@@ -0,0 +1,15 @@
+#!/bin/sh
+#@info
+#@strict
+#@include core
+cd $(dirname $0)
+U="${1:-$(id -u -n)}"
+H="$(grep "^$U" /etc/passwd | cut -d : -f 6)"
+krebsdir=${krebsdir:-/krebs}
+
+info "deploying for user $U to $H/.ssh"
+mkdir -p $H/.ssh
+
+cp -vr $krebsdir/infest/skel/home/.ssh/authorized_keys $H/.ssh
+chown $U $H
+chown -R $U $H/.ssh
diff --git a/ship/src/filehooker_configure_ncdc b/ship/src/filehooker_configure_ncdc
new file mode 100644
index 00000000..c980ebf2
--- /dev/null
+++ b/ship/src/filehooker_configure_ncdc
@@ -0,0 +1,15 @@
+#!/bin/sh
+#@info
+#@strict
+#@include filehooker
+
+dc_hub="adcs://elch.nsupdate.info:2781"
+rnd=`hexdump -n 2 -e '/2 "%u"' /dev/urandom`
+nick="filehooker_$rnd"
+
+
+ncdc_install
+ncdc_autostart
+
+ncdc_configure_nick "$nick"
+ncdc_configure_hub "$dc_hub"
diff --git a/ship/src/filehooker_configure_netshare b/ship/src/filehooker_configure_netshare
new file mode 100644
index 00000000..438ac133
--- /dev/null
+++ b/ship/src/filehooker_configure_netshare
@@ -0,0 +1,7 @@
+#!/bin/sh
+#@info
+#@strict
+#@include filehooker
+for i in $(prepare_netshares) ;do
+ ncdc_configure_netshare "$i" "${i##*/}"
+done
diff --git a/ship/src/filehooker_install b/ship/src/filehooker_install
new file mode 100755
index 00000000..eb2d5fd1
--- /dev/null
+++ b/ship/src/filehooker_install
@@ -0,0 +1,143 @@
+#/bin/sh
+#@info
+#@strict
+#@include core
+## colored logging
+#@include color
+#@include network
+
+## for tor hidden service
+#@include tor
+
+## for ncdc
+#@include filehooker
+pass=lolwut.aidsballs
+# 20gig
+#min_netshare_size=20000000000
+admin=pimp
+extra_pkg="vim sudo grub-bios ntp tor openssh btrfs-progs tmux"
+
+info "writing stdout to /tmp/install.log"
+
+
+installer_disk(){
+ find /dev/disk/by-label/ -name ARCH_\* 2>/dev/null | xargs readlink
+}
+
+find_rootdisk(){
+ for i in sd vd hd;do
+ for j in a b c;do
+ dsk="/dev/$i$j"
+ test ! -e "$dsk" && continue
+ test "$(installer_disk)" == "$dsk" && continue
+ test "$(get_disksize $dsk)" -gt "$min_netshare_size" && info "not using $dsk as it is too big" && continue
+ echo "$dsk" && return
+ done
+ done
+}
+
+rootdisk=$(find_rootdisk)
+test "$rootdisk" || die "cannot find your root disk"
+
+info "Your rootdisk is $rootdisk"
+sleep 3
+
+umount /mnt/boot ||:
+umount /mnt ||:
+info "overwriting partitioning"
+dd if=/dev/zero of=$rootdisk bs=2k count=10
+info "starting partitioning"
+(printf "o\nn\np\n\n\n+128M\n\a\nn\np\n\n\n\nw\n\n") |fdisk $rootdisk ||:
+partprobe $rootdisk
+info "done partitioning"
+sleep 1
+info "generating filesystem on /boot"
+mkfs.ext2 ${rootdisk}1
+info "Done"
+sleep 3
+sync
+vgchange -an
+info "generating filesystems"
+mkfs.btrfs -f ${rootdisk}2
+sleep 1
+info "finished generating filesystems"
+sleep 1
+info "mounting"
+mount ${rootdisk}2 /mnt
+mkdir /mnt/boot
+mount ${rootdisk}1 /mnt/boot
+
+info "finished mounting!"
+sleep 1
+info "installing!"
+
+info "Setting http proxy"
+
+info "Installing the following packages: $extra_pkg"
+if [ -n "${user_pkg:-}" ] ;then
+ info "User chooses additional packages: $user_pkg"
+else
+ info "No additional packages set by user (\$user_pkg unset)"
+fi
+pacstrap /mnt base $extra_pkg ${user_pkg:-}
+info "installation done"
+sleep 1
+info "generating configs"
+genfstab -U -p /mnt > /mnt/etc/fstab
+
+info "beginning chroot!"
+########### BEGIN CHROOT #####
+arch-chroot /mnt << EOF
+#@strict
+msg() { printf "\$*\n" >&2; }
+info() { msg "$green\$*$nc"; }
+error() { msg "$green\$*$nc"; }
+
+info "generating locales"
+ln -s /usr/share/zoneinfo/Europe/Berlin /etc/localtime
+echo "LANG=en_US.UTF-8" >> /etc/locale.conf
+echo "en_US.UTF-8 UTF-8" >> /etc/locale.gen
+locale-gen
+echo "filehooker$RANDOM" > /etc/hostname
+info "Done! "
+mkinitcpio -p linux ||
+info "setting root password"
+printf "${pass}\n${pass}\n" | (passwd )
+info "adding user"
+useradd -m -G audio,video,wheel $admin
+printf "${pass}\n${pass}\n" | (passwd $admin)
+
+info "editing sudoers"
+printf "root ALL=(ALL) ALL\n%s ALL=(ALL)NOPASSWD: ALL\n" %wheel >> /etc/sudoers
+for i in dhcpcd ntpd tor sshd ; do
+ info "enabling \$i"
+ systemctl enable \$i
+done
+
+info "installing grub"
+grub-install ${rootdisk} 2>/dev/null
+#echo "GRUB_DISABLE_LINUX_UUID=true" >> /etc/default/grub
+grub-mkconfig > /boot/grub/grub.cfg 2>/dev/null
+# prepare ncdc
+useradd -m hooker
+exit
+EOF
+######## END CHROOT ##########
+sync
+
+info "configuring tor"
+torrc=/mnt/etc/tor/torrc
+hidden_service_dir=/var/lib/tor/hidden_service/
+configure_hidden_service
+#info "publishing hidden service address"
+#cat $hidden_service_dir/hostname | send_irc
+info "configure ncdc"
+curl conf.krebsco.de/filehooker_configure_ncdc | arch-chroot /mnt
+info "configuring netshares"
+( curl conf.krebsco.de/filehooker_configure_netshare )| arch-chroot /mnt
+info "configuring tor announce"
+curl conf.krebsco.de/install_tor_announce | arch-chroot /mnt
+info "We're all done, rebooting!"
+sync
+sleep 5
+reboot
diff --git a/ship/src/find-supers-tinc b/ship/src/find-supers-tinc
new file mode 100644
index 00000000..3ea53d35
--- /dev/null
+++ b/ship/src/find-supers-tinc
@@ -0,0 +1,6 @@
+#!/bin/sh
+#@info
+#@include core
+#@include retiolum
+
+find_supernodes
diff --git a/ship/src/fix_dircolors b/ship/src/fix_dircolors
new file mode 100755
index 00000000..d427563f
--- /dev/null
+++ b/ship/src/fix_dircolors
@@ -0,0 +1,13 @@
+#!/bin/sh
+#@info
+#@strict
+#@include core
+exists dircolors || die "no dircolors in PATH, bailing out"
+
+info "fixing dircolors for $(id -un)"
+dircolors -p > $HOME/.dircolors
+sed -i 's/\(DIR \).*/\101;36/' $HOME/.dircolors
+! grep -q 'dircolors' $HOME/.profile && \
+ info "adding dircolors line to $HOME/.profile" && \
+ echo 'eval `dircolors -b $HOME/.dircolors`' >> $HOME/.profile
+info "done"
diff --git a/ship/src/get_repo b/ship/src/get_repo
new file mode 100644
index 00000000..5476e650
--- /dev/null
+++ b/ship/src/get_repo
@@ -0,0 +1,22 @@
+#!/bin/sh
+#@info
+#@strict
+#@include punani
+# Can be overwritten before install
+
+KREBSDIR=${KREBSDIR:-/krebs}
+( is_root || ! test "$KREBSDIR" = "/krebs" ) || die "not running as root, stuff may not work. change KREBSDIR env to bootstrap somewhere else!";
+
+info "installing git to clone repo"
+punani install git
+
+[ -e "$KREBSDIR" ] && die "krebs dir already exists"
+
+git clone --depth 1 https://github.com/krebscode/painload.git "$KREBSDIR" || die "cloning failed :("
+
+cd $KREBSDIR || die "cannot change into $KREBSDIR folder:(" ;
+
+info "installing make"
+punani install make
+
+info "have a nice day"
diff --git a/ship/src/install_tor_announce b/ship/src/install_tor_announce
new file mode 100644
index 00000000..b7b3662e
--- /dev/null
+++ b/ship/src/install_tor_announce
@@ -0,0 +1,5 @@
+#!/bin/sh
+#@strict
+#@include filehooker
+
+install_tor_announce
diff --git a/ship/src/punani b/ship/src/punani
new file mode 100755
index 00000000..ceabd667
--- /dev/null
+++ b/ship/src/punani
@@ -0,0 +1,4 @@
+#! /bin/sh
+#@info
+#@include punani
+punani "$@"
diff --git a/ship/src/refresh-super-keys b/ship/src/refresh-super-keys
new file mode 100644
index 00000000..dddbe846
--- /dev/null
+++ b/ship/src/refresh-super-keys
@@ -0,0 +1,5 @@
+#!/bin/sh
+#@info
+#@include retiolum
+#@mainifyme
+refresh_supernode_keys
diff --git a/ship/src/refresh-supers b/ship/src/refresh-supers
new file mode 100644
index 00000000..6dc6e8ab
--- /dev/null
+++ b/ship/src/refresh-supers
@@ -0,0 +1,35 @@
+#!/bin/sh
+#@info
+# usage: [DEBUG=1] [tincconf=/not/tinc/retiolum/tinc.conf] $0
+# This is the implementation of the proposal how to update tinc supernode
+# connections
+
+#@include core
+#@include retiolum
+ # using find_supernodes
+ # tinc_path
+ # netname
+
+#@strict
+#@mainifyme
+
+refresh_supernode_keys
+
+max_connect_to=${max_connect_to:-5}
+tincconf=${tincconf:-$tinc_path/$netname/tinc.conf}
+tmp_tincconf=$(mktemp)
+defer "rm -f $tmp_tincconf"
+
+sed '/^[ ]*ConnectTo/d' "$tincconf" > "$tmp_tincconf"
+
+
+# TODO find_supernodes requires netcat
+find_supernodes | cut -d\ -f 1 | shuf \
+ | head -n "${max_connect_to}" \
+ | xargs -n1 printf "ConnectTo=%s\n" >> "$tmp_tincconf"
+
+info "replacing old tinc.conf with one"
+test "${DEBUG:-}" && diff "$tincconf" "$tmp_tincconf"
+mv "$tmp_tincconf" "$tincconf"
+
+reload_tinc
diff --git a/ship/src/remaster_arch_shack_installstick b/ship/src/remaster_arch_shack_installstick
new file mode 100755
index 00000000..3ad985af
--- /dev/null
+++ b/ship/src/remaster_arch_shack_installstick
@@ -0,0 +1,104 @@
+#!/bin/sh
+#@include core
+#@include iso
+#@mainifyme
+
+## TODO: provide a parameter which defines what to be done in the new iso root
+set -efu
+isofile=${1:-archlinux-2013.06.01-dual.iso}
+outfile=$(basename ${isofile%.iso}.krebs.iso)
+info "outfile will be at $outfile"
+bdir=${bdir:-$HOME/build/arch}
+isodir=$bdir/iso
+isomnt=$bdir/isomount
+rootdir=$bdir/root
+outdir=$bdir/out
+auto_url=${2:-conf.krebsco.de/arch_autoinstall}
+info "bdir is at $bdir"
+[ ! -e "$isofile" ] && die "$isofile does not exist."
+esudo "$@"
+arch_label="$(get_volid "$isofile")"
+info "Arch iso label is ${arch_label}"
+info "auto_url is $auto_url"
+
+info "cleanup root dir"
+rm -rf $bdir
+mkdir -p $isomnt $rootdir
+info "mounting isofile ($isofile)"
+if is_root;then
+ mount -t iso9660 -o loop,ro $isofile $isomnt
+else
+ die 'we are not root enough to mount the iso.'
+fi
+defer "info 'unmounting $isomnt';umount $isomnt"
+
+info "copying from '$isomnt' to '$isodir'"
+cp -a "$isomnt" "$isodir"
+defer "info 'removing $isodir';rm -rf $isodir"
+info "extracting root-image squashfs"
+# we will not touch the kernel ... yet
+
+for arch in x86_64 i686;do
+ info "unpacking $isomnt/arch/$arch/root-image.fs.sfs"
+ mkdir -p "$outdir/$arch"
+ defer "info 'removing $outdir/$arch';rm -rf $outdir/$arch"
+ mkdir -p "$rootdir/$arch"
+ defer "info 'removing $rootdir/$arch';rm -rf $rootdir/$arch"
+ unsquashfs -f -d "$outdir/$arch" "$isodir/arch/$arch/root-image.fs.sfs"
+
+ mount "$outdir/$arch/root-image.fs" "$rootdir/$arch"
+ defer "info 'unmounting $rootdir/$arch';umount $rootdir/$arch||info 'not mounted'"
+
+ info "Starting of the rootdir verkrepelung"
+ # do the magic here
+ arch-chroot $rootdir/$arch <<EOF
+ cat >> /root/.zshrc<<EOL
+cat << EOD
+This is the Krebs Autoinstaller, we will do all the right things.
+Just Wait until everything finished.
+
+- Make sure that RJ45 is connected
+- you can bail out of the progress at any time with CTRL-C
+ /krebs/autoinstall (args)
+EOD
+/krebs/autoinstall
+EOL
+
+ mkdir /krebs
+ cat > /krebs/autoinstall <<EOL
+internet() { ping -w 1 google.de >/dev/null 2>&1; }
+while ! internet;do
+ echo "no Internet yet, waiting ..."
+ sleep 3
+done
+
+echo "Grabbing current version of install-script from $auto_url"
+echo
+echo "AGENTS ARE GOOOOOOOOOOO!"
+curl "$auto_url" 2>/dev/null | sh -s "\\\$@"
+EOL
+chmod 755 /krebs/autoinstall
+EOF
+ info "deleting old squashfs"
+ rm "$isodir/arch/$arch/root-image.fs.sfs"
+ info "creating squashfs at $isodir/arch/$arch/root-image.fs.sfs"
+ umount "$rootdir/$arch"
+ mksquashfs "$outdir/$arch/root-image.fs" "$isodir/arch/$arch/root-image.fs.sfs"
+done
+
+info "creating Iso Image"
+rm -f "${outdir}/${outfile}"
+xorriso -as mkisofs \
+ -iso-level 3 \
+ -full-iso9660-filenames \
+ -volid "${arch_label}" \
+ -appid "Shackspace Krebs Installer" \
+ -publisher "Shackspace/Krebs" \
+ -preparer "prepared by krebs" \
+ -eltorito-boot isolinux/isolinux.bin \
+ -eltorito-catalog isolinux/boot.cat \
+ -no-emul-boot -boot-load-size 4 -boot-info-table \
+ -isohybrid-mbr ${isomnt}/isolinux/isohdpfx.bin \
+ -output "${outdir}/${outfile}" \
+ "$isodir"
+
diff --git a/ship/src/retiolum b/ship/src/retiolum
new file mode 100755
index 00000000..ede1fd6a
--- /dev/null
+++ b/ship/src/retiolum
@@ -0,0 +1,292 @@
+#!/bin/sh
+#@include core
+#@include network
+main(){
+
+ set -euf
+ get_root
+
+ SUBNET4=${SUBNET4:-10.243}
+ # TODO: some retard servers may not support ipv6
+ SUBNET6=${SUBNET6:-42}
+ TEMPDIR=${TEMPDIR:-auto}
+ TINCDIR=${TINCDIR:-auto}
+
+
+ #overwrite `found` hostname
+ HOSTN="`get_hostname`"
+ NETNAME=${NETNAME:-retiolum}
+ MASK4=${MASK4:-16}
+ MASK6=${MASK6:-16}
+ RMASK=${RMASK:-255.255.0.0}
+ URL=${URL:-http://euer.krebsco.de/retiolum/hosts.tar.gz}
+ SURL=${SURL:-http://euer.krebsco.de/retiolum/supernodes.tar.gz}
+
+ IRCCHANNEL=${IRCCHANNEL:-"#krebs_incoming"}
+ IRCSERVER=${IRCSERVER:-"irc.freenode.net"}
+ IRCPORT=${IRCPORT:-6667}
+
+ OS=$(get_os)
+
+ IP4=${IP4:-0}
+ IP6=${IP6:-0}
+
+ RAND4=1
+ RAND6=1
+
+
+ if [ $IP4 -eq 0 ]; then
+ RAND4=1
+ elif ! check_ip_valid4 $IP4; then
+ die 'ip4 is invalid'
+ fi
+ if [ $IP6 -eq 0 ]; then
+ RAND6=1
+ elif ! check_ip_valid6 $IP6; then
+ die 'ip6 is invalid'
+ fi
+
+ #check if everything is installed
+ if ! exists awk ; then
+ die 'Please install awk'
+ fi
+
+
+ if ! http_head $SURL >/dev/null 2>/dev/null ;then
+ die 'Cannot find supernode package, check if your internet is working'
+ fi
+
+ #check if everything is installed
+ if [ $OS = 'android' ]; then
+ if ! test -e /data/data/org.poirsouille.tinc_gui/files/tincd; then
+ die 'Please install tinc-gui'
+ else
+ TINCBIN=/data/data/org.poirsouille.tinc_gui/files/tincd
+ DEV="/dev/tun"
+ if [ $TINCDIR = 'auto' ]; then TINCDIR="/usr/local/etc/tinc" ;fi
+ if [ $TEMPDIR = 'auto' ]; then TEMPDIR="/storage/sdcard0/tinc-fu" ;fi
+ mount -o remount,rw /
+ mount -o remount,rw /system
+ fi
+ elif [ $OS = 'osx' ]; then
+ if ! exists tincd >/dev/null; then
+ die 'Please install tinc'
+ else
+ TINCBIN=tincd
+ DEV="/dev/net/tun"
+ if [ $TINCDIR = 'auto' ]; then TINCDIR="/usr/local/etc/tinc" ;fi
+ if [ $TEMPDIR = 'auto' ]; then TEMPDIR="/tmp/tinc-install-fu" ;fi
+ fi
+ else
+ if ! exists tincd >/dev/null; then
+ die 'Please install tinc'
+ else
+ TINCBIN=tincd
+ DEV="/dev/net/tun"
+ if [ $TINCDIR = 'auto' ]; then TINCDIR="/etc/tinc" ;fi
+ if [ $TEMPDIR = 'auto' ]; then TEMPDIR="/tmp/tinc-install-fu" ;fi
+ fi
+ fi
+
+ #generate full subnet information for v4
+
+ #test if tinc directory already exists
+ if test -e $TINCDIR/$NETNAME; then
+ die "tinc config directory $TINCDIR/$NETNAME does already exist. (backup and) delete config directory and restart"
+ fi
+
+ #get tinc-hostfiles
+ mkdir -p $TEMPDIR/hosts
+ http_get $URL | tar zx -C $TEMPDIR/hosts/
+
+ #check for free ip
+ #version 4
+ until check_ip_taken $IP4; do
+ if [ $RAND4 -eq 1 ]; then
+ IP4="$SUBNET4.$(( $(head /dev/urandom | tr -dc "123456789" | head -c3) %255)).$(( $(head /dev/urandom | tr -dc "123456789" | head -c3) %255))"
+ else
+ printf 'choose new ip: '
+ read IP4
+ while ! check_ip_valid4 $IP4; do
+ printf 'the ip is invalid, retard, choose a valid ip: '
+ read IP4
+ done
+ fi
+ done
+
+ #version 6
+
+ until check_ip_taken $IP6; do
+ if [ $RAND6 -eq 1 ]; then
+ NETLENGTH=$(expr $(expr 128 - $MASK6) / 4)
+ IP6="$SUBNET6$(head /dev/urandom | tr -dc "0123456789abcdef" | head -c$NETLENGTH | sed 's/..../:&/g')" #todo: generate ip length from hostmask
+ else
+ printf 'ip taken, choose new ip: '
+
+ read IP6
+ while ! check_ip_valid6 $IP6; do
+ printf 'the ip is invalid, retard, choose a valid ip: '
+ read IP6
+ done
+ fi
+ done
+
+
+ #check for free hostname
+ get_hostname $HOSTN
+
+
+ #create the configs
+ mkdir -p $TINCDIR/$NETNAME
+ cd $TINCDIR/$NETNAME
+
+ if [ $OS = 'openwrt' ]; then
+ mkdir hosts
+ http_get $SURL | tar xz -C hosts/
+ else
+ mv $TEMPDIR/hosts ./
+ fi
+
+ rm -r $TEMPDIR || echo "$TEMPDIR does not exist, skipping removal"
+
+ echo "Subnet = $IP4" > hosts/$HOSTN
+ echo "Subnet = $IP6" >> hosts/$HOSTN
+
+ cat>tinc.conf<<EOF
+Name = $HOSTN
+Device = $DEV
+
+#newer tinc features
+LocalDiscovery = yes
+AutoConnect = 3
+
+#ConnectTos
+ConnectTo = slowpoke
+ConnectTo = pigstarter
+ConnectTo = pico
+EOF
+
+ host2subnet $MASK4
+
+ #check if ip is installed
+ if exists ip >/dev/null; then
+ echo 'dirname="`dirname "$0"`"' > tinc-up
+ echo '' >> tinc-up
+ echo 'conf=$dirname/tinc.conf' >> tinc-up
+ echo '' >> tinc-up
+ echo 'name=$(sed -n "s|^ *Name *= *\([^ ]*\) *$|\\1|p" $conf)' >> tinc-up
+ echo '' >> tinc-up
+ echo 'host=$dirname/hosts/$name' >> tinc-up
+ echo '' >> tinc-up
+ echo 'ip link set $INTERFACE up' >> tinc-up
+ echo '' >> tinc-up
+ echo "addr4=\$(sed -n \"s|^ *Subnet *= *\\($SUBNET4[.][^ ]*\\) *\$|\\\\1|p\" \$host)" >> tinc-up
+ echo 'ip -4 addr add $addr4 dev $INTERFACE' >> tinc-up
+ echo "ip -4 route add $FULLSUBNET/$MASK4 dev \$INTERFACE" >> tinc-up
+ echo '' >> tinc-up
+ echo "addr6=\$(sed -n \"s|^ *Subnet *= *\\($SUBNET6[:][^ ]*\\) *\$|\\\\1|p\" \$host)" >> tinc-up
+ echo 'ip -6 addr add $addr6 dev $INTERFACE' >> tinc-up
+ echo "ip -6 route add $SUBNET6::/$MASK6 dev \$INTERFACE" >> tinc-up
+ else
+ echo 'dirname="`dirname "$0"`"' > tinc-up
+ echo '' >> tinc-up
+ echo 'conf=$dirname/tinc.conf' >> tinc-up
+ echo '' >> tinc-up
+ echo 'name=$(sed -n "s|^ *Name *= *\([^ ]*\) *$|\\1|p" $conf)' >> tinc-up
+ echo '' >> tinc-up
+ echo 'host=$dirname/hosts/$name' >> tinc-up
+ echo '' >> tinc-up
+ echo "addr4=\$(sed -n \"s|^ *Subnet *= *\\($SUBNET4[.][^ ]*\\) *$|\\\\1|p\" \$host)" >> tinc-up
+ echo 'ifconfig $INTERFACE $addr4' >> tinc-up
+ echo "route add -net $FULLSUBNET netmask $RMASK dev \$INTERFACE " >> tinc-up
+ fi
+
+ #fix permissions
+ chmod +x tinc-up
+ chown -R 0:0 .
+
+ #generate keys with tinc
+ if exists tinc ; then
+ yes | tinc -n $NETNAME generate-keys
+ else
+ yes | $TINCBIN -n $NETNAME -K
+ fi
+
+ if [ $OS = 'android' ]; then
+ mkdir /etc/tinc
+ cd /
+ mv $TINCDIR/$NETNAME /etc/tinc/
+ cd /etc/tinc/$NETNAME
+ fi
+
+ (echo "This is $HOSTN";cat "hosts/$HOSTN" ) | send_irc
+
+ # finish what you have begun!
+ tincd -n $NETNAME
+}
+
+
+#convert hostmask to subnetmask only version 4
+host2subnet()
+{
+ NEEDDOTSINSUB=$(expr 3 - $( echo $SUBNET4 | tr -C -d . | wc -c))
+ case $NEEDDOTSINSUB in
+ 3) FULLSUBNET=$SUBNET4.0.0.0 ;;
+ 2) FULLSUBNET=$SUBNET4.0.0 ;;
+ 1) FULLSUBNET=$SUBNET4.0 ;;
+ 0) FULLSUBNET=$SUBNET4 ;;
+ *) die 'cannot read subnet';;
+ esac
+}
+
+#check if ip is valid ipv4 function
+check_ip_valid4()
+{
+ if [ "$(echo $1 | awk -F"\." ' $0 ~ /^([0-9]{1,3}\.){3}[0-9]{1,3}$/ && $1 <=255 && $2 <= 255 && $3 <= 255 && $4 <= 255 ' 2>/dev/null)" == "$1" ] && [ ${1:0:${#SUBNET4}} == $SUBNET4 ]
+ then
+ return 0
+ else
+ return 1
+ fi
+}
+
+#check if ip is valid ipv6 function
+check_ip_valid6()
+{
+ if [ "$(echo $1 | awk -F"." ' $0 ~ /^([0-9a-fA-F]{1,4}\:){7}[0-9a-fA-F]{1,4}$/' 2>/dev/null)" == $1 ] && [ ${1:0:${#SUBNET6}} == $SUBNET6 ]
+ then
+ return 0
+ else
+ return 1
+ fi
+}
+
+#check if ip is taken function
+check_ip_taken()
+{
+ if grep -q -r -E "$1(#|/)" $TEMPDIR/hosts/ ;then
+ return 1
+ else
+ return 0
+ fi
+}
+
+#if hostname is taken, count upwards until it isn't taken function
+get_hostname()
+{
+ TSTFILE=$TEMPDIR/hosts/$1
+ LCOUNTER=0
+ if test -e $TSTFILE; then
+ while test -e $TSTFILE; do
+ : $((LCOUNTER+=1))
+ TSTFILE=$TEMPDIR/hosts/$1$LCOUNTER
+ done
+ HOSTN=$1$LCOUNTER
+ else
+ HOSTN=$1
+ fi
+}
+
+#os autodetection
+
+main
diff --git a/ship/src/tahoe_install b/ship/src/tahoe_install
new file mode 100644
index 00000000..d956ff13
--- /dev/null
+++ b/ship/src/tahoe_install
@@ -0,0 +1,15 @@
+#!/bin/sh
+#@strict
+#@core
+#@color
+#@include tahoe
+esudo "$@"
+tahoe_init
+tahoe_create_node
+if sudo -u tahoe tahoe start ;then
+ info "everything went fine, autostart tahoe somewhere with: 'sudo -u tahoe tahoe start'"
+else
+ error "somewhere something went wrong, could not start tahoe daemon"
+ error "tahoe should be installed under /home/tahoe/.tahoe"
+ die "sorry :("
+fi
diff --git a/ship/src/tor_publish_ssh b/ship/src/tor_publish_ssh
new file mode 100755
index 00000000..14cb9cb4
--- /dev/null
+++ b/ship/src/tor_publish_ssh
@@ -0,0 +1,14 @@
+#!/bin/sh
+#@include core
+#@include network
+#@include punani
+#@include tor
+
+
+
+punani install tor
+
+test -w "$torrc" || ( error "$torrc is not writable!"; exit 1 ) || exit 1
+
+configure_hidden_service
+cat $hidden_service_dir/hostname | send_irc
diff --git a/ship/src/vim_sane_defaults b/ship/src/vim_sane_defaults
new file mode 100644
index 00000000..4c6f1b8f
--- /dev/null
+++ b/ship/src/vim_sane_defaults
@@ -0,0 +1,11 @@
+#!/bin/sh
+#@strict
+#@include core
+#@include vim
+#@include punani
+#@mainifyme
+info "installing punani"
+punani install vim
+touch $vimrc
+info "configuring vim"
+vim_conf_sane_defaults
diff --git a/ship/t/docker/docker_remote_punani.sh b/ship/t/docker/docker_remote_punani.sh
new file mode 100755
index 00000000..1eab1a42
--- /dev/null
+++ b/ship/t/docker/docker_remote_punani.sh
@@ -0,0 +1,5 @@
+#!/bin/sh
+cd $(dirname $(readlink -f $0))
+docker_id=$(docker run -d -v $PWD/punani/:/test ubuntu /bin/sh /test/remote_punani)
+trap "docker rm $docker_id" INT TERM EXIT QUIT
+docker wait $docker_id
diff --git a/ship/t/docker/punani/remote_punani b/ship/t/docker/punani/remote_punani
new file mode 100644
index 00000000..4d8570e3
--- /dev/null
+++ b/ship/t/docker/punani/remote_punani
@@ -0,0 +1,11 @@
+#!/bin/sh
+rhost=http://conf.krebsco.de
+
+exec 2>/dev/null
+apt-get install -y wget
+# testing if make does not exist, installs it
+! ( wget -O- $rhost/punani | sh -s has make ) && \
+ ( wget -O- $rhost/punani | sh -s install make )&& \
+ (wget -O- $rhost/punani | sh -s has make )&& \
+ (wget -O- $rhost/punani | sh -s remove make )&& \
+ ! ( wget -O- $rhost/punani | sh -s has make )
diff --git a/ship/tmp/.placeholder b/ship/tmp/.placeholder
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/ship/tmp/.placeholder
[cgit] Unable to lock slot /tmp/cgit/97000000.lock: No such file or directory (2)