diff --git a/.bashrc b/.bashrc
index 4389688a37394c36a2d27c4ac21147b3541dd1df..68d1a070e83a80db7273c7f2dfcb1a1e6d6d33fb 100644
--- a/.bashrc
+++ b/.bashrc
@@ -73,6 +73,7 @@ alias apt-daily="sudo /bin/sh -c 'apt-get update && apt-get dist-upgrade --downl
 alias docker-build='docker build -t "$(basename $PWD)" ./'
 alias cdtemp='cd $(mktemp -d)'
 alias 0-day-cleanup='ssh xbmc "sudo -u debian-transmission find /srv/library/Comics -name *.part -path *0-Day\ Week\ of* -delete"'
+alias httpbin='tox -c $HOME/.tox.ini.httpbin --'
 
 deduce-aws-region () {
     export AWS_DEFAULT_REGION="$(curl --silent \
@@ -105,4 +106,22 @@ docker-dev () {
                --workdir "$PWD" "$repo:dev" /bin/sh -l
 }
 
+sync-comics () {
+    this_month="$( date '+xbmc:/srv/library/Comics/0-Day\ Week\ of\ %Y.%m.*' )"
+    last_month="$( date --date '1 month ago' '+xbmc:/srv/library/Comics/0-Day\ Week\ of\ %Y.%m.*' )"
+    rsync --recursive --compress --progress --exclude "*.part" "$last_month" "$this_month" "$HOME/Downloads/Comics/"
+}
+
+update-requirements () {
+    cd $(git rev-parse --show-toplevel)
+    for file in $(git ls-files *requirements*.txt)
+    do
+        pur --requirement $file
+        git add $file
+    done
+    git commit -m"- Updated requirements."
+    git push
+    cd - > /dev/null
+}
+
 . $HOME/Documents/Shore/bundle_certs/bundle_certs
diff --git a/.gitconfig b/.gitconfig
index 96c4eb61ec609cb8767b3e4e6e4e26764a373a37..c4de81d342ed2bc3c137e7398983e3f52eca18f7 100644
--- a/.gitconfig
+++ b/.gitconfig
@@ -19,10 +19,11 @@
     staash = stash --all
     stat = status --short --branch
     tag-version = !git tag -f "v$(cat VERSION)"
+    trigger = !git commit --allow-empty --no-edit --amend && git push --force-with-lease
 [color]
     grep = true
 [core]
-    excludesfile = /home/nimrod/.gitignore_global
+    excludesfile = ~/.gitignore_global
 [diff]
 	tool = meld
 [difftool]
diff --git a/.ssh/config.d/10_global b/.ssh/config.d/10_global
index 957126184cf98a86a64c211126696f7181c7b044..8d056019e4e6fe70ad07ebf0ab8d5c9d55978c8a 100644
--- a/.ssh/config.d/10_global
+++ b/.ssh/config.d/10_global
@@ -3,5 +3,6 @@ ControlMaster auto
 ControlPath ~/.ssh/%r@%h:%p.sock
 ControlPersist 3m
 ServerAliveInterval 30
+IdentitiesOnly yes
 #StrictHostKeyChecking yes
 #UserKnownHostsFile=/dev/null
diff --git a/.ssh/config.d/20_fdna b/.ssh/config.d/20_fdna
index 7b91594b8d170a3039849d2eb56886c8e047b185..578dd07085a9223c745fc7df7792a1f7dcb5acd8 100644
--- a/.ssh/config.d/20_fdna
+++ b/.ssh/config.d/20_fdna
@@ -15,22 +15,37 @@ HostName bitbucket.org
 User git
 IdentityFile ~/.ssh/fdna_rsa
 
-Host monster
-HostName monster
+Host monster.fdna.local
+HostName 10.0.0.209
 User nimrod
 IdentityFile ~/.ssh/fdna_rsa
 
-Host backup
-HostName backup
+Host backup.fdna.local
+HostName 10.0.0.210
 User nimrod
 IdentityFile ~/.ssh/fdna_rsa
 
-Host dl-fdna*
+Host xen01.fdna.local
+HostName 10.0.0.110
+User root
+IdentityFile ~/.ssh/fdna_rsa
+
+Host adm1.fdna.local
+HostName 10.0.0.111
+User nimrod
+IdentityFile ~/.ssh/fdna_rsa
+
+Host 10.0.0.20?
 User nimrod
 IdentityFile ~/.ssh/fdna_rsa
 
-Host storage
-HostName storage
+Host storage.fdna.local
+HostName 10.0.0.220
+User nimrod
+IdentityFile ~/.ssh/fdna_rsa
+
+Host data-management.fdna.local
+HostName 10.0.0.109
 User nimrod
 IdentityFile ~/.ssh/fdna_rsa
 
