From: Mark Wooding Date: Fri, 15 Apr 2016 18:53:37 +0000 (+0100) Subject: Update automatically managed build utilities. X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~mdw/git/preload-hacks/commitdiff_plain/e6ecd2c12033354c49a8bf67d0815b7e7a23e2ab?hp=85b8dbe6c9e505a3d37769d03af0af374bed47f7 Update automatically managed build utilities. --- diff --git a/.gitignore b/.gitignore index 7ae0ae4..abef1d9 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,5 @@ build noip uopen COPYING +*.o +auto-version diff --git a/.links b/.links index 5ecd9c6..89b2d6f 100644 --- a/.links +++ b/.links @@ -1 +1,2 @@ COPYING +auto-version diff --git a/Makefile b/Makefile index f69375a..c8424a3 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ PACKAGE = preload-hacks -VERSION = 1.0.1 +VERSION := $(shell ./auto-version) prefix = /usr/local exec_prefix = ${prefix} @@ -10,8 +10,10 @@ man1dir = ${mandir}/man1 CC = gcc LD = gcc -CFLAGS = -O2 -g -fPIC -Wall -LDFLAGS = -shared +CFLAGS = -O2 -g -Wall +LDFLAGS = +REAL_CFLAGS = $(CFLAGS) -fPIC +REAL_LDFLAGS = $(LDFLAGS) -shared LDLIBS = -ldl INST_BIN = install -c -m755 INST_LIB = install -c -m644 @@ -27,11 +29,11 @@ TARGETS = $(LIBS) $(SCRIPTS) SOURCES = noip.c uopen.c withlib.in all: $(TARGETS) %.o: %.c - $(CC) -c $(CFLAGS) $< -o $@ + $(CC) -c $(REAL_CFLAGS) $< -o $@ noip.so: $(patsubst %.c, %.o, noip.c) - $(LD) $(LDFLAGS) $< $(LDLIBS) -o $@ + $(LD) $(REAL_LDFLAGS) $< $(LDLIBS) -o $@ uopen.so: $(patsubst %.c, %.o, uopen.c) - $(LD) $(LDFLAGS) $< $(LDLIBS) -o $@ + $(LD) $(REAL_LDFLAGS) $< $(LDLIBS) -o $@ $(SCRIPTS): withlib.in for i in $(SCRIPTS); do \ sed "s/@lib@/$$i/" withlib.in >$$i.new || exit 1; \ @@ -53,7 +55,8 @@ DISTTAR = $(DISTDIR).tar.gz distdir: rm -rf $(DISTDIR) mkdir $(DISTDIR) - ln $(SOURCES) $(MAN1) Makefile COPYING $(DISTDIR) + ln $(SOURCES) $(MAN1) Makefile COPYING README auto-version $(DISTDIR) + echo $(VERSION) >$(DISTDIR)/RELEASE mkdir $(DISTDIR)/debian ln debian/rules debian/copyright debian/changelog debian/control \ debian/*.install $(DISTDIR)/debian diff --git a/README b/README new file mode 100644 index 0000000..980f5a4 --- /dev/null +++ b/README @@ -0,0 +1,268 @@ +PRELOAD-HACKS +~~~~~~~~~~~~~ + +What is it? + + The preload-hacks distribution contains a couple of LD_PRELOAD- + able libraries which I find very useful. Well, one useful one, + and one which is really handy in theory. + + uopen Traps when a process is trying to open(2) a Unix-domain + socket, and does the appropriate socket(2)/connect(2) + dance instead. I've no idea why it doesn't work like + this in the first place. + + noip Traps when a process is trying to make an Internet + socket, and makes a Unix-domain socket instead. + + The first one is the one which is useful in theory but I've not + really made much use of in practice. + + +uopen + + The main use-case is variable signatures. Many mail and news + clients nowadays have built-in sigmonsters, which choose a + .signature at random from a collection. Some don't, of course, + which is a shame. It would be nice if the sigmonster was + detachable, so you could just write a sigmonster and attach it + to your favourite newsreader. It would extra nice if + newsreaders (and mail clients) don't have to use some kind of + weirdo sigmonster interface just to do this stupid thing with + .signatures. + + All mail and news clients know how to read a .signature file. + It's why it's got that name. So the right answer seems to be to + make this file magically have different contents each time it's + read. Noticing when someone tries to read a regular file is + just awful so let's not think about that idea any more. We + could make .signature be a named pipe; but named pipe servers + are very difficult to get right when there are multiple + simultaneous clients. Sockets are, of course, the right answer + when client/server architectures come up. And we've got a + convenient way of stashing sockets in the filesystem: PF_UNIX + sockets. + + So, we write our sigmonster: + + $ fwd -d from unix:$HOME/.signature to exec.fortune + + And now we check to see whether it works. + + $ cat ~/.signature + cat: /home/mdw/.signature: No such device or address + + Hmm. That blows. Surely it's obvious how to read from a + socket. But, no, the kernel won't do the socket/connect thing + for us. + + Enter uopen. + + $ uopen cat ~/.signature + Noise proves nothing. Often a hen who has merely laid an egg + cackles as if she laid an asteroid. + -- Mark Twain + + Joy! + + This isn't perfect. The file is weird and not a proper file. + Emacs will refuse to visit it as a result. But it /will/ + happily insert the contents of the file into existing buffers. + Hopefully other editors are similar. `less' wants the -f option + before it will bother. But actually it works pretty well. + + The right place for the functionality of uopen is in the kernel. + It shouldn't be difficult. I even submitted a patch to the + Linux kernel list to do precisely that, once, back in the days + of 2.0.x. It was ignored, and I gave up; the patch bitrotted + hopelessly. My LD_PRELOAD hack still works. There's no + configuration. It just works. + + My .signature has been `-- [mdw]' for years now, and that's + unlikely to change. So I don't actually use uopen very much. + But it's cool to know that it exists. + + +noip + + The basic idea + + This I use every day. All the time. Here's the use case. + We'll see some more examples later. + + Some random program has a client/server split between the main + guts of the thing and its user interface, and the two + communicate over TCP sockets. There are lots of examples: SLIME + (the Superior Lisp Interaction Mode for Emacs) runs a Common + Lisp system as a separate process. The SAGE notebook runs a web + server and you're meant to use a Javascript-supporting web + browser to drive it. All sorts of stuff. Usually the + programmer knew just enough to remember to bind the server's + listening socket to 127.0.0.1, to stop everyone on the Internet + from connecting, but often the security consciousness stops + there. If you're very lucky, there's some sort of password + mechanism. + + The problem, of course, occurs on a multi-user system. Binding + to localhost doesn't stop any other user of the same machine + from connecting. In the cases of SLIME and SAGE, this is a big + problem: both provide a full programming environment + (respectively Common Lisp and Python) which would let an + attacker do anything he likes in your name. + + Passwords are wretched as a security mechanism. Besides, I + shouldn't need a damned password to talk to one of my own + processes from another one of my own processes! The operating + system should be able to ensure that processes owned by the same + user can communicate securely. There's a whole filesystem with + access control and everything. + + The right answer is to use Unix-domain sockets, which live in + the filesystem and have proper access control applied to them. + But programmers are lazy, and Unix-domain sockets don't exist on + Windows (well, unless you install Cygwin, but I can see why + that's an unpopular idea). + + The noip LD_PRELOAD hack intercepts the socket(2) system call. + If the process is asking for a PF_INET socket, then it hands out + a PF_UNIX socket instead. If the process tries to bind(2) its + socket to 127.0.0.1:12345, say, then noip binds it to + /tmp/noip-USER/127.0.0.1:12345 instead (having previously + created the directory /tmp/noip-USER and made sure that nobody + else can get to it). If the process tries to connect(2) + somewhere, noip fixes up the address. The noip hack intercepts + 14 different system calls in order to prevent its systematic + dishonesty from being discovered. + + Configuration + + Running a program under noip effectively only allows it to talk + to other programs running under noip. This is sort of the idea, + but it's rather restrictive in practice. I can happily run + + $ noip emacs + + and start up SLIME, and Emacs and SLIME will communicate + securely over a Unix-domain socket without either of them + noticing. But now Emacs can't talk to anything other than + SLIME, which makes w3m-el less useful than it used to be, and, + worse, my Common Lisp programs can't talk to anything external + either, which may make writing network-aware Lisp programs + annoying. + + It gets worse with SAGE. I can run + + $ noip sage -notebook + + and in another window + + $ noip iceweasel http://localhost:8000/ + + (or Firefox, on Ubuntu), and the two will communicate happily. + But now my Iceweasel is crippled and can't actually talk to the + rest of the Internet. The point of the exercise was to make my + SAGE process secure, not to make me run two copies of Iceweasel + and have to cope with the inevitable profile fork. + + So noip can be configured. It still defaults to safety: + whenever the process asks for a new Internet socket, noip hands + it a fake plastic Unix-domain socket instead. But when the + process tries to bind or connect its socket, noip will look the + address up in a list decide what to do. If the result comes + back `allow', then noip will do a three-card Monte, rustling up + a real PF_INET socket and replacing the plastic imitation; if + the result comes back `deny' then noip will continue with its + elaborate deception. + + The configuration file lives in $HOME/.noip. Mine says + something like this. + + ## standard configuration + + ## debug + realconnect +172.29.199.2:25 + realconnect +172.29.199.2:53 + realconnect +172.29.199.2:80 + realconnect +172.29.199.2:3128 + realconnect +127.0.0.1:6010-6020 + realconnect -127.0.0.0/8 + realconnect -local + + (172.29.199.2 is the IP address of the machine I took this + from.) What this says is as follows. + + * Don't produce debugging output, but let me turn it on easily + if I feel the urge. + + * Allow direct connection to my SMTP server, on port 25. (The + `+' means `allow'.) + + * Allow conversations with my local DNS server. (The noip + hack is not particularly discriminating. It replaces UDP + sockets with Unix-domain datagram sockets, just as it + replaces TCP sockets with Unix-domain stream sockets.) + + * Allow conversations with my local web server. + + * Allow conversations with my local squid proxy. + + * Allow conversations with SSH-forwarded X displays. + + * Don't allow any other communication with anything else on + the loopback network 127.0.0.0/8. (I've still no idea why + each machine needs 16 million IP addresses for talking to + itself. The `-' means `deny'.) + + * Don't allow any other communication with any of my other + local IP addresses. (noip will work out which IP addresses + are local from your network interface configuration.) + + * And finally, implicitly, allow anything else. + + The rules follow the squid convention: the default is to do + whatever the last rule didn't do, so if the last rule says + `deny' then the default is `allow', and vice versa. + + Armed with this configuration, I now routinely run both Emacs + and Iceweasel exclusively under the control of noip. And I've + done this for several years. + + SSH tricks + + SSH is made of win. Its X forwarding is lovely. Its port + forwarding divine. Almost. + + Here's a common scenario. I'm running on a multi-user server, + shared with several other people whom I don't necessarily trust. + I want to check some files out from my office's version-control + system. Traditional answer: + + $ ssh -L 12345:vcs.work.com:345 mdw@gateway.work.com + + Now I can run + + $ vcs -d localhost:12345 checkout ... + + and all works well. Of course, anyone else on the server can do + the same thing, so I've just leaked my company's secret sauce. + (I don't believe in secret sauce, but I ought to show willing.) + + How do I fix this? Easy! + + $ noip ssh -L 12345:vcs.work.com:345 mdw@gateway.work.com + + $ noip vcs -d localhost:12345 checkout ... + + And it all works. In this case, in particular, it's essential + that the /same/ SSH process binds a safe, plastic local end to + its forwarded VCS port, and is able to make a real, potentially + dangerous Internet connection to gateway.work.com. Of course, + since I run Emacs under noip anyway, all the version control + stuff that Emacs does magically find the SSH tunnel and work + without me having to care. + + +Local variables: +mode: text +fill-column: 72 +End: diff --git a/auto-version b/auto-version new file mode 100755 index 0000000..79bb44c --- /dev/null +++ b/auto-version @@ -0,0 +1,102 @@ +#! /bin/sh +### -*-sh-*- +### +### Make autoconf-like substitutions in files +### +### (c) 2008 Mark Wooding +### + +###----- Licensing notice --------------------------------------------------- +### +### This file is part of the Common Files Distribution (`common'). +### +### `Common' is free software; you can redistribute it and/or modify +### it under the terms of the GNU General Public License as published by +### the Free Software Foundation; either version 2 of the License, or +### (at your option) any later version. +### +### `Common' is distributed in the hope that it will be useful, +### but WITHOUT ANY WARRANTY; without even the implied warranty of +### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +### GNU General Public License for more details. +### +### You should have received a copy of the GNU General Public License +### along with `common'; if not, write to the Free Software Foundation, +### Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +set -e +VERSION="1.3.10.1" + +###-------------------------------------------------------------------------- +### Parse command line arguments. + +while [ $# -gt 0 ]; do + case $1 in + -h | --h | --he | --hel | --help) + cat <&2 + exit 1 + ;; + *) + break + ;; + esac + shift +done + +if [ $# -ne 0 ]; then + echo >&2 "Usage: auto-version" + exit 1 +fi + +###-------------------------------------------------------------------------- +### Main program. + +## If this is a Git checkout then Git should be able to identify the version. +if [ -d .git ] && version=$(git describe --abbrev=4 2>/dev/null); then + + ## If the working tree is dirty, indicate with a `+'. + case "$(git diff-index --name-only HEAD)" in + "") ;; + *) version="$version+" ;; + esac + echo "$version" + exit 0 +fi + +## If this was unpacked from a source distribution, the RELEASE file sould +## say what the version was. +if [ -f RELEASE ]; then + cat RELEASE + exit 0 +fi + +## If we're Debianized, then the Debian changelog ought to know. +if [ -f debian/changelog ]; then + sed -n '/^.*(\(.*\)).*$/ { s::\1:p; q; }' debian/changelog + exit 0 +fi + +## Otherwise we're screwed. +echo UNKNOWN +exit 0 + +###----- That's all, folks -------------------------------------------------- diff --git a/debian/.gitignore b/debian/.gitignore index 4193c2f..48e3561 100644 --- a/debian/.gitignore +++ b/debian/.gitignore @@ -5,4 +5,6 @@ substvars *.debhelper noip uopen - +*.log +compat +stamp-* diff --git a/debian/changelog b/debian/changelog index 44c48bc..c2c0e83 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,10 @@ +preload-hacks (1.0.2) experimental; urgency=low + + * Useful README added. + * Various build system enhancements. + + -- Mark Wooding Sun, 21 Dec 2008 20:31:28 +0000 + preload-hacks (1.0.1) experimental; urgency=low * Fix noip to have more faithful error reporting. diff --git a/debian/noip.install b/debian/noip.install index 018d14a..53b5ef3 100644 --- a/debian/noip.install +++ b/debian/noip.install @@ -1,3 +1,3 @@ -usr/bin/noip -usr/lib/noip.so -usr/share/man/man1/noip.1 +debian/tmp/usr/bin/noip +debian/tmp/usr/lib/noip.so +debian/tmp/usr/share/man/man1/noip.1 diff --git a/debian/rules b/debian/rules index 6739f8f..3d24648 100755 --- a/debian/rules +++ b/debian/rules @@ -1,48 +1,11 @@ #! /usr/bin/make -f -export DH_COMPAT = 4 +CDBS = /usr/share/cdbs/1 -build: - make clean - make - touch build +include $(CDBS)/rules/debhelper.mk +include $(CDBS)/class/makefile.mk -clean: - dh_clean - make clean - -install: build - dh_clean - make install \ - prefix=/usr \ - mandir=/usr/share/man \ - DESTDIR=`pwd`/debian/tmp - dh_install --sourcedir=debian/tmp - rm -rf debian/tmp - -binary-indep: - -binary-arch: install - dh_testdir -a - dh_testroot -a - dh_compress -a - dh_installdocs -a - dh_strip -a - dh_shlibdeps -a - dh_gencontrol -a - dh_fixperms -a - dh_installdeb -a - dh_md5sums -a - dh_builddeb -a - -binary: binary-indep binary-arch - -source: - rm -rf deb-dist.tar.gz =deb= - make dist DISTTAR=deb-dist.tar.gz - mkdir =deb= - cd =deb=; tar xvfz ../deb-dist.tar.gz - d=`pwd`; cd ..; dpkg-source -i -i'/\.svn/' -b $$d/=deb=/* - rm -rf deb-dist.tar.gz =deb= - -.PHONY: binary binary-arch binary-indep clean install source +DEB_MAKE_CLEAN_TARGET = clean +DEB_MAKE_INSTALL_TARGET = install \ + prefix=/usr mandir=/usr/share/man \ + DESTDIR=debian/tmp diff --git a/debian/uopen.install b/debian/uopen.install index cb36fa7..957cd42 100644 --- a/debian/uopen.install +++ b/debian/uopen.install @@ -1,3 +1,3 @@ -usr/bin/uopen -usr/lib/uopen.so -usr/share/man/man1/uopen.1 +debian/tmp/usr/bin/uopen +debian/tmp/usr/lib/uopen.so +debian/tmp/usr/share/man/man1/uopen.1