From af38cb02a9ca95b20056bc92e73fe72a45d1f523 Mon Sep 17 00:00:00 2001 From: Peter Wu Date: Tue, 23 Apr 2013 18:59:15 +0200 Subject: Initial checkin. --- build-chroot | 116 +++++++++++++++++++++++++++++++++++++++++++++++++ cert-info | 128 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ find-libs | 44 +++++++++++++++++++ kde-logout | 16 +++++++ socket-info | 84 +++++++++++++++++++++++++++++++++++ tabize | 30 +++++++++++++ tmp-upload | 124 ++++++++++++++++++++++++++++++++++++++++++++++++++++ udpsoundserver.py | 98 +++++++++++++++++++++++++++++++++++++++++ xstat | 21 +++++++++ 9 files changed, 661 insertions(+) create mode 100755 build-chroot create mode 100755 cert-info create mode 100755 find-libs create mode 100755 kde-logout create mode 100755 socket-info create mode 100755 tabize create mode 100755 tmp-upload create mode 100755 udpsoundserver.py create mode 100755 xstat diff --git a/build-chroot b/build-chroot new file mode 100755 index 0000000..cd608e6 --- /dev/null +++ b/build-chroot @@ -0,0 +1,116 @@ +#!/bin/bash +VERSION=0.1 +find_libs=~/scripts/find-libs +usage() { + cat < + +Usage: $0 [OPTION] file... + +Options: + -n, --dry-run Do not copy files, just print the action that would be + performed. + -d DIR, --destdir DIR Destination directory for the files. + -c, --continue Continue even if a given file cannot be located. + -h, --help Print this help text, then exit. + --version Prints the version of this program, then exit. + +Environment: + DESTDIR If --destdir is not given, this environment variable is sought. If + this variable does not exist either, a temporary directory is + created which is printed on termination. +HELP +} + +opts=`getopt --name "$0" -o nd:ch \ + --longoptions dry-run,destdir:,continue,help,version \ + -- "$@"` +if [ $? != 0 -o -z "$opts" ]; then + usage + exit 1 +fi +eval set -- "$opts" + +DRY_RUN=false +CONT_ON_ERR=false +while :; do + case "$1" in + -n|--dry-run) DRY_RUN=true ;; + -d|--destdir) DESTDIR="$2" ; shift ;; + -c|--continue) CONT_ON_ERR=true ;; + -h|--help) usage; exit 0 ;; + --version) echo "$VERSION" ; exit 0 ;; + --) shift; break ;; + *) echo "Internal error!"; exit 1 ;; + esac + shift +done + +if [ $# -eq 0 ]; then + echo "Need at least one binary or library to isolate." + echo "Try '$0 --help' for more information." + exit 1 +fi + +subjects=() +for subject; do + realsubject="$subject" + #realsubject="$(readlink -e "$subject")" + [ -e "$realsubject" ] || realsubject="$(which "$subject" 2>/dev/null)" || true + if [ -n "$realsubject" ]; then + subjects[${#subjects[@]}]="$realsubject" + else + echo "Missing file: $subject" + fi +done + +if ! [ $# = ${#subjects[@]} ]; then + echo "Some files could not be found" + echo "Expected $#, got ${#subjects[@]} valid args." + if ! $CONT_ON_ERR; then + echo "Aborting. To ignore this, pass the '--continue' option." + exit 255 + fi +fi + +info="$("$find_libs" "${subjects[@]}")" +echo "$info" +count=${info%% *} +filelist="${info#* }" + +try_install() { + local file="$1" + # target without leading ../../etc + local target="$DESTDIR/$(sed 's,\(\.\./\)*,,' <<<"$file")" + if [ ! -e "$target" ]; then + if $DRY_RUN; then + echo "Installing $file" + else + install -v -D "$file" "$target" + fi + fi +} +if [ $count -gt 0 ]; then + tmpdir= + if [ -z "$DESTDIR" ]; then + tmpdir="$(mktemp -d)" + DESTDIR="$tmpdir" + fi + umask 002 + while read file; do + try_install "$file" + done < "$filelist" + [ -z "$tmpdir" ] || rmdir --ignore-fail-on-non-empty "$tmpdir" +else + echo "No files to copy" +fi +for subject in "${subjects[@]}"; do + try_install "$subject" +done +rm "$filelist" diff --git a/cert-info b/cert-info new file mode 100755 index 0000000..b4aa9b1 --- /dev/null +++ b/cert-info @@ -0,0 +1,128 @@ +#!/bin/bash +# see also Docs/ssl-infos/tools/ +# i= &&tail -n+$((i*5000)) /tmp/top-1m.csv | head -5000 |~/scripts/cert-info csv $i +# killall -v cert-info -s 0 +usage() { + [ -z "$1" ] || echo "$1" >&2 + echo "Usage: $0 [options] hostname[:port] [hostname[:port]].." >&2 + echo " $0 csv out-dir &2 + echo "options (may be interleaved between hosts):" + awk '/^parse_arg\(/{p=1} + /}/{if(p)exit} + /#/{if(p){sub(/\).*# */,"\t");print}}' "$0" + echo "csv file from http://s3.amazonaws.com/alexa-static/top-1m.csv.zip" + exit 1 +} + +auto_less() { + [ ! -t 1 ] || { "$0" "$@" | less; exit $?; } +} + +main() { +if [ "$1" = "csv" ]; then + [ $# -ge 2 ] || usage "Missing outdir" + outdir="${2:-.}/" + mkdir -p "$outdir" + tmp=$(mktemp); trap "rm -f $tmp" EXIT + shift 2 + for arg; do parse_arg "$arg" || usage "Unrecognized option $arg"; done + i=0 + while IFS=,; read -r no host; do + # strip path if any + host="${host%%/*}" + [ -n "$host" ] || continue + outfile="$outdir$host.txt" + if [ -e "$outfile" ]; then + echo "Skipping existing $outfile" + else + printf "%5d %s %6d %s\n" $((++i)) "$(date -R)" "$no" "$host" + get_cert "$host" 443 | parse_cert > "$tmp" 2>&1 + mv "$tmp" "$outfile" + #[ -s "$outfile" ] || echo "# no cert for $host" + fi + done +elif [ ! -t 0 ]; then + auto_less "$@" + for arg; do + parse_arg "$arg" || : + done + parse_cert +elif [ $# -gt 0 ]; then + auto_less "$@" + for arg; do + ! parse_arg "$arg" || continue + host="${arg%%:*}" + port="${arg##*:}" + [ "$port" != "$arg" -a -n "$port" ] || port=443 + echo "# === $host:$port ===" + get_cert "$host" "$port" | parse_cert + done +else + usage +fi +} + +get_cert() { + local host="$1" port="$2" + if ! nc -z -w 2 "$host" "$port"; then + echo "# conn timeout for $host:$port!" >&2 + return 1 + fi + /dev/null \ + timeout 5 openssl s_client -connect "$host:$port" -showcerts +} + +parse_arg() { + case "$1" in + -) depth_1=1 ;; # less certificates [def] + +) depth_1=0 ;; # more certificates + -=) cert_only=1 ;; # less output (just raw cert) + +=) cert_only=0 ;; # more output (verbose details) [def] + -cert) include_cert=0 ;; # hide raw cert (-noout) + +cert) include_cert=1 ;; # include raw cert [def] + *) return 1 ;; + esac +} +parse_arg - +parse_arg += +parse_arg +cert + +parse_cert() { + infocmd="openssl x509 -text -nameopt sep_comma_plus_space" + [ $include_cert -eq 1 ] || infocmd="$infocmd -noout" + awk -vOneOnly="$depth_1" -vCertOnly="$cert_only" \ + -vinfocmd="$infocmd" ' +BEGIN { + sep="# "; + for (i=0; i<77; i++) { + sep=sep"-"; + } +} +/^-----BEGIN CERTIFICATE-----$/ { + in_cert=1; +} +{ + if (in_cert) { + cert = cert $0 "\n"; + } +} +/^-----END CERTIFICATE-----$/ { + in_cert = 0; +} +{ + if (!in_cert && cert) { + if (CertOnly) { + print cert; + } else { + print cert | infocmd; + close(infocmd); + print sep; + } + cert=""; + if (OneOnly) exit; + } +} +' +} + +main "$@" diff --git a/find-libs b/find-libs new file mode 100755 index 0000000..575490d --- /dev/null +++ b/find-libs @@ -0,0 +1,44 @@ +#!/bin/bash +libs="$(mktemp)" + +dbg() { + [ -z "$DEBUG" ] || echo "$*" >&2 +} + +# prints all libraries directly depending on a binary / library +find_libs() { + local file="$1" + # regular libs + ldd "$file" | awk -F'> | \\(' '{if($2 ~ "^/")print $2}' | sort -u +} + +# returns 1 if a library was known before, 0 otherwise +add_lib() { + local lib="$1" + if ! grep -q -x -F "$lib" "$libs"; then + dbg "Adding $lib" + echo "$lib" >> "$libs" + return 0 + fi + return 1 +} +recurse_find_libs() { + local file="$1" + dbg "Checking $file" + while read lib; do + if add_lib "$lib"; then + recurse_find_libs "$lib" + fi + done < <(find_libs "$file") + dbg "Done with $file" +} + +for bin; do + # ld-linux.so + while read lib; do + add_lib "$lib" || true + done < <(ldd "$bin" | awk '/^[ \t]*\//{print $1}') + recurse_find_libs "$bin" +done + +wc -l "$libs" diff --git a/kde-logout b/kde-logout new file mode 100755 index 0000000..dee150a --- /dev/null +++ b/kde-logout @@ -0,0 +1,16 @@ +#!/bin/sh +# x = 0 = noconfirm, 1 = confirm +# 0 2 0 = shutdown +# 0 1 0 = restart +# 0 0 0 = logoff? +case $1 in +l*) action=0 ;; +r*) action=1 ;; +s*) action=2 ;; +*) + echo "Usage: $0 {logout|restart|shutdown}" + exit 1 + ;; +esac + +qdbus org.kde.ksmserver /KSMServer org.kde.KSMServerInterface.logout 0 $action 0 diff --git a/socket-info b/socket-info new file mode 100755 index 0000000..5c066ea --- /dev/null +++ b/socket-info @@ -0,0 +1,84 @@ +#!/bin/bash +# Prints information about a file descriptor socket +# Author: Peter Wu +# Date: 2013-02-06 + +rootcmd=sudo + +sockno=$1 +pipeno= + +sockfd=$(readlink "$1") +if [[ $sockfd =~ ^socket:\[[0-9]+\]$ ]]; then + sockno=${sockfd#socket:[} + sockno=${sockno%]} +fi + +# not a socket but a pipe +if [[ $sockfd =~ ^pipe:\[[0-9]+\]$ ]]; then + pipeno=${sockfd#pipe:[} + pipeno=${pipeno%]} + find /proc/[0-9]*/fd -lname "pipe:\\[$pipeno\\]" -ls 2>/dev/null | \ + awk -F/ '{ + pid=$3; + print ""; + print; + system("ps huwwp " pid); + }' + exit +fi + +if ! [[ $sockno =~ ^[0-9]+$ ]]; then + echo "Numeric socket number required" >&2 + exit 1 +fi + +# expects: $prot $sockno +# arg1: field index for inode +find_by_inode() { + &2 + return 1 + fi + done + + $rootcmd gdb -q "$vmlinux" /proc/kcore \ + -ex "p ((struct unix_sock*)0x$addr)->peer" -ex q \ + | grep -Po '\(struct sock \*\) 0x\K[0-9a-f]+' +} + +line= +for prot in udp tcp; do + line=$(find_by_inode 10) + [ -z "$line" ] || break +done + +if [ -z "$line" ]; then + prot=unix + line=$(find_by_inode 7) + addr=$(cut -d: -f1 <<<"$line") + find_by_inode 7 + if [[ $addr =~ ^[0-9a-f]+$ ]]; then + addr2=$(find_other_sock $addr) + line2=$(grep "^$addr2:" /proc/net/$prot) + [ -z "$line2" ] || line="$line"$'\n'"$line2" + fi +fi + +if [ -n "$line" ]; then + (head -1 /proc/net/$prot; + echo "$line") | column -t + exit 0 +fi + +echo "No info found for $sockno [$sockfd]" diff --git a/tabize b/tabize new file mode 100755 index 0000000..467581a --- /dev/null +++ b/tabize @@ -0,0 +1,30 @@ +#!/bin/sh +# Input: space-separated +column -t \ +| sed 's/ */&| /g' \ +| tac | awk 'BEGIN { + s=""; + line=""; +} +{ + if (line) print line; + if (s == "") { + split($0, chars, ""); + for (i=1; i<=length(chars); i++) { + if (chars[i] == "|") + s=s "+"; + else + s=s "-"; + } + } else { + while (length(s) < length($0)) { + s = s "-"; + } + } + line = $0; +} +END { + print s; + s=""; + print line; +}' | tac diff --git a/tmp-upload b/tmp-upload new file mode 100755 index 0000000..913c129 --- /dev/null +++ b/tmp-upload @@ -0,0 +1,124 @@ +#!/bin/bash +host=0.0.0.0 +port=1111 + +out="$(mktemp /tmp/tmp-upload-php.XXXXXXXX)" +cleanup() { + rm -v "$out" +} +trap cleanup EXIT + +# wrap +startline=$(grep -hn -F -m 1 "# stuff ""below" "$0" | cut -d: -f1) +tail -n+$((startline+1)) "$0" > "$out" + +php -d post_max_size=128M -d upload_max_filesize=128M \ + -S "$host:$port" "$out" +exit +# stuff below +file($file); + } + return false; +} + +$url = $_SERVER['REQUEST_URI']; +if ($url != '/') { + /* Simply returning false causes PHP to parse (index).php. Unwanted, + * therefore serve it here. First check whether the path is within the + * current working directory, then whether the file exists or not. */ + $cwdir = realpath("."); + if ($cwdir === FALSE) { + http_response_code(500); + exit; + } + + $path = realpath("." . $url); + if ($path === FALSE) { + http_response_code(404); + exit; + } + if (strpos($path, $cwdir . DIRECTORY_SEPARATOR) !== 0) { + http_response_code(403); + exit; + } + + /* determine content type and size in bytes */ + $filesize = filesize($path); + $mimetype = get_mime_type($path); + if (!$mimetype) { + http_response_code(500); + exit; + } + + header("Content-Type: $mimetype"); + if ($filesize !== false) { + header("Content-Length: $filesize"); + } + + readfile($path); + exit; +} + +$msg = NULL; +if (isset($_FILES["file"]["name"])) { + $name = trim(basename($_FILES["file"]["name"]), "."); + if (!$name) { + $msg = "No filename is given!"; + } else if (!$_FILES["file"]["size"]) { + $msg = "I do not accept empty files!"; + } else { + $filename = $name; + for ($i=1; file_exists($filename); $i++) { + $filename = "$filename.$i"; + } + if (move_uploaded_file($_FILES["file"]["tmp_name"], $filename)) { + $msg = "File is saved as " . htmlspecialchars($filename); + } else { + $msg = "File could not be saved."; + } + } +} +?> + + + +
+ + +
+$msg