@@ -63,7 +78,6 @@ Host nag01.fdna.com
 HostName nag01.cloudapp.net
 User fdna_srv
 IdentityFile ~/.ssh/fdna_rsa
-ProxyCommand ssh ns1 nc %h %p
 
 Host dev2_ops
 HostName 52.213.235.92
@@ -89,3 +103,20 @@ Host ci_ops
 HostName 52.208.181.7
 User nimrod
 IdentityFile ~/.ssh/fdna_rsa
+
+Host *.dev-f2g.com
+User nimrod
+IdentityFile ~/.ssh/fdna_rsa
+
+Host *.face2gene.com
+User nimrod
+IdentityFile ~/.ssh/fdna_rsa
+
+Host *.fdna.com
+User nimrod
+IdentityFile ~/.ssh/fdna_rsa
+
+Host gitolite_ops
+HostName 52.211.215.151
+User nimrod
+IdentityFile ~/.ssh/fdna_rsa
diff --git a/.ssh/config.d/20_shore b/.ssh/config.d/20_shore
index 42278b4648b08c1fe632fb8a2e652bc7e70498bb..7b981081a4c33af040534864ab1be3ef5c7a91f1 100644
--- a/.ssh/config.d/20_shore
+++ b/.ssh/config.d/20_shore
@@ -1,53 +1,53 @@
 # shore.co.il infrastructure
 
-Host ns1 www.shore.co.il
+Host ns1.shore.co.il www.shore.co.il
 HostName ns1.shore.co.il
-LocalForward 9091 xbmc.trusted:9091
+LocalForward 9091 xbmc.shore.co.il:9091
 DynamicForward 8080
 User nimrod
 IdentityFile ~/.ssh/shore_ecdsa
 IdentityFile ~/.ssh/shore_rsa
 
-Host xbmc
-HostName xbmc.trusted
+Host xbmc.shore.co.il
+HostName xbmc.shore.co.il
 User nimrod
 ForwardX11 yes
 IdentityFile ~/.ssh/shore_ecdsa
 IdentityFile ~/.ssh/shore_rsa
-ProxyCommand ssh ns1 nc %h %p
+ProxyCommand ssh ns1.shore.co.il nc %h %p
 
-Host ns2
+Host ns2.shore.co.il
 HostName ns2.shore.co.il
 User admin
 DynamicForward 9999
 IdentityFile ~/.ssh/shore_ecdsa
 IdentityFile ~/.ssh/shore_rsa
 
-Host cgit
-HostName cgit.trusted
-ProxyCommand ssh ns1 nc %h %p
+Host cgit.shore.co.il
+HostName cgit.shore.co.il
+ProxyCommand ssh ns1.shore.co.il nc %h %p
 User nimrod
 IdentityFile ~/.ssh/shore_ecdsa
 IdentityFile ~/.ssh/shore_rsa
 
-Host ns3
+Host ns3.shore.co.il
 HostName ns3.shore.co.il
 User root
 IdentityFile ~/.ssh/shore_ecdsa
 IdentityFile ~/.ssh/shore_rsa
 DynamicForward 8081
 
-Host host01
-HostName host01.trusted
+Host host01.shore.co.il
+HostName host01.shore.co.il
 User nimrod
-ProxyCommand ssh ns1 nc %h %p
+ProxyCommand ssh ns1.shore.co.il nc %h %p
 IdentityFile ~/.ssh/shore_ecdsa
 IdentityFile ~/.ssh/shore_rsa
 
-Host wdr4300
-HostName wdr4300.trusted
+Host wdr4300.shore.co.il
+HostName wdr4300.shore.co.il
 User root
-ProxyCommand ssh ns1 nc %h %p
+ProxyCommand ssh ns1.shore.co.il nc %h %p
 IdentityFile ~/.ssh/shore_ecdsa
 IdentityFile ~/.ssh/shore_rssa
 LocalForward 8082 localhost:80
