# tinyp2p.py 1.0 (documentation at http://freedom-to-tinker.com/tinyp2p.html)
import sys, os, SimpleXMLRPCServer, xmlrpclib, re, hmac # (C) 2004, E.W. Felten
ar,pw,res = (sys.argv,lambda u:hmac.new(sys.argv[1],u).hexdigest(),re.search)
pxy,xs = (xmlrpclib.ServerProxy,SimpleXMLRPCServer.SimpleXMLRPCServer)
def ls(p=""):return filter(lambda n:(p=="")or res(p,n),os.listdir(os.getcwd()))
if ar[2]!="client": # license: http://creativecommons.org/licenses/by-nc-sa/2.0
myU,prs,srv = ("http://"+ar[3]+":"+ar[4], ar[5:],lambda x:x.serve_forever())
def pr(x=[]): return ([(y in prs) or prs.append(y) for y in x] or 1) and prs
def c(n): return ((lambda f: (f.read(), f.close()))(file(n)))[0]
f=lambda p,n,a:(p==pw(myU))and(((n==0)and pr(a))or((n==1)and [ls(a)])or c(a))
def aug(u): return ((u==myU) and pr()) or pr(pxy(u).f(pw(u),0,pr([myU])))
pr() and [aug(s) for s in aug(pr()[0])]
(lambda sv:sv.register_function(f,"f") or srv(sv))(xs((ar[3],int(ar[4]))))
for url in pxy(ar[3]).f(pw(ar[3]),0,[]):
for fn in filter(lambda n:not n in ls(), (pxy(url).f(pw(url),1,ar[4]))[0]):
(lambda fi:fi.write(pxy(url).f(pw(url),2,fn)) or fi.close())(file(fn,"wc"))
TinyP2Pは15行のコードからなる、実際に使用可能なピアツーピア(P2P)型ファイル共有アプリケーションである。プログラミング言語Pythonで書かれている。 TinyP2Pが作られた目的は、ピアツーピア・アプリケーションに対する規制の難しさを示すためである。P2Pアプリケーションは非常にシンプルにでき、そこそこの技能を備えたプログラマならば誰でも書くことができるため、書かれたコードを禁止しようとする試みに効果は望めないだろう。
(各行は80字以下。最初の1行は人間用のラベルでコンピュータには無視されるため含めない。)
私がこのプログラムを書いた目的は著作権侵害を助長することではない。私は著作権侵害を容認していない。 このプログラムの設計のいかなる部分も、著作権を侵害するファイルの共有に最適化されてはいない。 このプログラムが有用なのは主にコンセプトの実証としてである。 もっと実用的なプログラムはより速く、より安全で、よりエラーに強くなるだろう――が、それにはもう何行か必要だ。
TinyP2Pのプログラムはここからダウンロードできる: http://www.freedom-to-tinker.com/tinyp2p.py.
このプログラムは、友人や同僚グループ内でファイルを共有するために使えるスモールワールド・ネットワーク(small-world network)を構築する。 大規模なネットワークには不向きだが、多数の小ネットワークを共存させることができる。 各ネットワークはパスワードで保護され、パスワードを知っている者だけがアクセスできる。 (ただし、通信を盗聴できるアタッカーからは安全ではない)。
本プログラムは標準的な通信プロトコルであるHTTPおよびXML-RPCを使用する。 HTTPはウェブブラウザがページを取得するために使われるのと同じプロトコルであり、XML-RPCはウェブサービスで広く利用されている。
本プログラムはサーバかクライアントいずれかのモードで作動する。
サーバとして実行されたときは指定された他サーバと接続し、カレントディレクトリにあるすべてのファイルを同一ネットワーク内のユーザに対してダウンロード可能にする。
(サーバ稼働中に共有ディレクトリに追加されたファイルは直ちにダウンロード可能になる)。
サーバとして実行するには以下のコマンドをタイプする:
python tinyp2p.py password server hostname
portnum [otherurl]
passwordはネットワークのパスワードであり、hostnameとportnumはサーバが接続を受け付けるURLを構成するために使われる
(http://hostname:portnum)。
省略可能なotherurlには、すでに他のネットワークで稼働している他サーバのアドレスを指定できる。
(otherurlはサーバを他のネットワークに接続するために使われる。
省略した場合は新しいネットワークが作成される。)
クライアントとして実行するには以下のコマンドを使う:
python tinyp2p.py password client
serverurl pattern
passwordは接続するネットワークのパスワード。serverurlはネットワークを構成するサーバのURL。
patternには任意の文字列を指定する。このコマンドはネットワークを構成するすべてのサーバ上のすべてのファイルを走査する。
ファイルは2つの条件:(a) ファイル名がpatternを含み、かつ(b) カレントディレクトリに既に同名のファイルが存在しない、
が満たされた場合にダウンロードされ、カレントディレクトリに保存される。
(スーパーハカー諸氏へ:patternにはPythonの正規表現が使える。ファイル名の検索にはreライブラリのre.searchが使われる。)
同じディレクトリでサーバとクライアントを同時に実行している場合、クライアントがダウンロードしたファイルは自動的にサーバによって共有されることに注意。 状況によってこれは望ましい動作ではないかもしれない。 また、それぞれ別のネットワークに属する複数のサーバを同一のディレクトリで実行することもできる。
