├── .gitmodules ├── README.md ├── _BROKEN_sprunge-forced-ssl-proxy ├── arm-cross-compile-kernel ├── arm-make-cross-compiler ├── ascii-art-maker ├── bash-prompt.sh ├── boilerplate-bash ├── boilerplater ├── build_kernel ├── build_tor ├── check-commit-signature ├── cybercyber ├── days-until ├── deuteranopia ├── dnswithtor ├── exclude-slow-tor-relays ├── executioner ├── exit-probability-factors.py ├── get-ssl-fingerprint ├── git-fix-author ├── git-fix-date ├── git-mkchangelog ├── git-prompt.sh ├── gitdate ├── golang ├── gpg-download-missing-signers ├── gpg-recv-key-tor ├── gpg-send-key-tor ├── gpg-sig-counter ├── gpg_key_to_web ├── gpgkey2bc.py ├── include └── dstevens │ ├── mPDF.py │ ├── make-pdf-embedded.py │ ├── make-pdf-javascript.py │ ├── pdf-parser.py │ └── pdfid.py ├── irssi-and-transproxy ├── irssi_encrypt_and_email_logs ├── keysign ├── local-http-server.py ├── magnetlink ├── mailwithtor ├── mandelbrot.py ├── move-blog-dirs.sh ├── only ├── pastebin-photo ├── ppmascii ├── ps_mem ├── quantumquantum ├── smtp-tunnel ├── sprunge ├── ssh-one-key-per-host ├── transproxy.firewall.sh ├── utcdammit ├── verify-gitian-builder-signatures ├── verify-riseup-server-fingerprints ├── world_time ├── xephyr_awesome └── youtube-to-mp3 /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "include/l33tutils"] 2 | path = include/l33tutils 3 | url = https://github.com/infinity0/l33tutils.git 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | scripts 3 | ------- 4 | 5 | '''XXX fill me in!''' 6 | 7 | -------------------------------------------------------------------------------- /_BROKEN_sprunge-forced-ssl-proxy: -------------------------------------------------------------------------------- 1 | paste=$(echo "sprunge=<-`cat ./dnswithtor`") ; $(echo -e "POST -f -U -S -E -a -b http://sprunge.us -H "'"'"User Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:17.0) Gecko/20100201 Firefox/17.0"'"'" HTTP/1.1\r\nHost: g-proxy.appspot.com\r\n$paste\r\n\r\n"; sleep 10; $paste ; )|usewithtor openssl s_client -connect 74.125.143.106:443 -------------------------------------------------------------------------------- /arm-cross-compile-kernel: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | ############################################################################## 3 | # 4 | # arm-cross-compile-kernel 5 | # ------------------------ 6 | # Build a Debian kernel for ARM architectures. 7 | # 8 | # This will create packages with names such as 9 | # linux-image-3.2.9-dreamplug_0custom.20120313_armel.deb and 10 | # linux-headers-3.2.9-dreamplug_0custom.20120313_armel.deb which can be 11 | # installed with dpkg -i; after they have been installed, the uImage file can 12 | # be created on the target using something like this: 13 | # 'mkimage -A arm -O linux -T kernel -C none -a 0x00008000 -e \ 14 | # 0x00008000 -n Linux-3.2.9-dreamplug \ 15 | # -d /boot/vmlinuz-3.2.9-dreamplug uImage' 16 | # (where the mkimage program is from the package named uboot-mkimage or 17 | # u-boot-tools). 18 | # 19 | # @author Isis Agora Lovecruft, 0x2cdb8b35 20 | # @date 11 October 2012 21 | # @version 0.0.1 22 | #----------------------------------------------------------------------------- 23 | # Changelog: 24 | ############################################################################## 25 | 26 | 27 | PATH=/opt/arm-linux-gnueabi-tools/bin:$PATH 28 | export PATH 29 | day="`date +%Y%m%d`" 30 | make-kpkg --arch armel --cross-compile arm-linux-gnueabi- \ 31 | --revision=0custom.${day} --append-to-version=-dreamplug \ 32 | --config menuconfig configure 33 | CONCURRENCY_LEVEL="4" make-kpkg --arch armel --cross-compile \ 34 | arm-linux-gnueabi- --revision=0custom.${day} \ 35 | --append-to-version=-dreamplug \ 36 | --rootcmd fakeroot kernel_image kernel_headers 37 | -------------------------------------------------------------------------------- /arm-make-cross-compiler: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | ############################################################################## 3 | # 4 | # make_cross_compiler.sh 5 | # ------------------- 6 | # Make an arm toolchain for building a dreamplug kernel. 7 | # 8 | # @author Isis Agora Lovecruft, 0x2cdb8b35 9 | # @date 11 October 2012 10 | # @version 0.0.1 11 | #----------------------------------------------------------------------------- 12 | # Changelog: 13 | ############################################################################## 14 | 15 | 16 | mkdir /opt/arm-linux-gnueabi 17 | mkdir /opt/arm-linux-gnueabi-tools 18 | dpkg-deb -x libc6_2.13-27_armel.deb /opt/arm-linux-gnueabi 19 | dpkg-deb -x libc6-dev_2.13-27_armel.deb /opt/arm-linux-gnueabi 20 | dpkg-deb -x linux-libc-dev_3.2.9-1_armel.deb /opt/arm-linux-gnueabi 21 | (cd /opt/arm-linux-gnueabi/usr ; tar cf - *) | (cd /opt/arm-linux-gnueabi ; tar xf -) 22 | rm -rf /opt/arm-linux-gnueabi/usr 23 | ln -s . /opt/arm-linux-gnueabi/usr 24 | cd /tmp ; apt-get source binutils 25 | cd binutils-2.22 26 | ./debian/rules patch 27 | mkdir /tmp/binutils-build 28 | cd /tmp/binutils-build 29 | /tmp/binutils-2.22/configure --target=arm-linux-gnueabi --prefix=/opt/arm-linux-gnueabi-tools --enable-shared --enable-plugins --with-sysroot=/opt/arm-linux-gnueabi 30 | make -j4 && make install 31 | cd /tmp ; apt-get source gcc-4.6 32 | cd gcc-4.6-4.6.3 33 | DEB_CROSS_NO_BIARCH=yes ./debian/rules patch 34 | mkdir /tmp/gcc-build 35 | cd /tmp/gcc-build 36 | /tmp/gcc-4.6-4.6.3/src/configure --target=arm-linux-gnueabi --prefix=/opt/arm-linux-gnueabi-tools --with-sysroot=/opt/arm-linux-gnueabi --enable-languages=c 37 | make -j4 && make install 38 | -------------------------------------------------------------------------------- /ascii-art-maker: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | ##################################################################### 4 | # 5 | # ascii_art_maker.py 6 | # 7 | # Makes ascii art out of an image on the internet and prints it to 8 | # stdout. 9 | # 10 | # @author Isis Lovecruft, 0x2cdb8b35 11 | # @version 1.0.0 12 | # 13 | # Taken from http://jwilk.net/software/python-aalib 14 | ##################################################################### 15 | 16 | import aalib 17 | import Image 18 | import urllib2 19 | from PIL import ImageOps 20 | from optparse import OptionParser 21 | from cStringIO import StringIO 22 | 23 | def make_options(): 24 | return options, args 25 | 26 | def asciify(image_url, width, height, invert): 27 | """ 28 | Takes an image from the interwebs and turns it into ascii art. 29 | 30 | FTFW like wut. 31 | """ 32 | width = ((width * 7) // 4) 33 | screen = aalib.AsciiScreen(width=width, height=height) 34 | grabbed_image = urllib2.urlopen(image_url).read() 35 | fp = StringIO(grabbed_image) 36 | resized = Image.open(fp).convert('L').resize(screen.virtual_size) 37 | 38 | if invert: 39 | image = ImageOps.invert(resized) 40 | else: 41 | image = resized 42 | 43 | screen.put_image((0, 0), image) 44 | print screen.render() 45 | 46 | if __name__ == "__main__": 47 | 48 | usage = "Usage: %prog [options] " 49 | parser = OptionParser(usage=usage) 50 | parser.add_option("-H", "--height", type="int", dest="height", 51 | help="The height, in number of characters, that the image should be printed with", 52 | metavar="HEIGHT") 53 | parser.add_option("-W", "--width", type="int", dest="width", 54 | help="The width, in number of characters, that the image should be printed with", 55 | metavar="WIDTH") 56 | parser.add_option("-I", "--invert", action="store_true", dest="invert", 57 | help="Invert the image's colours") 58 | (options, args) = parser.parse_args() 59 | 60 | if not options.width: 61 | width = 80 62 | else: 63 | width = options.width 64 | 65 | if not options.height: 66 | height = 40 67 | else: 68 | height = options.width 69 | 70 | if not options.invert: 71 | invert = False 72 | else: 73 | invert = True 74 | 75 | if len(args) != 1: 76 | parser.print_help() 77 | else: 78 | asciify(args[0], width, height, invert) 79 | -------------------------------------------------------------------------------- /bash-prompt.sh: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 ; mode: sh -*- 2 | # 3 | # bash-prompt.sh 4 | # -------------- 5 | # Source me for a git-enabled, utf-8, coloured bash prompt and extra functions 6 | # 'shorten' and 'lengthen' for showing the full path or the rightmost 7 | # directory name for the current working directory. 8 | # 9 | # Be sure to source the git-prompt.sh script first! 10 | # 11 | # :authors: Isis Agora Lovecruft 0xa3adb67a2cdb8b35 12 | # :version: 0.1.0 13 | # :license: WTFPL 14 | # 15 | 16 | ## uncomment for a colored prompt 17 | force_color_prompt=yes 18 | if [ -n "$force_color_prompt" ]; then 19 | if [ -x /usr/bin/tput ] && tput setaf 1 >&/dev/null; then 20 | ## We have color support; assume it's compliant with Ecma-48 21 | ## (ISO/IEC-6429). (Lack of such support is extremely rare, and such 22 | ## a case would tend to support setf rather than setaf.) 23 | color_prompt=yes 24 | else 25 | color_prompt=no 26 | fi 27 | fi 28 | 29 | ## Allow git repos to be discovered on other filesystems: 30 | GIT_DISCOVERY_ACROSS_FILESYSTEM=true 31 | export GIT_DISCOVERY_ACROSS_FILESYSTEMS 32 | 33 | ## If you set GIT_PS1_SHOWDIRTYSTATE to a nonempty 34 | ## value, unstaged (*) and staged (+) changes will be shown next 35 | ## to the branch name. You can configure this per-repository 36 | ## with the bash.showDirtyState variable, which defaults to true 37 | ## once GIT_PS1_SHOWDIRTYSTATE is enabled. 38 | GIT_PS1_SHOWDIRTYSTATE=true 39 | 40 | ## You can also see if currently something is stashed, by setting 41 | ## GIT_PS1_SHOWSTASHSTATE to a nonempty value. If something is stashed, 42 | ## then a '$' will be shown next to the branch name. 43 | GIT_PS1_SHOWSTASHSTATE=true 44 | 45 | ## If you would like to see if there're untracked files, then you can 46 | ## set GIT_PS1_SHOWUNTRACKEDFILES to a nonempty value. If there're 47 | ## untracked files, then a '%' will be shown next to the branch name. 48 | ## 49 | #GIT_PS1_SHOWUNTRACKEDFILES=true 50 | 51 | ## If you would like to see the difference between HEAD and its 52 | ## upstream, set GIT_PS1_SHOWUPSTREAM="auto". A "<" indicates 53 | ## you are behind, ">" indicates you are ahead, and "<>" 54 | ## indicates you have diverged. You can further control 55 | ## behaviour by setting GIT_PS1_SHOWUPSTREAM to a space-separated 56 | ## list of values: 57 | ## verbose show number of commits ahead/behind (+/-) upstream 58 | ## legacy don't use the '--count' option available in recent 59 | ## versions of git-rev-list 60 | ## git always compare HEAD to @{upstream} 61 | ## svn always compare HEAD to your SVN upstream 62 | ## auto just the '<', '>', or '<>' 63 | ## By default, __git_ps1 will compare HEAD to your SVN upstream 64 | ## if it can find one, or @{upstream} otherwise. Once you have 65 | ## set GIT_PS1_SHOWUPSTREAM, you can override it on a 66 | ## per-repository basis by setting the bash.showUpstream config 67 | ## variable. 68 | GIT_PS1_SHOWUPSTREAM="auto" 69 | #GIT_PS1_SHOWUPSTREAM="verbose" 70 | 71 | if [ "$color_prompt" = yes ]; then 72 | if [ $(id -u) != "0" ]; then 73 | PROMPT_COMMAND='prmcmd=`__git_ps1 "(%s)"`' 74 | PS1='\[\033[0m\033[32m\]∃!\[\033[33m\]\u\[\033[32m\]Ⓐ\[\033[36m\]\h\[\033[32m\]:\[\033[33m\]$prmcmd\w\[\033[32m\] ∴ \[\033[0m' 75 | else 76 | ## If root make the prompt red so that we notice we're in a root shell 77 | PROMPT_COMMAND='prmcmd=`__git_ps1 "(%s)"`' 78 | PS1='\[\033[0m\033[32m\]∃!\[\033[33m\]\u\[\033[32m\]Ⓐ\[\033[36m\]\h\[\033[32m\]:\[\033[33m\]$prmcmd\w\[\033[31m\] ∴ \[\033[0m' 79 | fi 80 | else 81 | PS1='\[\u@\h:\w\]\$ ' 82 | fi 83 | 84 | ## load the longer prompt 85 | function lengthen () { 86 | if [ $(id -u) != "0" ]; then 87 | PROMPT_COMMAND='prmcmd=`__git_ps1 "(%s)"`' 88 | PS1='\[\033[0m\033[32m\]∃!\[\033[33m\]\u\[\033[32m\]Ⓐ\[\033[36m\]\h\[\033[32m\]:\[\033[33m\]$prmcmd\w\[\033[32m\] ∴ \[\033[0m' 89 | else 90 | PROMPT_COMMAND='prmcmd=`__git_ps1 "(%s)"`' 91 | PS1='\[\033[0m\033[32m\]∃!\[\033[33m\]\u\[\033[32m\]Ⓐ\[\033[36m\]\h\[\033[32m\]:\[\033[33m\]$prmcmd\w\[\033[31m\] ∴ \[\033[0m' 92 | fi 93 | } 94 | 95 | function shorten () { 96 | if [ $(id -u) != "0" ]; then 97 | PROMPT_COMMAND='prmcmd=`__git_ps1 "(%s)"`' 98 | PS1='\[\033[0m\033[32m\]∃!\[\033[33m\]\u\[\033[32m\]Ⓐ\[\033[36m\]\h\[\033[32m\]:\[\033[33m\]$prmcmd\W\[\033[32m\] ∴ \[\033[0m' 99 | else 100 | PROMPT_COMMAND='prmcmd=`__git_ps1 "(%s)"`' 101 | PS1='\[\033[0m\033[32m\]∃!\[\033[33m\]\u\[\033[32m\]Ⓐ\[\033[36m\]\h\[\033[32m\]:\[\033[33m\]$prmcmd\W\[\033[31m\] ∴ \[\033[0m' 102 | fi 103 | } 104 | 105 | PS2='… ' 106 | PS3='… ' 107 | PS4='… ' 108 | unset color_prompt force_color_prompt 109 | -------------------------------------------------------------------------------- /boilerplate-bash: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | ################################################################################ 3 | # 4 | # boilerplate-bash 5 | # ---------------- 6 | # A simple utility to copy a file to a new location with a new name, and then 7 | # immediately start editing it. For boilerplates. 8 | # 9 | # @author Isis Agora Lovecruft, 0x2cdb8b35 10 | # @date 16 May 2012 11 | # @version 0.0.1 12 | # 13 | ################################################################################ 14 | 15 | -------------------------------------------------------------------------------- /boilerplater: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | ############################################################################## 3 | # 4 | # boilerplater 5 | # ------------ 6 | # A simple utility to copy a file to a new location with a new name, and then 7 | # immediately start editing it. For boilerplates. 8 | # 9 | # You should create a file containing the boilerplate to use, see the examples 10 | # boilerplate-bash and boilerplate-python, and then (probably in your 11 | # .bashrc) do: 12 | # 13 | # alias boilerpy="/path/to/boilerplate.sh boilerplate-python " 14 | # 15 | # and use that alias like this "$ boilerpy foobar.py". 16 | # 17 | # @author Isis Agora Lovecruft, 0x2cdb8b35 18 | # @date 16 May 2012 19 | # @version 0.0.1 20 | ############################################################################## 21 | 22 | ## Local variables: 23 | AUTHOR_NAME="Isis Agora Lovecruft" 24 | AUTHOR_GPG_KEY="0x2cdb8b35" 25 | 26 | function usage () { 27 | echo "Usage: $0 " 28 | echo 29 | echo "You should set the following environment variables:" 30 | echo "\$AUTHOR_NAME The name to be credited" 31 | echo "\$AUTHOR_GPG_KEY The GPG keyID or email address of the author" 32 | echo "\$EDITOR Your preferred editor" 33 | echo 34 | } 35 | 36 | if [[ "$#" != "2" ]]; then 37 | usage 38 | else 39 | echo "Please provide a short docstring description of the file " 40 | echo "which you are about to create: " 41 | 42 | read FDOCSTR 43 | 44 | ## If docstring is blank, boilerplate that too: 45 | if [[ "x${FDOCSTR}" == "x" ]] ; then 46 | FDOCSTR="XXX fill me in" 47 | fi 48 | 49 | ## Wrap docstring lines: 50 | INT=0 51 | while [[ ${#FDOCSTR} > 75 ]] ; do 52 | NEWSTR=FDOCSTR_${INT} 53 | eval ${NEWSTR}="# "${FDOCSTR:0:75} 54 | INT=$(( $INT + 1 )) 55 | FDOCSTR=${FDOCSTR:75:} 56 | done 57 | 58 | if [[ x$1 == x*sh ]] ; then 59 | cat >$2 <<-EOF 60 | #!/usr/bin/env bash 61 | ############################################################################## 62 | # 63 | # $2 64 | # ------------------- 65 | EOF 66 | 67 | if [[ $INT -gt "0" ]] ; then 68 | for int in `seq 0 $INT`; do 69 | cat >>$2 <>$2 <$2 <<-EOF 88 | #!/usr/bin/env python 89 | #-*- coding: utf-8 -*- 90 | ############################################################################## 91 | # 92 | # $2 93 | # -------------------- 94 | EOF 95 | 96 | if [[ $INT > 0 ]] ; then 97 | for int in `seq 0 $INT`; do 98 | CURRENT_STR=FDOCSTR_$int 99 | cat >>$2 <<<$CURRENT_STR 100 | done 101 | fi 102 | 103 | cat >>$2 <<-EOF 104 | # $FDOCSTR 105 | # 106 | # @author $AUTHOR_NAME, $AUTHOR_GPG_KEY 107 | # @date `date "+%e %B %Y"` 108 | # @version 0.0.1 109 | ############################################################################## 110 | 111 | import os 112 | 113 | 114 | def foo(): 115 | """ 116 | 117 | """ 118 | pass 119 | 120 | 121 | if __name__ == "__main": 122 | 123 | 124 | EOF 125 | else 126 | cp $1 $2 127 | fi 128 | ## Make it executable and start the editor 129 | chmod +x $2 130 | $EDITOR $2 131 | fi 132 | -------------------------------------------------------------------------------- /build_kernel: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | ## 3 | ## build_kernel 4 | ## ------------ 5 | ## Normally I'd opt for a *more* arcane name, but... 6 | ## 7 | ## This script is meant to be used on a Debian-based system to build a kernel 8 | ## package from a git checkout of a kernel source tree branch. For example: 9 | ## 10 | ## $ git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 11 | ## $ git checkout -b 3.8 v3.8 12 | ## 13 | ## Dependencies: 14 | ## * git-core 15 | ## * fakeroot 16 | ## * make, gcc || build-essentials 17 | ## * hardening-wrapper 18 | ## * make-kpkg 19 | ## * dpkg-buildpackage 20 | ## 21 | ## Recommends: 22 | ## * X11 (only for using xmenuconfig for kernel .config editing) 23 | ## * libncurses5-dev (only for using menuconfig for kernel .config editing) 24 | ## * git-what-branch https://github.com/SethRobertson/git-what-branch 25 | ## 26 | ## Suggests: 27 | ## * devscripts 28 | ## * quilt 29 | ## * dpkg-dev-el (for emacs editing of CHANGELOG files) 30 | ## 31 | ## @author: Isis Lovecruft, 0xa3adb67a2cdb8b35 32 | ## @date: 13 November 2012 33 | ## @version: 0.0.4 34 | ##---------------------------------------------------------------------------- 35 | 36 | ## must be root 37 | if [ "$(id -u)" != "0" ] ; then 38 | printf "You gotta be root.\nExiting...\n" 39 | exit 1 40 | fi 41 | 42 | ## Whether or not to display a lot of text about all the commands being run: 43 | KBUILD_VERBOSE=1 44 | 45 | ## Add the '-V=1' flag to Makefiles: 46 | MAKE_VERBOSE=1 47 | 48 | ## This should be the number of CPUs to use in the build-process 49 | ## (default: *all of the CPUs*): 50 | CONCURRENCY_LEVEL= 51 | 52 | ## The GnuPG key to sign the .dsc and CHANGELOG files with: 53 | SIGNING_KEY=0xa3adb67a2cdb8b35 54 | 55 | ## You should increment this by one for each build of the same kernel source: 56 | REV=1 57 | 58 | ## This should be the kernel version you are building. If git-what-branch is 59 | ## installed, we'll calculate it from the name of the immediate ancestor 60 | ## branch. 61 | KVER= 62 | 63 | ## Architecture to build for. Defaults to the output of 64 | ## `dpkg --print-archictecture`. 65 | KPKG_ARCH= 66 | 67 | ## Whether to include the architecture compiled for in the package name: 68 | ARCH_IN_NAME=1 69 | 70 | ## This should specify any optional extra tags to append to the end of the 71 | ## package name, specifying why it is special (i.e. 'rt' if the kernel 72 | ## RT_PREEMPT patches have been included): 73 | ## 74 | ## Note that this variable may only contain a-z ~ - + . 75 | ## and it will be appended to the end of the package name with a '+'. 76 | APPEND_TO_VERSION= 77 | 78 | ## INTERNAL VARIABLES (you shouldn't need to touch these) 79 | child=$(basename $0) ## this script, its pid, and 80 | childpid=$(ps --no-headers -C $0) ## dependencies 81 | deps={ make fakeroot make-kpkg gcc dpkg-buildpackage } 82 | 83 | function log() { test -n "$1" && logger -t "$child [$childpid]" -s "$1" } 84 | 85 | function exists() { hash "$1" 2>/dev/null || log "Could not find $1" } 86 | 87 | function havedeps() { 88 | for dep in $deps ; do 89 | exists $dep 90 | if [ "$?" != "0" ] ; then 91 | log "Unable to run without dependency $dep ..." 92 | log "Exiting ..." & exit 1 93 | fi 94 | done 95 | } 96 | 97 | if test -z "$CONCURRENCY_LEVEL" ; then 98 | CONCURRENCY_LEVEL=$(grep -c '^processor' /proc/cpuinfo) 99 | if test -n "$CONCURRENCY_LEVEL" ; then 100 | log "Building with CONCURRENCY_LEVEL set to $CONCURRENCY_LEVEL CPUs." 101 | else 102 | log "ERROR: Unable to number of available cores from /proc/cpuinfo." 103 | fi 104 | fi 105 | 106 | if test -z "$KVER" ; then 107 | if which git-what-branch >/dev/null 2>&/dev/null ; then 108 | ## try to get the kernel version from the our ancestor branch: 109 | eldergod=$(git what-branch `git merge-base --octopus HEAD`) 110 | if test -n "$eldergod" ; then 111 | KVER=$eldergod 112 | else 113 | log "Couldn't figure out kernel version." 114 | log "Set the environment variable KVER and try again." 115 | fi 116 | fi 117 | fi 118 | 119 | if test -z "$KPKG_ARCH" ; then KPKG_ARCH=$(dpkg --print-architecture) ; fi 120 | 121 | ## And putting them all together, we get the kernel package name: 122 | KREV="${KVER}-${REV}-${KPKG_ARCH}" 123 | if test -n "${APPEND_TO_VERSION}" ; then 124 | APPEND_TO_VERSION="+${APPEND_TO_VERSION}" 125 | KREV="${KREV}${APPEND_TO_VERSION}" 126 | fi 127 | 128 | function usage () { 129 | cat < .config 159 | log "Running make oldconfig ..." 160 | make oldconfig 161 | else 162 | log "Couldn't find current kernel configuration file..." 163 | icanhazx=$(ps --no-headers -C X) ## if we're running X11 164 | if test -z "$icanhazx" && ! test "$upthex" ; then 165 | log "Running make xconfig ..." 166 | make xconfig 167 | else 168 | log "Running make menuconfig ..." 169 | make menuconfig 170 | fi 171 | fi 172 | 173 | log "Cleaning up working directory..." 174 | make-kpkg clean 175 | 176 | log "Building source..." 177 | 178 | ## Uncomment to use all flags in hardening-wrapper. 179 | ## see https://wiki.debian.org/HardeningWalkthrough 180 | export DEB_BUILD_MAINT_OPTIONS = hardening=+all 181 | 182 | export CONCURRENCY_LEVEL 183 | export APPEND_TO_VERSION 184 | export KBUILD_VERBOSE 185 | export KPKG_ARCH 186 | export ARCH_IN_NAME 187 | 188 | #make-kpkg --noexec --rootcommand --append-to-version -j3 \ 189 | # --initrd --revision=3.6.0-6 \ 190 | # --added_modules tp_smapi kernel_image kernel_headers 191 | 192 | #CONCURRENCY_LEVEL=$CONCURRENCY_LEVEL fakeroot make-kpkg --initrd \ 193 | # --revision=$REV --append-to-version=${APPEND_TO_VERSION} 194 | 195 | if test "$MAKE_VERBOSE" -eq "1" ; then 196 | make-kpkg --verbose --root-command fakeroot \ 197 | --initrd --revision=$REV kernel_image kernel_headers 198 | else 199 | make-kpkg --root-command fakeroot \ 200 | --initrd --revision=$REV kernel_image kernel_headers 201 | fi 202 | } 203 | # mkdir linux-headers-$KVER$KREV 204 | # chgrp src linux-headers-$KVER$KREV 205 | # chmod g+rxw linux-headers-$KVER$KREV 206 | # usermod -aG src isis 207 | # exit 208 | # ## to reload group information 209 | # su -u isis 210 | # tar -zx --strip-components=1 -C linux-headers-$KVER$KREV -f $KSOURCETARBALL 211 | # cd linux-headers-$KVER$KREV 212 | # cp /boot/config-`uname -r` .config 213 | # make oldconfig 214 | # make menuconfig 215 | # make-kpkg --rootcmd fakeroot --append-to-version +toi-3.2-1-amd64 --initrd -j $NCPUS kernel_image 216 | # make-kpkg --rootcmd fakeroot --append-to-version $KREV --initrd -j $NCPUS kernel_headers 217 | # sudo su 218 | # dpkg -i linux-image-$KVER*.deb 219 | # dpkg -i linux-headers$KVER*.deb 220 | # ## Just in case 221 | # update-initramfs -k $KVER$KREV -c 222 | # update-grub 223 | # ## When you have booted to the TOI enabled kernel 224 | # ## you can read the swap file location by issuing 225 | # ## $ cat /sys/power/tuxonice/swap/headerlocations 226 | # ## You will get the exact resume line that you will 227 | # ## have to provide as kernel boot parameter (starting 228 | # ## with resume=) e.g. 229 | # ## For swapfile `/var/swap`, 230 | # ## use resume=swap:/dev/sda5:0x503a400. 231 | 232 | 233 | ## start: 234 | 235 | main 236 | -------------------------------------------------------------------------------- /build_tor: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # cd /home/isis/code/sources/openssl && \ 4 | # { make clean ; make clean-shared;} || echo "ALREADY CLEAN" && \ 5 | # git stash save && git stash drop stash@{0} && \ 6 | # git checkout master && \ 7 | # git fetch --all && \ 8 | # git merge --ff-only origin/master && \ 9 | # git checkout OpenSSL_1_0_2-stable && \ 10 | # git merge --ff-only origin/OpenSSL_1_0_2-stable && \ 11 | # ./config threads shared --prefix=/usr/local/ \ 12 | # --openssldir=/usr/local/openssl -DENGINEDYNAMIC_SUPPORT -DREENTRANT && \ 13 | # make depend && make && make test && \ 14 | # sudo make install 15 | 16 | if test -f "src/or/tor" ; then 17 | printf "Previously built Tor binary already found. Running make clean...\n" 18 | make clean #&& make distclean 19 | fi 20 | 21 | if [[ "$#" != "1" ]] ; then 22 | printf "Adding program suffix based on last git tag...\n" 23 | 24 | LAST_TAG=`git describe --abbrev=0 --tags` 25 | SUFFIX="-${LAST_TAG##tor-}" 26 | 27 | read -p"The last git tag was '${LAST_TAG}'.\ 28 | Use '${SUFFIX}' for program suffix? (Y/n) " 29 | case $REPLY in 30 | N|n) read -p"Please specify suffix: " SUFFIX 31 | ;; 32 | *) ;; 33 | esac 34 | else 35 | SUFFIX="${1}" 36 | fi 37 | printf "Okay, using '%s' as program suffix.\n" "${SUFFIX}" 38 | 39 | #./autogen.sh && \ 40 | ./configure --program-suffix="$SUFFIX" \ 41 | --with-tor-user=tor --with-tor-group=tor \ 42 | --enable-gcc-warnings-advisory && \ 43 | make -j 10 && \ 44 | make -j 10 test 45 | 46 | printf "Compilation finished!\n\n" 47 | read -p"Install tor${SUFFIX} now? (Y/n) " 48 | case $REPLY in 49 | N|n) ;; 50 | *) printf "Installing... " 51 | sudo make install 52 | ;; 53 | esac 54 | 55 | printf "All done! Have a good night, and hack the planet.\n" 56 | 57 | #--with-openssl-dir=/usr/local/lib --enable-static-openssl \ 58 | -------------------------------------------------------------------------------- /cybercyber: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # -*- coding: utf-8 -*- 3 | #------------------------------------------------------------------------------ 4 | # 5 | # cybercyber 6 | # ---------- 7 | # A simple cyberscript which cyberpicks a random cyberword from a cyberlist, 8 | # cyberprepends "cyber" to it, and cyberannouces it with espeak. Perfect for 9 | # cyberuse as a cybergeneral cybernotification callback, cybermaking slightly 10 | # cyberinappropriate cyberremarks at the wrong cybertime. 11 | # 12 | # To cyberuse with agl's xmpp-client (https://github.com/agl/xmpp-client), 13 | # cyberput this into your ~/.xmpp-client cyberconfiguration file: 14 | # 15 | # "NotifyCommand": ["/path/to/cybercyber"], 16 | # "IdleSecondsBeforeNotification": 300, 17 | # 18 | # Cyberrequirements: espeak 19 | # 20 | # :authors: Isis Agora Lovecruft, 0xa3adb67a2cdb8b35 21 | # :license: MIT licence 22 | # :version: 0.0.1 23 | #------------------------------------------------------------------------------ 24 | 25 | CYBER="activism addict advocacy affair age agent anarchism" 26 | CYBER=$CYBER" anarchy anarchist apocalypse architecture assault" 27 | CYBER=$CYBER" attack babble babe banking battle begging blackmail" 28 | CYBER=$CYBER" boyfriend bro buddy bullying caliphate capabilities cash" 29 | CYBER=$CYBER" censorship chat colonialism command commuter computery conflict" 30 | CYBER=$CYBER" celebrity conspiracy conversation cop cowboy crime critic crook cult" 31 | CYBER=$CYBER" cyber cybering czar dating death defense dildonic dimension" 32 | CYBER=$CYBER" discourse defense doctrine domain economy effects elite" 33 | CYBER=$CYBER" emergency enterprise environment equivalents exploitation" 34 | CYBER=$CYBER" erotic espionage ethics evangelist explosion extortion fashion" 35 | CYBER=$CYBER" feminism flaneur flirting forces forensics fraud freak freedom" 36 | CYBER=$CYBER" friend funeral future gambling gaming gang geek generation" 37 | CYBER=$CYBER" ghetto girlfriend goths government group hacker" 38 | CYBER=$CYBER" harassment hatred ho heaven heist hero heroin hug identity" 39 | CYBER=$CYBER" immorality imperialism industry information infrastructure" 40 | CYBER=$CYBER" intelligence intruder intrusion issues jargon jihad jihadi" 41 | CYBER=$CYBER" journalism junk junkie kid laundering law libertarian" 42 | CYBER=$CYBER" liberty literacy loafing looting locker loser lover" 43 | CYBER=$CYBER" marketplace marriage martyr media mob money mosque nation" 44 | CYBER=$CYBER" naut nerd network operations ninja ostracism payment peer penetration" 45 | CYBER=$CYBER" person physical philosopher phobia pioneer piracy pirate police" 46 | CYBER=$CYBER" politics porn pornography president" 47 | CYBER=$CYBER" privacy prostitute protest punk revolution rific romance" 48 | CYBER=$CYBER" sabotage scam security sex sexual shame shopper slacker samurai" 49 | CYBER=$CYBER" slut smut space spacetime sphere spy squatter " 50 | CYBER=$CYBER" squatting stalker stalking strategy" 51 | CYBER=$CYBER" stud team terrorism terrorist theft thief threat" 52 | CYBER=$CYBER" thug trail trash trespasser utopia villain war warfare" 53 | CYBER=$CYBER" warrior weapon wizard witchcraft" 54 | 55 | CYBER_LIST=($CYBER) 56 | CYBER_LENGTH=${#CYBER_LIST[@]} 57 | CYBER_WORD="${CYBER_LIST[$((RANDOM%CYBER_LENGTH))]}" 58 | 59 | function usage () 60 | { 61 | printf '%s [OPTIONS]\n\n' "$(basename $0)" 62 | printf 'OPTIONS\n' 63 | printf -- '-h\t\tThis cruft.\n' 64 | printf -- '-a\t\tAll of the cybercybers!\n' 65 | printf -- "-q\t\tDon't print to stdout.\n" 66 | } 67 | 68 | function allofthecybers () 69 | { 70 | for CYBER_WORD in $CYBER ; do 71 | printf " Cyber${CYBER_WORD}!\n" 72 | espeak -x --ipa=1 -s 130 -k 20 -p 25 "Cyber${CYBER_WORD}!" 2>/dev/null 73 | done 74 | } 75 | 76 | quiet=1 77 | 78 | while getopts haqv f; do 79 | case $f in 80 | h) usage ; exit 0 ;; 81 | a) allofthecybers ; shift ;; 82 | q) quiet=1 ;; 83 | v) quiet= ;; 84 | # don't we need `shift 2` above? or `shift $(( OPTIND - 1))`? 85 | esac 86 | done 87 | 88 | if test -z "$quiet" ; then 89 | printf " Cyber${CYBER_WORD}!\n" 90 | espeak -x --ipa=1 -s 130 -k 20 -p 25 "Cyber${CYBER_WORD}!" 2>/dev/null 91 | else 92 | espeak -x --ipa=1 -s 130 -k 20 -p 25 "Cyber${CYBER_WORD}!" 1>/dev/null 2>&1 93 | fi 94 | 95 | exit 0 96 | -------------------------------------------------------------------------------- /days-until: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8; -*- 3 | #_____________________________________________________________________________ 4 | # 5 | # days-until 6 | # ---------- 7 | # Prints the number of days remaining until some event. 8 | # 9 | # Usage: $ days-until 'the eschaton' 2012-06-21 10 | #_____________________________________________________________________________ 11 | 12 | 13 | from datetime import date 14 | import sys 15 | 16 | 17 | def days_until(when): 18 | year, month, day = when.split('-', 3) 19 | remaining = date(int(year), int(month), int(day)) - date.today() 20 | return remaining.days 21 | 22 | 23 | if __name__ == "__main__": 24 | message = None 25 | 26 | if len(sys.argv) == 3: 27 | when = sys.argv[2] 28 | message = sys.argv[1] 29 | elif len(sys.argv) == 2: 30 | when = sys.argv[1] 31 | else: 32 | sys.stdout.write("Usage: %s [MESSAGE] YEAR-MONTH-DAY\n" % __file__) 33 | 34 | remaining = days_until(when) 35 | sys.stdout.write("Days remaining until %s: %d\n" % 36 | (message if message else "event", remaining)) 37 | -------------------------------------------------------------------------------- /deuteranopia: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ############################################################################### 3 | # 4 | # deuteranopia 5 | # -------------- 6 | # mount/unmount LUKS partition 7 | # 8 | # @author Isis Agora Lovecruft, 0xa3adb67a2cdb8b35 9 | # @date 03 December 2014 10 | # @version 0.0.1 11 | #______________________________________________________________________________ 12 | # Changelog: 13 | ############################################################################### 14 | 15 | # If the partition UUID changes, you can retrieve new one by doing: 16 | # $ sudo cryptsetup luksDump /dev/sdb1 17 | DEUTERANOPIA_PARTUUID="3d4c7174-73cb-41c4-bdaa-1e937a4267fc" 18 | DEUTERANOPIA_PARTITION=`blkid -U "$DEUTERANOPIA_PARTUUID"` 19 | DEUTERANOPIA_MAPTO='deuteranopia' 20 | DEUTERANOPIA_MAPPER="/dev/mapper/$DEUTERANOPIA_MAPTO" 21 | DEUTERANOPIA_MOUNT="/media/$DEUTERANOPIA_MAPTO" 22 | 23 | 24 | function deuterMount() { 25 | mapped= 26 | mounted= 27 | printf "Opening LUKS container for deuteranopia:\n" 28 | 29 | printf " Searching for deuteranopia's partition... " 30 | if test -n "$DEUTERANOPIA_PARTITION" ; then 31 | printf "%s\n" "$DEUTERANOPIA_PARTITION" 32 | 33 | isMapped=`sudo cryptsetup status "${DEUTERANOPIA_MAPTO}" | grep "${DEUTERANOPIA_PARTITION}"` 34 | printf " Checking that %s is not already mapped... " \ 35 | "${DEUTERANOPIA_MAPTO}" 36 | if test -z "$isMapped" ; then 37 | printf "ok\n" 38 | 39 | printf " Checking that %s is not mounted... " \ 40 | "$DEUTERANOPIA_PARTITION" 41 | if test -z "$(mount | grep $DEUTERANOPIA_PARTITION)" ; then 42 | printf "ok\n" 43 | 44 | printf " Mapping deuteranopia LUKS container %s to '%s'... \n" \ 45 | "$DEUTERANOPIA_PARTITION" "$DEUTERANOPIA_MAPTO" 46 | sudo cryptsetup luksOpen \ 47 | "$DEUTERANOPIA_PARTITION" "$DEUTERANOPIA_MAPTO" 48 | if test "$?" -eq "0" ; then 49 | 50 | printf " Checking for %s... " "$DEUTERANOPIA_MAPPER" 51 | if test -L "$DEUTERANOPIA_MAPPER" ; then 52 | printf "ok\n" 53 | mapped=true 54 | else 55 | printf "FAIL\n" # couldn't find mapper 56 | printf "ERROR: cryptsetup says %s is mapped, but cannot find %s" \ 57 | "$DEUTERANOPIA_MAPTO" "$DEUTERANOPIA_MAPPER" 58 | fi 59 | else 60 | printf "FAIL\n" # luksOpen failed 61 | fi 62 | else 63 | printf "FAIL\n" # already mounted 64 | mounted=true 65 | fi 66 | else 67 | printf "FAIL\n" # already mapped 68 | 69 | printf " Checking for %s... " "$DEUTERANOPIA_MAPPER" 70 | if test -L "$DEUTERANOPIA_MAPPER" ; then 71 | printf "ok\n" 72 | mapped=true 73 | else 74 | printf "FAIL\n" # couldn't find mapper 75 | printf "ERROR: cryptsetup says %s is mapped, but cannot find %s" \ 76 | "$DEUTERANOPIA_MAPTO" "$DEUTERANOPIA_MAPPER" 77 | fi 78 | fi 79 | 80 | if test -z "$mounted" -a -n "$mapped" ; then 81 | printf " Checking that %s is not already mounted... " \ 82 | "$DEUTERANOPIA_MAPPER" 83 | if test -z "$(mount | grep $DEUTERANOPIA_MAPPER)" ; then 84 | printf "ok\n" 85 | 86 | printf " Mounting %s on %s... " \ 87 | "$DEUTERANOPIA_MAPPER" "$DEUTERANOPIA_MOUNT" 88 | mount "$DEUTERANOPIA_MOUNT" 89 | if test "$?" -eq "0" ; then 90 | printf "ok\n" 91 | else 92 | printf "FAIL\n" # mounting failed 93 | fi 94 | 95 | else 96 | printf "FAIL\n" # Already mounted 97 | fi 98 | fi 99 | 100 | printf " Checking that %s is mounted... " \ 101 | "$DEUTERANOPIA_PARTITION" 102 | if test -n "$(mount | grep $DEUTERANOPIA_MAPPER)" ; then 103 | printf "ok\n" 104 | mounted=true 105 | else 106 | printf "FAIL\n" # mounting didn't work 107 | fi 108 | 109 | else 110 | printf "FAIL\n" # partition not found 111 | printf "ERROR: Are you sure the drive for %s is connected?\n" \ 112 | "$DEUTERANOPIA_MAPTO" 113 | fi 114 | } 115 | 116 | function deuterUnmount() { 117 | mounted=true 118 | mapped=true 119 | printf "Closing LUKS container for deuteranopia:\n" 120 | 121 | printf " Searching for deuteranopia's partition... " 122 | if test -n "$DEUTERANOPIA_PARTITION" ; then 123 | printf "%s\n" "$DEUTERANOPIA_PARTITION" 124 | 125 | printf " Checking if %s is mounted... " "$DEUTERANOPIA_MAPPER" 126 | if test -n "$(mount | grep $DEUTERANOPIA_MAPPER)" ; then 127 | printf "ok\n" 128 | 129 | printf " Unmounting %s... " "$DEUTERANOPIA_MOUNT" 130 | umount "$DEUTERANOPIA_MOUNT" 131 | if test "$?" -eq "0" ; then 132 | printf "ok\n" 133 | mounted= 134 | else 135 | printf "FAIL\n" # unmounting failed 136 | fi 137 | else 138 | printf "FAIL\n" # not mounted 139 | fi 140 | 141 | if test "$mapped" -a -z "$mounted" ; then 142 | isMapped=`sudo cryptsetup status "${DEUTERANOPIA_MAPTO}" | grep "${DEUTERANOPIA_PARTITION}"` 143 | printf " Checking if %s is mapped... " "${DEUTERANOPIA_MAPTO}" 144 | if test -n "$isMapped" ; then 145 | printf "ok\n" 146 | 147 | printf " Checking for %s... " "$DEUTERANOPIA_MAPPER" 148 | if test -L "$DEUTERANOPIA_MAPPER" ; then 149 | printf "ok\n" 150 | 151 | printf " Unmapping deuteranopia LUKS container %s... " \ 152 | "$DEUTERANOPIA_MAPTO" 153 | sudo cryptsetup luksClose "$DEUTERANOPIA_MAPTO" 154 | if test "$?" -eq "0" ; then 155 | printf "ok\n" 156 | else 157 | printf "FAIL\n" # luksClose failed 158 | fi 159 | else 160 | printf "FAIL\n" # couldn't find mapper 161 | printf "ERROR: cryptsetup says %s is mapped, but cannot find %s" \ 162 | "$DEUTERANOPIA_MAPTO" "$DEUTERANOPIA_MAPPER" 163 | fi 164 | else 165 | printf "FAIL\n" # not mapped 166 | fi 167 | fi 168 | else 169 | printf "FAIL\n" # partition not found 170 | printf "ERROR: Are you sure the drive for %s is connected?\n" \ 171 | "$DEUTERANOPIA_MAPTO" 172 | fi 173 | } 174 | 175 | function usage() { 176 | prog="${0##*/}" 177 | printf "Usage: %s [-m|-u]\n" "$prog" 178 | printf "\n" 179 | printf "Options:\n" 180 | printf " -m\tMount deuteranopia\n" 181 | printf " -u\tUnmount deuteranopia\n" 182 | printf "\n" 183 | printf "The default, if called without any arguments, is '%s -m'.\n\n" \ 184 | "$prog" 185 | } 186 | 187 | if [[ "$#" == "0" ]] ; then 188 | deuterMount 189 | else 190 | while getopts umh x; do 191 | case $x in 192 | u) deuterUnmount;; 193 | m) deuterMount;; 194 | h) usage;; 195 | esac 196 | done 197 | fi 198 | -------------------------------------------------------------------------------- /dnswithtor: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | ############################################################################## 3 | # 4 | # dnssecwithtor 5 | # ------------------- 6 | # Configures Unbound, socat, and Tor, for resolving, validating, and caching 7 | # DNS requests through the Tor network. 8 | # 9 | # see https://labs.nic.cz/page/993/dnssec-validation-over-tor--linux-/ 10 | # 11 | # @author Isis Agora Lovecruft, 0x2cdb8b35 12 | # @date 25 August 2012 13 | # @version 0.0.1 14 | # 15 | ############################################################################## 16 | 17 | TOR_SOCKS_PORT="9050" 18 | 19 | PATH_UNBOUND=`which unbound` 20 | PATH_SOCAT=`which socat` 21 | PATH_TOR=`which tor` 22 | PATH_DIG=`which dig` 23 | 24 | OARC_RES="149.20.64.20" 25 | CZ_NIC_RES="217.31.204.130" 26 | 27 | function check_deps () 28 | { 29 | FAILZ="" 30 | ## XXX TODO offer to get dependencies for user 31 | test -x $PATH_UNBOUND || FAILZ="unbound " 32 | test -x $PATH_SOCAT || FAILZ=$FAILZ"socat " 33 | test -x $PATH_TOR || FAILZ=$FAILZ"tor " 34 | test -x $PATH_DIG || FAILZ=$FAILZ"bind-utils " 35 | 36 | if [[ "$FAILZ" != "" ]] ; then 37 | echo "do \"apt-get install $FAILZ" 38 | exit 1 39 | fi 40 | } 41 | 42 | function explain_all_of_the_things () { 43 | echo "DNS resolution will follow this chain:" 44 | echo "" 45 | echo "QUERY" 46 | echo " \\-> localhost:53 " 47 | echo " \\-> unbound -> 0.0.0.0:5353 -> 127.0.0.1:5353 " 48 | echo " / " 49 | echo " socat <--------------------------- " 50 | echo " \\-> local SOCKS4a proxy -> 127.0.0.1:$TOR_SOCKS_PORT " 51 | echo " / " 52 | echo " tor <----------------------------------------- " 53 | echo " \\ " 54 | echo " \\-> guard " 55 | echo " \\-> middle " 56 | echo " \\-> exit -> ?.?.?.?:53 <--> recursive DNS resolve" 57 | echo " / " 58 | echo " exit <-------- " 59 | echo " middle <-/ " 60 | echo " guard <-/ " 61 | echo " tor <-/ " 62 | echo " \\ " 63 | echo " \\-> local SOCKS4a proxy " 64 | echo " \\-> socat " 65 | echo " \\-> unbound " 66 | echo " \\-> validation -> local DNS cache " 67 | echo " / " 68 | echo "RESPONSE <------------------------------------- " 69 | echo "" 70 | echo "Totally not confusing at all, right?" 71 | echo "" 72 | echo "" 73 | } 74 | 75 | function check_dns () 76 | { 77 | ## Check that recursive, validated DNS resolves correctly without unbound 78 | 79 | MSG1="Testing DNS resolution over TCP to recursive validating resolver" 80 | 81 | echo "$MSG1 OARC at $OARC_RES ... "; echo; 82 | ANS1=`dig +tcp +dnssec labs.nic.cz @$OARC_RES | grep -C 1 ';; flags'` 83 | echo "$ANS1"; echo; 84 | CHECK1=$(echo $ANS1 | grep "NOERROR" | wc -l) 85 | if [[ "$CHECK1" == "1" ]] ; then 86 | echo "The resolver at $OARC_RES is working correctly." 87 | else 88 | echo "The resolver at $OARC_RES either could not be reached or something else went wrong!" 89 | echo "Please debug your unbound installation and network settings." 90 | echo "Exiting ..." 91 | exit 1 92 | fi 93 | 94 | echo "$MSG1 labs.nic.cz at $CZ_NIC_RES" 95 | ANS2=`dig +tcp +dnssec labs.nic.cz @$OARC_RES | grep -C 1 ';; flags'` 96 | echo "$ANS2"; echo; 97 | CHECK2=$(echo $ANS2 | grep "NOERROR" | wc -l) 98 | if [[ "$CHECK2" == "1" ]] ; then 99 | echo "The resolver at $CZ_NIC_RES is working correctly." 100 | else 101 | echo "The resolver at $CZ_NIC_RES either could not be reached or something else went wrong!" 102 | echo "Please debug your unbound installation and network settings." 103 | echo "Exiting ..." 104 | exit 1 105 | fi 106 | } 107 | 108 | function check_tor () 109 | { 110 | echo "Checking that Tor is currently running ... " 111 | CHECK5=$(pgrep tor | wc -l) 112 | if [[ "$CHECK5" == "0" ]] ; then 113 | echo "Process for Tor not found ..." 114 | echo "Tor is not currently running ..." 115 | echo "Starting Tor ..." 116 | if test -x /etc/init.d/tor ; then 117 | sudo /etc/init.d/tor start 118 | else 119 | echo "Could not find init script for Tor ..." 120 | echo "Exiting ..." 121 | exit 1 122 | fi 123 | else 124 | echo "Tor process found ..." 125 | echo "Tor is currently running ..." 126 | fi 127 | } 128 | 129 | function check_socat () 130 | { 131 | if [ "$(pidof socat && echo $?)" != 0 ] ; then 132 | echo "Starting socat tunnel ..." 133 | coproc socat TCP4-LISTEN:5353,bind=localhost,reuseaddr,fork SOCKS4A:localhost:149.20.64.20:53,socksport=$TOR_SOCKS_PORT 134 | fi 135 | } 136 | 137 | function kill_socat () 138 | { 139 | if [ "$(pidof socat >/dev/null 2>&1 && echo $?)" = 0 ] ; then 140 | kill $(pidof socat) 141 | fi 142 | } 143 | 144 | 145 | function check_socat_conn_tor () 146 | { 147 | echo "Testing that the socat tunnel is connecting to Tor ..." 148 | ANS4=`dig -p 5353 +tcp +dnssec labs.nic.cz @localhost` 149 | CHECK4=$(echo $ANS4 | grep "NOERROR" | wc -l) 150 | if [[ "$CHECK4" == "0" ]] ; then 151 | echo "Socat was unable to talk to Tor ..." 152 | echo "We currently believe that your SOCKS port is $TOR_SOCKS_PORT." 153 | echo "Please check your torrc to make sure this is correct, if your" 154 | echo "torrc says otherwise, then edit the top line of this script " 155 | echo "to match your torrc." 156 | echo "" 157 | echo "Exiting ..." 158 | else 159 | echo "Socat tunnel is connected to Tor, and a DNS request was completed:" 160 | echo "$ANS4" 161 | echo "" 162 | fi 163 | } 164 | 165 | function check_unbound () 166 | { 167 | echo "Checking that unbound is currently running ... " 168 | CHECK3=`pgrep unbound | wc -l` 169 | if [[ "$CHECK3" == "0" ]] ; then 170 | echo "Process for unbound not found ..." 171 | echo "Unbound is not currently running ..." 172 | echo "Starting unbound ..." 173 | if test -x /etc/init.d/unbound ; then 174 | sudo /etc/init.d/unbound start 175 | else 176 | echo "Could not find init script for unbound ..." 177 | echo "Exiting ..." 178 | exit 1 179 | fi 180 | else 181 | echo "Unbound process found ..." 182 | echo "Unbound is currently running ..." 183 | fi 184 | } 185 | 186 | function check_dnssec () 187 | { 188 | echo "Testing DNS resolution of a DNSSEC query through unbound instance ..." 189 | ANS6=`dig +dnssec labs.nic.cz @localhost` 190 | CHECK6=$(echo $ANS6 | grep "NOERROR" | wc -l) 191 | if [[ "$CHECK6" == "0" ]] ; then 192 | echo "Unbound appears to not be working ..." 193 | echo "Although, we are about to backup the current config for unbound" 194 | echo "and continue with a new config...should we continue doing so?" 195 | select yn in "yes" "no" ; do 196 | case $yn in 197 | yes ) 198 | break 199 | ;; 200 | no ) 201 | echo "Exiting ..." 202 | exit 0 203 | ;; 204 | * ) 205 | exit 1 206 | ;; 207 | esac 208 | done 209 | else 210 | echo "Unbound resolved the query correctly ..." 211 | echo "Checking that DNSSEC answer was validated according to root anchor ..." 212 | CHECK7=$(echo $ANS6 | grep "flags.*ad" | wc -l) 213 | if [[ "$CHECK7" != "1" ]] ; then 214 | echo "DNSSEC flag was missing from query results!" 215 | echo "Maybe you haven't yet configured the root anchor?" 216 | echo "See http://unbound.net/documentation/howto_anchor.html" 217 | else 218 | echo "DNSSEC flags present in query results ..." 219 | echo "DNSSEC validation check passed ..." 220 | fi 221 | fi 222 | } 223 | 224 | function backup_unbound_conf () 225 | { 226 | MAYBECONF=$(locate -l 1 unbound.conf) 227 | MAYBEBACK=$MAYBECONF".orig.bak" 228 | DINOCONF="/etc/unbound/unbound.dinosaur" 229 | if test -x $MAYBECONF ; then 230 | if [[ "$MAYBECONF" == "/etc/unbound/unbound.conf" ]] ; then 231 | echo "Backing up $MAYBECONF to $MAYBEBACK ..." 232 | sudo cp $MAYBECONF $MAYBEBACK 233 | fi 234 | else 235 | echo "Couldn't find /etc/unbound/unbound.conf ..." 236 | echo "Hum. Do you have some strange configuration settings for unbound?" 237 | echo "We weren't able to backup /etc/unbound/unbound.conf, so we're" 238 | echo "going to go ahead and create the new config in its place ..." 239 | fi 240 | } 241 | 242 | function make_unbound_conf () 243 | { 244 | echo "Creating new unbound.conf file ..." 245 | sudo touch $DINOCONF && \ 246 | sudo chmod a+rw $DINOCONF 247 | cat > $DINOCONF< socat -> Tor ..." 281 | check_dnssec 282 | else 283 | ## it wouldn't be a script without it... 284 | cat <<"EOF" 285 | ____________________________________ 286 | | DiNoSaur! Recursive, validating, | 287 | | caching, DNSSEC-enabled resolution | 288 | | through Unbound, socat, and Tor\! | 289 | ------------------------------------ 290 | \ . . 291 | \ / `. .' " 292 | \ .---. < > < > .---. 293 | \ | \ \ - ~ ~ - / / | 294 | _____ ..-~ ~-..-~ 295 | | (A)| \~~~\.' `./~~~/ 296 | --------- \__/ \__/ 297 | .' O \ / / \ " 298 | (_____, `._.' | } \/~~~/ 299 | `----. / } | / \__/ 300 | `-. | / | / `. ,~~| 301 | ~-.__| /_ - ~ ^| /- _ `..-' 302 | | / | / ~-. `-. _ _ _ 303 | |_____| |_____| ~ - . _ _ _ _ _> 304 | 305 | EOF 306 | fi 307 | -------------------------------------------------------------------------------- /exclude-slow-tor-relays: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | """ 4 | exclude-slow-tor-relays 5 | ----------------------- 6 | 7 | Generate a torrc file with an ExcludeNodes lines containing all relays whose 8 | observed bandwidth is less than a given amount. 9 | 10 | :author: Isis 0x0A6A58A14B5946ABDE18E207A3ADB67A2CDB8B35 11 | :version: 0.0.1 12 | :license: AGPLv3 13 | :copyright: © 2014-2015 Isis Agora Lovecruft 14 | """ 15 | 16 | from __future__ import print_function 17 | from __future__ import unicode_literals 18 | 19 | import argparse 20 | import logging 21 | import os 22 | import sys 23 | 24 | try: 25 | from stem.descriptor import parse_file 26 | from stem.descriptor import router_status_entry 27 | except ImportError: 28 | print("""\ 29 | This script requires Stem. If you're on a Debian-based system, try installing\n 30 | the `python-stem` package. See https://stem.torproject.org/ for more info.""") 31 | except Exception: 32 | print("There was an error importing Stem.") 33 | 34 | 35 | #: The minimum bandwidth a relay should have, in kilobytes. Relays with less 36 | #: than this amount of bandwidth will be added to the ExcludeNodes line and 37 | #: therefore not used by your Tor client. (default: 600 KB/s) 38 | MINIMUM_BANDWIDTH = 600 39 | 40 | #: The path to the directory which your Tor process stores data in. In your 41 | #: torrc file, this directory is given under the option `DataDirectory`. Please 42 | #: see `man (1) tor` for more information, including the default path. 43 | TOR_DATA_DIR = "/var/lib/tor" 44 | 45 | #: The path to Tor's init.d script (default: "/etc/init.d/tor-git") 46 | TOR_INITD_SCRIPT = "/etc/init.d/tor" 47 | 48 | #: The names of various flavours of consensus files which we might find in the 49 | #: :data:`TOR_DATA_DIR`. These files should hold basic information on all the 50 | #: relays we know about, including bandwidth information. You probably don't 51 | #: need to change this setting. 52 | POTENTIAL_CONSENSII = ["cached-consensus", "cached-microdesc-consensus"] 53 | 54 | 55 | log = logging.getLogger() 56 | 57 | 58 | def _get_args(): 59 | parser = argparse.ArgumentParser() 60 | parser.add_argument('-d', '--data-dir', 61 | help=("Path to Tor's DataDir (default: %s)" 62 | % TOR_DATA_DIR)) 63 | parser.add_argument('-c', '--consensus-file', 64 | help=("The filename of Tor's consensus file (default: " 65 | "%s)" % POTENTIAL_CONSENSII[-1])) 66 | parser.add_argument('-b', '--min-bandwidth', type=int, 67 | help=("Relays under this bandwidth (in KB/s) will be " 68 | "excluded (default: %s KB/s)" % MINIMUM_BANDWIDTH)) 69 | parser.add_argument('-f', '--file', 70 | help=("The path to the file to write the new ExcludeNodes " 71 | "torrc to (default: DATA_DIR/../torrc.exclude-nodes)")) 72 | parser.add_argument('-i', '--in-place', 73 | help=("Edit the primary torrc file in place. Provide the" 74 | " path to the torrc file to edit in place")) 75 | log_group = parser.add_argument_group(title='Logging', 76 | description="Options and settings for logging") 77 | log_group.add_argument('--stderr', action='store_true', help="Log to stderr") 78 | log_group.add_argument('--stdout', action='store_true', help="Log to stdout") 79 | log_group.add_argument('--logfile', help="Log to file") 80 | log_group.add_argument('--loglevel', help="Log level", default="INFO", 81 | choices=["DEBUG", "INFO", "WARN", "ERROR", "CRITICAL"]) 82 | 83 | args = parser.parse_args() 84 | return args 85 | 86 | def create_exclude_nodes_line(fingerprints): 87 | exclude_nodes = 'ExcludeNodes ' + ','.join(fingerprints) + '\n' 88 | return exclude_nodes 89 | 90 | def find_slow_nodes(consensus, minimum_bandwidth): 91 | consensus_file = open(consensus, 'rb') 92 | descriptors = list(parse_file(consensus_file)) 93 | total_relays = len(descriptors) 94 | 95 | consensus_file.close() 96 | 97 | too_slow = [] 98 | 99 | for relay in descriptors: 100 | if relay.bandwidth <= minimum_bandwidth: 101 | too_slow.append(relay.fingerprint) 102 | log.debug("Excluding %s with bandwidth=%s" % 103 | (relay.fingerprint, relay.bandwidth)) 104 | elif relay.is_unmeasured: 105 | too_slow.append(relay.fingerprint) 106 | log.debug("Excluding %s with unmeasured bandwidth=%s" % 107 | (relay.fingerprint, relay.bandwidth)) 108 | 109 | too_slow = ['$%s' % fingerprint for fingerprint in too_slow] 110 | log.info("Excluding %s/%s relays with bandwidth <= %s KB/s." 111 | % (len(too_slow), total_relays, minimum_bandwidth)) 112 | 113 | return too_slow 114 | 115 | def add_new_torrc_to_initd(initd_script, torrc): 116 | """TODO Add the torrc filepath returned from write_torrc() to the ARGS= 117 | variable in TOR_INITD_SCRIPT if it is not already there. 118 | """ 119 | log.info("\n" + "-" * 80) 120 | 121 | line = '\tARGS="${ARGS} -f %s"' % torrc 122 | usage = "You should add `-f %s` to your usual invocation of Tor. " % torrc 123 | initd = os.path.isfile(TOR_INITD_SCRIPT) 124 | 125 | if initd: 126 | usage = usage + "For example, you might wish to add the line:\n" 127 | 128 | for index in range(0, len(usage), 80): 129 | log.info(usage[index:index+80]) 130 | if initd: 131 | log.info(line) 132 | log.info("\nto your Tor init.d script (%s)." % TOR_INITD_SCRIPT) 133 | 134 | log.info("-" * 80) 135 | 136 | def write_torrc(data_dir, lines): 137 | filename = 'torrc.exclude-slow' 138 | filepath = os.path.join(os.path.dirname(data_dir), filename) 139 | 140 | stat = os.stat(data_dir) 141 | uid = stat.st_uid 142 | gid = stat.st_gid 143 | 144 | with open(filepath, 'w') as fh: 145 | fh.writelines(lines) 146 | fh.flush() 147 | os.fchown(fh.fileno(), uid, gid) 148 | 149 | log.debug("Wrote ExcludeNodes line to new torrc file: %s" % filepath) 150 | 151 | return filepath 152 | 153 | def write_torrc_in_place(torrc_path, exclude): 154 | torrc_lines = [] 155 | orig_exclude_line = '' 156 | 157 | with open(torrc_path) as fh: 158 | for line in fh.readlines(): 159 | if line.lower().startswith('excludenodes'): 160 | orig_exclude_line = line 161 | excluded_nodes = line.strip().replace("ExcludeNodes ", "").split(',') 162 | excluded_nodes.extend(exclude) 163 | excluded_nodes = list(set(excluded_nodes)) 164 | 165 | line = create_exclude_nodes_line(excluded_nodes) 166 | 167 | torrc_lines.append(line) 168 | 169 | if not orig_exclude_line: 170 | torrc_lines.append(exclude) 171 | 172 | with open(torrc_path, 'w') as fh: 173 | fh.writelines(torrc_lines) 174 | fh.flush() 175 | 176 | if orig_exclude_line: 177 | log.debug("Overwrote ExcludeNodes line in torrc file: %s" % torrc_path) 178 | else: 179 | log.debug("Appended ExcludeNodes line to torrc file: %s" % torrc_path) 180 | 181 | return torrc_path 182 | 183 | def main(args): 184 | too_slow = [] 185 | data_dir = None 186 | consensus = None 187 | consensii = [] 188 | min_bandwidth = None 189 | 190 | if args.logfile: 191 | log.addHandler(logging.FileHandler(args.logfile)) 192 | elif args.stderr: 193 | log.addHandler(logging.StreamHandler(sys.stderr)) 194 | elif args.stdout: 195 | log.addHandler(logging.StreamHandler(sys.stdout)) 196 | else: 197 | log.addHandler(logging.StreamHandler(sys.stdout)) 198 | 199 | log.setLevel(logging._levelNames[args.loglevel]) 200 | 201 | if args.consensus_file: 202 | consensii.append(args.consensus_file) 203 | consensii.extend(POTENTIAL_CONSENSII) 204 | 205 | data_dir = args.data_dir if args.data_dir else TOR_DATA_DIR 206 | min_bw = args.min_bandwidth if args.min_bandwidth else MINIMUM_BANDWIDTH 207 | cur_uid = os.getuid() 208 | 209 | if os.path.isdir(data_dir) and os.access(data_dir, os.R_OK): 210 | for filename in consensii: 211 | filepath = os.path.join(data_dir, filename) 212 | if os.path.exists(filepath) and os.path.isfile(filepath): 213 | if os.access(filepath, os.R_OK): 214 | consensus = filepath 215 | break 216 | else: 217 | log.info("Your user (%s) can't read the consensus file %s." 218 | % (cur_uid, filepath)) 219 | else: 220 | log.warn("Your user (%s) can't read Tor's DataDirectory (%s)." 221 | % (cur_uid, data_dir)) 222 | 223 | if not consensus: 224 | log.error("Could not find or read consensus file.") 225 | sys.exit(1) 226 | 227 | too_slow = find_slow_nodes(consensus, min_bw) 228 | 229 | if too_slow: 230 | exclude_nodes = create_exclude_nodes_line(too_slow) 231 | if args.in_place: 232 | write_torrc_in_place(args.in_place, too_slow) 233 | if args.file: 234 | torrc = write_torrc(data_dir, exclude_nodes) 235 | add_new_torrc_to_initd(TOR_INITD_SCRIPT, torrc) 236 | 237 | return exclude_nodes 238 | 239 | 240 | if __name__ == "__main__": 241 | main(_get_args()) 242 | -------------------------------------------------------------------------------- /executioner: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | ############################################################################## 3 | # executioner 4 | # ----------- 5 | # Run process $2 for $1 seconds and then kill the process. 6 | # 7 | # :authors: Isis Agora Lovecruft, 0xa3adb67a2cdb8b35 8 | # :date: 21 April 2013 9 | # :version: 0.0.2 10 | ############################################################################## 11 | 12 | set -vx -- 13 | 14 | function killitwithfire () { 15 | trap - ALRM 16 | kill -ALRM $prog 2>/dev/null 17 | kill -9 $! 2>/dev/null && exit 0 18 | } 19 | 20 | function waitforit () { 21 | trap "killitwithfire" ALRM 22 | sleep $1& wait 23 | kill -ALRM $$ 24 | } 25 | 26 | waitforit $1& prog=$! ; shift ; 27 | trap "killitwithfire" ALRM INT 28 | "$@"& wait $! 29 | RET=$? 30 | if [[ "$(ps -ef | awk -v pid=$prog '$2==pid{print}{}')" != "" ]]; then 31 | kill -ALRM $prog 32 | wait $prog 33 | fi 34 | exit $RET 35 | -------------------------------------------------------------------------------- /exit-probability-factors.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # 4 | # exit-probability-factors.py 5 | # --------------------------- 6 | # Script for generating factors for multiplying monetary compensation of Tor 7 | # Exit Node operators. 8 | # 9 | # From JSON data taken from Compass, [0] it creates a multidimensional array 10 | # of country codes and the probability of exiting from that country. Then, it 11 | # generates a winsorized standard deviation and a trimmed standard deviation 12 | # of the probabilities within that array. Next, it takes the standard 13 | # deviation of all combined exit-by-country probabilities, subtracts either 14 | # the winsorized or trimmed standard deviation of all combined exit-by-country 15 | # probabilities, adds the probability of for exiting in that country, takes 16 | # the absolute value of this whole mess and computes the inverse squared: This 17 | # gives us an incentivization factor for disbursal of funds to exit relay 18 | # operators in countries with less exit relays. 19 | 20 | # Q: "Why all the maths?" 21 | # 22 | # A: "Without this, say for example if we just took the inverse of probability 23 | # of exiting in each country, the distribution of incentivizaton factors would 24 | # be severely skewed on each end of the spectrum. 25 | # 26 | # Simple English Wikipedia Version: "Without the maths, the numbers on each 27 | # end of the spectum are too extreme: operators in the USA and Germany would 28 | # get pennies for running relays, and we would be highly incentivizing a 29 | # ratrace to run Tor exit relays in places like Trinidad & Tobago and Jersey. 30 | # (Who knew New Jersey get kicked out of the Union?! And, can we kick out 31 | # states like Arkansas too?) 32 | # 33 | # Q: "Qu'est-ce que fuck do I do with this script?" 34 | # 35 | # A: "If you're normal, nothing. Otherwise, you run this script, and the 36 | # factors and their country CCs are stored in 37 | # ~/compass-incentive-factors.json. If you have €1000 to give to exit relay 38 | # operators this month, you divide that €1000 by the number of operators 39 | # you're donating to, let's say 42 operators: 40 | # €1000 / 42 = €23.81 41 | # Then you take each operator and whatever country their exit relay is running 42 | # in, find the factor for that relay, and multiply to get the ammount you 43 | # should give them." 44 | # 45 | # BEWARE: LIKELY INSANELY BUG- AND BADSTATISTICS- INFESTED. 46 | # 47 | # [0]: https://gitweb.torproject.org/compass.git 48 | # 49 | # :authors: Isis 0xA3ADB67A2CDB8B35 50 | # :license: Three-clause BSD 51 | # :copyright: (c) 2013 Isis Agora Lovecruft, The Tor Project, Inc. 52 | 53 | from __future__ import print_function 54 | from pprint import pprint 55 | 56 | import numpy 57 | import os 58 | import simplejson 59 | import sys 60 | 61 | 62 | compass_file = os.path.expanduser("~/compass.json") 63 | json_output_file = os.path.expanduser("~/compass-incentive-factors.json") 64 | 65 | if not os.path.isfile(compass_file): 66 | if ( len(sys.argv) == 2 ) and os.path.isfile(sys.argv[1]): 67 | compass_file = os.path.abspath(sys.argv[1]) 68 | else: 69 | cmd = os.system( 70 | '`locate compass.py` --by-country -t -1 --json > ~/compass.json') 71 | if not cmd == 0: 72 | print("Need JSON formatted output from compass.") 73 | print("Using compass JSON file: %s" % compass_file) 74 | 75 | compass_data = open(compass_file).read() 76 | compass_json = simplejson.loads(compass_data) 77 | 78 | countries = [country for country in compass_json.items()[1][1]] 79 | crange = xrange(len(countries)) 80 | 81 | def get_field(field): 82 | """Get the JSON `field` for every country in the list.""" 83 | return [countries[x].get(field) for x in crange] 84 | 85 | def sort_by_column(array): 86 | """Sort a two-dimensional array by the values in the second column.""" 87 | return array[array[:,1].argsort()] 88 | 89 | def winsorized_std_deviation(sorted_array, min_percentile, max_percentile): 90 | """Calculate the winsorized standard deviation, given a one-dimensional 91 | pre-sorted array and the cutoff percentiles. 92 | 93 | :type sorted_array: A :class:`numpy.array` or something passably so. 94 | :param sorted_array: A one-dimensional N-array of floats, corresponding to 95 | probabilities of exiting from a given country, pre-sorted from lowest 96 | (first) to highest (last). 97 | :param float min_percentile: The minimum percentile (i.e. '0.05)' for 98 | the 5th percentile), for which all values below should be replaced 99 | with the first value in the array which is above the min_percentile. 100 | :param float min_percentile: The maximum percentile, ibidem. 101 | """ 102 | numcc = float(len(sorted_array)) 103 | print("Number of countries calculated for: %d" % numcc ) 104 | low = numpy.round(min_percentile * numcc) 105 | high = numpy.round((1. - max_percentile) * numcc) 106 | print("Winsorization discarding", int(low), 107 | "elements beneath minimum percentile", min_percentile, "...") 108 | print("Winsorization discarding", int(high), 109 | "elements above maximum percentile", max_percentile, "...") 110 | 111 | ## XXX ↓ not working 112 | # xmin = numpy.float(sorted_array.item( (low,) )) 113 | # xmax = numpy.float(sorted_array.item( (high,) )) 114 | # print("xmin =", xmin, "; xmax =", xmax) 115 | # new = [] 116 | # for i in xrange(numcc): 117 | # if (low <= sorted_array.item(i) < high): 118 | # new.append(sorted_array.item(i)) 119 | # elif (low > sorted_array.item(i)): 120 | # new.append(xmin) 121 | # elif (high <= sorted_array.item(i)): 122 | # new.append(xmax) 123 | # print("New array:", new) 124 | # print("Clipped:", numpy.asarray(sorted_array.clip(xmin, xmax))) 125 | ## XXX ↑ none of this works, we need to use dtype() and argsort(): 126 | ## http://docs.scipy.org/doc/numpy/reference/generated/numpy.argsort.html#numpy.argsort 127 | 128 | return sorted_array[int(low):int(high)].std(ddof=0) 129 | 130 | def trimmed(array, min_percent, max_percent): 131 | """Calculate the trimmed standard deviation.""" 132 | tmp = numpy.asarray(array) 133 | return tmp[(min_percent <= tmp) & (tmp < max_percent)].std() 134 | 135 | def incentive(array, weight_factor): 136 | """Calculate the incentivization factor, for encouraging Tor exit relay 137 | operators in countries with less exit relays to run more nodes. 138 | 139 | :param array: A two-dimensional 3xN array of country codes, exit 140 | probabilities, and factors. 141 | :param float weight_factor: Should be winsorized standard deviation of 142 | exit probabilities, or trimmed standard deviation of exit 143 | probabilities. 144 | """ 145 | array_copy = numpy.asarray(array[:,1], dtype=numpy.float) 146 | main_stddev = numpy.float(array_copy.std()) 147 | 148 | incentivized = list() 149 | for ccname, pexit, _ in array[::]: 150 | ccname = numpy.string_(ccname) ## oh, Python2.x, how i despise you… 151 | pexit = numpy.float(pexit) 152 | 153 | weighted = main_stddev - weight_factor + pexit 154 | inverted = 1. / (abs(weighted)**2) 155 | shifted = inverted * 10. 156 | factor = shifted 157 | 158 | incentivized.append({'cc': ccname, 159 | 'p_exit': pexit, 160 | 'incentive_factor': factor}) 161 | return incentivized 162 | 163 | def sanity_check(incentives): 164 | """Check that √Σ^(crange)_i=1{factor/10} == 1. 165 | 166 | :param list incentives_list: The return value of :func:`incentivize`. 167 | """ 168 | print("Doing a sanity check:\n") 169 | sane = numpy.sqrt(sum([ (incentives[x].get('incentive_factor')/10.) 170 | for x in crange ]) ) 171 | if sane == 1: print("\tSanity check passed:") 172 | else: print("\tSanity check failed:") 173 | print("\t√Σ^(crange)_i=1{√(factor)/10} == %f" % sane) 174 | 175 | cc_list = get_field('cc') 176 | p_exit_list = get_field('p_exit') 177 | p_exit_array = numpy.asarray(p_exit_list) 178 | 179 | cc_array = numpy.asarray(zip(cc_list, p_exit_list, [float(0) for x in crange])) 180 | p_exit_i = numpy.asarray(zip(crange, p_exit_list)) 181 | ## XXX probably don't need this next one ↓ after all, unless we want to resort by 182 | ## weight and country code the indexed arrays now. 183 | cc_i = numpy.asarray(zip(crange, cc_list)) 184 | 185 | sorted_p_exits = numpy.asarray(sort_by_column(p_exit_i)) 186 | sorted_p_exits_col2 = numpy.asarray(sorted_p_exits[:,1]) 187 | 188 | winsorized_p_exits = winsorized_std_deviation(sorted_p_exits_col2, 0.10, 0.95) 189 | print("Winsorized standard deviation: ", winsorized_p_exits) 190 | 191 | ## the trimmed standard deviation of exit probabilities by country: 192 | trimmed_std = trimmed(sorted_p_exits_col2, 0.02, 6.50) 193 | print("Trimmed standard deviation: ", trimmed_std, "\n") 194 | 195 | incentivized = incentive(cc_array, trimmed_std) 196 | sanity_check(incentivized) 197 | json_output = simplejson.dumps(incentivized) 198 | 199 | with open(json_output_file, "wb") as output: 200 | output.write(json_output) 201 | print("Results stored as JSON string in %s\n" % json_output_file) 202 | 203 | print("Results:\n--------\n") 204 | pprint(simplejson.load(open(json_output_file)), depth=5) 205 | -------------------------------------------------------------------------------- /get-ssl-fingerprint: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | ############################################################################## 3 | # 4 | # get-ssl-fingerprint 5 | # ------------------- 6 | # Get a cert fingerprint after pulling the cert down. 7 | # 8 | # @author Isis Agora Lovecruft, 0x2cdb8b35 9 | # @date 22 February 2013 10 | # @version 0.0.2 11 | ############################################################################## 12 | 13 | function usage () { 14 | this="${0##*/}" 15 | printf "Usage: %s [-h] [-t digest] \n\n" $this 16 | cat </dev/null 29 | if test "$?" -eq "0"; then 30 | openssl list-message-digest-algorithms 31 | else 32 | printf "Your OpenSSL version is very old. You should update it.\n\n" 33 | openssl list-message-digest-commands 34 | fi 35 | } 36 | 37 | if test "$#" -ge "1"; then 38 | while getopts hlt: x; do 39 | case $x in 40 | h ) usage && exit 0 ;; 41 | l ) listdigests && exit 0 ;; 42 | t ) fprtype='-'$OPTARG ;; 43 | * ) usage && exit 2 ;; 44 | esac 45 | done 46 | shift $((OPTIND - 1)) 47 | 48 | host=$1 49 | if test -n "$host"; then 50 | if test -n "${fprtype}"; then 51 | openssl s_client -connect $host /dev/null | \ 52 | openssl x509 -in /dev/stdin -noout -fingerprint $fprtype 53 | else 54 | openssl s_client -connect $host /dev/null | \ 55 | openssl x509 -in /dev/stdin -noout -fingerprint 56 | fi 57 | fi 58 | exit $? 59 | else 60 | usage 61 | exit 1 62 | fi 63 | -------------------------------------------------------------------------------- /git-fix-author: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | ############################################################################## 3 | # 4 | # git-fix-author 5 | # ------------------- 6 | # Change all occurences of one author in git commits to another. 7 | # 8 | # @author Isis Agora Lovecruft, 0x2cdb8b35 9 | # @date 24 March 2013 10 | # @version 0.0.1 11 | ############################################################################## 12 | 13 | ## git filter-branch to remove authorname 14 | 15 | cat <", then the 18 | author's name would be given as "Anon") 19 | EOF 20 | 21 | read -p"What is the name of the author you would like to filter?" orig_author 22 | read -p"What name would you like to replace it with?" new_author 23 | read -p"What is the new author's email address?" new_email 24 | echo "Should we filter the current branch now, changing all occurences of" 25 | read -p"$orig_author to $new_author <$new_email> ? (y/N)" choice 26 | 27 | case $choice in 28 | y|Y) 29 | git filter-branch --commit-filter 'if [ "$GIT_AUTHOR_NAME" = "$orig_author" ]; then export GIT_AUTHOR_NAME="$new_author" ; export GIT_AUTHOR_EMAIL="$new_email" ; fi; git commit-tree "$@"' 30 | ;; 31 | *) 32 | echo "Exiting..." && exit 0 33 | ;; 34 | esac 35 | 36 | -------------------------------------------------------------------------------- /git-fix-date: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | ############################################################################## 3 | # 4 | # git-fix-date 5 | # ------------------- 6 | # Change all occurences of one timezone in git commits to another. 7 | # 8 | # @author Isis Agora Lovecruft, 0x2cdb8b35 9 | # @date 24 March 2013 10 | # @version 0.0.1 11 | ############################################################################## 12 | 13 | ## git filter-branch to replace GIT_AUTHOR_DATE and GIT_COMMITTER_DATE, setting 14 | ## all times to their equivalent in UTC. 15 | 16 | ## The path to your copy of my gitdate script: 17 | GITDATE=`which gitdate` 18 | 19 | if test -z "$DONT_CARE_IF_ITS_BROKEN" ; then 20 | printf "\nThis script is broken. Please fix me!\n\nIt currently needs:\n" 21 | printf " * A way to run git-filter-branch in a coproc, taking the function filterdate()\n" 22 | printf " (included in this script), or the contents of it, as an argument to either\n" 23 | printf " '--env-filter' or '--commit-filter'.\n" 24 | printf " * A way to cause the '$@' variables in filterdate() to not apply to the cmdline\n" 25 | printf " arguments for this file, but to the commit hashes iterated through \n" 26 | printf " filterdate(). I think this would be something like 'set -e -' combined with\n" 27 | printf " git-filter-branch's internal map() function, but I'm not sure.\n" 28 | printf " * The thing I was trying to do with coproc will not work because coprocesses\n" 29 | printf " in bash are not designed as usual, and will not handle loops. \n" 30 | printf " see http://stackoverflow.com/q/7689100 http://stackoverflow.com/q/7682196 \n\n" 31 | exit 1 32 | fi 33 | 34 | skip_commit() 35 | { 36 | shift; 37 | while [ -n "$1" ]; 38 | do 39 | shift; 40 | map "$1"; 41 | shift; 42 | done; 43 | } 44 | 45 | function filterdate () 46 | { 47 | if [ "${GIT_AUTHOR_DATE: -5}" = "$orig_tz" ] ; then 48 | . /home/isis/scripts/gitdate "$GIT_AUTHOR_DATE" 49 | export GIT_AUTHOR_DATE 50 | git commit-tree "$@" 51 | else 52 | skip_commit "$@" 53 | fi 54 | } 55 | 56 | cat <&3 ;} 3>&1 98 | 99 | #exec >&${fdate[0]} 100 | #while IFS= read -ru 3 x; do 101 | # printf '%s\n' "$x" 1>&0 102 | #done 103 | ;; 104 | esac 105 | ;; 106 | *) 107 | echo "Exiting..." && exit 0 108 | ;; 109 | esac 110 | 111 | -------------------------------------------------------------------------------- /git-mkchangelog: -------------------------------------------------------------------------------- 1 | eval '(exit $?0)' && eval 'exec perl -wS "$0" ${1+"$@"}' 2 | & eval 'exec perl -wS "$0" $argv:q' 3 | if 0; 4 | # Convert git log output to ChangeLog format. 5 | 6 | my $VERSION = '2012-01-24 15:58 (wk)'; # UTC 7 | # The definition above must lie within the first 8 lines in order 8 | # for the Emacs time-stamp write hook (at end) to update it. 9 | # If you change this file with Emacs, please let the write hook 10 | # do its job. Otherwise, update this string manually. 11 | 12 | # Copyright (C) 2008-2012 Free Software Foundation, Inc. 13 | 14 | # This program is free software: you can redistribute it and/or modify 15 | # it under the terms of the GNU General Public License as published by 16 | # the Free Software Foundation, either version 3 of the License, or 17 | # (at your option) any later version. 18 | 19 | # This program is distributed in the hope that it will be useful, 20 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 21 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 22 | # GNU General Public License for more details. 23 | 24 | # You should have received a copy of the GNU General Public License 25 | # along with this program. If not, see . 26 | 27 | # Written by Jim Meyering 28 | # Custom bugs bred by Werner Koch 29 | 30 | use strict; 31 | use warnings; 32 | use Getopt::Long; 33 | use POSIX qw(strftime); 34 | 35 | (my $ME = $0) =~ s|.*/||; 36 | 37 | # use File::Coda; # http://meyering.net/code/Coda/ 38 | END { 39 | defined fileno STDOUT or return; 40 | close STDOUT and return; 41 | warn "$ME: failed to close standard output: $!\n"; 42 | $? ||= 1; 43 | } 44 | 45 | sub usage ($) 46 | { 47 | my ($exit_code) = @_; 48 | my $STREAM = ($exit_code == 0 ? *STDOUT : *STDERR); 49 | if ($exit_code != 0) 50 | { 51 | print $STREAM "Try `$ME --help' for more information.\n"; 52 | } 53 | else 54 | { 55 | print $STREAM < ChangeLog 82 | $ME -- -n 5 foo > last-5-commits-to-branch-foo 83 | 84 | In a FILE specified via --amend, comment lines (starting with "#") are ignored. 85 | FILE must consist of pairs where SHA is a 40-byte SHA1 (alone on 86 | a line) referring to a commit in the current project, and CODE refers to one 87 | or more consecutive lines of Perl code. Pairs must be separated by one or 88 | more blank line. 89 | 90 | Here is sample input for use with --amend=FILE, from coreutils: 91 | 92 | 3a169f4c5d9159283548178668d2fae6fced3030 93 | # fix typo in title: 94 | s/all tile types/all file types/ 95 | 96 | 1379ed974f1fa39b12e2ffab18b3f7a607082202 97 | # Due to a bug in vc-dwim, I mis-attributed a patch by Paul to myself. 98 | # Change the author to be Paul. Note the escaped "@": 99 | s,Jim .*>,Paul Eggert , 100 | 101 | EOF 102 | } 103 | exit $exit_code; 104 | } 105 | 106 | # If the string $S is a well-behaved file name, simply return it. 107 | # If it contains white space, quotes, etc., quote it, and return the new string. 108 | sub shell_quote($) 109 | { 110 | my ($s) = @_; 111 | if ($s =~ m![^\w+/.,-]!) 112 | { 113 | # Convert each single quote to '\'' 114 | $s =~ s/\'/\'\\\'\'/g; 115 | # Then single quote the string. 116 | $s = "'$s'"; 117 | } 118 | return $s; 119 | } 120 | 121 | sub quoted_cmd(@) 122 | { 123 | return join (' ', map {shell_quote $_} @_); 124 | } 125 | 126 | # Parse file F. 127 | # Comment lines (starting with "#") are ignored. 128 | # F must consist of pairs where SHA is a 40-byte SHA1 129 | # (alone on a line) referring to a commit in the current project, and 130 | # CODE refers to one or more consecutive lines of Perl code. 131 | # Pairs must be separated by one or more blank line. 132 | sub parse_amend_file($) 133 | { 134 | my ($f) = @_; 135 | 136 | open F, '<', $f 137 | or die "$ME: $f: failed to open for reading: $!\n"; 138 | 139 | my $fail; 140 | my $h = {}; 141 | my $in_code = 0; 142 | my $sha; 143 | while (defined (my $line = )) 144 | { 145 | $line =~ /^\#/ 146 | and next; 147 | chomp $line; 148 | $line eq '' 149 | and $in_code = 0, next; 150 | 151 | if (!$in_code) 152 | { 153 | $line =~ /^([0-9a-fA-F]{40})$/ 154 | or (warn "$ME: $f:$.: invalid line; expected an SHA1\n"), 155 | $fail = 1, next; 156 | $sha = lc $1; 157 | $in_code = 1; 158 | exists $h->{$sha} 159 | and (warn "$ME: $f:$.: duplicate SHA1\n"), 160 | $fail = 1, next; 161 | } 162 | else 163 | { 164 | $h->{$sha} ||= ''; 165 | $h->{$sha} .= "$line\n"; 166 | } 167 | } 168 | close F; 169 | 170 | $fail 171 | and exit 1; 172 | 173 | return $h; 174 | } 175 | 176 | { 177 | my $since_date; 178 | my $format_string = '%s%n%b%n'; 179 | my $amend_file; 180 | my $append_dot = 0; 181 | my $tear_off = 0; 182 | GetOptions 183 | ( 184 | help => sub { usage 0 }, 185 | version => sub { print "$ME version $VERSION\n"; exit }, 186 | 'since=s' => \$since_date, 187 | 'format=s' => \$format_string, 188 | 'amend=s' => \$amend_file, 189 | 'append-dot' => \$append_dot, 190 | 'tear-off' => \$tear_off, 191 | ) or usage 1; 192 | 193 | 194 | defined $since_date 195 | and unshift @ARGV, "--since=$since_date"; 196 | 197 | # This is a hash that maps an SHA1 to perl code (i.e., s/old/new/) 198 | # that makes a correction in the log or attribution of that commit. 199 | my $amend_code = defined $amend_file ? parse_amend_file $amend_file : {}; 200 | 201 | my @cmd = (qw (git log --log-size), 202 | '--pretty=format:%H:%ct %an <%ae>%n%n'.$format_string, @ARGV); 203 | open PIPE, '-|', @cmd 204 | or die ("$ME: failed to run `". quoted_cmd (@cmd) ."': $!\n" 205 | . "(Is your Git too old? Version 1.5.1 or later is required.)\n"); 206 | 207 | my $prev_date_line = ''; 208 | my @prev_coauthors = (); 209 | 210 | while (1) 211 | { 212 | defined (my $in = ) 213 | or last; 214 | $in =~ /^log size (\d+)$/ 215 | or die "$ME:$.: Invalid line (expected log size):\n$in"; 216 | my $log_nbytes = $1; 217 | 218 | my $log; 219 | my $n_read = read PIPE, $log, $log_nbytes; 220 | $n_read == $log_nbytes 221 | or die "$ME:$.: unexpected EOF\n"; 222 | 223 | # Skip log entries with the default merge commit message. 224 | $log =~ /^.*\n\nMerge branch '.*\n\s*/ 225 | and goto SKIPCOMMIT; 226 | 227 | # Skip log entries if the body starts with a tear off marker. 228 | if ($tear_off) 229 | { 230 | $log =~ /^.*\n\n.*\n--\s*/ 231 | and goto SKIPCOMMIT; 232 | } 233 | 234 | # Extract leading hash. 235 | my ($sha, $rest) = split ':', $log, 2; 236 | defined $sha 237 | or die "$ME:$.: malformed log entry\n"; 238 | $sha =~ /^[0-9a-fA-F]{40}$/ 239 | or die "$ME:$.: invalid SHA1: $sha\n"; 240 | 241 | # If this commit's log requires any transformation, do it now. 242 | my $code = $amend_code->{$sha}; 243 | if (defined $code) 244 | { 245 | eval 'use Safe'; 246 | my $s = new Safe; 247 | # Put the unpreprocessed entry into "$_". 248 | $_ = $rest; 249 | 250 | # Let $code operate on it, safely. 251 | my $r = $s->reval("$code") 252 | or die "$ME:$.:$sha: failed to eval \"$code\":\n$@\n"; 253 | 254 | # Note that we've used this entry. 255 | delete $amend_code->{$sha}; 256 | 257 | # Update $rest upon success. 258 | $rest = $_; 259 | } 260 | 261 | my @line = split "\n", $rest; 262 | my $author_line = shift @line; 263 | defined $author_line 264 | or die "$ME:$.: unexpected EOF\n"; 265 | $author_line =~ /^(\d+) (.*>)$/ 266 | or die "$ME:$.: Invalid line " 267 | . "(expected date/author/email):\n$author_line\n"; 268 | 269 | my $date_line = sprintf "%s $2\n", strftime ("%F", localtime ($1)); 270 | 271 | # Format 'Co-authored-by: A U Thor ' lines in 272 | # standard multi-author ChangeLog format. 273 | my @coauthors = grep /^Co-authored-by:.*$/, @line; 274 | for (@coauthors) 275 | { 276 | s/^Co-authored-by:\s*/\t /; 277 | s/\s*/ 280 | or warn "$ME: warning: missing email address for " 281 | . substr ($_, 5) . "\n"; 282 | } 283 | 284 | # If this header would be the same as the previous date/name/email/ 285 | # coauthors header, then arrange not to print it. 286 | if ($date_line ne $prev_date_line or "@coauthors" ne "@prev_coauthors") 287 | { 288 | $prev_date_line eq '' 289 | or print "\n"; 290 | print $date_line; 291 | @coauthors 292 | and print join ("\n", @coauthors), "\n"; 293 | } 294 | $prev_date_line = $date_line; 295 | @prev_coauthors = @coauthors; 296 | 297 | # Omit "Co-authored-by..." and "Signed-off-by..." lines. 298 | @line = grep !/^Signed-off-by: .*>$/, @line; 299 | @line = grep !/^Co-authored-by: /, @line; 300 | 301 | # Remove everything after a line with 2 dashes at the beginning. 302 | if ($tear_off) 303 | { 304 | my @tmpline; 305 | foreach (@line) 306 | { 307 | last if /^--\s*$/; 308 | push @tmpline,$_; 309 | } 310 | @line = @tmpline; 311 | } 312 | 313 | # Remove leading and trailing blank lines. 314 | if (@line) 315 | { 316 | while ($line[0] =~ /^\s*$/) { shift @line; } 317 | while ($line[$#line] =~ /^\s*$/) { pop @line; } 318 | } 319 | 320 | # If there were any lines 321 | if (@line == 0) 322 | { 323 | warn "$ME: warning: empty commit message:\n $date_line\n"; 324 | } 325 | else 326 | { 327 | if ($append_dot) 328 | { 329 | # If the first line of the message has enough room, then 330 | if (length $line[0] < 72) 331 | { 332 | # append a dot if there is no other punctuation or blank 333 | # at the end. 334 | $line[0] =~ /[[:punct:]\s]$/ 335 | or $line[0] .= '.'; 336 | } 337 | } 338 | 339 | # Prefix each non-empty line with a TAB. 340 | @line = map { length $_ ? "\t$_" : '' } @line; 341 | 342 | print "\n", join ("\n", @line), "\n"; 343 | } 344 | 345 | SKIPCOMMIT: 346 | defined ($in = ) 347 | or last; 348 | $in ne "\n" 349 | and die "$ME:$.: unexpected line:\n$in"; 350 | } 351 | 352 | close PIPE 353 | or die "$ME: error closing pipe from " . quoted_cmd (@cmd) . "\n"; 354 | # FIXME-someday: include $PROCESS_STATUS in the diagnostic 355 | 356 | # Complain about any unused entry in the --amend=F specified file. 357 | my $fail = 0; 358 | foreach my $sha (keys %$amend_code) 359 | { 360 | warn "$ME:$amend_file: unused entry: $sha\n"; 361 | $fail = 1; 362 | } 363 | 364 | exit $fail; 365 | } 366 | 367 | # Local Variables: 368 | # mode: perl 369 | # indent-tabs-mode: nil 370 | # eval: (add-hook 'write-file-hooks 'time-stamp) 371 | # time-stamp-start: "my $VERSION = '" 372 | # time-stamp-format: "%:y-%02m-%02d %02H:%02M (wk)" 373 | # time-stamp-time-zone: "UTC" 374 | # time-stamp-end: "'; # UTC" 375 | # End: 376 | -------------------------------------------------------------------------------- /gitdate: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | #_____________________________________________________________________________ 3 | # Git Nowhere 4 | #----------------------------------------------------------------------------- 5 | # 6 | # Use: Run as "$ . ./gitdate" before "$ git commit" to manually set 7 | # the date to UTC in order to obscure timezone-based geodata tracking. 8 | # 9 | # If you would always like your timestamps to be obscured for a specific 10 | # project, then you'll need to either source this file BEFORE EACH COMMIT 11 | # while committing code. You *cannot* set it as a git hook, because git 12 | # hooks open child shell processes which are unable to affect the parent 13 | # shell's environment. To make this easier, however, you could set an 14 | # alias in whichever shell you use: 15 | # 16 | # alias gc=". /path/to/gitdate && git commit -v " 17 | # 18 | # NOTE: If you use "$ git commit -S -v" to create GnuPG signatures for your 19 | # git commits, the timestamp on the GnuPG signature will *NOT* match 20 | # the git AuthorDate and CommitDate lines, giving away that you are 21 | # lying. It would also be suspicious looking if you customarily sign 22 | # your commits, and signature(s) were inexplicably missing. 23 | # 24 | # :authors: Isis Lovecuft 0xA3ADB67A2CDB8B35 25 | # :version: 0.0.4 26 | # :copyright: (c) 2012-2013 Isis Lovecruft 27 | # :license: AGPLv3, see https://www.gnu.org/licenses/agpl-3.0.txt 28 | # 29 | # v0.0.5: It now knows if it's been sourced or executed, and if it was executed, 30 | # it prints the export commands which need to be run on stdout. Because 31 | # they are printed exacted as they should be run. 32 | # 33 | # We *should* be able to coproc that output from other scripts, piping 34 | # stdout of the coproc into the stdin of the other script, and wrap it 35 | # in an exec call, something like this: 36 | # 37 | # GD=`which gitdate` 38 | # { coproc gitdate { $GD "$@" ;} >&3;} 3>&1 39 | # { echo 'Thu Feb 28 11:47:04 2045 -1000' >&${gitdate[1]} ;} >&0 40 | # 41 | # except that is not right yet and still not working. 42 | # 43 | # v0.0.4: Fix so that timezones east of UTC shift backwards. 44 | # Add better date string parsing and some other fixes. 45 | # v0.0.3: Also changes the months and years, because that would suck if your 46 | # commits were accidentally made last year 47 | # v0.0.2: Changes the days too 48 | # v0.0.1: Changes the hours 49 | #_____________________________________________________________________________ 50 | 51 | ## Uncomment for debugging: 52 | #DEBUG=true 53 | 54 | ## Uncomment for really verbose debugging, and be sure to uncomment the 55 | ## the corresponding line at the end 56 | #set -x - 57 | 58 | ## Git uses the system time settings through mktime(). Do a "$ git log" to see 59 | ## the timezone offset for your system. This script gets your timezone offset 60 | ## by doing '$ date +"%z"'. If these two values are different, or for some 61 | ## reason you would like to manually specify the offset between timezones to 62 | ## change, then you can set this shell environment variable: 63 | ## 64 | ## TIMEOFFSET=-0400 65 | ## 66 | ## Which would mean that your current timestamps were made in the UTC-0400 67 | ## timezone (i.e. 'America/New_York'), and they will be modified by adding four 68 | ## hours to change them into UTC. 69 | 70 | #TIMEOFFSET=-0400 71 | 72 | if [ "x$0" == 'x-bash' ] ; then 73 | if test "$DEBUG" ; then printf "Detected that we were sourced.\n"; fi 74 | elif test -n "${0#gitdate}" ; then 75 | if test "$DEBUG" ; then printf "We weren't sourced.\n"; fi 76 | fi 77 | 78 | ## git stores datestrings as: Sun Aug 19 08:34:12 2012 -0400 79 | ## date uses: Mon May 6 21:00:18 UTC 2013 80 | 81 | if test $# -eq 0 ; then 82 | if test "$DEBUG" ; then 83 | printf "We didn't get a datestring argument.\n" 84 | fi 85 | if [ "$#" = '0' ] ; then 86 | DAY=$(date +"%a") 87 | MONTH=$(date +"%b") 88 | DATE=$(date +"%d") 89 | HOUR=$(date +"%H") 90 | MINSEC=$(date +"%M:%S") 91 | YEAR=$(date +"%Y") 92 | TIMEZONE=$(date +"%z") 93 | fi 94 | elif test $# -eq 1 ; then 95 | if test "$DEBUG" ; then 96 | printf "Converting git datestring: %s\n" "$1" 97 | fi 98 | DAY=$(echo "$1" | cut -d ' ' -f 1) 99 | MONTH=$(echo "$1" | cut -d ' ' -f 2) 100 | DATE=$(echo "$1" | cut -d ' ' -f 3) 101 | TIME=$(echo "$1" | cut -d ' ' -f 4) 102 | YEAR=$(echo "$1" | cut -d ' ' -f 5) 103 | TIMEZONE=$(echo "$1" | cut -d ' ' -f 6) 104 | HOUR=$(echo "$TIME" | cut -d ':' -f 1) 105 | MIN=$(echo "$TIME" | cut -d ':' -f 2) 106 | SEC=$(echo "$TIME" | cut -d ':' -f 3) 107 | MINSEC=$(echo "${MIN}:${SEC}") 108 | unset TIME 109 | unset MIN 110 | unset SEC 111 | else 112 | printf "\nUsage:\nTo change a specific commit's date, run as:\n" 113 | printf " . gitdate 'Mon Dec 29 17:45:54 2011 +0800'\n" 114 | printf "or as:\n" 115 | printf " gitdate 'Mon Dec 29 17:45:54 2011 +0800'\n" 116 | printf "and then run the printed export commands to change your shell's\n" 117 | printf "variables.\n" 118 | fi 119 | 120 | for mnth in Jan Mar May Jul Aug Oct Dec ; do 121 | if [[ "$mnth" = "$MONTH" ]]; then LONG_MONTH=true ; fi 122 | done 123 | 124 | TIMEOFFSET=${TIMEOFFSET:=$TIMEZONE} 125 | TIMEOFFSET=${TIMEOFFSET%%00} 126 | if [[ "${TIMEOFFSET:0:1}" = '-' ]] ; then 127 | TIMEOFFSET=${TIMEOFFSET:1} 128 | IS_WEST=true 129 | elif [[ "${TIMEOFFSET:0:1}" = '+' ]] ; then 130 | TIMEOFFSET=${TIMEOFFSET:1} 131 | IS_EAST=true 132 | else 133 | printf "Error: TIMEOFFSET variable did not start with '-' or '+'" 134 | fi 135 | 136 | ## 'let' requires the leading zero stripped 137 | if [[ "${TIMEOFFSET:0:1}" = '0' ]] ; then 138 | TIMEOFFSET=${TIMEOFFSET:1} 139 | fi 140 | 141 | if test "$IS_WEST" ; then 142 | let SPILLOVER=24-TIMEOFFSET 143 | if [ "$HOUR" -lt "$SPILLOVER" ]; then 144 | let HOUR+=TIMEOFFSET 145 | else 146 | let TILMIDNIGHT=24-HOUR 147 | let HOUR=TIMEOFFSET-TILMIDNIGHT 148 | FALSEDAWN=true 149 | unset TILMIDNIGHT 150 | fi 151 | unset TIMEOFFSET 152 | unset SPILLOVER 153 | 154 | # If the hour is one digit, prepend a zero. 155 | if [ "${#HOUR}" -eq "1" ]; then 156 | HOUR=$(printf "%02d" $HOUR) 157 | fi 158 | 159 | # If it is tomorrow in UTC, make sure we increment the day. 160 | if test "$FALSEDAWN" ; then 161 | if [ "$DAY" = "Mon" ]; then NEXTDAY=$(echo "Tue") ; 162 | elif [ "$DAY" = "Tue" ]; then NEXTDAY=$(echo "Wed") ; 163 | elif [ "$DAY" = "Wed" ]; then NEXTDAY=$(echo "Thu") ; 164 | elif [ "$DAY" = "Thu" ]; then NEXTDAY=$(echo "Fri") ; 165 | elif [ "$DAY" = "Fri" ]; then NEXTDAY=$(echo "Sat") ; 166 | elif [ "$DAY" = "Sat" ]; then NEXTDAY=$(echo "Sun") ; 167 | elif [ "$DAY" = "Sun" ]; then NEXTDAY=$(echo "Mon") ; 168 | fi 169 | DAY=$NEXTDAY 170 | unset NEXTDAY 171 | 172 | if test "$LONG_MONTH" ; then 173 | if [[ "$DATE" -lt "31" ]]; then let DATE+=1 ; 174 | elif [[ "$DATE" -eq "31" ]]; then 175 | if [[ "$MONTH" = "Jan" ]]; then NEXTMONTH=$(echo "Feb") ; 176 | elif [[ "$MONTH" = "Mar" ]]; then NEXTMONTH=$(echo "Apr") ; 177 | elif [[ "$MONTH" = "May" ]]; then NEXTMONTH=$(echo "Jun") ; 178 | elif [[ "$MONTH" = "Jul" ]]; then NEXTMONTH=$(echo "Aug") ; 179 | elif [[ "$MONTH" = "Aug" ]]; then NEXTMONTH=$(echo "Sep") ; 180 | elif [[ "$MONTH" = "Oct" ]]; then NEXTMONTH=$(echo "Nov") ; 181 | elif [[ "$MONTH" = "Dec" ]]; then 182 | NEXTMONTH=$(echo "Jan") 183 | let YEAR+=1 184 | fi 185 | DATE=1 186 | fi 187 | elif [[ "$MONTH" = "Feb" ]] && [[ "$DATE" -lt "28" ]]; then 188 | let DATE+=1 189 | elif [[ "$MONTH" = "Feb" ]] && [[ "$DATE" -eq "28" ]]; then 190 | NEXTMONTH=$(echo "Mar") 191 | DATE=1 192 | else 193 | if [[ "$DATE" -lt "30" ]]; then let DATE+=1 ; 194 | elif [[ "$DATE" -eq "30" ]]; then 195 | if [[ "$MONTH" = "Apr" ]]; then NEXTMONTH=$(echo "May") ; 196 | elif [[ "$MONTH" = "Jun" ]]; then NEXTMONTH=$(echo "Jul") ; 197 | elif [[ "$MONTH" = "Sep" ]]; then NEXTMONTH=$(echo "Oct") ; 198 | elif [[ "$MONTH" = "Nov" ]]; then NEXTMONTH=$(echo "Dec") ; 199 | fi 200 | DATE=1 201 | fi 202 | fi 203 | fi 204 | unset FALSEDAWN 205 | if [[ -n "$NEXTMONTH" ]]; then 206 | MONTH=$NEXTMONTH 207 | fi 208 | unset NEXTMONTH 209 | 210 | elif test "$IS_EAST" ; then 211 | if [ "$HOUR" -lt "$TIMEOFFSET" ]; then 212 | let SPILLOVER=24-TIMEOFFSET 213 | let HOUR=HOUR+SPILLOVER 214 | MAKE_YESTERDAY=true 215 | else 216 | ## 'let' requires the leading zero stripped 217 | if [[ "${HOUR:0:1}" = '0' ]] ; then 218 | HOUR=${HOUR:1} 219 | fi 220 | let HOUR=HOUR-TIMEOFFSET 221 | fi 222 | unset TIMEOFFSET 223 | unset SPILLOVER 224 | 225 | # If the hour is one digit, prepend a zero. 226 | if [ "${#HOUR}" -eq "1" ]; then 227 | HOUR=$(printf "%02d" "$HOUR") 228 | fi 229 | 230 | # If it is yesterday in UTC, make sure we decrement the day. 231 | if test "$MAKE_YESTERDAY" ; then 232 | if [ "$DAY" = "Mon" ]; then LASTDAY=$(echo "Sun") ; 233 | elif [ "$DAY" = "Tue" ]; then LASTDAY=$(echo "Mon") ; 234 | elif [ "$DAY" = "Wed" ]; then LASTDAY=$(echo "Tue") ; 235 | elif [ "$DAY" = "Thu" ]; then LASTDAY=$(echo "Wed") ; 236 | elif [ "$DAY" = "Fri" ]; then LASTDAY=$(echo "Thu") ; 237 | elif [ "$DAY" = "Sat" ]; then LASTDAY=$(echo "Fri") ; 238 | elif [ "$DAY" = "Sun" ]; then LASTDAY=$(echo "Sat") ; 239 | fi 240 | DAY=$LASTDAY 241 | unset LASTDAY 242 | 243 | if $LONG_MONTH ; then 244 | if [[ "$DATE" -eq "1" ]]; then 245 | if [[ "$MONTH" = "Jan" ]]; then LASTMONTH=$(echo "Dec"); 246 | let YEAR=YEAR-1 ; 247 | elif [[ "$MONTH" = "May" ]]; then LASTMONTH=$(echo "Apr") ; 248 | elif [[ "$MONTH" = "Jul" ]]; then LASTMONTH=$(echo "Jun") ; 249 | elif [[ "$MONTH" = "Aug" ]]; then LASTMONTH=$(echo "Jul") ; 250 | elif [[ "$MONTH" = "Oct" ]]; then LASTMONTH=$(echo "Sep") ; 251 | elif [[ "$MONTH" = "Dec" ]]; then LASTMONTH=$(echo "Nov") ; 252 | fi 253 | DATE=30 254 | if [[ "$MONTH" = "Mar" ]]; then LASTMONTH=$(echo "Feb"); 255 | DATE=28 ; 256 | fi 257 | else 258 | let DATE=DATE-1 259 | fi 260 | else 261 | if [[ "$DATE" -eq "1" ]]; then 262 | if [[ "$MONTH" = "Feb" ]]; then LASTMONTH=$(echo "Jan") ; 263 | elif [[ "$MONTH" = "Apr" ]]; then LASTMONTH=$(echo "Mar") ; 264 | elif [[ "$MONTH" = "Jun" ]]; then LASTMONTH=$(echo "May") ; 265 | elif [[ "$MONTH" = "Sep" ]]; then LASTMONTH=$(echo "Aug") ; 266 | elif [[ "$MONTH" = "Nov" ]]; then LASTMONTH=$(echo "Oct") ; 267 | fi 268 | DATE=31 269 | else 270 | let DATE=DATE-1 271 | fi 272 | fi 273 | unset LONGMONTH 274 | fi 275 | unset MAKE_YESTERDAY 276 | if [[ -n "$LASTMONTH" ]]; then 277 | MONTH=$LASTMONTH 278 | fi 279 | unset LASTMONTH 280 | fi 281 | unset IS_EAST 282 | unset IS_WEST 283 | unset LONG_MONTH 284 | 285 | export GIT_AUTHOR_DATE=$(echo "$DAY $MONTH $DATE $HOUR:$MINSEC $YEAR +0000") 286 | export GIT_COMMITTER_DATE=$GIT_AUTHOR_DATE 287 | 288 | ## only print what we exported if we were not sourced: 289 | if ! [ "x$0" = 'x-bash' ] ; then 290 | if test -n "${0#gitdate}" ; then 291 | if test "$DEBUG" ; then 292 | printf "\nPlease copy and run the following export commands:\n\n" 293 | fi 294 | printf "export GIT_AUTHOR_DATE='%s'\nexport GIT_COMMITTER_DATE='%s'\n" \ 295 | "$GIT_AUTHOR_DATE" "$GIT_COMMITTER_DATE" 296 | fi 297 | fi 298 | 299 | unset DAY 300 | unset MONTH 301 | unset DATE 302 | unset HOUR 303 | unset MINSEC 304 | unset YEAR 305 | unset TIMEZONE 306 | 307 | ## If debugging was enabled at the top, make sure it's off when we return 308 | ## to a normal shell: 309 | #set +x 310 | -------------------------------------------------------------------------------- /gpg-download-missing-signers: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | #----------------------------------------------------------------------------- 3 | # gpg-download-missing-signers 4 | # ---------------------------- 5 | # Given Alice's public key, you check the signatures and see a bunch of 6 | # [User ID not found]s. This script retrieves (over tor) all of the 7 | # [User ID not found] keys, given Alice's key. 8 | # 9 | # Taken from the GnuPG FAQ, "Advanced Topics" section. 10 | # 11 | # :authors: Isis Agora Lovecruft, 0xa3adb67a2cdb8b35 12 | # :license: AGPLv3, see https://www.gnu.org/licenses/agpl-3.0.txt for text 13 | # :date: 2011-12-21 14 | # :version: 0.0.1 15 | #----------------------------------------------------------------------------- 16 | 17 | 18 | if [ "$#" != "1" ] ; then 19 | printf "Please give an OpenPGP keyid as an argument.\n" 20 | exit 1 21 | fi 22 | 23 | printf "Downloading missing signing keys for %s...\n" "$1" 24 | 25 | gpg2 --check-sigs --with-colon $1 \ 26 | | awk -F: '$1 == "sig" && $2 == "?" { print $5 }' \ 27 | | sort | uniq | xargs torsocks gpg2 --recv-keys 28 | -------------------------------------------------------------------------------- /gpg-recv-key-tor: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | #----------------------------------------------------------------------------- 3 | # gpg-recv-keys-tor 4 | # ----------------- 5 | # Download GPG keys over Tor. The default keyserver is 6 | # http://cryptonomicon.mit.edu. 7 | # 8 | # :authors: Isis Agora Lovecruft, 0xa3adb67a2cdb8b35 9 | # :license: GPLv3+ 10 | # :version: 0.0.3 11 | #----------------------------------------------------------------------------- 12 | 13 | TOR_SOCKSPORT=59050 14 | 15 | keyservopts="verbose no-honor-keyserver-url no-honor-pka-record include-subkeys" 16 | keyservopts=$keyservopts"no-include-attributes http-proxy=socks4a://127.0.0.1:" 17 | keyservopts=$keyservopts$TOR_SOCKSPORT 18 | 19 | #keyserver='http://18.9.60.141' ## cryptonomicon.mit 20 | #keyserver='hkp://209.234.253.170' ## keys.mayfirst.org 21 | #kerservopts=$keyservopts" ca-cert-file=~/.keys.indymedia.org.pem" 22 | #keyserver='hkps://2eghzlv2wwcq7u7y.onion' ## keys.indymedia.org (hkps) 23 | #kerserver='https://qtt2yl5jocgrk7nu.onion' 24 | 25 | if ! dpkg -l gnupg-curl 2>&1 >/dev/null ; then 26 | printf "Install gnupg-curl." 27 | fi 28 | 29 | if test $# -lt 1 ; then 30 | printf "Usage: %s \n" "${0%%\/}" 31 | else 32 | ## We would use this cert, if using gnupg-curl, and using keys.indymedia.org 33 | ## for the keyserver, but this seems broken on most boxes :( 34 | 35 | # cat > ~/.keys.indymedia.org.pem <\n" "${0%%\/}" 36 | else 37 | ## This keyserver is hkp://cryptonomicon.mit.edu 38 | gpg --keyserver hkp://18.9.60.141 \ 39 | --keyserver-options "$keyservopts" --send-keys $@ 40 | fi 41 | -------------------------------------------------------------------------------- /gpg-sig-counter: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | #----------------------------------------------------------------------------- 3 | # gpg-sig-counter 4 | # ---------------- 5 | 6 | # This is a script which can be used to keep track of the number of signatures 7 | # for a GPG signing key. It is not meant for certifications 8 | # (a.k.a. signatures) on others' keys. To use it, put it somewhere on your 9 | # $PATH and create a repo somewhere for keeping a record of signatures. At the 10 | # top of this script, fill out the variables $SIG_REPO, $REMOTE, $BRANCH for 11 | # the local directory containing the repo for storing signature data, the name 12 | # of the remote to push to, and the name of the branch, respectively. 13 | # 14 | # This script can be called like this, assuming you want to sign the file 15 | # 'email.txt': 16 | # 17 | # ∃!isisⒶwintermute:(master *$)~ ∴ gpg-sig-counter -f email.txt \ 18 | # … -h patternsinthevoid.net 19 | # 20 | # Where the domain after the '-d' flag should be the domain name of your 21 | # default GPG key which you are signing with. If you want you can put the 22 | # locations of your signature repo in your signatures too, to do this put: 23 | # 24 | # sig-keyserver-url https://where.your.repo.is/ 25 | # 26 | # into your gpg.conf. This script embeds the filename which you are signing, 27 | # as well as the current count of signatures made by your key as notation data 28 | # in each signature you make using this script. For example, looking at the 29 | # following packet dump of the signature for 'email.txt', these would be the 30 | # first two subpackets which start with 'Hashed Sub: notation data': 31 | # 32 | # ∃!isisⒶwintermute:(master *$)~ ∴ pgpdump -p email.txt.asc 33 | # Old: Signature Packet(tag 2)(870 bytes) 34 | # Ver 4 - new 35 | # Sig type - Signature of a canonical text document(0x01). 36 | # Pub alg - RSA Encrypt or Sign(pub 1) 37 | # Hash alg - SHA512(hash 10) 38 | # Hashed Sub: signature creation time(sub 2)(4 bytes) 39 | # Time - Sat Sep 7 18:04:11 UTC 2013 40 | # Hashed Sub: signature expiration time(sub 3)(critical)(4 bytes) 41 | # Time - Sun Sep 7 18:04:11 UTC 2014 42 | # Hashed Sub: notation data(sub 20)(41 bytes) 43 | # Flag - Human-readable 44 | # Name - sig.count@patternsinthevoid.net 45 | # Value - 19 46 | # Hashed Sub: notation data(sub 20)(61 bytes) 47 | # Flag - Human-readable 48 | # Name - signed.data@patternsinthevoid.net 49 | # Value - /home/isis/email.txt 50 | # Hashed Sub: notation data(sub 20)(74 bytes) 51 | # Flag - Human-readable 52 | # Name - isis@patternsinthevoid.net 53 | # Value - 0A6A58A14B5946ABDE18E207A3ADB67A2CDB8B35 54 | # Hashed Sub: policy URL(sub 26)(45 bytes) 55 | # URL - https://blog.patternsinthevoid.net/policy.txt 56 | # Hashed Sub: preferred key server(sub 24)(93 bytes) 57 | # URL - https://code.patternsinthevoid.net/?p=sigs-0xA3ADB67A2CDB8B35.git;a=blob_plain;f=sigs;hb=HEAD 58 | # Sub: issuer key ID(sub 16)(8 bytes) 59 | # Key ID - 0xA3ADB67A2CDB8B35 60 | # Hash left 2 bytes - d2 27 61 | # RSA m^d mod n(4094 bits) - ... 62 | # -> PKCS-1 63 | # 64 | # which show that this signature was the 19th one I made with this script, and 65 | # the file I signed was 'email.txt'. 66 | # 67 | # So, what this script does: 68 | # -------------------------- 69 | # 1. It embeds the above extra notation data into the signature packets. 70 | # 71 | # 2. Then it commits the file containing the signature count, with a commit 72 | # message containing a timestamp and the signature count. 73 | # 74 | # 3. Next, *it signs the commit*, meaning that for every signature count 75 | # *two* signatures are actually being made, but I only cared to keep 76 | # trach of the first ones, so deal with it. 77 | # 78 | # 4. Then it tries to push to whatever remote you've configured. 79 | # 80 | # :authors: Isis Agora Lovecruft, 0xa3adb67a2cdb8b35 81 | # :license: AGPLv3, see https://www.gnu.org/licenses/agpl-3.0.txt for text 82 | # :version: 0.0.1 83 | #----------------------------------------------------------------------------- 84 | 85 | ## SIG_REPO should be set to the local directory your signature count repo is 86 | ## located at: 87 | SIG_REPO=~/.gnupg/sigs-0xA3ADB67A2CDB8B35 88 | 89 | ## REMOTE should be set to the name of the remote you wish to push to, if any: 90 | REMOTE=origin 91 | 92 | ## BRANCH should be set the the name of the branch to push, if any: 93 | BRANCH=master 94 | 95 | ## Don't touch anything else, unless you've found a bug and are patching it. 96 | ## ---------------------------------------------------------------------------- 97 | 98 | NAME=${0%%/} 99 | 100 | function usage () { 101 | printf "Usage: %s -f FILE -d DOMAIN [other gpg options]\n\n" $NAME 102 | printf "Options:\n" 103 | printf " -f FILE\tThe file to create a signature for\n" 104 | printf " -d DOMAIN\tThe domain of the email address on your GPG key\n" 105 | printf " -h\t\tThis cruft\n" 106 | exit 1 107 | } 108 | 109 | ## check that we have at least some arguments 110 | if test "$#" -lt 1 ; then usage ; fi 111 | 112 | while getopts f:d:h x; do 113 | case $x in 114 | f) 115 | file=$OPTARG; 116 | if test -n "${file}" -a -n "${domain}" ; then 117 | break 118 | fi ;; 119 | d) 120 | domain=$OPTARG; 121 | if test -n "${file}" -a -n "${domain}" ; then 122 | break 123 | fi ;; 124 | h) usage;; 125 | *) break;; 126 | esac 127 | done 128 | shift $((OPTIND - 1)) 129 | gpgopts=$* 130 | 131 | if test -z "$gpgopts" ; then 132 | gpgopts='-a --clearsign' 133 | fi 134 | 135 | scf="${SIG_REPO}"/sig-count 136 | printf "Using signature count file %s" $scf 137 | 138 | gpg -s $gpgopts \ 139 | --sig-notation signed.data@"$domain"="$file" \ 140 | --sig-notation sig.count@"$domain"=$(( `cat $scf` + 1 )) $file && \ 141 | { ns=$(( `cat $scf` + 1 )) ; 142 | echo -n "$ns" |& tee > "$scf" ; } && \ 143 | { d=`date +"%s"`; 144 | cd $SIG_REPO && \ 145 | { git add $scf && \ 146 | git commit -q -S -m "$d $ns" (2)%H %n%CredCommit message:%Cgreen %>(2)%s %n%CredSigned commit verification:%n%C(auto)%GG%n" HEAD^.. ;}; } 149 | -------------------------------------------------------------------------------- /gpg_key_to_web: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | ############################################################################## 3 | # 4 | # gpg_key_to_web 5 | # ------------------- 6 | # Upload a signed, timestamped copy of your gpg public key and fingerprint. 7 | # 8 | # @author Isis Agora Lovecruft, 0x2cdb8b35 9 | # @date 1 April 2012 10 | # @version 0.1.0 11 | #----------------------------------------------------------------------------- 12 | # Changelog: 13 | # v0.1.0: Added features to optionally input OTR fingerprints as well. 14 | ############################################################################## 15 | 16 | set -efu 17 | 18 | function usage () 19 | { 20 | echo "$0 [options] " 21 | echo "-------------------------------------------------------------------" 22 | echo "Prepend a message which includes a timestamp and a display of the " 23 | echo "key's fingerprints and user IDs (and, also, optionally, and XMPP " 24 | echo "account with an OTR fingerprint) to a copy of the public key. Then " 25 | echo "a detached signature file of the public key with prepended message " 26 | echo "is created, and these can be optionally uploaded to a remote " 27 | echo "webserver, and/or stored locally in the user's home directory." 28 | echo "If only the key ID is given, uploading will be left to user."; echo; 29 | echo "------------------------------------------------------------------" 30 | echo " the GPG key ID, i.e. \"2cdb8b35\"" 31 | echo; 32 | echo "Options:" 33 | echo; 34 | echo "-u @: upload files to webserver" 35 | echo "-o output to file (default: $HOME/.asc" 36 | echo "-f include otr fingerprint " 37 | exit 1 38 | } 39 | 40 | ## @param1 user's keyID 41 | ## @param2 fake prompt string 42 | function prepend_gpg_fpr () { 43 | echo "Creating message to prepend to public key, which will include both" 44 | echo "a fingerprint and a timestamp ..."; echo; 45 | FPR=`gpg --fingerprint $1` 46 | cat >> $1.prepend<> $1.prepend<> $1.prepend<> $1.prepend<> $1.prepend<> $1.prepend<> $2 143 | 144 | if test -r $2 ; then 145 | echo "Cleaning up temporary files ..." 146 | rm $1.pub 147 | else 148 | echo "Error appending message to public key file. Exiting." 149 | exit 1 150 | fi 151 | else 152 | echo "Error finding prepend message. Exiting." 153 | exit 1 154 | fi 155 | } 156 | 157 | ## @param $1: the outfile 158 | ## @param $2: the sigfile 159 | function create_sig_file () 160 | { 161 | if test -r $1; then 162 | echo "Creating signature file ..." 163 | gpg -a -o $2 --detach-sign $1 164 | else 165 | echo "Error: could not read public key file" 166 | exit 1 167 | fi 168 | } 169 | 170 | if [[ "$#" == "0" ]] ; then 171 | usage 172 | else 173 | cd $HOME 174 | upload_to= 175 | outfile= 176 | otrfpr= 177 | fakeprompt=$USER"@"$HOSTNAME":~\$" 178 | 179 | while getopts u:o:f: x; do 180 | case $x in 181 | u ) upload_to=$OPTARG;; 182 | o ) outfile=$OPTARG;; 183 | f ) otrfpr=$OPTARG;; 184 | * ) usage;; 185 | esac 186 | done 187 | shift $((OPTIND - 1)) 188 | 189 | keyid=$1 190 | if test -z $outfile ; then 191 | outfile=$keyid".asc" 192 | sigfile=$keyid".sig.asc" 193 | else 194 | outfile=$outfile 195 | sigfile=$outfile".sig.asc" 196 | fi 197 | 198 | echo 199 | echo "Exporting public key and prepending fingerprint and timestamp ..." 200 | if ! test -r $1.prepend ; then 201 | prepend_gpg_fpr $keyid $fakeprompt 202 | prepend_otr_fpr $keyid $otrfpr 203 | prepend_sig_location $keyid $sigfile $fakeprompt 204 | fi 205 | add_prepend_and_key $keyid $outfile 206 | create_sig_file $outfile $sigfile 207 | echo; echo "Done!" 208 | 209 | if [ "$upload_to" != "" ] ; then 210 | echo; echo "Uploading to public web root ..." 211 | scp $outfile $sigfile $upload_to 212 | echo "Done!" 213 | fi 214 | echo "Key file with prepended message at $HOME/$outfile" 215 | echo "Signature file at $HOME/$sigfile" 216 | exit 0 217 | fi 218 | -------------------------------------------------------------------------------- /gpgkey2bc.py: -------------------------------------------------------------------------------- 1 | # Require Python 3.2 or later 2 | 3 | import sys, binascii, hashlib 4 | from subprocess import check_output 5 | 6 | b58chars = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz' 7 | 8 | def b58encode(bytes_str): 9 | l = int.from_bytes(bytes_str, byteorder='big') 10 | result = '' 11 | while l >= 58: 12 | l, mod = divmod(l, 58) 13 | result = b58chars[mod] + result 14 | result = b58chars[l] + result 15 | # leading 0-bytes in the input will be leading-1s. 16 | n = 0 17 | for c in bytes_str: 18 | if c == 0: 19 | n += 1 20 | else: 21 | break 22 | return ('1'*n) + result 23 | 24 | def get_public_key_data(keyid): 25 | r = check_output(["gpg2", "-k", "--with-colons", "--with-key-data", keyid]) 26 | i = 0 27 | keyid_bytes = bytes(keyid, 'ascii') 28 | while True: 29 | i = r.find(b'\nsub:u:256:19:', i) 30 | if i < 0: 31 | print("Not found (1)") 32 | exit(2) 33 | elif r[i+22:i+30] == keyid_bytes: 34 | i_pkd = i+30 35 | while True: 36 | i_pkd = r.find(b'\npkd', i_pkd) 37 | if i_pkd < 0: 38 | print("Not found (2)") 39 | exit(2) 40 | elif r[i_pkd+5:i_pkd+6] == b'1': 41 | i_pub = i_pkd + 11 42 | break 43 | else: 44 | i_pkd += 4 45 | break 46 | else: 47 | i += 14 48 | return r[i_pub:i_pub+130] 49 | 50 | def main(keyid): 51 | pubkey_raw = binascii.unhexlify(get_public_key_data(keyid)) 52 | pubkey_raw_sha256sum = hashlib.sha256(pubkey_raw).digest() 53 | ripemd160sum = hashlib.new('ripemd160',pubkey_raw_sha256sum).digest() 54 | pubkey_internal = b'\x00' + ripemd160sum 55 | pubkey_sha256sum_1st = hashlib.sha256(pubkey_internal).digest() 56 | pubkey_sha256sum = hashlib.sha256(pubkey_sha256sum_1st).digest() 57 | address = pubkey_internal + pubkey_sha256sum[0:4] 58 | b58address = b58encode(address) 59 | print(b58address) 60 | 61 | if __name__ == '__main__': 62 | keyid=sys.argv[1] 63 | main(keyid) 64 | -------------------------------------------------------------------------------- /include/dstevens/mPDF.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | # module with simple class to build PDF documents with basic PDF elements 4 | # Source code put in public domain by Didier Stevens, no Copyright 5 | # https://DidierStevens.com 6 | # Use at your own risk 7 | # 8 | # History: 9 | # 10 | # 2008/05/18: continue 11 | # 2008/05/19: continue 12 | # 2008/05/28: stream2 13 | # 2008/11/09: cleanup for release 14 | # 2008/11/21: Added support for other OSes than Windows 15 | # 2009/05/04: Added support for abbreviated filters (/AHx and /Fl), thanks Binjo 16 | # 2011/03/03: Added support for info in trailer and xrefAndTrailer 17 | # 2011/07/01: V0.1.4: Added support for filters i and I; added support for Python 3 18 | # 2012/02/25: fixed printing \n for filters i and I 19 | 20 | # Todo: 21 | # - add support for extra filters to stream2 22 | 23 | __author__ = 'Didier Stevens' 24 | __version__ = '0.1.4' 25 | __date__ = '2012/02/25' 26 | 27 | import sys 28 | import zlib 29 | import platform 30 | 31 | def SplitByLength(input, length): 32 | result = [] 33 | while len(input) > length: 34 | result.append(input[0:length] + '\n') 35 | input = input[length:] 36 | result.append(input + '>') 37 | return result 38 | 39 | class cPDF: 40 | def __init__(self, filename): 41 | self.filename = filename 42 | self.indirectObjects = {} 43 | 44 | def appendString(self, str): 45 | fPDF = open(self.filename, 'a') 46 | fPDF.write(str) 47 | fPDF.close() 48 | 49 | def appendBinary(self, str): 50 | fPDF = open(self.filename, 'ab') 51 | if sys.version_info[0] == 2: 52 | fPDF.write(str) 53 | else: 54 | fPDF.write(bytes(str, 'ascii')) 55 | fPDF.close() 56 | 57 | def filesize(self): 58 | fPDF = open(self.filename, 'rb') 59 | fPDF.seek(0, 2) 60 | size = fPDF.tell() 61 | fPDF.close() 62 | return size 63 | 64 | def IsWindows(self): 65 | return platform.system() in ('Windows', 'Microsoft') 66 | 67 | def header(self): 68 | fPDF = open(self.filename, 'w') 69 | fPDF.write("%PDF-1.1\n") 70 | fPDF.close() 71 | 72 | def binary(self): 73 | self.appendString("%\xD0\xD0\xD0\xD0\n") 74 | 75 | def indirectobject(self, index, version, io): 76 | self.appendString("\n") 77 | self.indirectObjects[index] = self.filesize() 78 | self.appendString("%d %d obj\n%s\nendobj\n" % (index, version, io)) 79 | 80 | def stream(self, index, version, streamdata, dictionary="<< /Length %d >>"): 81 | self.appendString("\n") 82 | self.indirectObjects[index] = self.filesize() 83 | self.appendString(("%d %d obj\n" + dictionary + "\nstream\n") % (index, version, len(streamdata))) 84 | self.appendBinary(streamdata) 85 | self.appendString("\nendstream\nendobj\n") 86 | 87 | def Data2HexStr(self, data): 88 | hex = '' 89 | if sys.version_info[0] == 2: 90 | for b in data: 91 | hex += "%02x" % ord(b) 92 | else: 93 | for b in data: 94 | hex += "%02x" % b 95 | return hex 96 | 97 | def stream2(self, index, version, streamdata, entries="", filters=""): 98 | """ 99 | * h ASCIIHexDecode 100 | * H AHx 101 | * i like ASCIIHexDecode but with 512 long lines 102 | * I like AHx but with 512 long lines 103 | * ASCII85Decode 104 | * LZWDecode 105 | * f FlateDecode 106 | * F Fl 107 | * RunLengthDecode 108 | * CCITTFaxDecode 109 | * JBIG2Decode 110 | * DCTDecode 111 | * JPXDecode 112 | * Crypt 113 | """ 114 | 115 | encodeddata = streamdata 116 | filter = [] 117 | for i in filters: 118 | if i.lower() == "h": 119 | encodeddata = self.Data2HexStr(encodeddata) + '>' 120 | if i == "h": 121 | filter.insert(0, "/ASCIIHexDecode") 122 | else: 123 | filter.insert(0, "/AHx") 124 | elif i.lower() == "i": 125 | encodeddata = ''.join(SplitByLength(self.Data2HexStr(encodeddata), 512)) 126 | if i == "i": 127 | filter.insert(0, "/ASCIIHexDecode") 128 | else: 129 | filter.insert(0, "/AHx") 130 | elif i.lower() == "f": 131 | encodeddata = zlib.compress(encodeddata) 132 | if i == "f": 133 | filter.insert(0, "/FlateDecode") 134 | else: 135 | filter.insert(0, "/Fl") 136 | else: 137 | print("Error") 138 | return 139 | self.appendString("\n") 140 | self.indirectObjects[index] = self.filesize() 141 | self.appendString("%d %d obj\n<<\n /Length %d\n" % (index, version, len(encodeddata))) 142 | if len(filter) == 1: 143 | self.appendString(" /Filter %s\n" % filter[0]) 144 | if len(filter) > 1: 145 | self.appendString(" /Filter [%s]\n" % ' '.join(filter)) 146 | if entries != "": 147 | self.appendString(" %s\n" % entries) 148 | self.appendString(">>\nstream\n") 149 | if filters[-1].lower() == 'i': 150 | self.appendString(encodeddata) 151 | else: 152 | self.appendBinary(encodeddata) 153 | self.appendString("\nendstream\nendobj\n") 154 | 155 | def xref(self): 156 | self.appendString("\n") 157 | startxref = self.filesize() 158 | max = 0 159 | for i in self.indirectObjects.keys(): 160 | if i > max: 161 | max = i 162 | self.appendString("xref\n0 %d\n" % (max+1)) 163 | if self.IsWindows(): 164 | eol = '\n' 165 | else: 166 | eol = ' \n' 167 | for i in range(0, max+1): 168 | if i in self.indirectObjects: 169 | self.appendString("%010d %05d n%s" % (self.indirectObjects[i], 0, eol)) 170 | else: 171 | self.appendString("0000000000 65535 f%s" % eol) 172 | return (startxref, (max+1)) 173 | 174 | def trailer(self, startxref, size, root, info=None): 175 | if info == None: 176 | self.appendString("trailer\n<<\n /Size %d\n /Root %s\n>>\nstartxref\n%d\n%%%%EOF\n" % (size, root, startxref)) 177 | else: 178 | self.appendString("trailer\n<<\n /Size %d\n /Root %s\n /Info %s\n>>\nstartxref\n%d\n%%%%EOF\n" % (size, root, info, startxref)) 179 | 180 | def xrefAndTrailer(self, root, info=None): 181 | xrefdata = self.xref() 182 | self.trailer(xrefdata[0], xrefdata[1], root, info) 183 | 184 | def template1(self): 185 | self.indirectobject(1, 0, "<<\n /Type /Catalog\n /Outlines 2 0 R\n /Pages 3 0 R\n>>") 186 | self.indirectobject(2, 0, "<<\n /Type /Outlines\n /Count 0\n>>") 187 | self.indirectobject(3, 0, "<<\n /Type /Pages\n /Kids [4 0 R]\n /Count 1\n>>") 188 | self.indirectobject(4, 0, "<<\n /Type /Page\n /Parent 3 0 R\n /MediaBox [0 0 612 792]\n /Contents 5 0 R\n /Resources <<\n /ProcSet [/PDF /Text]\n /Font << /F1 6 0 R >>\n >>\n>>") 189 | self.indirectobject(6, 0, "<<\n /Type /Font\n /Subtype /Type1\n /Name /F1\n /BaseFont /Helvetica\n /Encoding /MacRomanEncoding\n>>") 190 | 191 | -------------------------------------------------------------------------------- /include/dstevens/make-pdf-embedded.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | __description__ = 'tool to create a PDF document with an embedded file' 4 | __author__ = 'Didier Stevens' 5 | __version__ = '0.5.0' 6 | __date__ = '2011/07/01' 7 | 8 | """ 9 | Source code put in public domain by Didier Stevens, no Copyright 10 | https://DidierStevens.com 11 | Use at your own risk 12 | 13 | History: 14 | 2008/05/18: V0.1 15 | 2008/05/19: Refactoring 16 | 2008/05/23: Refactoring 17 | 2008/05/27: Refactoring 18 | 2008/06/27: V0.2, Refactoring, options, cleanup 19 | 2008/11/09: V0.3, added autostart and button 20 | 2009/06/15: V0.4.0: added stego 21 | 2011/07/01: V0.5.0: added support for Python 3 22 | 23 | Todo: 24 | """ 25 | 26 | import mPDF 27 | import optparse 28 | 29 | def ReadBinaryFile(name): 30 | """Read a binary file and return the content, return None if error occured 31 | """ 32 | 33 | try: 34 | fBinary = open(name, 'rb') 35 | except: 36 | return None 37 | try: 38 | content = fBinary.read() 39 | except: 40 | return None 41 | finally: 42 | fBinary.close() 43 | return content 44 | 45 | def CreatePDFWithEmbeddedFile(pdfFileName, embeddedFileName, embeddedFileContent, filters, nobinary, autoopen, button, stego, text): 46 | """Create a PDF document with an embedded file 47 | """ 48 | 49 | oPDF = mPDF.cPDF(pdfFileName) 50 | 51 | oPDF.header() 52 | 53 | if not nobinary: 54 | oPDF.binary() 55 | 56 | if stego: 57 | embeddedFiles = 'Embeddedfiles' 58 | else: 59 | embeddedFiles = 'EmbeddedFiles' 60 | if autoopen: 61 | openAction = ' /OpenAction 9 0 R\n' 62 | else: 63 | openAction = '' 64 | oPDF.indirectobject(1, 0, '<<\n /Type /Catalog\n /Outlines 2 0 R\n /Pages 3 0 R\n /Names << /%s << /Names [(%s) 7 0 R] >> >>\n%s>>' % (embeddedFiles, embeddedFileName, openAction)) 65 | oPDF.indirectobject(2, 0, '<<\n /Type /Outlines\n /Count 0\n>>') 66 | oPDF.indirectobject(3, 0, '<<\n /Type /Pages\n /Kids [4 0 R]\n /Count 1\n>>') 67 | if button: 68 | annots = ' /Annots [10 0 R]\n' 69 | else: 70 | annots = '' 71 | oPDF.indirectobject(4, 0, '<<\n /Type /Page\n /Parent 3 0 R\n /MediaBox [0 0 612 792]\n /Contents 5 0 R\n /Resources <<\n /ProcSet [/PDF /Text]\n /Font << /F1 6 0 R >>\n >>\n%s>>' % annots) 72 | if text == '': 73 | text = 'This PDF document embeds file %s' % embeddedFileName 74 | textCommands = '/F1 12 Tf 70 700 Td 15 TL (%s) Tj' % text 75 | if button: 76 | textCommands += " () ' () ' (Click inside the rectangle to save %s to a temporary folder and launch it.) ' () ' (Click here) '" % embeddedFileName 77 | oPDF.stream(5, 0, 'BT %s ET' % textCommands) 78 | oPDF.indirectobject(6, 0, '<<\n /Type /Font\n /Subtype /Type1\n /Name /F1\n /BaseFont /Helvetica\n /Encoding /MacRomanEncoding\n>>') 79 | oPDF.indirectobject(7, 0, '<<\n /Type /Filespec\n /F (%s)\n /EF << /F 8 0 R >>\n>>' % embeddedFileName) 80 | oPDF.stream2(8, 0, embeddedFileContent, '/Type /EmbeddedFile', filters) 81 | if autoopen or button: 82 | oPDF.indirectobject(9, 0, '<<\n /Type /Action\n /S /JavaScript\n /JS (this.exportDataObject({ cName: "%s", nLaunch: 2 });)\n>>' % embeddedFileName) 83 | if button: 84 | oPDF.indirectobject(10, 0, '<<\n /Type /Annot\n /Subtype /Link\n /Rect [65 620 130 640]\n /Border [16 16 1]\n /A 9 0 R\n>>') 85 | 86 | oPDF.xrefAndTrailer("1 0 R") 87 | 88 | def Main(): 89 | oParser = optparse.OptionParser(usage='usage: %prog [options] file-to-embed pdf-file', version='%prog ' + __version__) 90 | oParser.add_option('-f', '--filters', default='f', help='filters to apply, f for FlateDecode (default), h for ASCIIHexDecode') 91 | oParser.add_option('-t', '--nobinary', action='store_true', default=False, help="don't add the comment for binary format") 92 | oParser.add_option('-a', '--autoopen', action='store_true', default=False, help='open the embedded file automatically when the PDF is opened') 93 | oParser.add_option('-b', '--button', action='store_true', default=False, help='add a "button" to launch the embedded file') 94 | oParser.add_option('-s', '--stego', action='store_true', default=False, help='"hide" the embedded file by replacing /EmbeddedFiles with /Embeddedfiles') 95 | oParser.add_option('-m', '--message', default='', help='text to display in the PDF document') 96 | (options, args) = oParser.parse_args() 97 | 98 | if len(args) != 2: 99 | oParser.print_help() 100 | print('') 101 | print(' %s' % __description__) 102 | print(' Source code put in the public domain by Didier Stevens, no Copyright') 103 | print(' Use at your own risk') 104 | print(' https://DidierStevens.com') 105 | 106 | else: 107 | embeddedFileName = args[0] 108 | pdfFileName = args[1] 109 | 110 | embeddedFileContent = ReadBinaryFile(embeddedFileName) 111 | if embeddedFileContent == None: 112 | print('Error opening/reading file %s' % embeddedFileName) 113 | else: 114 | CreatePDFWithEmbeddedFile(pdfFileName, embeddedFileName, embeddedFileContent, options.filters, options.nobinary, options.autoopen, options.button, options.stego, options.message) 115 | 116 | if __name__ == '__main__': 117 | Main() 118 | -------------------------------------------------------------------------------- /include/dstevens/make-pdf-javascript.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | # V0.1 2008/05/23 4 | # make-pdf-javascript, use it to create a PDF document with embedded JavaScript that will execute automatically when the document is opened 5 | # requires module mPDF.py 6 | # Source code put in public domain by Didier Stevens, no Copyright 7 | # https://DidierStevens.com 8 | # Use at your own risk 9 | # 10 | # History: 11 | # 12 | # 2008/05/29: continue 13 | # 2008/11/09: cleanup for release 14 | 15 | import mPDF 16 | import optparse 17 | 18 | def Main(): 19 | """make-pdf-javascript, use it to create a PDF document with embedded JavaScript that will execute automatically when the document is opened 20 | """ 21 | 22 | parser = optparse.OptionParser(usage='usage: %prog [options] pdf-file', version='%prog 0.1') 23 | parser.add_option('-j', '--javascript', help='javascript to embed (default embedded JavaScript is app.alert messagebox)') 24 | parser.add_option('-f', '--javascriptfile', help='javascript file to embed (default embedded JavaScript is app.alert messagebox)') 25 | (options, args) = parser.parse_args() 26 | 27 | if len(args) != 1: 28 | parser.print_help() 29 | print '' 30 | print ' make-pdf-javascript, use it to create a PDF document with embedded JavaScript that will execute automatically when the document is opened' 31 | print ' Source code put in the public domain by Didier Stevens, no Copyright' 32 | print ' Use at your own risk' 33 | print ' https://DidierStevens.com' 34 | 35 | else: 36 | oPDF = mPDF.cPDF(args[0]) 37 | 38 | oPDF.header() 39 | 40 | oPDF.indirectobject(1, 0, '<<\n /Type /Catalog\n /Outlines 2 0 R\n /Pages 3 0 R\n /OpenAction 7 0 R\n>>') 41 | oPDF.indirectobject(2, 0, '<<\n /Type /Outlines\n /Count 0\n>>') 42 | oPDF.indirectobject(3, 0, '<<\n /Type /Pages\n /Kids [4 0 R]\n /Count 1\n>>') 43 | oPDF.indirectobject(4, 0, '<<\n /Type /Page\n /Parent 3 0 R\n /MediaBox [0 0 612 792]\n /Contents 5 0 R\n /Resources <<\n /ProcSet [/PDF /Text]\n /Font << /F1 6 0 R >>\n >>\n>>') 44 | oPDF.stream(5, 0, 'BT /F1 12 Tf 100 700 Td 15 TL (JavaScript example) Tj ET') 45 | oPDF.indirectobject(6, 0, '<<\n /Type /Font\n /Subtype /Type1\n /Name /F1\n /BaseFont /Helvetica\n /Encoding /MacRomanEncoding\n>>') 46 | 47 | if options.javascript == None and options.javascriptfile == None: 48 | javascript = """app.alert({cMsg: 'Hello from PDF JavaScript', cTitle: 'Testing PDF JavaScript', nIcon: 3});""" 49 | elif options.javascript != None: 50 | javascript = options.javascript 51 | else: 52 | try: 53 | fileJavasScript = open(options.javascriptfile, 'rb') 54 | except: 55 | print "error opening file %s" % options.javascriptfile 56 | return 57 | 58 | try: 59 | javascript = fileJavasScript.read() 60 | except: 61 | print "error reading file %s" % options.javascriptfile 62 | return 63 | finally: 64 | fileJavasScript.close() 65 | 66 | oPDF.indirectobject(7, 0, '<<\n /Type /Action\n /S /JavaScript\n /JS (%s)\n>>' % javascript) 67 | 68 | oPDF.xrefAndTrailer('1 0 R') 69 | 70 | if __name__ == '__main__': 71 | Main() 72 | -------------------------------------------------------------------------------- /irssi-and-transproxy: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | ############################################################################## 3 | # 4 | # install-irssi 5 | # ------------------- 6 | # Install irssi from source from the Debian git repository, to overcome the 7 | # bugs such as lack of TLS1/SSL3 support in irssi==0.8.15-4+b1, caused by 8 | # the switch from openssl-1.0.0e-2.1 to GnuTLS1.0.0/libssl1.0.0. 9 | # 10 | # @author Isis Agora Lovecruft, 0x2cdb8b35 11 | # @date 10 February 2013 12 | # @version 0.0.1 13 | ############################################################################## 14 | 15 | [[ "$(id -u)" != 0 ]] || $(echo "Must be root. Exiting."; exit 1) 16 | 17 | ## Irssi sources, debian patches, and dependencies 18 | irssi_svn=http://svn.irssi.org/repos/irssi/tags/r_0_8_15-rc1/ 19 | irssi_debian=git://git.deb.at/pkg/irssi.git 20 | irssi_depends="libc6 libglib2.0-0 libncurses5 perl-base libssl1.0.0 " 21 | irssi_depends+="libtinfo5 perl " 22 | irssi_suggests="irssi-scripts " 23 | 24 | our_build_depends="quilt debhelper build-essential libperl-dev lynx hardening-includes hardening-wrapper gcc ncurses-dev " 25 | 26 | ## Default locations for torrc file 27 | torrc=/etc/tor/torrc 28 | torrc_trans_port=9040 29 | torrc_dns_port=5353 30 | 31 | declare -A tor_configs=( ["VirtualAddrNetwork"]="10.192.0.0/10" 32 | ["TransPort"]="127.0.0.1:9040 IsolateClientProtocol" 33 | ["DNSPort"]="5353" 34 | ["AutomapHostsOnResolve"]="1" 35 | ["AutomapHostExits"]=".onion,.exit" ) 36 | 37 | 38 | cat<>${build_dir}/transproxy.iptables.sh< 0x2cdb8b35 157 | # @license: WTFPL 158 | # 159 | 160 | EOF 161 | for rl in "${ipt_rules[@]}"; do 162 | cat>>${build_dir}/transproxy.iptables.sh<" 21 | include_nick=true 22 | 23 | ## Comment out to disable using the gpg --throw-keyids option. see man(1) gpg. 24 | throw_keyids=true 25 | 26 | ## Directory containing the IRC logs to send: 27 | log_dir=/home/isis/.irssi/logs/oftc/ 28 | 29 | ## If you use mailx/sendmail, see below, you'll want to use the commented out 30 | ## section with the ${encrypted}</dev/null 2>&1 65 | if [[ "$?" != "0" ]]; then 66 | keyid=${email} && gpg --list-keys $keyid 1>/dev/null 2>&1 67 | if [[ "$?" != "0" ]]; then 68 | echo "Can't find key for ${keyid}..."; 69 | read -p"Should we try to fetch the key? (Y/n): " choice 70 | case $choice in 71 | n ) echo "Exiting..." && exit 2 ;; 72 | * ) gpg --search $keyid ;; 73 | esac 74 | fi 75 | fi 76 | 77 | echo "Storing encrypted log files in ${crypt}..." 78 | if ! test -d "$crypt" ; then 79 | echo "Creating directory ${crypt}..." && mkdir $crypt && echo 80 | fi 81 | 82 | for chan in $non_channels; do 83 | plaintext=${chan##*"/"} 84 | nick=${plaintext%%".log"} 85 | 86 | ## I don't really want an encrypted log of netsplits... 87 | for skip in "chanserv" "nickserv" "auth" ; do 88 | [[ "$nick" != "$skip" ]] || continue 89 | done 90 | 91 | ## /.irssi/logs/encrypted/-2012-12-31_21:59.gpg 92 | encrypted=${crypt}"/"${nick}"-"${now}".gpg" 93 | irc_nicks=${irc_nicks}${nick}" " 94 | 95 | ## the "--always-trust" flag is because gpg throws a fit when 96 | ## we encrypt to ourselves, if the primary has multiple subkeys 97 | ## because the fprs won't match. 98 | if [[ "${throw_keyids}" == "true" ]]; then 99 | gpg --no-verbose --always-trust \ 100 | -q --yes -a -o $encrypted \ 101 | -e -R $keyid $chan 102 | else 103 | gpg --no-verbose --always-trust \ 104 | -q --yes -a -o $encrypted \ 105 | -e -r $keyid $chan 106 | fi 107 | 108 | if ! test -r "$encrypted"; then 109 | echo "Error encrypting logfile $chan." 110 | echo "Exiting..." && exit $? 111 | fi 112 | 113 | if [[ "${include_nick}" == "true" ]]; then 114 | subj="${subject} from ${nick}" 115 | else 116 | subj="${subject}" 117 | fi 118 | 119 | echo "Sending ${subject} from ${nick} to ${email}..." 120 | 121 | ## for mutt and mutt-patched (and probably pine) 122 | cat $encrypted | $($mailcmd ${mailargs} -s "${subj}" ${email}) 123 | echo "Finished sending ${subject} from ${nick}." 124 | done 125 | 126 | ## Comment out the above lines and use these instead for mailx and sendmail: 127 | # $($mailcmd ${mailargs} -s "${subj}" ${email})<$encrypted 129 | #~. 130 | #EOF 131 | # echo "Finished sending ${subject} from ${nick}." 132 | # done 133 | 134 | if test -d "$our_temp" ; then 135 | rm -rf $our_temp 136 | echo "Cleaning temporary directory of created encrypted files..." 137 | fi 138 | 139 | echo "Sent IRC logs of messages from nicks: ${irc_nicks}" 140 | echo "Exiting..." && exit 0 141 | 142 | else 143 | echo "No logfiles found..." 144 | echo "Exiting..." 145 | exit 2 146 | fi 147 | fi 148 | -------------------------------------------------------------------------------- /keysign: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # 3 | # GPG keysigning utility, because it's uberannoying to type all these commands 4 | # over and over again. 5 | # 6 | # @author Isis Lovecruft, 0x2cdb8b35 7 | # @version 0.0.2 8 | # @license GPLv3 9 | 10 | CCZE_IS_INSTALLED=$(dpkg -l | awk '/^ii/{print $2}' | grep ccze) 11 | 12 | if [[ "$#" == "0" ]]; then 13 | echo -e "\033[40m\033[1;32m Usage: ./keysign \033[0m"; echo; 14 | echo -e "\033[40m\033[0;32m Requests the given keyID from the default keyserver, displays the fingerprint, \033[0m" 15 | echo -e "\033[40m\033[0;32m and enters the 'gpg --edit-key' menu for that key. From that menu, the user \033[0m" 16 | echo -e "\033[40m\033[0;32m will commonly want to type 'trust' to set the validity of the key, and then \033[0m" 17 | echo -e "\033[40m\033[0;32m type 'sign' to sign the key. More options can obviously be seen by typing 'help'. \033[0m" 18 | echo -e "\033[40m\033[0;32m Type 'save' to exit the edit-key menu. \033[0m"; echo; 19 | echo -e "\033[40m\033[0;32m Lastly, there is an option to send the newly signed key to the default keyserver, \033[0m" 20 | echo -e "\033[40m\033[0;32m store it locally only, or export it as an ascii-armoured file to give to the key's \033[0m" 21 | echo -e "\033[40m\033[0;32m owner. \033[0m"; echo; 22 | echo -e "\033[40m\033[0;32m If multiple keyIDs are specified, they will be processed in the order given. \033[0m"; echo; 23 | exit 1 24 | fi 25 | 26 | for i in "$@"; do 27 | clear 28 | if [[ "$i" != "" ]]; then 29 | gpg --recv-key $i 30 | FP=$(gpg --fingerprint $i | grep fingerprint) 31 | echo; echo -e "\033[40m\033[1;36m $FP \033[0m"; echo; sleep 2; 32 | echo; echo -e "\033[40m\033[0;36m Would you like to see $i's signatures before signing? (y/N): \033[0m" 33 | read opt 34 | case "$opt" in 35 | "Y"|"y"|"Yes"|"yes") 36 | if [[ "$CCZE_IS_INSTALLED" != "" ]]; then 37 | gpg --list-sigs $i | ccze -A 38 | else 39 | gpg --list-sigs $i | less 40 | fi 41 | ;; 42 | * ) 43 | ;; 44 | esac 45 | echo -e "\033[40m\033[1;36m Entering GPG edit-key menu... \033[0m"; echo; 46 | echo -e "\033[40m\033[0;36m Type \033[40m\033[1;36m'trust'\033[0m \033[40m\033[0;36mto assign trust for key $i, before typing \033[40m\033[1;36m'sign'\033[0m\033[40m\033[0;36m to\033[0m" 47 | echo -e "\033[40m\033[0;36m sign. Type \033[40m\033[1;36m'help'\033[0m \033[40m\033[0;36m for a list of more options, \033[40m\033[1;36m'quit'\033[0m\033[40m\033[0;36m to exit, or" 48 | echo -e "\033[40m\033[1;36m 'save'\033[0m \033[40m\033[0;36m to save. \033[0m"; echo; 49 | gpg --no-greeting --edit-key $i 50 | echo; echo -e "\033[40m\033[1;36m Would you like to send the signed key to a keyserver? (Y/n): \033[0m"; echo; 51 | read choice 52 | case "$choice" in 53 | "N"|"n"|"No"|"no") 54 | echo -e "\033[40m\033[0;36m Keeping signed key locally... \033[0m"; echo; 55 | echo -e "\033[40m\033[1;36m Would you like to export this key to send to its owner? (Y/n): \033[0m"; echo; 56 | read yn 57 | case "$yn" in 58 | "N"|"n"|"No"|"no") 59 | echo -e "\033[40m\033[0;36m Exiting... \033[0m"; echo; 60 | exit 0 61 | ;; 62 | * ) 63 | echo -e "\033[40m\033[0;36m Saving as "$HOME"/"$i"-signed.asc... \033[0m"; echo; 64 | gpg -a -o $HOME/$i-signed.asc --export $i 65 | exit 0 66 | ;; 67 | esac 68 | ;; 69 | * ) 70 | gpg --send-key $i; echo; 71 | exit 0 72 | ;; 73 | esac 74 | fi 75 | done 76 | -------------------------------------------------------------------------------- /local-http-server.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | ############################################################################### 4 | # 5 | # local-http-server.py 6 | # -------------------- 7 | # Serve a directory on the given address and port. Defaults to 127.0.0.1:8080. 8 | # 9 | # @authors: Isis Agora Lovecruft 0x2cdb8b35 10 | # @version: 0.0.1 11 | # @date: 25 December 2012 12 | # @license: WTFPL 13 | # @copyright: 2012 Isis Lovecruft 14 | ############################################################################### 15 | 16 | import os 17 | import sys 18 | import BaseHTTPServer 19 | 20 | from ipaddr import IPAddress 21 | from optparse import OptionParser 22 | from SimpleHTTPServer import SimpleHTTPRequestHandler 23 | 24 | 25 | HandlerClass = SimpleHTTPRequestHandler 26 | ServerClass = BaseHTTPServer.HTTPServer 27 | Protocol = "HTTP/1.0" 28 | 29 | HandlerClass.protocol_version = Protocol 30 | 31 | parser = OptionParser() 32 | parser.add_option('-p', '--port', dest='port', default=8080, 33 | help="Local port to listen on") 34 | parser.add_option('-a', '--address', dest='addr', default='127.0.0.1', 35 | help="Local IP address to listen on") 36 | parser.add_option('-d', '--dir', dest='dir', default='.', 37 | help='[Not Implemented] Local directory to use as root directory of webserver') 38 | 39 | 40 | if __name__ == "__main__": 41 | if len(sys.argv[1:]) <= 0: 42 | parser.print_help() 43 | sys.exit(1) 44 | else: 45 | (options, args) = parser.parse_args() 46 | 47 | if options.dir: 48 | print "WARNING! The local directory option is not implemented." 49 | 50 | try: 51 | IPAddress(options.addr) 52 | except ValueError, ve: 53 | print ve.message 54 | sys.exit(1) 55 | else: 56 | addr = options.addr 57 | 58 | try: 59 | port = int(options.port) 60 | if port <= 1024 and os.getuid() != 0: 61 | print "Server must be started as root to use port %d" % port 62 | sys.exit(1) 63 | except Exception, ex: 64 | print ex.message 65 | sys.exit(1) 66 | 67 | httpd = ServerClass((addr, port), HandlerClass) 68 | sa = httpd.socket.getsockname() 69 | 70 | print "Serving HTTP on", sa[0], "port", sa[1], "..." 71 | try: 72 | httpd.serve_forever() 73 | except KeyboardInterrupt, ki: 74 | print "\nStopping server...\nExiting...\n" 75 | sys.exit(0) 76 | -------------------------------------------------------------------------------- /magnetlink: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | ############################################################################### 3 | # 4 | # magnetlink 5 | # -------------- 6 | # A utility to convert a magnet link to a .torrent file and add it to the 7 | # watch directory so that rtorrent can find it. 8 | # 9 | # @author Isis Agora Lovecruft, 0x2cdb8b35 ; 10 | # Max Gonzih, 11 | # blog.gonzih.org/blog/2012/02/17/how-to-use-magnet-links-with-rtorrent/ 12 | # @date 21 August 2012 13 | # @version 0.0.1 14 | #______________________________________________________________________________ 15 | # Changelog: 16 | ############################################################################### 17 | 18 | ## set your watch directory here: 19 | WATCH_DIRECTORY="$HOME/video/watch" 20 | 21 | #cd $WATCH_DIRECTORY 22 | # 23 | #[[ "$1" =~ xt=urn:btih:([^&/]+) ]] || echo "bad magnet link..." && \ 24 | # logger "magnetlink error: bad magnet link!" && exit 1 ; 25 | # 26 | #echo "d10:magnet-uri${#1}:${1}e" > "meta-${BASH_REMATCH[1]}.torrent" && \ 27 | # logger "magnetlink: link copied as torrent to watch directory" && \ 28 | # exit 0 ; 29 | 30 | cd $WATCH_DIRECTORY || exit 31 | [[ "$1" =~ xt=urn:btih:([^&/]+) ]] || exit 32 | hashh=${BASH_REMATCH[1]} 33 | if [[ "$1" =~ dn=([^&/]+) ]];then 34 | filename=${BASH_REMATCH[1]} 35 | else 36 | filename=$hashh 37 | fi 38 | fn="meta-"$filename".torrent" 39 | touch $fn 40 | echo "d10:magnet-uri${#1}:${1}e" | cat > $fn -------------------------------------------------------------------------------- /mailwithtor: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | ############################################################################### 3 | # 4 | # mailwithtor 5 | # ----------- 6 | # A simple socat script to start a local SOCKS4a server to connect msmtp and 7 | # Tor. 8 | # 9 | # Usage: 10 | # $ ./mailwithtor & 11 | # $ mutt 12 | # 13 | # Note: This uses Tor between you and your mailserver. This means: 14 | # 15 | # A local passive observer will see that you're using Tor, and the email 16 | # recipient will see that the email came from your email account at your 17 | # mailserver. 18 | # 19 | # If your mailserver is crappily configured, and include an 20 | # "X-Originating-IP" header or something similar, then this will obscure 21 | # your real IP. 22 | # 23 | # Pretty much the only purpose of this script is to hide from passive 24 | # observers on your local network that you are connecting to a certain 25 | # mailserver. 26 | # 27 | # @author Isis Agora Lovecruft, 0xa3adb67a2cdb8b35 28 | # @date 13 May 2012 29 | # @version 0.0.3 30 | # 31 | ############################################################################### 32 | 33 | ## Directory where your mailconfigs are stored: 34 | MAILRC=$HOME/.mailrc 35 | 36 | ## Set this to your Tor SocksPort: 37 | SOCKSPORT=9050 38 | 39 | ## Set these to the IP address (or FQDN) and port of your mailserver: 40 | MAILSERVER_FQDN="mailserver.com" 41 | MAILSERVER_PORT=465 42 | 43 | ## The "Account" stanza in your msmtp config that you wish to use: 44 | MSMTP_ACCOUNT="default" 45 | 46 | ## YOU SHOULDN'T NEED TO CHANGE ANY OF THE FOLLOWING VARIABLES: 47 | ##---------------------------------------------------------------- 48 | LOG_FILE="${MAILRC}/mailwithtor.log" 49 | LOCK_FILE="${MAILRC}/mailwithtor-lockfile" 50 | 51 | ## Port for socat to pipe incoming connections to its own SOCKS server: 52 | SOCAT_LISTEN_PORT=2525 53 | 54 | ## Read the private settings file to override previous variables: 55 | test -r "${MAILRC}/mailwithtor.private" && source ${MAILRC}/mailwithtor.private 56 | 57 | # MAILWITHTORPID=$(pgrep -u "$USER" mailwithtor) 58 | # 59 | # if test -z "$MAILWITHTORPID" ; then 60 | # if test -e "$HOME/.mailrc/$LOCK_FILE" ; then 61 | # sudo rm -f $HOME/.mailrc/$LOCK_FILE &> $HOME/.mailrc/$LOG_FILE 62 | # fi 63 | # else 64 | # while [[ "$MAILWITHTORPID" != "" ]] ; do 65 | # sudo kill -9 "$MAILWITHTORPID" &> $HOME/.mailrc/$LOG_FILE 66 | # done 67 | # if test -f "$HOME/.mailrc/$LOCK_FILE" ; then 68 | # sudo rm -f $HOME/.mailrc/$LOCK_FILE &> $HOME/.mailrc/$LOG_FILE 69 | # fi 70 | # fi 71 | 72 | ## USING BEFORE STARTING MUTT (least buggiest): 73 | ## -------------------------------------------- 74 | ## If you're calling this from commandline before starting mutt, uncomment the 75 | ## following line and use like so: 76 | ## $ ./mailwithtor & 77 | ## $ mutt 78 | 79 | sudo socat -d -d -d -lu -L $MAILRC/$LOCK_FILE -lf $MAILRC/$LOG_FILE TCP4-LISTEN:$SOCAT_LISTEN_PORT,fork SOCKS4A:localhost:$MAILSERVER_FQDN:$MAILSERVER_PORT,socksport=$SOCKSPORT,socksuser="" 80 | 81 | ## If you're calling this from commandline before starting mutt, and you also 82 | ## wish to use SSL to connect to the server, uncomment the next line instead 83 | ## and call with "$ mailwithtor &": 84 | ## 85 | ## NOTE: Buggy. Sometimes fails. 86 | 87 | #sudo socat -d -d -d -lu -L $HOME/.mailrc/$LOCK_FILE -lf $HOME/.mailrc/$LOG_FILE OPENSSL-LISTEN:2525,method=TLSv1,verify=1,cafile=$HOME/.mailrc/CA/AddTrust_External_Root.pem,fork SOCK4a:localhost:$MAILSERVER_FQDN:$MAILSERVER_PORT,socksport=$SOCKSPORT,socksuser="" 88 | 89 | ## If you're setting "set sendmail='$HOME/path/to/mailwithtor'", then 90 | ## uncomment the following lines: 91 | ## 92 | ## NOTE: This is BROKEN. Specifically the getting-the-passphrase-from-the-sudo- 93 | ## prompt part, from inside mutt. 94 | 95 | #sudo %?p?--passphrase-fd 0? socat -d -d -d -lu -L ${LOCK_FILE} -lf ${LOG_FILE} TCP4-LISTEN:$SOCAT_LISTEN_PORT,fork SOCKS4A:localhost:$MAILSERVER_FQDN:$MAILSERVER_PORT,socksport=$SOCKSPORT,socksuser="" & /usr/bin/msmtp -a $MSMTP_ACCOUNT 96 | #/usr/bin/msmtp -a default $1 $2 $3 $4 $5 $6 $7 $8 97 | 98 | -------------------------------------------------------------------------------- /mandelbrot.py: -------------------------------------------------------------------------------- 1 | """ 2 | Black 0;30 Dark Gray 1;30 3 | Blue 0;34 Light Blue 1;34 4 | Green 0;32 Light Green 1;32 5 | Cyan 0;36 Light Cyan 1;36 6 | Red 0;31 Light Red 1;31 7 | Purple 0;35 Light Purple 1;35 8 | Brown 0;33 Yellow 1;33 9 | Light Gray 0;37 White 1;37 10 | """ 11 | 12 | import sys 13 | 14 | palette = [39, 34, 35, 36, 31, 33, 32, 37] 15 | colour_range = None # used for debugging 16 | 17 | 18 | def _getdimensions(): 19 | import termios,fcntl,struct 20 | call = fcntl.ioctl(1,termios.TIOCGWINSZ,"\000"*8) 21 | height,width = struct.unpack( "hhhh", call ) [:2] 22 | return height, width 23 | 24 | def get_terminal_width(): 25 | try: 26 | height, width = _getdimensions() 27 | except: 28 | # FALLBACK 29 | width = int(os.environ.get('COLUMNS', 80)) 30 | else: 31 | # XXX the windows getdimensions may be bogus, let's sanify a bit 32 | if width < 40: 33 | width = 80 34 | return width 35 | 36 | def ansi_print(text, esc, file=None, newline=True, flush=False): 37 | if file is None: 38 | file = sys.stderr 39 | text = text.rstrip() 40 | if esc and not isinstance(esc, tuple): 41 | esc = (esc,) 42 | if esc and sys.platform != "win32" and file.isatty(): 43 | text = (''.join(['\x1b[%sm' % cod for cod in esc]) + 44 | text + 45 | '\x1b[0m') # ANSI color code "reset" 46 | if newline: 47 | text += '\n' 48 | if esc: 49 | file.write(text) 50 | if flush: 51 | file.flush() 52 | 53 | def print_pixel(colour, value_range, invert=1): 54 | global colour_range 55 | chars = [".", ".", "+", "*", "%", "#"] 56 | idx = lambda chars: (colour+1) * (len(chars) - 1) / value_range 57 | if invert: 58 | idx = lambda chars, idx=idx:len(chars) - 1 - idx(chars) 59 | char = chars[idx(chars)] 60 | ansi_colour = palette[idx(palette)] 61 | ansi_print(char, ansi_colour, newline=False, flush=True) 62 | #if colour_range is None: 63 | # colour_range = [colour, colour] 64 | #else: 65 | # colour_range = [min(colour_range[0], colour), max(colour_range[1], colour)] 66 | 67 | 68 | class Mandelbrot: 69 | def __init__ (self, width=100, height=28, x_pos=-0.5, y_pos=0, distance=6.75): 70 | self.xpos = x_pos 71 | self.ypos = y_pos 72 | aspect_ratio = 1/3. 73 | factor = float(distance) / width # lowering the distance will zoom in 74 | self.xscale = factor * aspect_ratio 75 | self.yscale = factor 76 | self.iterations = 170 77 | self.x = width 78 | self.y = height 79 | self.z0 = complex(0, 0) 80 | 81 | def init(self): 82 | self.reset_lines = False 83 | xmin = self.xpos - self.xscale * self.x / 2 84 | ymin = self.ypos - self.yscale * self.y / 2 85 | self.x_range = [xmin + self.xscale * ix for ix in range(self.x)] 86 | self.y_range = [ymin + self.yscale * iy for iy in range(self.y)] 87 | 88 | #print "x", self.x_range[0], self.x_range[-1] 89 | #print "y", self.y_range[0], self.y_range[-1] 90 | 91 | def reset(self, cnt): 92 | self.reset_lines = cnt 93 | 94 | def generate(self): 95 | self.reset_lines = False 96 | iy = 0 97 | while iy < self.y: 98 | ix = 0 99 | while ix < self.x: 100 | c = complex(self.x_range[ix], self.y_range[iy]) 101 | z = self.z0 102 | colour = 0 103 | mind = 2 104 | 105 | for i in range(self.iterations): 106 | z = z * z + c 107 | d = abs(z) 108 | if d >= 2: 109 | colour = min(int(mind / 0.007), 254) + 1 110 | break 111 | else: 112 | mind = min(d, mind) 113 | 114 | yield ix, iy, colour 115 | if self.reset_lines is not False: # jump to the beginning of the line 116 | iy += self.reset_lines 117 | do_break = bool(self.reset_lines) 118 | self.reset_lines = False 119 | if do_break: 120 | break 121 | ix = 0 122 | else: 123 | ix += 1 124 | iy += 1 125 | 126 | 127 | class Driver(object): 128 | zoom_locations = [ 129 | # x, y, "distance", range 130 | (0.37865401, 0.669227668, 0.04, 111), 131 | (-1.15, -0.28, 0.9, 94), 132 | (-1.15, -0.28, 0.3, 58), 133 | (-1.15, -0.28, 0.05, 26), 134 | ] 135 | def __init__(self, **kwargs): 136 | self.kwargs = kwargs 137 | self.zoom_location = -1 138 | self.colour_range = 256 139 | self.invert = True 140 | self.init() 141 | 142 | def init(self): 143 | self.width = get_terminal_width() or 80 # in some envs, the py lib doesnt default the width correctly 144 | self.mandelbrot = Mandelbrot(width=(self.width or 1), **self.kwargs) 145 | self.mandelbrot.init() 146 | self.gen = self.mandelbrot.generate() 147 | 148 | def reset(self, cnt=0): 149 | """ Resets to the beginning of the line and drops cnt lines internally. """ 150 | self.mandelbrot.reset(cnt) 151 | 152 | def catchup(self): 153 | """ Fills the current line. """ 154 | x = 0 155 | while x != self.width - 1: 156 | x, y, c = self.gen.next() 157 | print_pixel(c, self.colour_range, self.invert) 158 | print >>sys.stderr 159 | 160 | def restart(self): 161 | """ Restarts the current generator. """ 162 | print >>sys.stderr 163 | self.init() 164 | 165 | def dot(self): 166 | """ Emits a colourful character. """ 167 | x = c = 0 168 | try: 169 | x, y, c = self.gen.next() 170 | if x == 0: 171 | width = get_terminal_width() 172 | if width != self.width: 173 | self.init() 174 | except StopIteration: 175 | kwargs = self.kwargs 176 | self.zoom_location += 1 177 | self.zoom_location %= len(self.zoom_locations) 178 | loc = self.zoom_locations[self.zoom_location] 179 | kwargs.update({"x_pos": loc[0], "y_pos": loc[1], "distance": loc[2]}) 180 | self.colour_range = loc[3] 181 | #global colour_range 182 | #print colour_range, loc[2] 183 | #colour_range = None 184 | return self.restart() 185 | print_pixel(c, self.colour_range, self.invert) 186 | if x == self.width - 1: 187 | print >>sys.stderr 188 | 189 | 190 | if __name__ == '__main__': 191 | import random 192 | from time import sleep 193 | 194 | d = Driver() 195 | for x in xrange(150000): 196 | sleep(random.random() / 200) 197 | d.dot() 198 | if 0 and random.random() < 0.01: 199 | d.catchup() 200 | print "WARNING! " * 3 201 | d.reset(1) 202 | # print "R", 203 | if 0 and random.random() < 0.01: 204 | string = "WARNING! " * 3 205 | d.jump(len(string)) 206 | print string, 207 | 208 | -------------------------------------------------------------------------------- /move-blog-dirs.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | #----------------------------------------------------------------------------- 3 | # move-blog-dirs.sh 4 | # ----------------- 5 | # Used with Pelican for patternsinthevoid.net to change the ownership and 6 | # permissions of generated HTML, then move the files and directories into the 7 | # webserver root. 8 | # 9 | # :author: isis lovecruft 0xa3adb67a2cdb8b35 10 | # :licence: WTFPL 11 | # :version: 0.0.1 12 | #---------------------------------------------------------------------------- 13 | 14 | sudo rsync -q -rthL --safe-links --protect-args \ 15 | --chmod=go=rX --chmod=u=rwX --cvs-exclude --delete-during \ 16 | --delete-excluded --force --prune-empty-dirs \ 17 | --log-file=/home/isis/update.log \ 18 | /home/isis/published/ /var/www/blog.patternsinthevoid.net/docroot/ 19 | sudo chown -R www-data:www-data /var/www/blog.patternsinthevoid.net/docroot/ 20 | -------------------------------------------------------------------------------- /only: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | ############################################################################### 3 | # 4 | # only 5 | # ---- 6 | # only run $@ if it isn't running already. 7 | # 8 | # @author Isis Agora Lovecruft, 0x2cdb8b35 9 | # @date 17 August 2012 10 | # @version 0.0.1 11 | #______________________________________________________________________________ 12 | # Changelog: 13 | ############################################################################### 14 | 15 | if [ -z "`ps -Af | grep -o -w ".*$1" | grep -v grep | grep -v only`" ] ; then 16 | $@ 17 | fi 18 | -------------------------------------------------------------------------------- /pastebin-photo: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | """ 4 | pastebin-photo 5 | -------------------- 6 | Share a photo by pastebin'ing the base64 de-/en- coded version of it. 7 | 8 | :authors: Isis Agora Lovecruft, 0xa3adb67a2cdb8b35 9 | :license: AGPLv3 10 | :date: 2011-01-04 11 | :version: 0.0.3 12 | """ 13 | 14 | from functools import wraps 15 | from urllib2 import base64 16 | 17 | import sys 18 | 19 | 20 | def dencode(oldfile, newfile): 21 | """ 22 | Take each line in the file containing the original image and base64 encode 23 | or decode it and then write to another file. 24 | """ 25 | def decorator(func): 26 | @wraps(func) 27 | def wrapper(*args): 28 | with open(oldfile) as fh: 29 | raw = fh.read(1073741824) ## limit to 1GB either direction 30 | with open(newfile, 'a+') as nf: 31 | def wrapped(line): 32 | return func(line) 33 | nf.write(wrapped(raw)) 34 | return 35 | return wrapper 36 | return decorator 37 | 38 | if __name__ == "__main__": 39 | 40 | if len(sys.argv) == 4: 41 | old = sys.argv[2] 42 | new = sys.argv[3] 43 | 44 | @dencode(old, new) 45 | def encode(line): 46 | return base64.b64encode(line) 47 | 48 | @dencode(old, new) 49 | def decode(line): 50 | return base64.b64decode(line) 51 | 52 | decode(old, new) if sys.argv[1] == "-d" else encode(old, new) 53 | else: 54 | use = """Usage: {p} [-d|-e] 55 | 56 | Examples: 57 | $ {p} -e original.jpg base64.txt (to encode) 58 | $ {p} -d base64.txt new.jpg (to decode) 59 | """.format(p=sys.argv[0]) 60 | 61 | raise SystemExit(use) 62 | -------------------------------------------------------------------------------- /ppmascii: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl -s 2 | # 3 | # ppmascii 4 | # -------- 5 | # Useful with ttytter, a commandline twitter client, for displaying users' 6 | # avatars as ascii art. 7 | # 8 | # Taken from http://www.floodgap.com/software/ppmascii/ 9 | # 10 | # @authors: Cameron Kaiser 11 | # @license: Floodgap Free Software License 12 | # http://www.floodgap.com/software/ffsl/license.txt 13 | # 14 | 15 | BEGIN { $^H |= 0x000000008 unless ($] < 5.006); } # "use bytes" 16 | 17 | if ($h || $help) { 18 | die <<"EOF"; 19 | ppmascii v1.2 by cameron kaiser 20 | 21 | options: 22 | -showheader show ppm height, width, etc. 23 | 24 | distortions and transformations: 25 | -x2 double pixels horizontally (averaged unless -nosmooth) 26 | -y2 double pixels vertically (simple reduplication) 27 | -winx=n scroll window to horizonal pixel n 28 | -winy=n scroll window to vertical pixel n 29 | -width=n set width to n columns (default 79) 30 | -height=n stop after n rows 31 | 32 | input-stage adjustments: 33 | -bright=n set bright to n (1.0=no change), 0= $height)); 107 | next if ($dwcc >= $width || $wcc < $winx || $rows < $winy); 108 | # normalized from 0.3R+0.59G+0.11B to the 3x we use here 109 | $olum = ($norgb) ? ($r + $g + $b) : (0.9*$r + 1.77*$g + 0.33*$b); 110 | unless ($nodither) { 111 | $lum = $olum+(7/16)*$lastlum+shift(@thisline); 112 | } else { 113 | $lum = $olum; 114 | } 115 | $cc = ($ppm_ccv - $lum) * $contrast; 116 | $cc += $lum; $cc=0 if ($cc<0); 117 | $llap = $lap; 118 | 119 | $lap = (!$scf) ? 0 : &clip($cc * $bright / $scf); 120 | unless ($nodither) { 121 | # setup matrix for f-s dither 122 | $lastlum = $olum-($diffscale*$lap); 123 | # remember that wcc 124 | $nextline[$wcc] += (5/16)*$lastlum; 125 | $nextline[$wcc+1] += (1/16)*$lastlum if ($wcc < $ppm_width); 126 | $nextline[$wcc-1] += (3/16)*$lastlum if ($wcc); 127 | } 128 | if ($x2 && $dwcc > 1 && !$nosmooth) { 129 | $elap = &clip(($lap + $llap) / 2); 130 | } else { 131 | $elap = $lap; 132 | } 133 | $j = ($elements[$elap]); 134 | $this_row .= $j; 135 | print $j; 136 | if ($x2) { 137 | $j = ($elements[$lap]); 138 | $this_row .= $j; 139 | print $j; 140 | } 141 | } 142 | 143 | exit; 144 | 145 | sub widthfix { 146 | if (++$wcc == $ppm_width) { 147 | if ($rows >= $winy) { 148 | print "\n"; 149 | print "$this_row\n" if ($y2); 150 | $drows++; 151 | $llap = 0; 152 | } 153 | $rows += 1 + $y2; 154 | $this_row = ''; 155 | $dwcc = $wcc = $lastlum = 0; 156 | @thisline = @nextline; 157 | @nextline = @empty; 158 | } 159 | $dwcc += 1 + $x2; 160 | } 161 | 162 | sub clip { 163 | local $g = shift; 164 | $g = $#elements if ($g > $#elements); 165 | return int($g); 166 | } 167 | 168 | sub loadppm { 169 | local ($p, $w) = ($/, @_); 170 | 171 | undef $/; 172 | $ppm_buf = scalar(<$w>); 173 | return 1; 174 | } 175 | 176 | sub initppm { 177 | $ppm_buf =~ s/^\s*//s; 178 | ($ppm_type, $ppm_buf) = split(/\s+/s, $ppm_buf, 2); 179 | $ppm_buf =~ s/#[^\r\l\n]*[\r\l\n]+/\n/gs 180 | if ($ppm_type ne 'P6'); 181 | $ppm_buf =~ s/^\s*//s; 182 | if ($ppm_type eq 'P1') { #pbm 183 | ($ppm_width, $ppm_height, $ppm_buf) = 184 | split(/\s+/s, $ppm_buf, 3); 185 | $ppm_ccv = 1; 186 | } else { 187 | ($ppm_width, $ppm_height, $ppm_ccv, $ppm_buf) = 188 | split(/\s+/s, $ppm_buf, 4); 189 | } 190 | $ppm_width += 0; 191 | $ppm_height += 0; 192 | $ppm_ccv += 0; 193 | $ppm_filepos = 0; 194 | return 1; 195 | } 196 | 197 | sub getnextcolour { 198 | local $nc; 199 | 200 | return -1 if (!length($ppm_buf) || $ppm_filepos >= length($ppm_buf)); 201 | 202 | if ($ppm_type eq 'P3' || $ppm_type eq 'P2') { 203 | $ppm_buf =~ s/^\s*//s; 204 | ($nc, $ppm_buf) = split(/\s+/s, $ppm_buf, 2); 205 | return (0+$nc); 206 | } elsif ($ppm_type eq 'P6' || $ppm_type eq 'P5') { 207 | $nc = substr($ppm_buf, $ppm_filepos, 1); 208 | $ppm_filepos++; 209 | return 0+unpack("C", $nc); 210 | } elsif ($ppm_type eq 'P1') { 211 | $nc = substr($ppm_buf, 0, 1); 212 | $ppm_buf = substr($ppm_buf, 1); 213 | $ppm_buf =~ s/^[\r\l\n\s]*//s; 214 | return ($nc+0); 215 | } else { 216 | die("unsupported format $ppm_type"); 217 | } 218 | } 219 | 220 | sub getnextpixel { 221 | local $r, $g, $b; 222 | if ($ppm_type eq 'P3' || $ppm_type eq 'P6') { 223 | $r = &getnextcolour; 224 | $g = &getnextcolour; 225 | $b = &getnextcolour; 226 | } else { # must be P1, P2 or P5 227 | $b = &getnextcolour; 228 | $r = $g = $b; 229 | } 230 | return (($r == -1 || $g == -1 || $b == -1) ? (-1, -1, -1) : 231 | ($r, $g, $b)); 232 | } 233 | 234 | 1; 235 | -------------------------------------------------------------------------------- /quantumquantum: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # -*- coding: utf-8 -*- 3 | #------------------------------------------------------------------------------ 4 | # 5 | # quantumquantum 6 | # ---------- 7 | # A simple quantumscript which quantumpicks a random quantumword from a quantumlist, 8 | # quantumprepends "quantum" to it, and quantumannouces it with espeak. Perfect for 9 | # quantumuse as a quantumgeneral quantumnotification callback, quantummaking slightly 10 | # quantuminappropriate quantumremarks at the wrong quantumtime. 11 | # 12 | # To quantumuse with agl's xmpp-client (https://github.com/agl/xmpp-client), 13 | # quantumput this into your ~/.xmpp-client quantumconfiguration file: 14 | # 15 | # "NotifyCommand": ["/path/to/quantumquantum"], 16 | # "IdleSecondsBeforeNotification": 300, 17 | # 18 | # Quantumrequirements: espeak 19 | # 20 | # :authors: Isis Agora Lovecruft, 0xa3adb67a2cdb8b35 21 | # :license: MIT licence 22 | # :version: 0.0.1 23 | #------------------------------------------------------------------------------ 24 | 25 | QUANTUM="activism addict advocacy affair age agent anarchism" 26 | QUANTUM=$QUANTUM" anarchy anarchist apocalypse architecture assault" 27 | QUANTUM=$QUANTUM" attack babble babe banking battle begging blackmail" 28 | QUANTUM=$QUANTUM" boyfriend bro buddy bullying caliphate capabilities cash" 29 | QUANTUM=$QUANTUM" censorship chat colonialism command commuter computery conflict" 30 | QUANTUM=$QUANTUM" celebrity conspiracy conversation cop cowboy crime critic crook cult" 31 | QUANTUM=$QUANTUM" quantum quantuming czar dating death defense dildonic dimension" 32 | QUANTUM=$QUANTUM" discourse defense doctrine domain economy effects elite" 33 | QUANTUM=$QUANTUM" emergency enterprise environment equivalents exploitation" 34 | QUANTUM=$QUANTUM" erotic espionage ethics evangelist explosion extortion fashion" 35 | QUANTUM=$QUANTUM" feminism flaneur flirting forces forensics fraud freak freedom" 36 | QUANTUM=$QUANTUM" friend funeral future gambling gaming gang geek generation" 37 | QUANTUM=$QUANTUM" ghetto girlfriend goths government group hacker" 38 | QUANTUM=$QUANTUM" harassment hatred ho heaven heist hero heroin hug identity" 39 | QUANTUM=$QUANTUM" immorality imperialism industry information infrastructure" 40 | QUANTUM=$QUANTUM" intelligence intruder intrusion issues jargon jihad jihadi" 41 | QUANTUM=$QUANTUM" journalism junk junkie kid laundering law libertarian" 42 | QUANTUM=$QUANTUM" liberty literacy loafing looting locker loser lover" 43 | QUANTUM=$QUANTUM" marketplace marriage martyr media mob money mosque nation" 44 | QUANTUM=$QUANTUM" naut nerd network operations ninja ostracism payment peer penetration" 45 | QUANTUM=$QUANTUM" person physical philosopher phobia pioneer piracy pirate police" 46 | QUANTUM=$QUANTUM" politics porn pornography president" 47 | QUANTUM=$QUANTUM" privacy prostitute protest punk revolution rific romance" 48 | QUANTUM=$QUANTUM" sabotage scam security sex sexual shame shopper slacker samurai" 49 | QUANTUM=$QUANTUM" slut smut space spacetime sphere spy squatter " 50 | QUANTUM=$QUANTUM" squatting stalker stalking strategy" 51 | QUANTUM=$QUANTUM" stud team terrorism terrorist theft thief threat" 52 | QUANTUM=$QUANTUM" thug trail trash trespasser utopia villain war warfare" 53 | QUANTUM=$QUANTUM" warrior weapon wizard witchcraft" 54 | 55 | QUANTUM_LIST=($QUANTUM) 56 | QUANTUM_LENGTH=${#QUANTUM_LIST[@]} 57 | QUANTUM_WORD="${QUANTUM_LIST[$((RANDOM%QUANTUM_LENGTH))]}" 58 | 59 | function usage () 60 | { 61 | printf '%s [OPTIONS]\n\n' "$(basename $0)" 62 | printf 'OPTIONS\n' 63 | printf -- '-h\t\tThis cruft.\n' 64 | printf -- '-a\t\tAll of the quantumquantums!\n' 65 | printf -- "-q\t\tDon't print to stdout.\n" 66 | } 67 | 68 | function allofthequantums () 69 | { 70 | for QUANTUM_WORD in $QUANTUM ; do 71 | printf " Quantum${QUANTUM_WORD}!\n" 72 | espeak -x --ipa=1 -s 130 -k 20 -p 25 "Quantum${QUANTUM_WORD}!" 2>/dev/null 73 | done 74 | } 75 | 76 | quiet=1 77 | 78 | while getopts haqv f; do 79 | case $f in 80 | h) usage ; exit 0 ;; 81 | a) allofthequantums ; shift ;; 82 | q) quiet=1 ;; 83 | v) quiet= ;; 84 | # don't we need `shift 2` above? or `shift $(( OPTIND - 1))`? 85 | esac 86 | done 87 | 88 | if test -z "$quiet" ; then 89 | printf " Quantum${QUANTUM_WORD}!\n" 90 | espeak -x --ipa=1 -s 130 -k 20 -p 25 "Quantum${QUANTUM_WORD}!" 2>/dev/null 91 | else 92 | espeak -x --ipa=1 -s 130 -k 20 -p 25 "Quantum${QUANTUM_WORD}!" 1>/dev/null 2>&1 93 | fi 94 | 95 | exit 0 96 | -------------------------------------------------------------------------------- /smtp-tunnel: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | # A SMTP-over-SSH Port Forwarding Scrpt 4 | # Copyright (c) 2010 Linode, LLC 5 | # Author: Philip C. Paradis 6 | # Modifications: Sam Kleinman 7 | # Usage: smtp-tunnel [start|stop] 8 | # Forward smtp traffic over ssh to a remote mailserver. 9 | 10 | ## Edit these values to reflect the authentication credentials for the 11 | ## SMTP server with which you wish to connect and send mail. If you 12 | ## have chosen to run your mailserver on your linode using an 13 | ## alternate port, modify the `$remote_port` value. You should not 14 | ## need to modify the `$remote_ip` value. 15 | 16 | $remote_user = "REMOTE-USER"; 17 | $remote_host = "REMOTE-HOST"; 18 | $remote_port = "25"; 19 | $remote_ip = "127.0.0.1"; 20 | 21 | ## Modify these values if you are running a local SMTP server on port 22 | ## 25, or if you need to start the tunnel as a non-root user, as 23 | ## OpenSSH only allows root users to start tunnels to low-numbered 24 | ## "privileged ports." If this is the case you will also need to 25 | ## modify the configuration of your local mail sending agent. 26 | 27 | $local_ip = "127.0.0.1"; 28 | $local_port = "2525"; 29 | 30 | ## You do not need to edit this file beyond this point. 31 | 32 | ###################################################################### 33 | 34 | $a = shift; 35 | $a =~ s/^\s+//; 36 | $a =~ s/\s+$//; 37 | 38 | $pid=`ps ax|grep ssh|grep $local_port|grep $remote_port`; 39 | $pid =~ s/^\s+//; 40 | @pids = split(/\n/,$pid); 41 | foreach $pid (@pids) 42 | { 43 | if ($pid =~ /ps ax/) { next; } 44 | split(/ /,$pid); 45 | } 46 | 47 | if (lc($a) eq "start") 48 | { 49 | if ($_[0]) { print "smtp-tunnel already running.\n"; exit 1; } 50 | else 51 | { 52 | system "ssh -f -L $local_ip:$local_port:$remote_ip:$remote_port $remote_user\@$remote_host -N"; 53 | exit 0; 54 | } 55 | } 56 | elsif (lc($a) eq "stop") 57 | { 58 | if ($_[0]) { kill 9,$_[0]; exit 0; } 59 | else { exit 1; } 60 | } 61 | else 62 | { 63 | print "Usage: smtp-tunnel [start|stop]\n"; 64 | exit 1; 65 | } 66 | -------------------------------------------------------------------------------- /sprunge: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | ############################################################################### 3 | # 4 | # sprunge 5 | # -------------- 6 | # Wraps Sprunge, a commandline pastebin tool, with SOCKS4a and a User-Agent, 7 | # so that it can be called from Mutt. 8 | # 9 | # Put it somewhere on your $PATH and use like this: 10 | # 11 | # $ echo "test" | sprunge 12 | # $ cat test.txt | sprunge 13 | # 14 | # @author Isis Agora Lovecruft, 0x2cdb8b35 15 | # @date 25 May 2012 16 | # @version 0.0.1 17 | #______________________________________________________________________________ 18 | # Changelog: 19 | ############################################################################### 20 | 21 | curl --socks4a 127.0.0.1:59050 -A 'Mozilla/5.0 (Windows NT 6.1; rv:17.0) Gecko/20100101 Firefox/17.0' -F 'sprunge=<-' http://sprunge.us $1 22 | -------------------------------------------------------------------------------- /ssh-one-key-per-host: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | ssh-one-key-per-host 6 | ----------------------- 7 | 8 | Given a list of hostnames, generate an SSH key for each one, then print out 9 | lines of ``allowed_hosts=[…]`` for each one, á la 10 | https://db.torproject.org/doc-mail.html or https://db.debian.org/doc-mail.html 11 | style. 12 | 13 | :author: Isis 0x0A6A58A14B5946ABDE18E207A3ADB67A2CDB8B35 14 | :version: 0.0.1 15 | :license: MIT 16 | :copyright: © 2017 Isis Agora Lovecruft 17 | """ 18 | 19 | from __future__ import print_function 20 | from __future__ import unicode_literals 21 | 22 | import argparse 23 | import logging 24 | import os 25 | import re 26 | import requests 27 | import subprocess 28 | import sys 29 | 30 | SSH_DIR = os.path.expanduser("~/.ssh") 31 | URL = "https://db.torproject.org/machines.cgi" 32 | REGEX = "host=[a-z]*\">([a-z]*\.torproject\.org)" 33 | 34 | 35 | log = logging.getLogger() 36 | 37 | 38 | def _get_args(): 39 | parser = argparse.ArgumentParser() 40 | parser.add_argument('-m', '--hosts', 41 | help=("Comma separated list of hosts")) 42 | parser.add_argument('-d', '--dir', 43 | help=("SSH config directory to place new keys into " 44 | "(default: %s)" % SSH_DIR)) 45 | parser.add_argument('-c', '--clobber', action='store_true', 46 | help=("Overwrite ssh keyfiles in DIR")) 47 | parser.add_argument('-C', '--comment', 48 | help=("Comment for all new ssh keys")) 49 | parser.add_argument('-p', '--password', action='store_true', 50 | help=("Ask for a password once, for all new ssh keys ")) 51 | 52 | fetch_group = parser.add_argument_group(title='Fetching', 53 | description="Options for fetching available hosts") 54 | fetch_group.add_argument('-u', '--url', help=("A URL to parse for hostnames, " 55 | "use -r to specify a regex to " 56 | "parse (default: %s)" % URL)) 57 | fetch_group.add_argument('-r', '--regex', help=("A regex to parse the URL for hostnames " 58 | "(default: %s)" % REGEX)) 59 | 60 | log_group = parser.add_argument_group(title='Logging', 61 | description="Options and settings for logging") 62 | log_group.add_argument('--stderr', action='store_true', help="Log to stderr") 63 | log_group.add_argument('--stdout', action='store_true', help="Log to stdout") 64 | log_group.add_argument('--logfile', help="Log to file") 65 | log_group.add_argument('--loglevel', help="Log level", default="INFO", 66 | choices=["DEBUG", "INFO", "WARN", "ERROR", "CRITICAL"]) 67 | 68 | args = parser.parse_args() 69 | return args 70 | 71 | def fetch_and_parse_url(url, regex): 72 | logging.info("Fetching %s ..." % url) 73 | 74 | try: 75 | req = requests.get(url) 76 | except requests.exceptions.ConnectionError as err: 77 | logging.error("Could not connect to %s: %s" % (url, err.msg)) 78 | raise SystemExit(2) 79 | 80 | if req.status_code != 200: 81 | logging.error("There was an error requesting the URL %s: %s %s" 82 | % (url, req.status_code, req.reason)) 83 | raise SystemExit(2) 84 | 85 | logging.debug("Parsing response...") 86 | regexp = re.compile(regex) 87 | matches = list(set(regexp.findall(req.content))) 88 | 89 | logging.debug("Found %d matches: %s" % (len(matches), matches)) 90 | 91 | return matches 92 | 93 | def create_key_for_host(host, password=None, comment=None, ssh_dir=None): 94 | keytype = "ed25519" 95 | hostname_regex = re.compile("([a-z]*)\.([a-z]*)\.[a-z]*") 96 | hostname, domain = hostname_regex.findall(host)[0] 97 | filename = os.path.sep.join([ssh_dir, "id_%s_%s_%s" % (keytype, domain, hostname)]) 98 | 99 | args = [ 100 | "ssh-keygen", 101 | "-t", "%s" % keytype, 102 | "-N", "%s" % password, 103 | "-f", "%s" % filename, 104 | ] 105 | 106 | if comment: 107 | args.append("-C") 108 | args.append("%s" % comment) 109 | 110 | logging.info("Generating key for %s..." % host) 111 | 112 | proc = subprocess.Popen(args, shell=False, 113 | stdin=subprocess.PIPE, 114 | stdout=subprocess.PIPE, 115 | stderr=subprocess.PIPE) 116 | returncode = proc.wait() 117 | 118 | if returncode: 119 | logging.error("There was an error calling `%s`: %s" 120 | % (' '.join(args), proc.stderr.read())) 121 | else: 122 | logging.debug(proc.stdout.read()) 123 | return "%s.pub" % filename 124 | 125 | def print_allowed_hosts_lines(pubkeys): 126 | for (host, pubkey_file) in pubkeys: 127 | with open(pubkey_file) as fh: 128 | pubkey = fh.read() 129 | print("allowed_hosts=%s %s" % (host, pubkey)) 130 | 131 | def print_ssh_config_lines(pubkeys): 132 | for (host, pubkey_file) in pubkeys: 133 | print("Host tor-%s\n Hostname %s\n IdentityFile %s\n" 134 | % (host.split('.', 1)[0], host, pubkey_file)) 135 | 136 | def main(args): 137 | hosts = [] 138 | pubkeys = [] 139 | 140 | if args.logfile: 141 | log.addHandler(logging.FileHandler(args.logfile)) 142 | elif args.stderr: 143 | log.addHandler(logging.StreamHandler(sys.stderr)) 144 | elif args.stdout: 145 | log.addHandler(logging.StreamHandler(sys.stdout)) 146 | else: 147 | log.addHandler(logging.StreamHandler(sys.stdout)) 148 | 149 | log.setLevel(logging._levelNames[args.loglevel]) 150 | 151 | password = '' 152 | dir = SSH_DIR 153 | 154 | if args.url: 155 | hosts = fetch_and_parse_url(args.url or URL, args.regex or REGEX) 156 | if args.hosts: 157 | hosts.append(args.hosts) 158 | if args.dir: 159 | dir = os.path.expanduser(args.dir) 160 | 161 | logging.info("Generating keys for %d hosts..." % len(hosts)) 162 | logging.debug("Generating keys for %s..." % " ".join(hosts)) 163 | 164 | if hosts: 165 | if args.password: 166 | password = raw_input("Please enter the new password for all generated keys: ") 167 | 168 | for host in hosts: 169 | pubkey_file = create_key_for_host(host, 170 | password, 171 | args.comment or '', 172 | args.dir) 173 | if pubkey_file: 174 | pubkeys.append((host, pubkey_file)) 175 | 176 | logging.info("Generated %d keys in total" % len(pubkeys)) 177 | 178 | if pubkeys: 179 | print_allowed_hosts_lines(pubkeys) 180 | print_ssh_config_lines(pubkeys) 181 | 182 | if __name__ == "__main__": 183 | main(_get_args()) 184 | -------------------------------------------------------------------------------- /utcdammit: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | ############################################################################### 3 | # 4 | # UTCdammit 5 | # --------- 6 | # Set the system timezone with tzselect to UTC, then select a different 7 | # timezone in this script, and call it to convert to the selected timezone, in 8 | # order to display the time and date correctly in shells. 9 | # 10 | # @author Isis Agora Lovecruft, 0x2cdb8b35 11 | # @date 25 July 2012 12 | # @version 0.0.1 13 | #______________________________________________________________________________ 14 | # Changelog: 15 | ############################################################################### 16 | 17 | TZ=UTC 18 | export TZ 19 | 20 | ## If you wish to set $LOCALTZ in this script, then set it here: 21 | #LOCALTZ="Pacific/Honolulu" 22 | #LOCALTZ="America/Los_Angeles" 23 | #LOCALTZ="America/New_York" 24 | #LOCALTZ="America/Sao_Paulo" 25 | #LOCALTZ="Europe/London" 26 | LOCALTZ="Europe/Amsterdam" 27 | #LOCALTZ="Europe/Berlin" 28 | #LOCALTZ="Asia/Tehran" 29 | #LOCALTZ="Asia/Kolkata" 30 | #LOCALTZ="Asia/Shanghai" 31 | #LOCALTZ="Asia/Hong_Kong" 32 | #LOCALTZ="Asia/Tokyo" 33 | #LOCALTZ="Australia/Melbourne" 34 | 35 | function usage 36 | { 37 | echo "Usage: $0 [options]"; echo; 38 | echo "In order for this script to work least painfully, you should set an" 39 | echo "environment variable, \$LOCALTZ, in your .profile or .bashrc, like so:" 40 | echo " LOCALTZ=\"America/Los_Angeles\"" 41 | echo " export LOCALTZ"; echo; 42 | echo "Options:" 43 | echo "-l, --localtz Set the local timezone" 44 | echo "-t, --time Display the local time (24-hour)" 45 | echo "-w, --weekday Display the local weekday (long)" 46 | echo "-d, --date Display the local date (day/month)" 47 | echo "-x, --tmux Display full local date for tmux" 48 | echo "-c, --clock Display full local date for clock" 49 | echo "-h, --help Show this cruft"; echo; 50 | echo "Examples:" 51 | echo " \$ utcdammit -l \"America/Los_Angeles\" -t" 52 | echo " 14:30 PDT"; echo; 53 | echo " \$ utcdammit -a" 54 | echo " 14:30 PDT Wednesday 25/07"; echo; 55 | exit -1 56 | } 57 | 58 | function setup 59 | { 60 | ## Source .bashrc and .profile: 61 | if [ -f "$HOME/.profile" ] ; then 62 | . $HOME/.profile 63 | else 64 | ## If no .profile, pretend we are one: 65 | if [ -n "$BASH_VERSION" ] ; then 66 | if [ -f "$HOME/.bashrc" ] ; then 67 | . $HOME/.bashrc 68 | fi 69 | fi 70 | fi 71 | 72 | if test -z "$LOCALTZ" ; then 73 | LOCALTZ=$_LOCALTZ_ 74 | export LOCALTZ 75 | fi 76 | } 77 | 78 | function fluxcapacitor 79 | { 80 | if [[ "$LOCALTZ" == "" ]] || [[ "$LOCALTZ" == "$TZ" ]] ; then 81 | echo "Error: No local timezone!"; echo; 82 | exit 1 83 | else 84 | if test -n "$LOCALTZ" && test -z "$LOCALTIMEDAMMIT" ; then 85 | echo "There was a problem setting the local time..."; echo; 86 | exit 1 87 | fi 88 | fi 89 | } 90 | 91 | function timewarp 92 | { 93 | if test -n $LOCALTZ ; then 94 | if [[ "$TZ" != "$LOCALTZ" ]]; then 95 | LOCALTIMEDAMMIT=`TZ=$LOCALTZ date +%H:%M%_4Z` 96 | LOCALTIMESHORT=`TZ=$LOCALTZ date +%H:%M` 97 | LOCALWEEKDAYDAMMIT=`TZ=$LOCALTZ date +%A` 98 | LOCALDATE=`TZ=$LOCALTZ date +%d` 99 | LOCALDATESHORT=`TZ=$LOCALTZ date +%d/%m` 100 | LOCALMONTH=`TZ=$LOCALTZ date +%B` 101 | LOCALTZDAMMIT_TMUX="$LOCALTIMEDAMMIT $LOCALWEEKDAYDAMMIT $LOCALDATESHORT" 102 | LOCALTZDAMMIT_FULL="$LOCALWEEKDAYDAMMIT $LOCALDATE $LOCALMONTH"", ""$LOCALTIMESHORT" 103 | 104 | export LOCALTIMEDAMMIT 105 | export LOCALWEEKDAYDAMMIT 106 | export LOCALDATE 107 | export LOCALDATESHORT 108 | export LOCALMONTH 109 | export LOCALTZDAMMIT_TMUX 110 | export LOCALTZDAMMIT_FULL 111 | else 112 | echo "If you're trying to obscure your timezone, then why is your system clock set to the same timezone as your local one?" 113 | fi 114 | fi 115 | } 116 | 117 | 118 | if [ "$#" == "0" ]; then 119 | usage 120 | exit -1 121 | fi 122 | 123 | #setup 124 | while [ "$1" != "" ]; do 125 | case $1 in 126 | -l | --localtz ) ## check number of args 127 | #echo "Number of args: $#" 128 | #ARE_WE_EVEN=$(expr $# / 2) 129 | #echo "$ARE_WE_EVEN" 130 | shift 131 | export LOCALTZ=$1 132 | fluxcapacitor 133 | ;; 134 | -t | --time ) timewarp 135 | fluxcapacitor 136 | echo "$LOCALTIMEDAMMIT" 137 | ;; 138 | -w | --weekday ) timewarp 139 | fluxcapacitor 140 | echo "$LOCALWEEKDAYDAMMIT" 141 | ;; 142 | -d | --date ) timewarp 143 | fluxcapacitor 144 | echo "$LOCALDATESHORT" 145 | ;; 146 | -x | --tmux ) timewarp 147 | fluxcapacitor 148 | echo "$LOCALTZDAMMIT_TMUX" 149 | ;; 150 | -c | --clock ) timewarp 151 | fluxcapacitor 152 | echo "$LOCALTZDAMMIT_FULL" 153 | ;; 154 | -h | --help ) usage 155 | exit -1 156 | ;; 157 | * ) echo "Error: You gave me an argument I didn't understand..." 158 | echo 159 | usage 160 | exit 1 161 | ;; 162 | esac 163 | shift 164 | done 165 | -------------------------------------------------------------------------------- /verify-gitian-builder-signatures: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | #----------------------------------------------------------------------------- 3 | # verify-gitian-builder-signatures 4 | # -------------------------------- 5 | # Given a directory containing a TBB-3.x tarball, a sha256sums.txt file, and 6 | # several files containing GnuPG signatures from gitian builders, check all 7 | # the signatures against their proper data files. 8 | # 9 | # Can be used within the directory containing the above files: 10 | # 11 | # $ verify-gitian-builder-signatures 12 | # 13 | # or given a directory path: 14 | # 15 | # $ verify-gitian-builder-signatures ~/tbb 16 | # 17 | # :authors: Isis Agora Lovecruft, 0xa3adb67a2cdb8b35 18 | # :license: MIT licence 19 | # :version: 0.0.1 20 | #----------------------------------------------------------------------------- 21 | 22 | 23 | do_extract= 24 | maybe_dir= 25 | bundle_download_dir= 26 | 27 | while getopts hxd: f; do 28 | case $f in 29 | h) 30 | printf '%s [-h] [-x] [-d DIRECTORY]\n\n' "$(basename $0)" 31 | printf 'OPTIONS\n' 32 | printf -- '-h\t\tThis cruft.\n' 33 | printf -- '-x\t\tExtract TBB and debug symbols if all signatures ' 34 | printf -- 'check out okay. (Unix only)\n' 35 | printf -- '-d DIRECTORY\tCheck the TBB files in DIRECTORY.\n' 36 | printf -- ' \t\t(default: `%s`)\n\n' "$(pwd)" 37 | exit 0 38 | ;; 39 | x) do_extract=true ; shift ;; 40 | d) maybe_dir=$OPTARG ;; 41 | # don't we need `shift 2` above? or `shift $(( OPTIND - 1))`? 42 | esac 43 | done 44 | 45 | test -z "$maybe_dir" && maybe_dir=`pwd` 46 | 47 | if test -d "$maybe_dir" ; then 48 | bundle_download_dir=$maybe_dir 49 | printf "Checking signature files in directory: %s\n" "$bundle_download_dir" 50 | else 51 | printf "Can't find directory '%s'… are you sure it exists?" "$maybe_dir" 52 | exit 1 53 | fi 54 | 55 | sums=$(find . -type f -regextype posix-extended \ 56 | -regex "(.*sha256sums)(-unsigned-build)?(\.txt)" -printf "%f " | tr -d '[[:space:]]') 57 | # TODO: Verify signatures for incremental (.mar) files, they are named like 58 | # (.*sha256sums\.incrementals\.txt)(.*)(\.asc) 59 | gitian_sigs=$(find . -type f -regextype posix-extended \ 60 | -regex "(.*sha256sums)(-unsigned-build)?(\.txt)(.*)(\.asc)" -printf "%f ") 61 | debug_sigs=$(find . -type f -regextype posix-extended \ 62 | -regex ".*(tor-)(browser-)?(.*)(debug)(.*)(\.asc)" -printf "%f ") 63 | debug_files= 64 | tbbs=$(find . -type f -regextype posix-extended \ 65 | -regex ".*([tT]or)(-)?([bB]rowser-)(install)?(.*)(\.)(tar\.xz|dmg|exe){1}" \ 66 | -printf "%f " | tr -d '[[:space:]]') 67 | 68 | red="$(tput setaf 1)" 69 | green="$(tput setaf 10)" 70 | lavender="$(tput setaf 13)" 71 | reset="$(tput sgr0)" 72 | 73 | CCZE=$(which ccze) 74 | 75 | GPG=$(which gpg2) # Default to gpg2, and fallback to gpg if not found. 76 | if test -z "$GPG"; then GPG=$(which gpg); fi 77 | if test -z "$GPG"; then printf "You must have GnuPG installed!\nExiting…\n"; fi 78 | 79 | printf "Found Tor Browser files: %s%s%s\n" "$lavender" "$tbbs" "$reset" 80 | 81 | printf "――――――――――――――――――――――――\n" 82 | printf "Checking all Gitian Builder signatures on %s…\n\n" "$lavender$sums$reset" 83 | #printf "DEBUG: All gitian builder sigfiles: %s" "${gitian_sigs}" 84 | 85 | # Check gitian builder signatures on the sha256sums.txt file first: 86 | for sig in ${gitian_sigs} ; do 87 | psig="$green$sig$reset" # Add some colour 88 | pver="$lavender$sums$reset" 89 | printf "Verifying signature file %s for %s… " "$psig" "$pver" 90 | 91 | valid=`gpg2 --quiet --status-fd 1 --verify $sig $sums 2>/dev/null | grep "VALIDSIG"` 92 | returncode="$?" 93 | 94 | # Exit noisily if one of the gitian builder signatures was not okay: 95 | if test "$returncode" -ne "0" ; then 96 | printf "\t[%sERROR%s]\n" "$red" "$reset" 97 | printf "Exiting…\n" 98 | exit 2 99 | elif test "$returncode" -eq "0" -a -n "$valid" ; then 100 | printf "\t[%sOKAY%s]\n" "$green" "$reset" 101 | fi 102 | done 103 | 104 | printf "\n%sAll signatures from participating Gitian Builders" "$green" 105 | printf " checked out OKAY!%s\n" "$reset" 106 | 107 | printf "――――――――――――――――――――――――\n" 108 | for tbb in ${tbbs} ; do 109 | printf "Checking sha256sum for %s%s%s…" "$lavender" "$tbb" "$reset" 110 | grep "$tbb" "$sums" | sha256sum -c - 2>&1 1>/dev/null 111 | returncode="$?" 112 | 113 | # Exit noisily if the sha256sum for the tarball doesn't match the one 114 | # found in sha256sums.txt: 115 | if test "$returncode" -ne "0" ; then 116 | printf "\t[%sERROR%s]\n" "$red" "$reset" 117 | printf "\n%sWARNING%s: The sha256sum of your Tor Browser Bundle, " "$red" "$reset" 118 | printf "'%s', does NOT MATCH the corresponding one " "$tbb" 119 | printf "given in %s!\n\n" "$sums" 120 | printf "Perhaps there was an error downloading it. Please try " 121 | printf "re-downloading $s and running this check again." "$tbb" 122 | printf "\n\n" 123 | exit 2 124 | elif test "$returncode" -eq "0" ; then 125 | printf "\t[%sOKAY%s]\n" "$green" "$reset" 126 | fi 127 | 128 | # Last, check the signature on the TBB tarball itself: 129 | tbb_sigfile="${tbb}.asc" 130 | if test -f "$tbb_sigfile" ; then 131 | printf "Verifying signature %s%s%s… " "$green" "$tbb_sigfile" "$reset" 132 | 133 | valid=`gpg2 --quiet --status-fd 1 --verify $tbb_sigfile $tbb_tarball 2>/dev/null | grep "VALIDSIG"` 134 | returncode="$?" 135 | 136 | # Exit noisily if the tarball signature wasn't okay: 137 | if test "$returncode" -ne "0" ; then 138 | printf "\t[%sERROR%s]\n" "$red" "$reset" 139 | printf "Exiting…\n" 140 | exit 2 141 | elif test "$returncode" -eq "0" -a -n "$valid" ; then 142 | printf "\t[%sOKAY%s]\n" "$green" "$reset" 143 | fi 144 | fi 145 | done 146 | 147 | printf "\n%sAll sha256sums and signatures for Tor Browser downloads checked " "$green" 148 | printf "out OKAY!%s\n" "$reset" 149 | 150 | if test -n "${debug_sigs}" ; then 151 | printf "――――――――――――――――――――――――\n" 152 | printf "Checking all signatures on debug symbols…\n\n" 153 | 154 | # And... check the signatures on debug symbol tarballs: 155 | for sig in ${debug_sigs} ; do 156 | psig="$green$sig$reset" # Add some colour 157 | debug_file="${sig%%.asc}" 158 | debug_files="${debug_files} $debug_file" 159 | pver="$lavender$debug_file$reset" 160 | printf "Verifying signature file %s for %s… " "$psig" "$pver" 161 | 162 | valid=`gpg2 --quiet --status-fd 1 --verify $sig $debug_file 2>/dev/null | grep "VALIDSIG"` 163 | returncode="$?" 164 | 165 | # Exit noisily if one of the debug signatures was not okay: 166 | if test "$returncode" -ne "0" ; then 167 | printf "\t[%sERROR%s]\n" "$red" "$reset" 168 | printf "Exiting…\n" 169 | exit 2 170 | elif test "$returncode" -eq "0" -a -n "$valid" ; then 171 | printf "\t[%sOKAY%s]\n" "$green" "$reset" 172 | fi 173 | done 174 | printf "\n%sAll signatures for Tor Browser debug symbols downloads checked " "$green" 175 | printf "out OKAY!%s\n" "$reset" 176 | fi 177 | 178 | # Exit now if we're not extracting 179 | test -z "$do_extract" && exit 0 180 | 181 | printf "――――――――――――――――――――――――\n" 182 | 183 | for tbb in ${tbbs} ; do 184 | printf "Extracting all files for %s%s%s…\n\n" "$lavender" "$tbb" "$reset" 185 | 186 | printf "Extracting %s%s%s…\n" "$lavender" "$tbb" "$reset" 187 | tar Jxf "$tbb" 188 | 189 | for debugfile in ${debug_files} ; do 190 | printf "Extracting debug symbols from %s%s%s…\n" "$lavender" "$debugfile" "$reset" 191 | unzip -qq "$debugfile" 192 | done 193 | 194 | if test -d "Debug" ; then 195 | printf "Moving Debug/ directory to tor-browser_en-US/Debug/ …\n" 196 | mv Debug tor-browser_en-US/ 197 | fi 198 | printf "\n%sExtraction complete!%s\n" "$green" "$reset" 199 | done 200 | 201 | printf "――――――――――――――――――――――――\n" 202 | 203 | exit 0 204 | -------------------------------------------------------------------------------- /verify-riseup-server-fingerprints: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | ############################################################################## 3 | # 4 | # verify-riseup-server-fingerprints.sh 5 | # ------------------- 6 | # Download the SSL cerificates for *.riseup.net and check their fingerprints. 7 | # 8 | # @author Isis Agora Lovecruft, 0xa3adb67a2cdb8b35 9 | # @date 19 May 2013 10 | # @version 0.0.1 11 | ############################################################################## 12 | 13 | #CERTHTML='https://help.riseup.net/en/certificates#verify-these-instructions' 14 | #CERTHTML='https://help.riseup.net/en/signed-certificate-fingerprints' 15 | CERTHTML='https://help.riseup.net/en/security/network-security/certificates/riseup-signed-certificate-fingerprints.txt' 16 | RISEUP_GPG_FPR=4E0791268F7C67EABE88F1B03043E2B7139A768E 17 | KEYSERVER='hkp://keys.mayfirst.org' 18 | MAIN_CERT='riseup.net' 19 | STATUS_CERT='status.riseup.net' 20 | 21 | printf "Obtaining signed list of server fingerprints from:\n\t%s..." $CERTHTML 22 | wget -q -O - $CERTHTML | \ 23 | sed -nr '/(-){5}(BEGIN PGP SIGNED MESSAGE){1}(-){5}/,/(-){5}(END PGP SIGNATURE){1}(-){5}/p' | \ 24 | sed -e :a -e 's/<[^>]*>//g;/ riseup-fpr.sig 25 | 26 | #printf "\n\nRequesting an updated copy of Riseup's GPG key, with fingerprint" 27 | #printf "\n\t%s" $RISEUP_GPG_FPR 28 | #printf "\nfrom the keyserver at %s ...\n\n" $KEYSERVER 29 | ## update our copy of riseup's GPG key: 30 | gpg --keyid-format long --keyserver-options 'no-include-revoked no-verbose' \ 31 | --keyserver $KEYSERVER --recv-key $RISEUP_GPG_FPR >&/dev/null 32 | 33 | printf "\n\nChecking the signature on the downloaded list..." 34 | printf "\nYou should see a line which starts with: " 35 | printf "\n\t\"gpg: Good signature \"\n\n" 36 | ## check the signature on the message 37 | gpg --verify-options 'show-uid-validity show-notations' \ 38 | --verify riseup-fpr.sig 39 | 40 | cat riseup-fpr.sig | grep -B3 -a1 -Ee 'SHA-1 fingerprint' 41 | 42 | printf "\n\nDownloading the certificate for $MAIN_CERT ..." 43 | printf "\nThe certificate for $MAIN_CERT has fingerprint:\n" 44 | openssl s_client -connect ${MAIN_CERT}:443 < /dev/null 2>/dev/null | openssl x509 -fingerprint -noout -in /dev/stdin 45 | 46 | printf "\nDownloading the certificate for $STATUS_CERT ..." 47 | printf "\nThe certificate for $STATUS_CERT has fingerprint:\n" 48 | openssl s_client -connect ${STATUS_CERT}:443 < /dev/null 2>/dev/null | openssl x509 -fingerprint -noout -in /dev/stdin 49 | -------------------------------------------------------------------------------- /world_time: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env dash 2 | 3 | alias datetime="date +%H:%M" 4 | 5 | echo "What time is it in _______?" 6 | echo '~~~~~~~~~~~~~~~~~~~~~~~~~~~' 7 | echo 'SF:\t' `TZ="America/Los_Angeles" datetime` 8 | echo 'NYC:\t' `TZ="America/New_York" datetime` 9 | echo 'UTC\t' `TZ="Europe/Reijkjavik" datetime` 10 | echo 'Berlin:\t' `TZ="Europe/Berlin" datetime` 11 | echo 'Tehran:\t' `TZ="Europe/Tehran" datetime` 12 | echo 'Tokyo:\t' `TZ="Asia/Tokyo" datetime` 13 | -------------------------------------------------------------------------------- /xephyr_awesome: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # Run Awesome in a nested server for tests 3 | # 4 | # Requirements: (Debian) 5 | # 6 | # apt-get install xserver-xephyr 7 | # apt-get install -t unstable awesome 8 | # 9 | # Based on original script by dante4d 10 | # See: http://awesome.naquadah.org/wiki/index.php?title=Using_Xephyr20 11 | # 12 | # URL: http://hellekin.cepheide.org/awesome/awesome_test21 13 | # 14 | # Copyright (c) 2009 Hellekin O. Wolf 15 | # 16 | # This program is free software: you can redistribute it and/or modify 17 | # it under the terms of the GNU General Public License as published by 18 | # the Free Software Foundation, either version 3 of the License, or 19 | # (at your option) any later version. 20 | # 21 | # This program is distributed in the hope that it will be useful, 22 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 23 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 24 | # GNU General Public License for more details. 25 | # 26 | # You should have received a copy of the GNU General Public License 27 | # along with this program. If not, see . 28 | # 29 | 30 | function usage() 31 | { 32 | cat <\" \"\" \033[0m"; echo; 20 | echo -e "\033[40m\033[0;32m Download into a temporary file the video from the youtube link and \033[0m" 21 | echo -e "\033[40m\033[0;32m extracts the audio to an 128kb/s mp3 with the given name. \033[0m"; echo; 22 | echo -e "Dependencies: youtube-dl avconv \033[0m"; echo; 23 | } 24 | 25 | function dependency_check () { 26 | MISSING="" 27 | if [[ "$YOUTUBEDL_IS_INSTALLED" == "" ]]; then 28 | MISSING+="youtube-dl " 29 | fi 30 | 31 | if [[ "$AVCONV_IS_INSTALLED" == "" ]]; then 32 | MISSING+="avconv " 33 | fi 34 | 35 | if [[ "$MISSING" != "" ]]; then 36 | echo -e "\033[40m\033[1;32m Missing dependencies: ${MISSING} \033[0m" 37 | exit 1 38 | fi 39 | unset MISSING 40 | } 41 | 42 | ## $1: filename of song 43 | function store_song () { 44 | where=$1 45 | avconv -i $YOUTUBE_FILE -acodec libmp3lame -ac 2 -ab 128k \ 46 | -vn -y $HOME/music/${where} 47 | } 48 | 49 | function cleanup () { 50 | if test -w $YOUTUBE_FILE ; then 51 | rm $YOUTUBE_FILE 52 | fi 53 | } 54 | 55 | if [[ "$#" == "0" ]] || [[ "$#" == "1" ]] ; then 56 | usage 57 | exit 1 58 | elif [[ "$#" == 2 ]]; then 59 | 60 | dependency_check 61 | 62 | YOUTUBE_URL=$1 63 | YOUTUBE_FILE=${HOME}/.youtube-dl-${RANDOM}-${RANDOM}.flv 64 | SONG_FILE=$2 65 | 66 | youtube-dl --output=$YOUTUBE_FILE --format=18 "$YOUTUBE_URL" 67 | 68 | if ! test -r $HOME/music/${SONG_FILE} ; then 69 | #ffmpeg -i $YTFILE -acodec libmp3lame -ac 2 -ab 128k -vn -y $HOME/music/"$2" 70 | ## XXX we're supposed to switch to using avconv from libav-tools 71 | store_song $SONG_FILE 72 | else 73 | read -ep"Please choose a different location: \033[0m" where 74 | 75 | if ! test -r $HOME/music/${where} ; then 76 | store_song $where 77 | else 78 | read -ep"File exists, overwrite? (Y/n) \033[0m" choice 79 | case $choice in 80 | n | N ) 81 | echo "Exiting..." 82 | cleanup 83 | exit 0 84 | ;; 85 | * ) 86 | echo "Overwriting ${where}..." 87 | store_song $where 88 | ;; 89 | esac 90 | fi 91 | fi 92 | 93 | cleanup 94 | exit 0 95 | 96 | else 97 | usage 98 | exit 1 99 | fi 100 | --------------------------------------------------------------------------------