diff --git a/.tox.ini.httpbin b/.tox.ini.httpbin
new file mode 100644
index 0000000000000000000000000000000000000000..f983e74c824a9f6d1ce21f8c712e4571c8f3804b
--- /dev/null
+++ b/.tox.ini.httpbin
@@ -0,0 +1,9 @@
+[tox]
+skipsdist = True
+
+[testenv]
+basepython = python3
+deps =
+    httpbin
+    gunicorn
+commands = gunicorn httpbin:app {posargs}
diff --git a/Documents/Shore/Ansible/ansible-desktop-playbooks b/Documents/Shore/Ansible/ansible-desktop-playbooks
index 8946b5f96a7ca6351aeeaf5ec85eb3759dd40b8f..bac3cf280ad670a14d776faa4c45b33eb50de572 160000
--- a/Documents/Shore/Ansible/ansible-desktop-playbooks
+++ b/Documents/Shore/Ansible/ansible-desktop-playbooks
@@ -1 +1 @@
-Subproject commit 8946b5f96a7ca6351aeeaf5ec85eb3759dd40b8f
+Subproject commit bac3cf280ad670a14d776faa4c45b33eb50de572
diff --git a/Documents/Shore/ssh-ca b/Documents/Shore/ssh-ca
index 8ac53385d080103b075c85a5979e0fbf2649056f..62215b03a40f325c75e2d9e7e71cf1ce46ac9c90 160000
--- a/Documents/Shore/ssh-ca
+++ b/Documents/Shore/ssh-ca
@@ -1 +1 @@
-Subproject commit 8ac53385d080103b075c85a5979e0fbf2649056f
+Subproject commit 62215b03a40f325c75e2d9e7e71cf1ce46ac9c90
diff --git a/Documents/train-wifi.sh b/Documents/train-wifi.sh
index 51130b37f1a34915faba01500df47969cc88666c..5cb8df8842a4908dea1d408df74ee6acc86815b2 100755
--- a/Documents/train-wifi.sh
+++ b/Documents/train-wifi.sh
@@ -1,8 +1,7 @@
 #!/bin/sh
-set -eu
 # The MIT License (MIT)
 #
-# Copyright (c) 2016 Adar Nimrod <nimrod@shore.co.il>
+# Copyright (c) 2017 Adar Nimrod <nimrod@shore.co.il>
 #
 # Permission is hereby granted, free of charge, to any person obtaining a copy
 # of this software and associated documentation files (the "Software"), to deal
@@ -23,17 +22,24 @@ set -eu
 # SOFTWARE.
 
 # Logs in to the Israeli train's wifi.
-# Requires: cURL, sh, awk, logger.
+# Requires: cURL, sh, awk, logger, nmcli.
 # To install run:
 # sudo cp --preserve=mode train-wifi.sh /etc/NetworkManager/dispatcher.d/90trainwifi
 
+set -eu
+
 die () {
-    echo $@ | logger
+    logger -p user.err $@
     exit 1
 }
 
-debug () {
-    [ -n ${DEBUG:+x} ] && echo $@ | logger
+iswifi () {
+    # TODO: Check if a network interface is passed.
+    [ "$(nmcli --terse --fields GENERAL.TYPE device show $1 | awk -F: '{print $2}')" = 'wifi' ]
+}
+
+wifi_connection () {
+    nmcli --terse --fields GENERAL.CONNECTION device show $1 | awk -F: '{print $2}'
 }
 
 if [ $# -ne 2 ]
@@ -47,15 +53,19 @@ fi
 
 which curl > /dev/null || die "Can't login to the train wifi, cURL is not installed."
 which awk > /dev/null || die "Can't login to the train wifi, awk is not installed."
-which logger > /dev/null || dir "Can't login to the train wifi, logger is not installed."
+which logger > /dev/null || die "Can't login to the train wifi, logger is not installed."
+which nmcli > /dev/null || die "Can't login to the train wifi, nmcli is not installed."
 
-if [ "$interface" = "ISRAEL-RAILWAYS" ] && [ "$action" = "up" ]
-then
-    redirect_url="$(curl --output /dev/null --silent --write-out '%{redirect_url}' http://google.com/)"
-    debug "Train wifi redirect url: $redirect_url"
-    login_url="$(echo "$redirect_url" | awk -F\? '{printf("%s?allowAccess=true", $1)}' )"
-    debug "Train wifi login url: $login_url"
-    curl "$login_url"
-else
-    debug "Interface isn't ISRAEL-RAILWAYS or action isn't up, not signing in to the train wifi."
-fi
+[ "$action" = 'up' ] || die "Can't login to the train wifi, action $action isn't up."
+iswifi "$interface" || die "Can't login to the train wifi, interface $interface isn't wifi."
+connection="$(wifi_connection $interface)"
+[ "$connection" = "ISRAEL-RAILWAYS" ] || die "Can't login to the train wifi, wifi network $connection isn't ISRAEL-RAILWAYS."
+
+redirect_url="$(curl --output /dev/null --silent --write-out '%{redirect_url}' http://google.com/)"
+logger -p user.debug "Train wifi redirect url: $redirect_url"
+login_ip="$(echo "$redirect_url" | grep --only-matching '[0-9]*\.[0-9]*\.[0-9]*\.[0-9]*')" || die "Can't login to the train wifi, redirect URL doesn't contain an IP."
+logger -p user.debug "Train wifi login IP: $ip"
+login_url="http://$ip/loginHandler.php?allowAccess=true"
+logger -p user.debug "Train wifi login URL: $login_url"
+http_code="$(curl --output /dev/null --silent --write-out '%{http_code}' "$login_url")"
+logger -p user.debug "Train wifi login HTTP code: $http_code"