"; + +?> +
+
+isDot()) {
+		continue;
+	}
+	$filename = $f->getFilename();
+	$len = mb_strlen($filename);
+	if ($len > 50) {
+		$dispName = mb_substr($filename, 0, 47) . '..>';
+	} else {
+		$dispName = $filename;
+	}
+
+	printf('%s%s %s %20d' . "\n",
+		htmlspecialchars($filename),
+		htmlspecialchars($dispName),
+		str_repeat(' ', max(0, 50 - $len)),
+		date('d-M-Y H:i', $f->getMTime()),
+		$f->getSize()
+		);
+}
+?>
+
diff --git a/udpsoundserver.py b/udpsoundserver.py new file mode 100755 index 0000000..f8e7c58 --- /dev/null +++ b/udpsoundserver.py @@ -0,0 +1,98 @@ +#!/usr/bin/env python + +"""Listen on a UDP port and play a sound when 'M' is received + +Starts the server listening on UDP port PORT (3533 by default) on address HOST +(by default all addresses). Valid commands are: +M - play Music +S - Stop the server +""" +try: + import socketserver +except ImportError: + import SocketServer as socketserver +from os import system,getpid +import threading +import sys + +# leave it empty to listen on all addresses +HOST = "" +PORT = 3533 + + +class UDPSvr(socketserver.BaseRequestHandler): + def handle(self): + data = self.request[0] + if sys.version >= '3': + data = str(data, "ISO-8859-1") + data = data.strip() + if data == "M": + ding.dong() + elif data == "S": + ding.die() + +class Worker(threading.Thread): + def __init__(self): + threading.Thread.__init__(self) + self.daemon = True + def run(self): + server.serve_forever(); + +class Handler(threading.Thread): + def __init__(self): + threading.Thread.__init__(self) + self.daemon = True + self.play = False + self.must_die = False + + def run(self): + self.event = threading.Event() + while True: + self.event.wait(1.) + if self.event.isSet(): + if self.play: + print("Playing...") + system("paplay /usr/share/sounds/KDE-Im-Irc-Event.ogg") + # no else if to allow shutdown signals + if self.must_die: + print("Shutting down...") + server.shutdown() + break + self.play = False + self.event.clear() + + def dong(self): + self.play = True + self.event.set() + + def die(self): + self.must_die = True + self.event.set() + +def ca(num, x): + print("Caught SIGINT, shutting down...") + ding.die() + +import signal +if __name__ == "__main__": + print("My PID is: " + str(getpid())) + + if len(sys.argv) > 1: + HOST = sys.argv[1] + if len(sys.argv) > 2: + PORT = int(sys.argv[2]) + + print("Host: " + HOST) + print("Port: " + str(PORT)) + server = socketserver.UDPServer((HOST, PORT), UDPSvr) + + ding = Handler() + signal.signal(signal.SIGINT, ca) + worker = Worker() + ding.start() + worker.start() + # might not be the cleanest, but it allows Ctrl + C + while ding.isAlive(): + ding.join(3600) + +# vim: set expandtab shiftwidth=4: diff --git a/xstat b/xstat new file mode 100755 index 0000000..d37c090 --- /dev/null +++ b/xstat @@ -0,0 +1,21 @@ +#!/bin/sh +file="$1" +file="$(readlink -f "$file")" +dir="$file" +dev= + +while [ -n "$dir" ] && [ -z "$dev" ]; do + dev=$(awk -vd="$dir" '{if($2 == d && substr($1, 1, 1) == "/")print $1}' &2 +fi -- cgit v1.2.1