├── .gitignore
├── COPYRIGHT
├── DONATE
├── LICENSE
├── Make.sh
├── README
├── THANKS
├── contrib
├── jsw
│ └── urcbot
│ │ └── urcbot.py
└── seekingfor
│ └── urc2server_rfc1459.py
├── db
└── urchub
│ ├── i2p
│ └── 7kmkqzx5egdannxhqt4b3fkqbo7jdjphwcf2viiph7qdqm3wlmaa.b32.i2p
│ │ ├── owner
│ │ └── port
│ ├── icann
│ ├── josephswilliams.com
│ │ ├── owner
│ │ └── port
│ └── urc.freeanons.info
│ │ ├── owner
│ │ └── port
│ └── tor
│ ├── allyour4nert7pkh.onion
│ ├── owner
│ └── port
│ ├── freeanonine7mgki.onion
│ ├── owner
│ └── port
│ ├── hppikcru545manbi.onion
│ ├── owner
│ └── port
│ └── ntwrkhhtqv73vwd4.onion
│ ├── owner
│ └── port
├── doc
├── README.bak.txt
├── URC.txt
└── topology.txt
├── env
├── addr
├── motd
├── path
├── port
└── serv
├── git-commit
├── git-push-github
├── gitd
├── install-daemontools.sh
├── install-libsodium.sh
├── install-libtai.sh
├── install-nacl.sh
├── install-ucspi-ssl.sh
├── install-ucspi-tcp.sh
├── run
├── run.log
├── run.urc2sd
├── run.urc2sd-tor
├── run.urcd-curvecp
├── run.urcd-ssl
├── scripts
├── add-curvecpconnect
├── add-curvecphubconnect
├── add-curvecphublisten
├── add-curvecplisten
├── add-curvecprecv
├── add-curvecpsend
├── add-hubconnect
├── add-hublisten
├── add-tcpconnect
├── add-tcplisten
├── add-tcprecv
├── add-tcpsend
├── add-torconnect
├── add-torhubconnect
├── add-torsend
├── add-udprecv
├── add-udpsend
├── add-urchub
├── add-urcstream2hub
├── scrubsocketdir
└── urcd.sh
├── src
├── base16.h
├── check-nacl.h
├── check-sodium.h
├── check-taia.c
├── cryptoserv.c
├── curvecpserver.c
├── dprintf.h
├── keypair.c
├── liburc.c
├── liburc.h
├── nacltaia.c
├── sign_keypair.c
├── socket_bind.c
├── tai_dec.h
├── tai_inc.h
├── taia96n.pyx
├── ucspi-client2server.c
├── ucspi-server2client.c
├── ucspi-socks4aclient.c
├── ucspi-stream.c
├── urc-udprecv.c
├── urc-udpsend.c
├── urc2sd.pyx
├── urccache-failover.c
├── urccache.c
├── urcd.pyx
├── urcd.pyx.test
├── urchub.c
├── urchubstream.c
├── urcrecv.c
├── urcrecv.pyx
├── urcsend.c
├── urcsend.pyx
├── urcstream.c
├── urcstream.pyx
└── urcstream2hub.c
└── stdin.cryptoserv
/.gitignore:
--------------------------------------------------------------------------------
1 | env
2 | log
3 | conf
4 | build
5 | urcd
6 | urc.db
7 | urc2sd
8 | urchub
9 | urcrecv
10 | urcsend
11 | urccache
12 | urcstream
13 | urchubstream
14 | urcstream2hub
15 | socket
16 | supervise
17 | stdin
18 | stdout
19 | channels
20 | auto_cmd
21 | nick
22 | ucspi-client2server
23 | ucspi-socks4aclient
24 | ucspi-stream
25 | libtai-*
26 | nacl-*
27 | check-taia
28 | nacltaia.so
29 | sign_keypair
30 | keypair
31 | conf-cc
32 | ucspi-server2client
33 | urc-udpsend
34 | urc-udprecv
35 | libsodium-0.6.0.tar.gz
36 | libsodium-0.6.0
37 | ucspi-tcp-0.88.tar.gz
38 | ucspi-tcp-0.88.tar
39 | ucspi-tcp-0.88
40 | cryptoservroot/
41 | cryptoserv
42 | taia96n.so
43 | taia96n.py
44 | liburc.so
45 |
--------------------------------------------------------------------------------
/COPYRIGHT:
--------------------------------------------------------------------------------
1 | Copyleft (c) 2015 Joseph S. Williams
2 |
--------------------------------------------------------------------------------
/DONATE:
--------------------------------------------------------------------------------
1 | BTC: 15FKo4HjiNmY1f9Z4kojqmgakjyf6YG4dn
2 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | URCd is an anonymous, decentralized, cipherchat suite with an IRCd interface :-)
2 |
3 | Copyright (C) 2015 Joseph S. Williams
4 |
5 | This program is free software: you can redistribute it and/or modify
6 | it under the terms of the GNU General Public License as published by
7 | the Free Software Foundation, either version 3 of the License, or
8 | (at your option) any later version.
9 |
10 | This program is distributed in the hope that it will be useful,
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | GNU General Public License for more details.
14 |
15 | You should have received a copy of the GNU General Public License
16 | along with this program. If not, see .
17 |
--------------------------------------------------------------------------------
/Make.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh -v
2 |
3 |
4 | # URCd requires user urcd
5 | if ! su urcd -c exit 0 ; then
6 | useradd urcd
7 | fi
8 |
9 |
10 | # Ivo's libnacl.so will break NaCl softwares
11 | if [ -e '/usr/lib/libnacl.so' ]; then
12 | echo $0': fatal error: move /usr/lib/libnacl.so temporarily' 1>&2
13 | exit 255
14 | fi
15 |
16 |
17 | # you can add gcc options to conf-cc
18 | touch conf-cc
19 |
20 |
21 | # configure a suitable python development library
22 | if ! which python-config; then
23 | if ! which python2.7-config; then
24 | echo $0': fatal error: no suitable python development files exist' 1>&2
25 | exit 255
26 | fi
27 | python_config=python2.7-config
28 | else python_config=python-config
29 | fi
30 |
31 | PYTHON_INCLUDE=`$python_config --includes` || exit 1
32 | PYTHON_LIBRARY=`$python_config --libs` || exit 1
33 |
34 |
35 | # OpenBSD and NetBSD need these paths
36 | export CPATH="/usr/pkg/include:/usr/local/include:$CPATH"
37 | export LIBRARY_PATH="/usr/pkg/lib:/usr/local/lib:$LIBRARY_PATH"
38 |
39 |
40 | # Support libsodium fanboys
41 | if gcc src/check-nacl.h -o /dev/null 2>/dev/null ; then
42 | src='src'
43 | nacl='nacl'
44 | test -e /usr/lib/randombytes.o && \
45 | randombytes=/usr/lib/randombytes.o
46 | test -e /usr/pkg/lib/randombytes.o && \
47 | randombytes=/usr/pkg/lib/randombytes.o
48 | test -e /usr/local/lib/randombytes.o && \
49 | randombytes=/usr/local/lib/randombytes.o
50 | if [ -z $randombytes ]; then
51 | echo $0': fatal error: randombytes.o not found' 1>&2
52 | exit 255
53 | fi
54 | elif gcc src/check-sodium.h -o /dev/null 2>/dev/null ; then
55 | src='libsodium_src'
56 | nacl='sodium'
57 | rm -rf $src
58 | mkdir -p $src
59 | ### *BSD's sed doesn't have -i ###
60 | for i in `ls src/` ; do
61 | sed 's|#include $src/$i
62 | done
63 | else
64 | echo $0': fatal error: no suitable NaCl library exists' 1>&2
65 | exit 255
66 | fi
67 |
68 |
69 | # compile c programs
70 | gcc `cat conf-cc` $src/urchub.c -o urchub || exit 1
71 | gcc `cat conf-cc` $src/urc-udpsend.c -o urc-udpsend || exit 1
72 | gcc `cat conf-cc` $src/urc-udprecv.c -o urc-udprecv || exit 1
73 | gcc `cat conf-cc` $src/ucspi-stream.c -o ucspi-stream || exit 1
74 | gcc `cat conf-cc` $src/urchubstream.c -o urchubstream || exit 1
75 | gcc `cat conf-cc` $src/cryptoserv.c -o cryptoserv -l $nacl || exit 1
76 | gcc `cat conf-cc` $src/urcstream2hub.c -o urcstream2hub -l tai || exit 1
77 | gcc `cat conf-cc` $src/ucspi-client2server.c -o ucspi-client2server || exit 1
78 | gcc `cat conf-cc` $src/ucspi-server2client.c -o ucspi-server2client || exit 1
79 | gcc `cat conf-cc` $src/ucspi-socks4aclient.c -o ucspi-socks4aclient || exit 1
80 | gcc `cat conf-cc` $src/keypair.c -o keypair -l $nacl $randombytes || exit 1
81 | gcc `cat conf-cc` $src/sign_keypair.c -o sign_keypair -l $nacl $randombytes || exit 1
82 | gcc -O2 -fPIC -DPIC $src/liburc.c -shared $PYTHON_INCLUDE -o liburc.so $PYTHON_LIBRARY -l tai -l $nacl || exit 1
83 | gcc -O2 -fPIC -DPIC $src/nacltaia.c -shared $PYTHON_INCLUDE -o nacltaia.so $PYTHON_LIBRARY -l tai -l $nacl $randombytes || exit 1
84 |
85 |
86 | # compile urccache.c and check for errors
87 | gcc `cat conf-cc` $src/check-taia.c -o check-taia -l tai -l $nacl || exit 1
88 |
89 | if ! $(./check-taia >/dev/null) ; then
90 | echo $0': fatal error: (security) potential cache error 00' 1>&2
91 | exit 255
92 | else
93 | gcc `cat conf-cc` $src/urccache.c -o urccache -l tai -l $nacl $randombytes || exit 1
94 | printf '' | ./urccache `pwd`/$src/
95 | if [ $? != 1 ] ; then
96 | echo $0': fatal error: (security) potential cache error 01' 1>&2
97 | exit 255
98 | fi
99 | fi
100 |
101 |
102 | # if cython is not installed use python scripts and exit
103 | if ! which cython 2>/dev/null ; then
104 | cp $src/urcd.pyx urcd || exit 1
105 | chmod +x urcd || exit 1
106 | cp $src/urc2sd.pyx urc2sd || exit 1
107 | chmod +x urc2sd || exit 1
108 | cp $src/taia96n.pyx taia96n.py || exit 1
109 | rm -rf libsodium_src
110 | exit 0
111 | fi
112 |
113 |
114 | # compile cython programs
115 | mkdir -p build || exit 1
116 |
117 | cython --embed $src/urcd.pyx -o build/urcd.c || exit 1
118 | gcc `cat conf-cc` -O2 -c build/urcd.c $PYTHON_INCLUDE -o build/urcd.o || exit 1
119 | gcc `cat conf-cc` -O1 -o urcd build/urcd.o $PYTHON_LIBRARY || exit 1
120 |
121 | cython --embed $src/urc2sd.pyx -o build/urc2sd.c || exit 1
122 | gcc `cat conf-cc` -O2 -c build/urc2sd.c $PYTHON_INCLUDE -o build/urc2sd.o || exit 1
123 | gcc `cat conf-cc` -O1 -o urc2sd build/urc2sd.o $PYTHON_LIBRARY || exit 1
124 |
125 | cython $src/taia96n.pyx -o build/taia96n.c || exit 1
126 | gcc `cat conf-cc` -O2 -shared -pthread -fPIC -fwrapv -Wall \
127 | -fno-strict-aliasing $PYTHON_INCLUDE build/taia96n.c -o taia96n.so || exit 1
128 |
129 |
130 | # clean up
131 | rm -rf build libsodium_src || exit 1
132 |
--------------------------------------------------------------------------------
/README:
--------------------------------------------------------------------------------
1 | URCd:
2 | 10,000 genomes of human lizard hybrid soldiers being sent server to server
3 | between Angola and Luxembourg with some 70's style casual sex peering
4 | arrangement.
5 |
6 | if you want a real description view doc/*
7 |
8 | depends:
9 | NaCl or libsodium, libtai, ucspi-tcp,
10 | python(>=2.6), python-dev(>=2.6),
11 | daemontools, sh, gcc
12 |
13 | your clock needs to be as reasonably accurate, possibly by using something like
14 | ntp, otherwise your messages could be dropped from the network.
15 |
16 | recommends:
17 | NaCl instead of libsodium,
18 | cython(>=0.18.0)
19 |
20 | install:
21 | # install dependencies, if you haven't already:
22 | ./install-daemontools.sh
23 | ./install-ucspi-tcp.sh
24 |
25 | # URCd with ssl.
26 | # if you actually get it to work let me know :-/
27 | # depends on openssl, libssl-dev, perl, libperl-dev
28 | ./install-ucspi-ssl.sh
29 |
30 | # this also patches libtai for 64-bit shared objects
31 | ./install-libtai.sh
32 |
33 | # recommended over ./install-libsodium.sh:
34 | ./install-nacl.sh
35 |
36 | # OpenBSD:
37 | echo '-ftrampolines' > conf-cc
38 |
39 | ./Make.sh
40 |
41 | # edit the network/hostmask
42 | $editor env/serv
43 |
44 | # edit the motd
45 | $editor env/motd
46 |
47 | ln -s `pwd` /service/urcd
48 |
49 | echo "`pwd`/urc.db" > env/URCDB
50 | svstat /service/urcd
51 |
52 | ### create your urchub, you only need to do this once
53 | ./scripts/add-urchub
54 |
55 | CryptoServ:
56 | ln -s stdin.cryptoserv stdin
57 |
58 | hub2hub:
59 | ./scripts/add-hublisten local.urc.example.tld 6789 /service/urcd-hub0/socket/
60 |
61 | ### add peers. i recommend between 2 and 4 at the most
62 | ./scripts/add-hubconnect remote.urc.example.tld 6789 /service/urcd-hub0/socket/
63 |
64 | no censorship (security):
65 | URC networks are censorship resistant. i recommend URCSIGN and/or URCCRYPTOBOX
66 | to ignore spam and trolls. URCd will replace the user field with VERIFIED-Nick
67 | for users with valid authentication or signature verification. All other user
68 | fields will be replaced with URCD-Nick. e.g.:
69 |
70 | Nick!URCD-Nick@server
71 | Nick!VERIFIED-Nick@server
72 |
73 | irssi ("ban/except"):
74 | /ignore *!*@* ALL
75 | /ignore -except friend!*@* ALL
76 | /ignore -except *!VERIFIED-*@* ALL
77 |
78 | xchat ("ban/except"):
79 | /ignore *!*@* ALL
80 | /ignore friend!*@* ALL UNIGNORE
81 | /ignore *!VERIFIED-*@* ALL UNIGNORE
82 |
83 | Contact:
84 | Joseph S. Williams, yhpargotpyrc at gmail. Please write URCd in the subject
85 | so that I will notice it and not accidentally delete it or mark it as spam.
86 |
87 | Thanks:
88 | Thank you for using URCd. If you appreciate this project, please consider
89 | running a public URC hub, or sending a small donation. Like other darknets,
90 | URC is a stronger, safer network the more people that actively participate
91 | in building reliable nodes. Small donations help me financially, thus giving
92 | me more time to focus on this project.
93 |
--------------------------------------------------------------------------------
/THANKS:
--------------------------------------------------------------------------------
1 | Thank you to everyone that supported, encouraged, tested, debugged, donated,
2 | reported bugs, and believed in me and the URC project. This project was inspired
3 | by the AnoNet crew, and the original authors of Ricochet and the UDPMSG family
4 | of protocols that were designed for decentralized, anonymous chat. I also
5 | received a great deal of testing and support from members of FreeAnons, and some
6 | other friendly hackers that I've met online and in the real world. I wrote this
7 | project to give the people of the world, especially activists, a safer place to
8 | express themselves and their ideas among one another in a safe place, where they
9 | can be free to talk without fear of violence or physical harm, and communicate
10 | among fellow citizens of the world without being censored, or being targeted by
11 | sharing their ideas with the public. Without you, URC could not have existed,
12 | and for that I am tremendously thankful. If you appreciate this project and
13 | everything it has to offer, please consider running a public urchub, and/or
14 | a urchub that is accessible to you and your peers. Like Tor, I2P, Anonet, and
15 | other decentralized darknets, URC is stronger and safer the more nodes that are
16 | available to transmit traffic. I love you all and it is my hope you get the
17 | most from this software, and are able to use it to make the world a better place
18 | for all of us.
19 |
20 | In solidarity,
21 |
22 | Joseph S. Williams
23 |
24 |
25 | A special thanks to Epoch, LulzPrincess, SeekingFor, Ivo, Psi, Talamon, Kieko,
26 | Nyx, SomeRandomNick, RedAcor, and others that had my back and were by my side
27 | throughout this project.
28 |
29 | Also a special thanks to Daniel J. Bernstein for all of his amazing works that
30 | made this project capable. You're a brilliant man, with incredible talent.
31 |
--------------------------------------------------------------------------------
/contrib/jsw/urcbot/urcbot.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # Usage: tcpclient $urchub_addr $urchub_port python urcbot.py
3 |
4 | import liburc
5 | import sys
6 | import os
7 | import re
8 |
9 | RE = 'a-zA-Z0-9^(\)\-_{\}[\]|\\\\'
10 | re_PRIVMSG = re.compile('^:['+RE+']+![~:#'+RE+'.]+@[~:#'+RE+'.]+ PRIVMSG [#&!+]?['+RE+']+ :.*$',re.IGNORECASE).search
11 |
12 | while 1:
13 | buff = os.read(6,2+12+4+8)
14 | if len(buff) < 2+12+4+8: break
15 | while len(buff[2+12+4+8:]) != ord(buff[0])*256 + ord(buff[1]):
16 | b = os.read(6,ord(buff[0])*256 + ord(buff[1]) - len(buff[2+12+4+8:]))
17 | if not b: sys.exit(0)
18 | buff += b
19 | buff = buff[2+12+4+8:]
20 |
21 | if re_PRIVMSG(buff):
22 | src = buff[1:].split('!',1)[0]
23 | dst = buff.split(' ',3)[2]
24 | msg = buff.split(' :',1)[1]
25 | if msg.lower()[:5] == '!ping':
26 | buff = liburc.urchub_fmt(':bot!bot@bot PRIVMSG '+dst+' :pong\n')
27 | os.write(7,buff)
28 |
--------------------------------------------------------------------------------
/contrib/seekingfor/urc2server_rfc1459.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # urc2server_rfc1459 v0.1
3 | # dirty code, you have been warned
4 | import unicodedata
5 | import collections
6 | import subprocess
7 | import liburc
8 | import codecs
9 | import select
10 | import socket
11 | import signal
12 | import time
13 | import pwd
14 | import sys
15 | import re
16 | import os
17 | from hashlib import sha1
18 |
19 | if not os.path.exists('env/LINKNAME') or not os.path.exists('env/LINKPASS'):
20 | exit(525)
21 |
22 | LINKNAME = open('env/LINKNAME','rb').read().split('\n')[0]
23 | LINKPASS = open('env/LINKPASS','rb').read().split('\n')[0]
24 | RE = 'a-zA-Z0-9^(\)\-_{\}[\]|.'
25 | re_SPLIT = re.compile(' +',re.IGNORECASE).split
26 | re_LINK_NICK = re.compile('^NICK ['+RE+']+ :.*$', re.IGNORECASE).search
27 | re_LINK_KILL = re.compile('^KILL ['+RE+']+ :.*$', re.IGNORECASE).search
28 | re_LINK_PRIVMSG_NOTICE_TOPIC = re.compile('^:['+RE+']+!urc2serverRFC1459@' + LINKNAME + ' ((PRIVMSG)|(NOTICE)|(TOPIC)) []['+RE+']+ :.*$',re.IGNORECASE).search
29 | re_LINK_PRIVMSG_PRIVATE = re.compile('^:['+RE+']+!urc2serverRFC1459@' + LINKNAME + ' ((PRIVMSG)|(NOTICE)|(TOPIC)) ['+RE+']+ :.*$',re.IGNORECASE).search
30 | re_LINK_PART = re.compile('^:['+RE+']+!urc2serverRFC1459@' + LINKNAME + ' PART []['+RE+']+( :)?',re.IGNORECASE).search
31 | re_LINK_QUIT = re.compile('^:['+RE+']+!urc2serverRFC1459@' + LINKNAME + ' QUIT( :)?',re.IGNORECASE).search
32 | #re_LINK_PING = re.compile('^PING :?.+$',re.IGNORECASE).search
33 | re_LINK_JOIN = re.compile('^:['+RE+']+!urc2serverRFC1459@' + LINKNAME + ' JOIN []['+RE+']+$',re.IGNORECASE).search
34 | re_LINK_KICK = re.compile('^:.+ KICK []['+RE+']+ ['+RE+']+',re.IGNORECASE).search
35 | re_BUFFER_CTCP_DCC = re.compile('\x01(?!ACTION )',re.IGNORECASE).sub
36 | re_BUFFER_COLOUR = re.compile('(\x03[0-9][0-9]?((?<=[0-9]),[0-9]?[0-9]?)?)|[\x02\x03\x0f\x1d\x1f]',re.IGNORECASE).sub
37 | re_URC_PRIVMSG_NOTICE_TOPIC = re.compile('^:['+RE+']+![~'+RE+']+@['+RE+']+ ((PRIVMSG)|(NOTICE)|(TOPIC)) [#&]['+RE+']+ :.*$',re.IGNORECASE).search
38 | re_URC_PRIVMSG_PRIVATE = re.compile('^:['+RE+']+![~'+RE+']+@['+RE+']+ ((PRIVMSG)|(NOTICE)|(TOPIC)) ['+RE+']+ :.*$',re.IGNORECASE).search
39 | re_URC_JOIN = re.compile('^:['+RE+']+![~'+RE+']+@['+RE+']+ JOIN :[]['+RE+']+.*$', re.IGNORECASE).search
40 | re_URC_PART = re.compile('^:['+RE+']+![~'+RE+'.]+@['+RE+'.]+ PART []['+RE+']+.*$',re.IGNORECASE).search
41 | re_URC_QUIT = re.compile('^:['+RE+']+![~'+RE+'.]+@['+RE+'.]+ QUIT :.*$',re.IGNORECASE).search
42 | re_LINK_INTERNAL = re.compile('^:'+LINKNAME+' ',re.IGNORECASE).sub
43 |
44 | LIMIT = float(open('env/LIMIT','rb').read().split('\n')[0]) if os.path.exists('env/LIMIT') else 1
45 | COLOUR = int(open('env/COLOUR','rb').read().split('\n')[0]) if os.path.exists('env/COLOUR') else 0
46 | UNICODE = int(open('env/UNICODE','rb').read().split('\n')[0]) if os.path.exists('env/UNICODE') else 0
47 | DEBUG = int(open('env/DEBUG','rb').read().split('\n')[0]) if os.path.exists('env/DEBUG') else 0
48 | PRESENCE = int(open('env/PRESENCE','rb').read().split('\n')[0]) if os.path.exists('env/PRESENCE') else 0
49 |
50 |
51 | user = str(os.getpid())
52 | def sock_close(sn,sf):
53 | try:
54 | os.remove(str(os.getpid()))
55 | except:
56 | pass
57 | if sn: sys.exit(0)
58 |
59 | signal.signal(signal.SIGHUP,sock_close)
60 | signal.signal(signal.SIGINT,sock_close)
61 | signal.signal(signal.SIGTERM,sock_close)
62 | signal.signal(signal.SIGCHLD,sock_close)
63 |
64 | rd = 0
65 | if os.access('stdin',1):
66 | p = subprocess.Popen(['./stdin'],stdout=subprocess.PIPE)
67 | rd = p.stdout.fileno()
68 | del p
69 |
70 | wr = 1
71 | if os.access('stdout',1):
72 | p = subprocess.Popen(['./stdout'],stdin=subprocess.PIPE)
73 | wr = p.stdin.fileno()
74 | del p
75 |
76 | uid, gid = pwd.getpwnam('urcd')[2:4]
77 | os.chdir(sys.argv[1])
78 | os.chroot(os.getcwd())
79 | os.setgid(gid)
80 | os.setuid(uid)
81 | root = os.getcwd()
82 | del uid, gid
83 |
84 | sock=socket.socket(socket.AF_UNIX,socket.SOCK_DGRAM)
85 | sock_close(0,0)
86 | sock.bind(str(os.getpid()))
87 | sock.setblocking(0)
88 | sd=sock.fileno()
89 |
90 | poll=select.poll()
91 | poll.register(rd,select.POLLIN|select.POLLPRI)
92 | poll.register(sd,select.POLLIN)
93 | poll=poll.poll
94 |
95 | client_revents=select.poll()
96 | client_revents.register(rd,select.POLLIN|select.POLLPRI)
97 | client_revents=client_revents.poll
98 |
99 | server_revents=select.poll()
100 | server_revents.register(sd,select.POLLIN)
101 | server_revents=server_revents.poll
102 |
103 | def try_read(fd,buffer_len):
104 | try:
105 | return os.read(fd,buffer_len)
106 | except:
107 | sock_close(15,0)
108 |
109 | def try_write(fd,buffer):
110 | try:
111 | os.write(fd,buffer)
112 | os.write(2,'[out] ' + buffer)
113 | except:
114 | sock_close(15,0)
115 |
116 | def sock_write(buffer):
117 | buffer = liburc.urchub_fmt(buffer)
118 | try: sock.sendto(buffer,'hub')
119 | except: pass
120 | # os.write(2,'[sockwrite] ' + buffer)
121 | # buffer = buffer[:-1] + ' ' + str(int(time.time()))
122 | # check = sha1(buffer).hexdigest()[:10]
123 | # buffer = buffer + ' ' + check + ' urc-integ\n'
124 | # for path in os.listdir(root):
125 | # try:
126 | # if path != user: sock.sendto(buffer,path)
127 | # except:
128 | # pass
129 |
130 | try_write(wr,
131 | 'PASS ' + LINKPASS + '\n'
132 | 'SERVER urc2serverLocal 1\n'
133 | )
134 |
135 |
136 | nicks=dict()
137 | tmpNicks=dict()
138 | localnicks=list()
139 | channels=list()
140 | lastCheck = time.time()
141 | inactiveInterval = 3 * 60 * 60
142 | while 1:
143 | now = time.time()
144 | if now - lastCheck > 60:
145 | #os.write(2,'checking for inactivity..\n')
146 | tmpNicks=dict()
147 | for nick in nicks:
148 | if now - nicks[nick][1] > inactiveInterval:
149 | try_write(wr, ':' + nicks[nick][0] + ' QUIT :Inactivity (3 hours)\n')
150 | if DEBUG: try_write(wr, ':urc2server PRIVMSG #status :nick removed because of inactivity: ' + nicks[nick][0] + '\n')
151 | else:
152 | tmpNicks[nick] = nicks[nick]
153 | nicks = tmpNicks
154 | lastCheck = now
155 | poll(-1)
156 |
157 | if client_revents(0):
158 |
159 | buffer = str()
160 | while 1:
161 | byte = try_read(rd,1)
162 | if byte == '': sock_close(15,0)
163 | if byte == '\n': break
164 | if byte != '\r' and len(buffer)<768: buffer += byte
165 |
166 | os.write(2,'[in] ' + buffer + '\n')
167 | buffer=re_LINK_INTERNAL('', buffer)
168 | if buffer[0] != ':':
169 | if re.search('^PING .*$', buffer):
170 | try_write(wr, 'PONG' + buffer[4:] + '\n')
171 | elif re.search('^SERVER .*$', buffer):
172 | channels.append('#status')
173 | try_write(wr,
174 | 'NICK urc2server :1\n'
175 | ':urc2server USER serverlink urc2server urc2server :real name\n'
176 | ':urc2server JOIN #status\n'
177 | ':urc2server PRIVMSG #status :Link established\n'
178 | 'NICK dummy :1\n'
179 | ':dummy USER dummy urc2server urc2server :real name\n'
180 | )
181 | elif re_LINK_NICK(buffer):
182 | nick = buffer.split(' ')[1]
183 | if not nick.lower() in localnicks:
184 | localnicks.append(nick.lower())
185 | if DEBUG: try_write(wr,':urc2server PRIVMSG #status :local nick ' + nick.lower() + ' added: ' + buffer + '\n')
186 | else:
187 | try_write(wr,':urc2server PRIVMSG #status :local nick ' + nick.lower() + ' is already in localnicks. wtf?: ' + buffer + '\n')
188 | elif re_LINK_KILL(buffer):
189 | nick = buffer.split(' ')[1]
190 | if nick.lower() in nicks:
191 | del nicks[nick.lower()]
192 | if nick.lower() in localnicks:
193 | localnicks.remove(nick.lower())
194 | try_write(wr,':urc2server PRIVMSG #status :nick killed: ' + buffer + '\n')
195 | elif not re.search('^PASS .*$', buffer):
196 | try_write(wr,':urc2server PRIVMSG #status :unknown command from irc server: ' + buffer + '\n')
197 | continue
198 |
199 | buffer = buffer.split(' ', 1)[0] + '!urc2serverRFC1459@' + LINKNAME + ' ' + buffer.split(' ', 1)[1]
200 | #os.write(2,'[got] ' + buffer+'\n')
201 | if re_LINK_PRIVMSG_NOTICE_TOPIC(buffer):
202 | #os.write(2, ' last message is PRIVMSG_NOTICE_TOPIC\n')
203 | #if buffer[1:].split('!',1)[0] == nick: continue
204 | sock_write(buffer+'\n')
205 |
206 | elif re_LINK_PART(buffer):
207 | pass
208 | #if len(buffer.split(' :'))<2: buffer += ' :'
209 | if PRESENCE: sock_write(buffer + '\n')
210 |
211 | elif re_LINK_QUIT(buffer):
212 | nick = buffer.split('!', 1)[0][1:]
213 | if nick.lower() in localnicks:
214 | try:
215 | if DEBUG: try_write(wr,':urc2server PRIVMSG #status :local nick ' + nick + ' removed\n')
216 | localnicks.remove(nick.lower())
217 | except Exception as e:
218 | try_write(wr,':urc2server PRIVMSG #status :exception while removing local nick ' + nick + ': ' + e + '\n')
219 | else:
220 | try_write(wr,':urc2server PRIVMSG #status :nick not in localnicks. wtf? ' + buffer + '\n')
221 | #if len(buffer.split(' :'))<2: buffer += ' :'
222 | if PRESENCE: sock_write(buffer + '\n')
223 |
224 | elif re_LINK_JOIN(buffer):
225 | chan = buffer.split(" ")[2]
226 | if chan not in channels:
227 | try_write(wr, ':dummy JOIN ' + chan + '\n')
228 | channels.append(chan)
229 | if PRESENCE: sock_write(buffer.split(' JOIN ', 1)[0] + ' JOIN :' + buffer.split(' JOIN ', 1)[1] + '\n')
230 |
231 | elif re_LINK_KICK(buffer):
232 | #if len(buffer.split(' :'))<2: buffer += ' :'
233 | sock_write(buffer+'\n')
234 |
235 | elif re_LINK_PRIVMSG_PRIVATE(buffer):
236 | sock_write(buffer+'\n')
237 |
238 | #elif re.search('^:['+RE+']+![~'+RE+'.]+@['+RE+'.]+ INVITE '+re.escape(nick).upper()+' :#['+RE+']+$',buffer.upper()):
239 | # dst = buffer[1:].split(':',1)[1].lower()
240 | # if not dst in channels: try_write(wr,'JOIN '+dst+'\n')
241 |
242 |
243 | while server_revents(0):
244 |
245 | time.sleep(LIMIT)
246 |
247 | buffer = try_read(sd,1024).split('\n',1)[0][2+12+4+8:]
248 | if not buffer: continue
249 | #os.write(2, 'socket-in: ' + buffer + '\n')
250 | parts = buffer.split(' ')
251 | if parts[-1] == 'urc-integ':
252 | try:
253 | timestamp, check = int(parts[-3]), parts[-2]
254 | length = len(parts[-3]) + len(parts[-2]) + len(parts[-1]) + 3
255 | buffer = buffer[:-length]
256 | if parts[1] == 'PRIVMSG':
257 | if sha1(buffer + ' ' + parts[-3]).hexdigest()[:10] == check:
258 | status = ' \x0309[v]\x0f'
259 | else:
260 | status = ' \x0305[check failed]\x0f'
261 | if buffer[-1] == '\x01':
262 | buffer = buffer[:-1] + status + '\x01'
263 | else:
264 | buffer += status
265 | del status
266 | del length, timestamp, check
267 | except Exception as e:
268 | pass
269 |
270 | elif len(parts[-1]) == 10:
271 | try:
272 | timestamp, check = int(parts[-2]), parts[-1]
273 | length = len(parts[-2])+len(parts[-1]) + 2
274 | buffer = buffer[:-length]
275 | if parts[1] == 'PRIVMSG':
276 | if sha1(buffer + ' ' + parts[-2]).hexdigest()[:10] == check:
277 | status = ' \x0309[v]\x0f'
278 | else:
279 | status = ' \x0305[check failed]\x0f'
280 | if buffer[-1] == '\x01':
281 | buffer = buffer[:-1] + status + '\x01'
282 | else:
283 | buffer += status
284 | del status
285 | del length, timestamp, check
286 | except Exception as e:
287 | pass
288 | del parts
289 |
290 | buffer = re_BUFFER_CTCP_DCC('',buffer) + '\x01' if '\x01ACTION ' in buffer.upper() else buffer.replace('\x01','')
291 | if not COLOUR: buffer = re_BUFFER_COLOUR('',buffer)
292 | if not UNICODE:
293 | buffer = codecs.ascii_encode(unicodedata.normalize('NFKD',unicode(buffer,'utf-8','replace')),'ignore')[0]
294 | buffer = ''.join(byte for byte in buffer if 127 > ord(byte) > 31 or byte in ['\x01','\x02','\x03','\x0f','\x1d','\x1f'])
295 | buffer += '\n'
296 | #os.write(2, 'socket-done: ' + buffer)
297 |
298 | #os.write(2, '[sock_read] ' + buffer)
299 | if re_URC_PRIVMSG_NOTICE_TOPIC(buffer) or re_URC_PRIVMSG_PRIVATE(buffer):
300 | dst = re_SPLIT(buffer,3)[2].lower()
301 | if re_URC_PRIVMSG_PRIVATE(buffer) and dst.lower() not in localnicks: continue
302 | nick = buffer.split('!', 1)[0][1:]
303 | while nick in localnicks: nick = nick + "_"
304 | host = buffer.split(' ', 1)[0].split('@', 1)[1]
305 | if nick.lower() not in nicks:
306 | try_write(wr, 'NICK ' + nick + ' :1\n')
307 | try_write(wr, ':' + nick + ' USER remote ' + host + ' noIdea :real name\n')
308 | nicks[nick.lower()] = list()
309 | nicks[nick.lower()].append(nick)
310 | nicks[nick.lower()].append(time.time())
311 | if DEBUG: try_write(wr,':urc2server PRIVMSG #status :nick added: ' + nick + '!remote@' + host + '\n')
312 | else:
313 | nicks[nick.lower()][1] = time.time();
314 | if DEBUG: try_write(wr,':urc2server PRIVMSG #status :nick activity refreshed: ' + nick.lower() + '\n')
315 | if dst[0] in ['#','&']: try_write(wr, ':' + nick + ' JOIN ' + dst + ' :1\n')
316 | try_write(wr, ':' + nick + ' ' + buffer.split(' ', 1)[1])
317 | elif re_URC_PART(buffer):
318 | nick = buffer.split('!', 1)[0][1:]
319 | if nick.lower() in nicks:
320 | dst = buffer.split(' ')[2]
321 | if DEBUG: try_write(wr,':urc2server PRIVMSG #status :' + nick + ' parted from channel ' + dst + '\n')
322 | try_write(wr, ':' + nick + ' ' + buffer.split(' ', 1)[1])
323 | elif re_URC_QUIT(buffer):
324 | nick = buffer.split('!', 1)[0][1:]
325 | if nick.lower() in nicks:
326 | if DEBUG: try_write(wr,':urc2server PRIVMSG #status :' + nick + ' quit\n')
327 | try_write(wr, ':' + nick + ' ' + buffer.split(' ', 1)[1])
328 | del nicks[nick.lower()]
329 | elif re_URC_JOIN(buffer):
330 | nick = buffer.split('!', 1)[0][1:]
331 | dst = buffer.split(' ')[2][1:]
332 | if not nick.lower() in nicks:
333 | while nick in localnicks: nick = nick + "_"
334 | host = buffer.split(' ', 1)[0].split('@', 1)[1]
335 | try_write(wr, 'NICK ' + nick + ' :1\n')
336 | try_write(wr, ':' + nick + ' USER remote ' + host + ' noIdea :real name\n')
337 | nicks[nick.lower()] = list()
338 | nicks[nick.lower()].append(nick)
339 | nicks[nick.lower()].append(time.time())
340 | if DEBUG: try_write(wr,':urc2server PRIVMSG #status :' + nick.lower() + ' added\n')
341 | if DEBUG: try_write(wr,':urc2server PRIVMSG #status :' + nick + ' joined ' + dst + '\n')
342 | try_write(wr, ':' + nick + ' ' + buffer.split(' ', 1)[1])
343 |
344 |
--------------------------------------------------------------------------------
/db/urchub/i2p/7kmkqzx5egdannxhqt4b3fkqbo7jdjphwcf2viiph7qdqm3wlmaa.b32.i2p/owner:
--------------------------------------------------------------------------------
1 | jsw
2 |
--------------------------------------------------------------------------------
/db/urchub/i2p/7kmkqzx5egdannxhqt4b3fkqbo7jdjphwcf2viiph7qdqm3wlmaa.b32.i2p/port:
--------------------------------------------------------------------------------
1 | 6789
2 |
--------------------------------------------------------------------------------
/db/urchub/icann/josephswilliams.com/owner:
--------------------------------------------------------------------------------
1 | jsw
2 |
--------------------------------------------------------------------------------
/db/urchub/icann/josephswilliams.com/port:
--------------------------------------------------------------------------------
1 | 6789
2 |
--------------------------------------------------------------------------------
/db/urchub/icann/urc.freeanons.info/owner:
--------------------------------------------------------------------------------
1 | lulzprincess
2 |
--------------------------------------------------------------------------------
/db/urchub/icann/urc.freeanons.info/port:
--------------------------------------------------------------------------------
1 | 6789
2 |
--------------------------------------------------------------------------------
/db/urchub/tor/allyour4nert7pkh.onion/owner:
--------------------------------------------------------------------------------
1 | psi
2 |
--------------------------------------------------------------------------------
/db/urchub/tor/allyour4nert7pkh.onion/port:
--------------------------------------------------------------------------------
1 | 4666
2 |
--------------------------------------------------------------------------------
/db/urchub/tor/freeanonine7mgki.onion/owner:
--------------------------------------------------------------------------------
1 | lulzprincess
2 |
--------------------------------------------------------------------------------
/db/urchub/tor/freeanonine7mgki.onion/port:
--------------------------------------------------------------------------------
1 | 6789
2 |
--------------------------------------------------------------------------------
/db/urchub/tor/hppikcru545manbi.onion/owner:
--------------------------------------------------------------------------------
1 | epoch
2 |
--------------------------------------------------------------------------------
/db/urchub/tor/hppikcru545manbi.onion/port:
--------------------------------------------------------------------------------
1 | 4666
2 |
--------------------------------------------------------------------------------
/db/urchub/tor/ntwrkhhtqv73vwd4.onion/owner:
--------------------------------------------------------------------------------
1 | jsw
2 |
--------------------------------------------------------------------------------
/db/urchub/tor/ntwrkhhtqv73vwd4.onion/port:
--------------------------------------------------------------------------------
1 | 6789
2 |
--------------------------------------------------------------------------------
/doc/README.bak.txt:
--------------------------------------------------------------------------------
1 | urcd:
2 | af_unix relay chat daemon and
3 | af_unix relay chat daemon accessories...
4 |
5 | for more information regarding this software
6 | and the URC protocols, `less doc/URC'.
7 |
8 | depends:
9 | NaCl or libsodium, libtai, ucspi-tcp,
10 | python(>=2.6), python-dev(>=2.6),
11 | daemontools, sh, gcc
12 |
13 | recommends:
14 | NaCl instead of libsodium,
15 | cython(>=0.18.0)
16 |
17 | todo:
18 | fix hostmasks in urcd
19 |
20 | create URCHUB/URCLOCAL
21 |
22 | consider crypto modes for cryptoserv
23 |
24 | implement ban/except for clients without regex ignore.
25 |
26 | add a global hostmask option for users sending messages into
27 | urc from an ircnet for urc2sd.
28 |
29 | implement presence notifications for the ircd side in urc2sd.
30 |
31 | add encrypted channels to urc2sd.
32 |
33 | quick install (not recommended):
34 |
35 | # install dependencies, if you haven't already
36 | ./install-ucspi-tcp.sh
37 | ./install-libtai.sh
38 |
39 | # recommended over ./install-libsodium.sh
40 | ./install-nacl.sh
41 |
42 | useradd urcd
43 |
44 | $editor env/*
45 |
46 | # OpenBSD
47 | echo '-ftrampolines' > conf-cc
48 |
49 | # if python2.6
50 | sed 's/\.7/.6/g' Make.sh | sh -v
51 |
52 | # elif python2.7
53 | ./Make.sh
54 | ./bin/urcd.sh $ntwrk
55 |
56 | install (recommended):
57 |
58 | # install dependencies, if you haven't already
59 | ./install-daemontools.sh
60 | ./install-ucspi-tcp.sh
61 | ./install-libtai.sh
62 |
63 | # recommended over ./install-libsodium.sh
64 | ./install-nacl.sh
65 |
66 | useradd urcd
67 |
68 | # OpenBSD
69 | echo '-ftrampolines' > conf-cc
70 |
71 | # if python2.6
72 | sed 's/\.7/.6/g' Make.sh | sh -v
73 |
74 | # elif python2.7
75 | ./Make.sh
76 |
77 | # edit the network/hostmask
78 | $editor env/serv
79 |
80 | # edit the motd
81 | $editor env/motd
82 |
83 | ln -s `pwd` /service/urcd
84 | ./bin/add-urchub
85 |
86 | sleep 4
87 | svstat /service/urcd
88 |
89 | ### see the hub2hub section below it is ###
90 | ### recommended to connect to 3 urchubs ###
91 |
92 | adding curvecp:
93 | mkdir -p /services/urcd-curvecp
94 |
95 | ln -s `pwd`/env /services/urcd-curvecp/env
96 | ln -s `pwd`/urcd /services/urcd-curvecp/urcd
97 | ln -s `pwd`/run.urcd-curvecp /services/urcd-curvecp/run
98 |
99 | curvecpmakekey /services/urcd-curvecp/curvecp
100 |
101 | find /services/urcd-curvecp/curvecp -type d -exec chmod 700 {} \;
102 | find /services/urcd-curvecp/curvecp -type f -exec chmod 600 {} \;
103 | chown urcd /services/urcd-curvecp/curvecp -R
104 |
105 | ln -s /services/urcd-curvecp /service/urcd-curvecp
106 |
107 | sleep 4
108 | svstat /service/urcd-curvecp
109 |
110 | echo "PUBKEY: `curvecpprintkey /services/urcd-curvecp/curvecp`"
111 |
112 | curvecp + irc client (test):
113 |
114 | tcpserver 127.0.0.1 6667 \
115 | curvecpclient irc.d3v11.ano `curvecpprintkey /services/urcd-curvecp/curvecp` \
116 | `cat env/addr` `cat env/port` 01110101011100100110001101100100 \
117 | curvecpmessage -c ./ucspi-stream &
118 |
119 | irssi -c 127.0.0.1
120 |
121 | interface:
122 | place an executable program in the cwd
123 | of urcd named 'stdin'. the program reads
124 | stdin from the irc client. anything your
125 | program writes to stdout will be written
126 | to urcd
127 |
128 | place an executable program in the cwd
129 | of urcd named 'stdout'. the program reads
130 | stdin from urcd. anything your program
131 | writes to stdout will be written to the
132 | irc client
133 |
134 | for urc2sd follow the same process. happy
135 | hacking.
136 |
137 | no censorship (security):
138 | URC networks are censorship resistant. i
139 | recommend URCSIGN and/or URCCRYPTOBOX to
140 | ignore spam and trolls. URCd will replace
141 | the user field with VERIFIED for users with
142 | valid authentication or signature verification.
143 | All other user fields will be replaced with
144 | URCD. e.g.:
145 |
146 | nick!URCD@server
147 | nick!VERIFIED@server
148 |
149 | irssi ("ban/except"):
150 | /ignore *!*@* ALL
151 | /ignore -except friend!*@* ALL
152 | /ignore -except *!VERIFIED@* ALL
153 |
154 | xchat ("ban/except"):
155 | /ignore *!*@* ALL
156 | /ignore friend!*@* ALL UNIGNORE
157 | /ignore *!VERIFIED@* ALL UNIGNORE
158 |
159 | URCSIGN (prototype, subject to change):
160 | ./sign_keypair
161 |
162 | # (global) save your seckey/pubkey and secure them
163 | $editor env/URCSIGNPUBKEY
164 | $editor env/URCSIGNSECKEY
165 | chmod 600 env/URCSIGNSECKEY
166 |
167 | # use a specific seckey for a destination, or override global
168 | mkdir -p urcsignseckeydir
169 | echo urcsignseckeydir > env/URCSIGNSECKEYDIR
170 | echo $seckey > urcsignseckeydir/\#channel
171 | chmod 600 urcsignseckeydir/
172 |
173 | # save your friends' pubkeys and secure them
174 | mkdir -p urcsigndb/
175 | chmod 600 urcsigndb/
176 | echo $pubkey > urcsigndb/$nick
177 | echo urcsigndb/ > env/URCSIGNDB
178 |
179 | # use a specific pubkey for a destination, or override global
180 | mkdir -p urcsignpubkeydir
181 | echo urcsignpubkeydir > env/URCSIGNPUBKEYDIR
182 | echo $pubkey > urcsignpubkeydir/\#channel/nick
183 | chmod 600 urcsignpubkeydir/
184 |
185 | # urcd will replace the user field with VERIFIED for valid
186 | # signatures and replace all other user fields with URCD.
187 | # see "no censorship" above.
188 |
189 | URCCRYPTOBOX:
190 | # urcd can provide secret and encrypted PM
191 |
192 | ./keypair
193 | echo $seckey > env/URCCRYPTOBOXSECKEY
194 | mkdir -p urccryptoboxdir/
195 | echo urccryptoboxdir > env/URCCRYPTOBOXDIR
196 | echo $pubkey > urccryptoboxdir/$nick
197 | chmod 600 urccryptoboxdir/
198 |
199 | # use a specific seckey for a destination, or override global
200 | mkdir -p urccryptoboxseckeydir/
201 | echo urccryptoboxseckeydir > env/URCCRYPTOBOXSECKEYDIR
202 | echo $seckey > urccryptoboxseckeydir/$nick
203 | chmod 600 urccryptoboxseckeydir/
204 |
205 | # urcd will replace the user field with VERIFIED for valid
206 | # authentication and replace all other user fields with URCD.
207 | # see "no censorship" above.
208 |
209 | URCCRYPTOBOXPFS:
210 | # urcd can provide secret perfect forward secrecy for encrypted PM
211 | # for destinations already configured for URCCRYPTOBOX. urcd will
212 | # send and error notice when unable to decrypt a session box. simply
213 | # respond to your friend to exchange session keys. if you want to
214 | # change session keys, simply /reconnect. urcd will not store any
215 | # session cryptography. both parties need to have this enabled to work.
216 |
217 | echo urccryptoboxpfs/ > env/URCCRYPTOBOXPFS
218 | mkdir -p urccryptoboxpfs/
219 | chmod 600 urccryptoboxpfs/
220 | touch urccryptoboxpfs/$nick
221 |
222 | URCSECRETBOX:
223 | urcd can provide secret and encrypted channels
224 | using a 64 byte hexadecimal key
225 |
226 | ./keypair # you only need the seckey
227 | mkdir -p urcsecretboxdir/
228 | echo urcsecretboxdir > env/URCSECRETBOXDIR
229 | echo $seckey > urcsecretboxdir/\#channel
230 | chmod 600 urcsecretboxdir/
231 |
232 | clients can also create channel encryption temporarily
233 | by submitting passwords to urcd.
234 | e.g.:
235 |
236 | /JOIN #channel password
237 | /MODE #channel +k password
238 |
239 | urcd PASS command (prototype, subject to change):
240 | remote clients can set or override URCSIGNSECKEY and/or
241 | URCCRYPTOBOXSECKEY by sending NaCl secret keys to urcd in
242 | hexadecimal format using the PASS command. there are three
243 | acceptable formats:
244 |
245 | 0.) a 128 byte key will set URCSIGNSECKEY only.
246 |
247 | 1.) a 64 byte key will set URCCRYPTOBOXSECKEY only.
248 |
249 | 2.) a 192 byte key will set URCCRYPTOBOXSECKEY using the first
250 | 64 bytes, and set URCSIGNSECKEY using the last 128 bytes.
251 |
252 | hub2hub:
253 | test -e /services/urcd-hub0/ || ./bin/add-urchub
254 | ./bin/add-urcstream2hub /service/urcd/socket/ /service/urcd-hub0/socket/
255 | ./bin/add-hublisten your.urcd.ano 6789 /service/urcd-hub0/socket/
256 | ./bin/add-hubconnect peer.urcd.ano 6789 /service/urcd-hub0/socket/
257 |
258 | CryptoServ (requires NaCl):
259 | # stdin.cryptoserv will create cryptoservroot/urcsigndb
260 | # cryptoservroot/urccryptoboxdir, and cryptoservroot/urccryptoboxpfs
261 | # and point env/URCCRYPTOBOXDIR, env/URCCRYPTOBOXPFS, and
262 | # env/URCSIGNDB accordingly.
263 |
264 | ln -s stdin.cryptoserv stdin
265 |
266 | urc2sd:
267 | #urc2sd follows a similar convention as urcd by using a format
268 | #that distinguishes signed messages from nonverified messages.
269 | #i.e: signed messages appear as: "nick!sign@server> msg",
270 | #while nonsigned messages appear as "nick!urcd@server> msg".
271 | #urc2sd filters traffic coming from the urc network reliably
272 | #this way by using the ban and except masks set by the chanops
273 | #on the the ircnet's channels.
274 |
275 | mkdir -p /services/urc2sd
276 |
277 | ln -s `pwd`/urc2sd /services/urc2sd/urc2sd
278 | ln -s `pwd`/ucspi-client2server /services/urc2sd/ucspi-client2server
279 |
280 | # default
281 | ln -s `pwd`/run.urc2sd /services/urc2sd/run
282 |
283 | # tor
284 | ln -s `pwd`/run.urc2sd-tor /services/urc2sd/run
285 | ln -s `pwd`/ucspi-socks4aclient /services/urc2sd/ucspi-socks4aclient
286 |
287 | printf $addr > /services/urc2sd/addr
288 | printf $port > /services/urc2sd/port
289 | printf '/services/urcd-hub0/socket/' > /services/urc2sd/path
290 | printf 'urcd' > /services/urc2sd/nick
291 | printf '#channel' > /services/urc2sd/channels
292 |
293 | touch /services/urc2sd/auto_cmd
294 |
295 | ln -s /services/urc2sd /service/urc2sd
296 |
297 | POLICY and ISUPPORT:
298 | these values are filenames inside env/ and contain different types of data.
299 |
300 | IDLE:
301 | integer argument with a default of 2048 seconds. this value dictates how long
302 | remote clients can idle before their presence is dropped.
303 |
304 | PING:
305 | integer argument with a default of 16 seconds. this value dictates the ping
306 | intervals to a client, and the amount of time a client has to perform
307 | a connection. if PING is activated and the client doesn't respond within
308 | the specified time before TIMEOUT, the client is dropped. a 0 value will
309 | disable this feature.
310 |
311 | URCDB:
312 | default is empty. adding a /path/to/urc.db will tell urcd where to store a
313 | database. the database stores information from the network. this prevents
314 | losing this information between connections. (security) set chmod 600 on
315 | this file after it is created. e.g.: /topic, /names, and /list.
316 |
317 | WARNING:
318 | using this option on public urcd's, or sharing a database from a private
319 | urcd can reveal /topic, /names, and /list to unprivileged clients.
320 |
321 | FLOOD:
322 | integer argument with a default threshold of 8. every write to the network
323 | by a client increments the flood counter. if the flood counter breaches the
324 | threshold the client will lose ability to write to the network until the
325 | counter returns below the threshold value. a 0 value will disable this
326 | feature.
327 |
328 | LIMIT:
329 | float argument default is 1.0. this is the maximum rate in which a client
330 | can write to the network.
331 |
332 | EXPIRY:
333 | integer argument with a default of 32 days. this is how long a CryptoServ
334 | account has until it is deleted from inactivity. setting this value to 0
335 | will disable account expirations.
336 |
337 | COLOUR:
338 | integer default is 0. changing this value to 1 will allow colour encoding
339 | to pass to the client.
340 |
341 | UNICODE:
342 | integer default is 0. changing this value to 1 will allow unicode encoding
343 | to pass to the client.
344 |
345 | NICKLEN:
346 | integer default is 32. this is the maximum byte length of acceptable nick's
347 | on the network.
348 |
349 | TIMEOUT:
350 | integer default is 256. this value represents the allowed time a client
351 | can remain silent before their connection is dropped. this value also
352 | represents how often URCDB is synchronized if enabled.
353 |
354 | PRESENCE:
355 | integer default is 0. changing this value to 1 will announce JOIN, PART,
356 | and QUIT messages from the client to the network.
357 |
358 | TOPICLEN:
359 | integer default is 512. this is the maximum byte length of acceptable
360 | topics.
361 |
362 | CHANLIMIT:
363 | integer default is 64. this value represents the maximum amount of channels
364 | and the maximum amount of users that can participate in channels.
365 |
366 | CHANNELLEN:
367 | integer default is 64. this value represents the maximum byte length of
368 | channels on the network.
369 |
370 | PADDING:
371 | integer default is 255. this value represents the block sizes of encrypted
372 | packets. setting a 0 value will disable this feature, however it is not
373 | recommended.
374 |
375 | BROADCAST:
376 | integer default is 0. setting this value to 1 enables UDP broadcasts in
377 | urc-udpsend and urc-udprecv.
378 |
379 | logging URC services:
380 | mkdir -p /path/to/urcd-service/log/
381 | ln -s run.log /path/to/urcd-service/log/run
382 | supervise /path/to/urcd-service/log 2>/dev/null & disown
383 | sleep 4
384 | svstat /path/to/urcd-service/log
385 | svc -t /path/to/urcd-service/
386 |
--------------------------------------------------------------------------------
/doc/URC.txt:
--------------------------------------------------------------------------------
1 | Description:
2 | An IRC style, private, security aware, open source project called URC.
3 | URC is supported by multiple daemons and programs in this suite for building,
4 | connecting, and/or bridging existing URC networks. If configured and understood
5 | properly, URC can be as easy as using the IRC client you favor, while being
6 | as private and secure as enterprise, military, and/or critical systems. In
7 | example, Alice can connect to her local URCd with her IRC client and listen to
8 | channels without anyone knowing she is present until she sends a message. If
9 | Alice sends Bob an encrypted private message while enjoying URC, the message
10 | will be delivered to Bob without anyone knowing exactly when Alice sent the
11 | message, to whom the message was delivered, the contents of the message, nor
12 | details, such as the size. URC can also support similar encrypted conferences
13 | in the password protected channels, or chat privately or publically among
14 | friends. The cryptography in URC also allows clients to verify who they are
15 | among other clients if necessary.
16 |
17 |
18 | Advantages:
19 | Anonymity - URC doesn't care about IP or Ident, and doesn't reveal this
20 | information to other users on the network. The server/hostmask section of a
21 | URCLINE is always a hostmask chosen by the user. When a client sends a URC
22 | packet across the network, the sender's physical location is protected, by
23 | scattering the packet throughout the network in a randomly chosen order, i.e.
24 | the receiver is also protected.
25 |
26 | No Government or Censorship - In the URC network, you decide the policies for
27 | yourself, rather than someone else choosing them for you.
28 |
29 | NO Presence - URCd, by default, does not announce JOIN, PART, or QUIT messages,
30 | therefore a user's activities and timing are protected.
31 |
32 | Plausible Deniability - URC packets that are not signed cannot prove a specific
33 | user created a message. Admins using URCd and CryptoServ also have a unique
34 | advantage, in that they can deny knowing a secret key because the keys can be
35 | sent remotely and are not stored on the server.
36 |
37 | NO NickServ/Chanserv - NickServ and ChanServ are replaced by signatures and
38 | encryption, that come optional to the user.
39 |
40 | NO CTCP/DCC - URCd automatically blocks both of these protocols before they can
41 | access an IRC client, preventing many leaks and exploits.
42 |
43 | NO Encoding - URCd automatically blocks colour and unicode unless the
44 | administrator allows encoding. This is due to a number of exploits in the past
45 | associated with parsing.
46 |
47 | AntiSurveillance - Encrypted URC packets do not reveal the source or
48 | destination of a packet. Instead they rely on NaCl's highspeed Poly1305, or
49 | encrypted signatures for authentication and verification. Thus, an attacker
50 | sniffing the network cannot target specific conversations because they contain
51 | no identifying marks compared against other encrypted traffic. Only user's with
52 | the correct keys can discover this information. By default, all encrypted
53 | packets are padded to protect against other side channels.
54 |
55 | Security Aware - URC is written in a small amount of open source C and Python
56 | code. URC daemons only function inside of a chroot jail with only the
57 | privileges necessary to run, and includes a simple urc_jail function with
58 | LibURC to make this easy to setup. URC supports the new record setting
59 | Networking and Cryptographic library (NaCl), rather than older, bloated, and
60 | slower libraries of the past. URC daemons also support CurveCP and TOR rather
61 | than SSL and TLS for links and encrypted connections. The current URCd software
62 | is however flexible enough to wrap the URCHUB protocol with other security
63 | layers.
64 |
65 | Simple API and Modularity - URCd allows the user to "hack" his or her
66 | conversation with their local daemon with any programming language, so long as
67 | the user can read and write with stdin and stdout, and can parse URCLINE
68 | (simplified IRC lines). URCd also ships with LibURC, a library for creating
69 | plaintext, encrypted, and signed URC packets from IRC lines. LibURC is a very
70 | simple library, that is written in C, and contains wrappers for Python, and
71 | soon other languages as well. URCd utilizes the wisdom of the Unix philosophy
72 | in its design, so that it's flexible, legible, and modular with interchangeable
73 | components.
74 |
75 | Stateless - URC is a stateless broadcast protocol that can easily use a variety
76 | of networks to send data, where each hop is a similar to a radio hub or signal
77 | repeater. This keeps overhead low and simplicity unlocks room for expansion and
78 | scalability. Demands like cpu and memory requirements can be kept to a minimum.
79 |
80 | Scalability - URC can span multiple networks, such as LAN, WLAN, VPN, TOR, I2P,
81 | and other networks, by using UDP broadcasts, multicast groups, and TCP streams.
82 | Other protocols can easily integrate URC into existing networks as well.
83 |
84 | Taia96n - LibURC's implementation can easily be modified to provide nano second
85 | accuracy, but this is not necessary. Taia96n is a 96 bit timestamp, accurate to
86 | roughly the first 60 bits in network byte order. Masking the last 36 bits
87 | allows URC nodes to mitigate the risk of leaking clockskew and other side
88 | channel attacks. The randomization of the last 36 bits also increases the
89 | entropy for the cryptographic nonce bytes used in the URCHUB protocol. This
90 | protocol will not expire within the next few billion years.
91 |
92 | No Trust - The URC protocol and supporting softwares take a different approach
93 | to an often overlooked point of failure used on many crypto and communication
94 | systems. URC does not need a third party to establish private, and secure
95 | communications over a decentralized network. For example, URC does not require,
96 | nor allow another server to verify the authenticity of a client's messages, nor
97 | does the protocol require or allow remote systems to overide or alter the
98 | policies on someone's local URCd.
99 |
100 | Entropy - LibURC ships with it's own secure randombytes implementation
101 | that is powered by NaCl's crypto_stream function, providing strong and reliable
102 | entropy, suitable in chroot environments. A nonce and a one time secret key are
103 | derived using the strongest nonblocking available RNG and crypto_hash_sha512 to
104 | generate an arbitrary amount of random data without depleting the system's
105 | entropy pool. Should the onboard RNG ever fail, the LibURC randombytes function
106 | will not. the implementation has a secure failover using variable information
107 | from the system clock and other status information.
108 |
109 |
110 | URCLINE:
111 | A URCLINE is similar to a line of IRC. These lines are wrapped and
112 | distributed using the URCHUB protocol.
113 |
114 | PRIVMSG, NOTICE, TOPIC, INVITE will send a message to URC node(s). These
115 | lines SHOULD have a similar effect as IRC equivalents.
116 |
117 | :nick!user@server PRIVMSG #channel :message\n
118 | :nick!user@server NOTICE #channel :message\n
119 | :nick!user@server TOPIC #channel :message\n
120 | :nick!user@server INVITE nick :#channel\n
121 |
122 | JOIN, PART, QUIT, KICK can be used by listeners to learn presence.
123 | There's no mandate for a URCd daemon to announce presence, as this can
124 | be learned through natural message traffic. Currently presence is only
125 | default in URC2sd to sync with URCd and to announce censorship from IRCd
126 | admins.
127 |
128 | :nick!user@server PART #channel :message\n
129 | :nick!user@server QUIT :message\n
130 | :nick!user@server JOIN :#channel\n
131 | :oper!user@server KICK #channel nick :message\n
132 |
133 | URCHUB:
134 | URCHUB is the default protocol for transporting URC packets across the
135 | network. The first field is a 16bit length (LEN) in network byte order.
136 | While 16bit LEN can represent 65535 bytes of data the MTU of URC is 1024
137 | bytes, or one kilobyte. The second field of URCHUB is taia96n, a 12 byte
138 | timestamp in network byte order that is accurate to nano seconds. The
139 | third field is a 32bit CMD and is currently used to distinguish types of
140 | packets. The last 24 bits of CMD SHOULD remain NULL until future usages
141 | are necessary. The fourth field are 64bits of random data that ensures
142 | uniqueness of a packet. The fifth field is the payload and it's size
143 | MUST be reflected by the 16bit LEN field. Generally this field is a
144 | URCLINE, but can also contain binary or alternative data.
145 |
146 | | 16bit LEN | 96bit taia96n | \0\0\0\0 | 64bit random | URCLINE |
147 |
148 | By default CMD is NULL unless stated otherwise.
149 |
150 | URCHUB/URCSIGN:
151 | | 16bit LEN | 96bit taia96n | \1\0\0\0 | 64bit random | URCLINE | 512bit
152 | SIGNATURE |
153 |
154 | SIGNATURE is the 64 signature bytes from the crypto_sign function in
155 | NaCl's API. The entire message is used to derive SIGNATURE with CMD set
156 | to prevent signatures from being replayed in other protocols of URC.
157 |
158 | URCHUB/URCSECRETBOX:
159 | | 16bit LEN | 96bit taia96n | \2\0\0\0 | 64bit random | CRYPTO_SECRETBOX |
160 |
161 | CRYPTO_SECRETBOX is a combination of poly1305 (MAC) and xsalsa20 (stream
162 | cipher) that is used to encrypt the URCLINE. The taia96n label, CMD, and
163 | random bytes are used as the NONCE, and the secret key is chosen prior
164 | to encryption.
165 |
166 | URCHUB/URCSIGNSECRETBOX:
167 | | 16bit LEN | 96bit taia96n | \3\0\0\0 | 64bit random | CRYPTO_SECRETBOX |
168 |
169 | A packet is signed the same manner described in URCSIGN before
170 | encryption, to prevent signature replays, and side channels.
171 |
172 | URCHUB/URCCRYPTOBOX:
173 | | 16bit LEN | 96bit taia96n | \4\0\0\0 | 64bit random | CRYPTO_BOX |
174 |
175 | CRYPTO_BOX is a combination of curve25519 (DH), poly1305 (MAC), and
176 | xsalsa20 (stream cipher) that is used to encrypt the URCLINE. The
177 | taia96n label, CMD, and random bytes are used as the NONCE. The secret
178 | key is derived from a curve25519 diffie-hellman key exchange.
179 |
180 | URCHUB/URCCRYPTOBOX/PFS:
181 | | 16bit LEN | 96bit taia96n | \5\0\0\0 | 64bit random | [ CRYPTO_BOX1
182 | |CRYPTO_BOX0| ] |
183 |
184 | CRYPTO_BOX1 is derived using the same method as URCHUB/URCCRYPTOBOX and
185 | contains a 32 byte temporary public key from the sender followed by the
186 | encrypted URCLINE. NONCE bytes are the same in CRYPTO_BOX0 and
187 | CRYPTO_BOX1.
188 |
189 | Download and Install:
190 |
191 | Upstream:
192 | git clone git://josephswilliams.com/urcd.git /usr/local/src/urcd
193 |
194 | GitHub:
195 | git clone git://github.com/JosephSWilliams/urcd /usr/local/src/urcd
196 |
197 | Tor:
198 | torify git clone git://ntwrkhhtqv73vwd4.onion/urcd.git /usr/local/src/urcd
199 |
200 | Simply follow the instructions in the urcd/README. Feel free to contact me
201 | if you have complaints or suggestions. Happy hacking :-).
202 |
--------------------------------------------------------------------------------
/doc/topology.txt:
--------------------------------------------------------------------------------
1 | /*
2 | This document decribes the magick of URC routing.
3 | */
4 |
5 |
6 | A node will consist of a urchub that SHOULD accept public connections and a
7 | private URCd on localhost. Hosting a seperate public URCd is optional. IRC
8 | clients connect to a URCd, that acts as an IRC server by translating URC packets
9 | that travel a URC network of urchubs. When an IRC client sends a message to
10 | URCd, it converts it to a urchub format and broadcasts it across the network.
11 | There are a number of factors that ensure messages can remain as private as
12 | possible while mechanisms in urchub protocols allow noise to be filtered easily.
13 | Noise can be defined messages like spam, or messages from unverified sources, or
14 | unencrypted clients. If you are interested in cryptography and URC primitives
15 | then view doc/URC.
16 |
17 |
18 | ------------------
19 | | | | |
20 | | | | |
21 | -------- ----
22 | | ----- ---
23 | |----- ---
24 | ------------
25 | /* example URC network */
26 |
27 |
28 | In the above example, an IRC client sending a message to URCd, is able to
29 | reach every other IRC client connected to a URCd on any URC node. Messages
30 | sent from a URC node to a urchub, are broadcasted to each other urchub connected
31 | to it, and each correct IRC client once it is translated by URCd. URC allows
32 | messages to seemlessly flow among multiple networks, such as Tor, i2p,
33 | Anonet, and other networks without additional software or configurations if
34 | there is at least one route between each client. A client connected to any URC
35 | node in the example above could send a message that would be available to each
36 | IRC client connected to another URC node. Every URC node using the URCd software
37 | suite has builtin protection mechanisms against flood, DoS/DDOS, and exploits.
38 | Countermeasures are taken in URC's timing, encryption, authentication, and
39 | signature algorithms to maximize privacy.
40 |
41 |
42 | /* example program map */
43 |
44 |
45 | ircclient
46 | |
47 | <------. ircclient |
48 | | *------> ircd <- urc2sd -.
49 | v |
50 | urchubstream -. |
51 | | |
52 | urcd -> urchub/urccache -> urchubstream |
53 | | \ |
54 | | ircclient ---------> urcd -> urchub/urccache
55 | | |
56 | *-> ircclient urchubstream
57 | *-> ircclient |
58 | v
59 |
60 |
61 | The urchub is the cornerstone of any URC node. Data flows among all the hubs
62 | on the network, and each packet reaches each node. URC does not restrict you
63 | from methods of communication. If you find that URC is difficult to traffic
64 | with your network and/or particular software, please complain so that *I* can
65 | fix it, or at least point you in the right direction. I make no guarantees,
66 | however URC has a history of little to no issues here.
67 |
68 | URC's cache detects duplicate packets and instructs the hub to discard them.
69 | The cache communicates to the hub via pipe and the other URC programs use
70 | AF_UNIX, SOCK_DGRAM. Multiple protocols in the transport layer can carry URC
71 | packets between urchubs.
72 |
--------------------------------------------------------------------------------
/env/addr:
--------------------------------------------------------------------------------
1 | 127.0.0.1
--------------------------------------------------------------------------------
/env/motd:
--------------------------------------------------------------------------------
1 |
2 | "I have tried everything from voting petitions to peaceful
3 | protest and have found that those in power do not want the
4 | truth to be exposed. When we speak truth to power we are
5 | ignored at best and brutally suppressed at worst. We are
6 | confronting a power structure that does not respect its own
7 | system of checks and balances, never mind the rights of it’s
8 | own citizens or the international community." - Jeremy Hammond
9 |
10 | "Information is power. But like all power, there are those who
11 | want to keep it for themselves. The world’s entire scientific
12 | and cultural heritage, published over centuries in books and
13 | journals, is increasingly being digitized and locked up by a
14 | handful of private corporations." - Aaron Swartz
15 |
16 | "Ten years ago it would have been infeasible for tens of
17 | thousands of individuals with no physical connection or
18 | central leadership to conceive, announce, and implement a
19 | massive act of civil disobedience against a significant
20 | Western power, crippling a portion of its online
21 | infrastructure in the process - and to do all of this in a
22 | matter of days, and without anyone involved having to contend
23 | with the tear-gas-and-horseback response with which states
24 | have traditionally been in the habit of contending with mass
25 | action. But such a thing as this is happening today, and having
26 | been done once will almost certainly be done again - repeatedly,
27 | increasingly, and with potentially significant consequences for
28 | the nation-state and implications regarding that which will
29 | perhaps someday come to replace it." - Barrett Brown
30 |
--------------------------------------------------------------------------------
/env/path:
--------------------------------------------------------------------------------
1 | /service/urcd-hub0/socket/
2 |
--------------------------------------------------------------------------------
/env/port:
--------------------------------------------------------------------------------
1 | 6667
--------------------------------------------------------------------------------
/env/serv:
--------------------------------------------------------------------------------
1 | irc.urcd.ano
2 |
--------------------------------------------------------------------------------
/git-commit:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | git add -f \
3 | git-commit \
4 | git-push-github \
5 | .gitignore \
6 | gitd \
7 | Make.sh \
8 | run \
9 | run.log \
10 | run.urcd-curvecp \
11 | run.urc2sd \
12 | run.urc2sd-tor \
13 | src \
14 | README \
15 | install-*.sh \
16 | db \
17 | contrib/ \
18 | doc/ \
19 | stdin.cryptoserv \
20 | COPYRIGHT \
21 | THANKS \
22 | LICENSE \
23 | DONATE
24 |
25 | TZ=UTC git commit --date="`date -u +'%s'`"
26 | test -x /usr/lib/git-core/git-update-server-info && /usr/lib/git-core/git-update-server-info
27 |
--------------------------------------------------------------------------------
/git-push-github:
--------------------------------------------------------------------------------
1 | #!/bin/sh -e
2 | # bet you wish you had the passwd
3 |
4 | torify git push https://github.com/JosephSWilliams/urcd.git master
5 |
--------------------------------------------------------------------------------
/gitd:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | repodir="$(dirname $0)"
3 | touch "$repodir"/.git/git-daemon-export-ok
4 | exec git daemon --listen="$(cat "$repodir"/conf/gitd_ip)" --base-path="$(cat "$repodir"/conf/gitd_basepath)" --reuseaddr
5 |
--------------------------------------------------------------------------------
/install-daemontools.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | ### is this really necessary? ###
4 | mkdir -p /package
5 | chmod 1755 /package
6 | cd /package
7 |
8 | ### download and unpack daemontools ###
9 | if which wget 2>/dev/null 1>&2; then
10 | retr=wget
11 | elif which curl 2>/dev/null 1>&2; then
12 | retr="curl -O"
13 | elif which ftp 2>/dev/null 1>&2; then
14 | retr="ftp"
15 | else
16 | echo "could not find any appropiate way to download sources, no wget, curl or ftp in PATH";
17 | exit 1;
18 | fi
19 | $retr http://cr.yp.to/daemontools/daemontools-0.76.tar.gz
20 | gunzip daemontools-0.76.tar
21 | tar -xpf daemontools-0.76.tar
22 | rm -f daemontools-0.76.tar
23 | cd admin/daemontools-0.76
24 |
25 | ### workaround libc bug ###
26 | sed -i 's/gcc/gcc -include errno.h/' src/conf-cc
27 |
28 | ### compile and install ###
29 | package/install
30 |
31 | ### workaround debian/ubuntu ###
32 | if which apt-get; then
33 | sed -i 's/^exit 0/\/command\/svscanboot \&\n\nexit 0/' /etc/rc.local
34 | ### i don't think we need a reboot to bootstrap daemontools ###
35 | /command/svscanboot 2>/dev/null & disown
36 | chmod +x /etc/rc.local
37 | fi
38 |
39 | ### we want this directory ###
40 | mkdir -p /services/
41 |
--------------------------------------------------------------------------------
/install-libsodium.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | if which wget 2>/dev/null 1>&2; then
4 | retr=wget
5 | elif which curl 2>/dev/null 1>&2; then
6 | retr="curl -O"
7 | elif which ftp 2>/dev/null 1>&2; then
8 | retr="ftp"
9 | else
10 | echo "could not find any appropiate way to download sources, no wget, curl or ftp in PATH";
11 | exit 1;
12 | fi
13 |
14 | rm -rf libsodium-0.6.0
15 | [ -f libsodium-0.6.0.tar.gz ] || $retr http://download.libsodium.org/libsodium/releases/libsodium-0.6.0.tar.gz
16 | tar xzf libsodium-0.6.0.tar.gz
17 |
18 | cd libsodium-0.6.0
19 |
20 | ./configure && make && make install
21 |
--------------------------------------------------------------------------------
/install-libtai.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # Workaround script for creating shared objects on 64-bit
3 | # architectures with libtai.
4 |
5 | # OpenBSD: check for nroff (groff)
6 | if ! which nroff 1>/dev/null; then
7 | echo 'fatal error: need to install nroff (groff)'
8 | exit 1
9 | fi
10 |
11 | if which wget 2>/dev/null 1>&2; then
12 | retr=wget
13 | elif which curl 2>/dev/null 1>&2; then
14 | retr="curl -O"
15 | elif which ftp 2>/dev/null 1>&2; then
16 | retr="ftp"
17 | else
18 | echo "could not find any appropiate way to download sources, no wget, curl or ftp in PATH";
19 | exit 1;
20 | fi
21 |
22 | rm -rf libtai-0.60
23 | [ -f libtai-0.60.tar.gz ] || $retr http://cr.yp.to/libtai/libtai-0.60.tar.gz
24 | tar xzf libtai-0.60.tar.gz
25 |
26 | cd libtai-0.60
27 |
28 | if ! sed -i 's/$/ -fPIC/' conf-* 2>/dev/null; then
29 | for item in $(ls conf-*); do
30 | sed 's/$/ -fPIC/' $item > $item{new}
31 | mv $item{new} $item
32 | done
33 | fi
34 |
35 | make
36 |
37 | cp libtai.a /usr/lib/libtai.a
38 | cp *.h /usr/include/
39 | cp leapsecs.dat /etc/leapsecs.dat
40 |
--------------------------------------------------------------------------------
/install-nacl.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # Workaround script for creating shared objects on 64-bit
3 | # architectures with NaCl. Much thanks to Ivo Smits for
4 | # doing a lot of the work. Thanks to SeekingFor, some
5 | # strange anonymous type person, for OpenBSD support.
6 |
7 | if which wget 2>/dev/null 1>&2; then
8 | retr=wget
9 | elif which curl 2>/dev/null 1>&2; then
10 | retr="curl -O"
11 | elif which ftp 2>/dev/null 1>&2; then
12 | retr=ftp
13 | else
14 | echo "could not find any appropiate way to download sources, no wget, curl or ftp in PATH";
15 | exit 1;
16 | fi
17 | rm -rf nacl-20110221
18 | [ -f nacl-20110221.tar.bz2 ] || $retr http://hyperelliptic.org/nacl/nacl-20110221.tar.bz2
19 | bunzip2 < nacl-20110221.tar.bz2 | tar -xf -
20 |
21 | # Use my patched copy of curvecpserver.c
22 | # sets env $CURVECPCLIENTPUBKEY from a curvecpclient
23 | # clientlongtermpk for programs to check client authentication.
24 | # I hope we'll see this in the main distribution. ucspi-tcp
25 | # style environment variables with *.cdb rules would be nice :-)
26 | # (I replaced all the \tabs with 2 spaces, eww tab)
27 | cat src/curvecpserver.c > nacl-20110221/curvecp/curvecpserver.c
28 |
29 | # Use my patched copy of socket_bind.c
30 | # if AF_UNSPEC fails then try using AF_INET
31 | cat src/socket_bind.c > nacl-20110221/curvecp/socket_bind.c
32 |
33 | cd nacl-20110221
34 |
35 | # ./do will compile an alternative MAC implementation
36 | # that works with shared objects.
37 | rm -r crypto_onetimeauth/poly1305/amd64
38 |
39 | # android patch
40 | echo 'gcc' >> okcompilers/c
41 |
42 | # patch the library for making shared objects on 64 bit
43 | # architectures by compiling with PIC.
44 | if ! sed -i "s/$/ -fPIC/" okcompilers/c 2>/dev/null; then
45 | sed "s/$/ -fPIC/" okcompilers/c > okcompilers/c{new}
46 | mv okcompilers/c{new} okcompilers/c
47 | fi
48 | echo "Starting to compile and benchmark NaCl so it will use the best available implementations for your specific hardware. This might take some time."
49 | ./do
50 |
51 | gcc okcompilers/abiname.c -o abiname
52 | ABINAME="$(./abiname "" | cut -b 2-)"
53 | BUILDDIR="build/$(hostname | sed 's/\..*//' | tr -cd '[a-z][A-Z][0-9]')"
54 |
55 | # install nacl/build in meaningful directories
56 | mkdir -p /usr/include/nacl
57 | cp -i "${BUILDDIR}/bin/"* /usr/bin/
58 | cp -i "${BUILDDIR}/lib/${ABINAME}/"* /usr/lib/
59 | cp -i "${BUILDDIR}/include/${ABINAME}/"* /usr/include/nacl/
60 |
--------------------------------------------------------------------------------
/install-ucspi-ssl.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | ### is this really necessary? ###
4 | mkdir -p /package
5 | chmod 1755 /package
6 | cd /package
7 |
8 | if which wget 2>/dev/null 1>&2; then
9 | retr=wget
10 | elif which curl 2>/dev/null 1>&2; then
11 | retr="curl -O"
12 | elif which ftp 2>/dev/null 1>&2; then
13 | retr="ftp"
14 | else
15 | echo "could not find any appropiate way to download sources, no wget, curl or ftp in PATH";
16 | exit 1;
17 | fi
18 |
19 | $retr http://www.fehcom.de/ipnet/ucspi-ssl/ucspi-ssl-0.95b.tgz
20 | tar -xf ucspi-ssl-0.95b.tgz
21 | cd host/superscript.com/net/ucspi-ssl-0.95b
22 |
23 | ### compile and install ###
24 | package/install
25 |
--------------------------------------------------------------------------------
/install-ucspi-tcp.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | if which wget 2>/dev/null 1>&2; then
4 | retr=wget
5 | elif which curl 2>/dev/null 1>&2; then
6 | retr="curl -O"
7 | elif which ftp 2>/dev/null 1>&2; then
8 | retr="ftp"
9 | else
10 | echo "could not find any appropiate way to download sources, no wget, curl or ftp in PATH";
11 | exit 1;
12 | fi
13 |
14 | $retr http://cr.yp.to/ucspi-tcp/ucspi-tcp-0.88.tar.gz
15 | gunzip ucspi-tcp-0.88.tar
16 | tar -xf ucspi-tcp-0.88.tar
17 | cd ucspi-tcp-0.88/
18 | sed -i 's/^gcc/gcc -include errno.h/' conf-cc
19 | make
20 | make setup check
21 |
--------------------------------------------------------------------------------
/run:
--------------------------------------------------------------------------------
1 | #!/bin/sh -e
2 | exec tcpserver -H -R -l `cat env/addr` `cat env/addr` `cat env/port` ./urcd `cat env/path` 2>&1
3 |
--------------------------------------------------------------------------------
/run.log:
--------------------------------------------------------------------------------
1 | #!/bin/sh -e
2 | mkdir -p main/
3 | chown urcd main/
4 | exec setuidgid urcd multilog t ./main
5 |
--------------------------------------------------------------------------------
/run.urc2sd:
--------------------------------------------------------------------------------
1 | #!/bin/sh -e
2 | exec tcpclient `cat addr` `cat port` ./ucspi-client2server ./urc2sd `cat path` 2>&1
3 |
--------------------------------------------------------------------------------
/run.urc2sd-tor:
--------------------------------------------------------------------------------
1 | #!/bin/sh -e
2 | exec tcpclient 127.0.0.1 9050 ./ucspi-socks4aclient `cat addr` `cat port` ./ucspi-client2server ./urc2sd `cat path` 2>&1
3 |
--------------------------------------------------------------------------------
/run.urcd-curvecp:
--------------------------------------------------------------------------------
1 | #!/bin/sh -e
2 | exec curvecpserver `cat env/serv` curvecp `cat env/addr` `cat env/port` 01110101011100100110001101100100 curvecpmessage ./urcd `cat env/path` 2>&1
3 |
--------------------------------------------------------------------------------
/run.urcd-ssl:
--------------------------------------------------------------------------------
1 | #!/bin/sh -e
2 |
3 | export DHFILE="env/urcd.pem"
4 | export KEYFILE="env/urcd.key"
5 | export CERTFILE="env/urcd.crt"
6 |
7 | exec sslserver -H -R -l `cat env/addr` `cat env/addr` `cat env/port` ./urcd `cat env/path` 2>&1
8 |
--------------------------------------------------------------------------------
/scripts/add-curvecpconnect:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | [ -z $5 ] && \
3 | echo $0' ' 1>&2 && \
4 | exit 64
5 |
6 | mkdir -p /services/urcd-curvecpconnect-"$1:$2" || exit 1
7 |
8 | printf $4 > /services/urcd-curvecpconnect-"$1:$2"/serv || exit 1
9 |
10 | printf $5 > /services/urcd-curvecpconnect-"$1:$2"/pubkey || exit 1
11 |
12 | printf \
13 | "#!/bin/sh -e
14 | export TCPCLIENT=1
15 | exec curvecpclient \`cat serv\` \`cat pubkey\` $1 $2 01110101011100100110001101100100 curvecpmessage -c ./urcstream $3\n" > \
16 | /services/urcd-curvecpconnect-"$1:$2"/run || exit
17 |
18 | chmod +x /services/urcd-curvecpconnect-"$1:$2"/run || exit 1
19 |
20 | test -L /services/urcd-curvecpconnect-"$1:$2"/urcstream || \
21 | ln -s `pwd`/urcstream /services/urcd-curvecpconnect-"$1:$2"/urcstream || \
22 | exit 1
23 |
24 | test -L /service/urcd-curvecpconnect-"$1:$2" || \
25 | ln -s /services/urcd-curvecpconnect-"$1:$2" \
26 | /service/urcd-curvecpconnect-"$1:$2" || \
27 | exit 1
28 |
--------------------------------------------------------------------------------
/scripts/add-curvecphubconnect:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | [ -z $5 ] && \
3 | echo $0' ' 1>&2 && \
4 | exit 64
5 |
6 | mkdir -p /services/urcd-curvecphubconnect-"$1:$2" || exit 1
7 |
8 | printf $4 > /services/urcd-curvecphubconnect-"$1:$2"/serv || exit 1
9 |
10 | printf $5 > /services/urcd-curvecphubconnect-"$1:$2"/pubkey || exit 1
11 |
12 | printf \
13 | "#!/bin/sh -e
14 | export TCPCLIENT=1
15 | exec curvecpclient \`cat serv\` \`cat pubkey\` $1 $2 01110101011100100110001101100100 curvecpmessage -c ./urchubstream $3\n" > \
16 | /services/urcd-curvecphubconnect-"$1:$2"/run || exit
17 |
18 | chmod +x /services/urcd-curvecphubconnect-"$1:$2"/run || exit 1
19 |
20 | test -L /services/urcd-curvecphubconnect-"$1:$2"/urcstream || \
21 | ln -s `pwd`/urchubstream /services/urcd-curvecphubconnect-"$1:$2"/urchubstream || \
22 | exit 1
23 |
24 | test -L /service/urcd-curvecphubconnect-"$1:$2" || \
25 | ln -s /services/urcd-curvecphubconnect-"$1:$2" \
26 | /service/urcd-curvecphubconnect-"$1:$2" || \
27 | exit 1
28 |
--------------------------------------------------------------------------------
/scripts/add-curvecphublisten:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | [ -z $3 ] && \
3 | echo $0' ' 1>&2 && \
4 | exit 64
5 |
6 | mkdir -p /services/urcd-curvecphublisten-"$1:$2" || exit 1
7 |
8 | test -L /services/urcd-curvecphublisten-"$1:$2"/serv || \
9 | ln -s `pwd`/env/serv /services/urcd-curvecphublisten-"$1:$2"/serv || \
10 | exit 1
11 |
12 | curvecpmakekey /services/urcd-curvecphublisten-"$1:$2"/curvecp || exit 1
13 |
14 | find /services/urcd-curvecphublisten-"$1:$2"/curvecp -type d -exec chmod 700 {} \;
15 | find /services/urcd-curvecphublisten-"$1:$2"/curvecp -type f -exec chmod 600 {} \;
16 | chown urcd /services/urcd-curvecphublisten-"$1:$2"/curvecp -R
17 |
18 | printf \
19 | "#!/bin/sh -e
20 | exec curvecpserver \`cat serv\` curvecp $1 $2 01110101011100100110001101100100 curvecpmessage ./urchubstream $3\n" > \
21 | /services/urcd-curvecphublisten-"$1:$2"/run || exit
22 |
23 | chmod +x /services/urcd-curvecphublisten-"$1:$2"/run || exit 1
24 |
25 | test -L /services/urcd-curvecphublisten-"$1:$2"/urchubstream || \
26 | ln -s `pwd`/urchubstream /services/urcd-curvecphublisten-"$1:$2"/urchubstream || \
27 | exit 1
28 |
29 | test -L /service/urcd-curvecphublisten-"$1:$2" || \
30 | ln -s /services/urcd-curvecphublisten-"$1:$2" \
31 | /service/urcd-curvecphublisten-"$1:$2" || \
32 | exit 1
33 |
34 | printf \
35 | "PUBKEY: `curvecpprintkey /services/urcd-curvecphublisten-"$1:$2"/curvecp`\n"
36 |
--------------------------------------------------------------------------------
/scripts/add-curvecplisten:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | [ -z $3 ] && \
3 | echo $0' ' 1>&2 && \
4 | exit 64
5 |
6 | mkdir -p /services/urcd-curvecplisten-"$1:$2" || exit 1
7 |
8 | test -L /services/urcd-curvecplisten-"$1:$2"/serv || \
9 | ln -s `pwd`/env/serv /services/urcd-curvecplisten-"$1:$2"/serv || \
10 | exit 1
11 |
12 | curvecpmakekey /services/urcd-curvecplisten-"$1:$2"/curvecp || exit 1
13 |
14 | find /services/urcd-curvecplisten-"$1:$2"/curvecp -type d -exec chmod 700 {} \;
15 | find /services/urcd-curvecplisten-"$1:$2"/curvecp -type f -exec chmod 600 {} \;
16 | chown urcd /services/urcd-curvecplisten-"$1:$2"/curvecp -R
17 |
18 | printf \
19 | "#!/bin/sh -e
20 | exec curvecpserver \`cat serv\` curvecp $1 $2 01110101011100100110001101100100 curvecpmessage ./urcstream $3\n" > \
21 | /services/urcd-curvecplisten-"$1:$2"/run || exit
22 |
23 | chmod +x /services/urcd-curvecplisten-"$1:$2"/run || exit 1
24 |
25 | test -L /services/urcd-curvecplisten-"$1:$2"/urcstream || \
26 | ln -s `pwd`/urcstream /services/urcd-curvecplisten-"$1:$2"/urcstream || \
27 | exit 1
28 |
29 | test -L /service/urcd-curvecplisten-"$1:$2" || \
30 | ln -s /services/urcd-curvecplisten-"$1:$2" \
31 | /service/urcd-curvecplisten-"$1:$2" || \
32 | exit 1
33 |
34 | printf \
35 | "PUBKEY: `curvecpprintkey /services/urcd-curvecplisten-"$1:$2"/curvecp`\n"
36 |
--------------------------------------------------------------------------------
/scripts/add-curvecprecv:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | [ -z $3 ] && \
3 | echo $0' ' 1>&2 && \
4 | exit 64
5 |
6 | mkdir -p /services/urcd-curvecprecv-"$1:$2" || exit 1
7 |
8 | test -L /services/urcd-curvecprecv-"$1:$2"/serv || \
9 | ln -s `pwd`/env/serv /services/urcd-curvecprecv-"$1:$2"/serv || \
10 | exit 1
11 |
12 | curvecpmakekey /services/urcd-curvecprecv-"$1:$2"/curvecp || exit 1
13 |
14 | find /services/urcd-curvecprecv-"$1:$2"/curvecp -type d -exec chmod 700 {} \;
15 | find /services/urcd-curvecprecv-"$1:$2"/curvecp -type f -exec chmod 600 {} \;
16 | chown urcd /services/urcd-curvecprecv-"$1:$2"/curvecp -R
17 |
18 | printf \
19 | "#!/bin/sh -e
20 | exec curvecpserver \`cat serv\` curvecp $1 $2 01110101011100100110001101100100 curvecpmessage ./urcrecv $3\n" > \
21 | /services/urcd-curvecprecv-"$1:$2"/run || exit
22 |
23 | chmod +x /services/urcd-curvecprecv-"$1:$2"/run || exit 1
24 |
25 | test -L /services/urcd-curvecprecv-"$1:$2"/urcrecv || \
26 | ln -s `pwd`/urcrecv /services/urcd-curvecprecv-"$1:$2"/urcrecv || \
27 | exit 1
28 |
29 | test -L /service/urcd-curvecprecv-"$1:$2" || \
30 | ln -s /services/urcd-curvecprecv-"$1:$2" \
31 | /service/urcd-curvecprecv-"$1:$2" || \
32 | exit 1
33 |
34 | printf \
35 | "PUBKEY: `curvecpprintkey /services/urcd-curvecprecv-"$1:$2"/curvecp`\n"
36 |
--------------------------------------------------------------------------------
/scripts/add-curvecpsend:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | [ -z $5 ] && \
3 | echo $0' ' 1>&2 && \
4 | exit 64
5 |
6 | mkdir -p /services/urcd-curvecpsend-"$1:$2" || exit 1
7 |
8 | printf $4 > /services/urcd-curvecpsend-"$1:$2"/serv || exit 1
9 |
10 | printf $5 > /services/urcd-curvecpsend-"$1:$2"/pubkey || exit 1
11 |
12 | printf \
13 | "#!/bin/sh -e
14 | export TCPCLIENT=1
15 | exec curvecpclient \`cat serv\` \`cat pubkey\` $1 $2 01110101011100100110001101100100 curvecpmessage -c ./urcsend $3\n" > \
16 | /services/urcd-curvecpsend-"$1:$2"/run || exit
17 |
18 | chmod +x /services/urcd-curvecpsend-"$1:$2"/run || exit 1
19 |
20 | test -L /services/urcd-curvecpsend-"$1:$2"/urcsend || \
21 | ln -s `pwd`/urcsend /services/urcd-curvecpsend-"$1:$2"/urcsend || \
22 | exit 1
23 |
24 | test -L /service/urcd-curvecpsend-"$1:$2" || \
25 | ln -s /services/urcd-curvecpsend-"$1:$2" \
26 | /service/urcd-curvecpsend-"$1:$2" || \
27 | exit 1
28 |
--------------------------------------------------------------------------------
/scripts/add-hubconnect:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | [ -z $3 ] && \
3 | echo $0' ' 1>&2 && \
4 | exit 64
5 |
6 | mkdir -p /services/urcd-hubconnect-"$1:$2" || exit 1
7 |
8 | printf '#!/bin/sh -e\n' > \
9 | /services/urcd-hubconnect-"$1:$2"/run || exit 1
10 |
11 | printf 'export TCPCLIENT=1\n' >> \
12 | /services/urcd-hubconnect-"$1:$2"/run || exit 1
13 |
14 | printf "exec tcpclient -H -R $1 $2 ./urchubstream $3\n" >> \
15 | /services/urcd-hubconnect-"$1:$2"/run || exit 1
16 |
17 | chmod +x /services/urcd-hubconnect-"$1:$2"/run || exit 1
18 |
19 | test -L /services/urcd-hubconnect-"$1:$2"/urchubstream || \
20 | ln -s `pwd`/urchubstream /services/urcd-hubconnect-"$1:$2"/urchubstream || \
21 | exit 1
22 |
23 | test -L /service/urcd-hubconnect-"$1:$2" || \
24 | ln -s /services/urcd-hubconnect-"$1:$2" \
25 | /service/urcd-hubconnect-"$1:$2" || \
26 | exit 1
27 |
--------------------------------------------------------------------------------
/scripts/add-hublisten:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | [ -z $3 ] && \
3 | echo $0' ' 1>&2 && \
4 | exit 64
5 |
6 | mkdir -p /services/urcd-hublisten-"$1:$2" || exit 1
7 |
8 | printf '#!/bin/sh -e\n' > \
9 | /services/urcd-hublisten-"$1:$2"/run || exit 1
10 |
11 | printf "exec tcpserver -H -R $1 $2 ./urchubstream $3\n" >> \
12 | /services/urcd-hublisten-"$1:$2"/run || exit 1
13 |
14 | chmod +x /services/urcd-hublisten-"$1:$2"/run || exit 1
15 |
16 | test -L /services/urcd-hublisten-"$1:$2"/urchubstream || \
17 | ln -s `pwd`/urchubstream /services/urcd-hublisten-"$1:$2"/urchubstream || \
18 | exit 1
19 |
20 | test -L /service/urcd-hublisten-"$1:$2" || \
21 | ln -s /services/urcd-hublisten-"$1:$2" \
22 | /service/urcd-hublisten-"$1:$2" || \
23 | exit 1
24 |
--------------------------------------------------------------------------------
/scripts/add-tcpconnect:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | [ -z $3 ] && \
3 | echo $0' ' 1>&2 && \
4 | exit 64
5 |
6 | mkdir -p /services/urcd-tcpconnect-"$1:$2" || exit 1
7 |
8 | printf '#!/bin/sh -e\n' > \
9 | /services/urcd-tcpconnect-"$1:$2"/run || exit 1
10 |
11 | printf 'export TCPCLIENT=1\n' >> \
12 | /services/urcd-tcpconnect-"$1:$2"/run || exit 1
13 |
14 | printf "exec tcpclient -H -R $1 $2 ./urcstream $3\n" >> \
15 | /services/urcd-tcpconnect-"$1:$2"/run || exit 1
16 |
17 | chmod +x /services/urcd-tcpconnect-"$1:$2"/run || exit 1
18 |
19 | test -L /services/urcd-tcpconnect-"$1:$2"/urcstream || \
20 | ln -s `pwd`/urcstream /services/urcd-tcpconnect-"$1:$2"/urcstream || \
21 | exit 1
22 |
23 | test -L /service/urcd-tcpconnect-"$1:$2" || \
24 | ln -s /services/urcd-tcpconnect-"$1:$2" \
25 | /service/urcd-tcpconnect-"$1:$2" || \
26 | exit 1
27 |
--------------------------------------------------------------------------------
/scripts/add-tcplisten:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | [ -z $3 ] && \
3 | echo $0' ' 1>&2 && \
4 | exit 64
5 |
6 | mkdir -p /services/urcd-tcplisten-"$1:$2" || exit 1
7 |
8 | printf '#!/bin/sh -e\n' > \
9 | /services/urcd-tcplisten-"$1:$2"/run || exit 1
10 |
11 | printf "exec tcpserver -H -R $1 $2 ./urcstream $3\n" >> \
12 | /services/urcd-tcplisten-"$1:$2"/run || exit 1
13 |
14 | chmod +x /services/urcd-tcplisten-"$1:$2"/run || exit 1
15 |
16 | test -L /services/urcd-tcplisten-"$1:$2"/urcstream || \
17 | ln -s `pwd`/urcstream /services/urcd-tcplisten-"$1:$2"/urcstream || \
18 | exit 1
19 |
20 | test -L /service/urcd-tcplisten-"$1:$2" || \
21 | ln -s /services/urcd-tcplisten-"$1:$2" \
22 | /service/urcd-tcplisten-"$1:$2" || \
23 | exit 1
24 |
--------------------------------------------------------------------------------
/scripts/add-tcprecv:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | [ -z $3 ] && \
3 | echo $0' ' 1>&2 && \
4 | exit 64
5 |
6 | mkdir -p /services/urcd-tcprecv-"$1:$2" || exit 1
7 |
8 | printf '#!/bin/sh -e\n' > \
9 | /services/urcd-tcprecv-"$1:$2"/run || exit 1
10 |
11 | printf "exec tcpserver -H -R $1 $2 ./urcrecv $3\n" >> \
12 | /services/urcd-tcprecv-"$1:$2"/run || exit 1
13 |
14 | chmod +x /services/urcd-tcprecv-"$1:$2"/run || exit 1
15 |
16 | test -L /services/urcd-tcprecv-"$1:$2"/urcrecv || \
17 | ln -s `pwd`/urcrecv /services/urcd-tcprecv-"$1:$2"/urcrecv || \
18 | exit 1
19 |
20 | test -L /service/urcd-tcprecv-"$1:$2" || \
21 | ln -s /services/urcd-tcprecv-"$1:$2" \
22 | /service/urcd-tcprecv-"$1:$2" || \
23 | exit 1
24 |
--------------------------------------------------------------------------------
/scripts/add-tcpsend:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | [ -z $3 ] && \
3 | echo $0' ' 1>&2 && \
4 | exit 64
5 |
6 | mkdir -p /services/urcd-tcpsend-"$1:$2" || exit 1
7 |
8 | printf '#!/bin/sh -e\n' > \
9 | /services/urcd-tcpsend-"$1:$2"/run || exit 1
10 |
11 | printf "exec tcpclient -H -R $1 $2 ./urcsend $3\n" >> \
12 | /services/urcd-tcpsend-"$1:$2"/run || exit 1
13 |
14 | chmod +x /services/urcd-tcpsend-"$1:$2"/run || exit 1
15 |
16 | test -L /services/urcd-tcpsend-"$1:$2"/urcsend || \
17 | ln -s `pwd`/urcsend /services/urcd-tcpsend-"$1:$2"/urcsend || \
18 | exit 1
19 |
20 | test -L /service/urcd-tcpsend-"$1:$2" || \
21 | ln -s /services/urcd-tcpsend-"$1:$2" \
22 | /service/urcd-tcpsend-"$1:$2" || \
23 | exit 1
24 |
--------------------------------------------------------------------------------
/scripts/add-torconnect:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | [ -z $3 ] && \
3 | echo $0' ' 1>&2 && \
4 | exit 64
5 |
6 | mkdir -p /services/urcd-torconnect-"$1:$2" || exit 1
7 |
8 | test -L /services/urcd-torconnect-"$1:$2"/ucspi-socks4aclient || \
9 | ln -s `pwd`/ucspi-socks4aclient /services/urcd-torconnect-"$1:$2"/ucspi-socks4aclient || exit 1
10 |
11 | printf '#!/bin/sh -e\n' > \
12 | /services/urcd-torconnect-"$1:$2"/run || exit 1
13 |
14 | printf 'export TCPCLIENT=1\n' >> \
15 | /services/urcd-torconnect-"$1:$2"/run || exit 1
16 |
17 | printf "exec tcpclient -H -R 127.0.0.1 9050 ./ucspi-socks4aclient $1 $2 ./urcstream $3\n" >> \
18 | /services/urcd-torconnect-"$1:$2"/run || exit 1
19 |
20 | chmod +x /services/urcd-torconnect-"$1:$2"/run || exit 1
21 |
22 | test -L /services/urcd-torconnect-"$1:$2"/urcstream || \
23 | ln -s `pwd`/urcstream /services/urcd-torconnect-"$1:$2"/urcstream || \
24 | exit 1
25 |
26 | test -L /service/urcd-torconnect-"$1:$2" || \
27 | ln -s /services/urcd-torconnect-"$1:$2" \
28 | /service/urcd-torconnect-"$1:$2" || \
29 | exit 1
30 |
--------------------------------------------------------------------------------
/scripts/add-torhubconnect:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | [ -z $3 ] && \
3 | echo $0' ' 1>&2 && \
4 | exit 64
5 |
6 | mkdir -p /services/urcd-torhubconnect-"$1:$2" || exit 1
7 |
8 |
9 | test -L /services/urcd-torhubconnect-"$1:$2"/ucspi-socks4aclient || \
10 | ln -s `pwd`/ucspi-socks4aclient /services/urcd-torhubconnect-"$1:$2"/ucspi-socks4aclient || exit 1
11 |
12 | printf '#!/bin/sh -e\n' > \
13 | /services/urcd-torhubconnect-"$1:$2"/run || exit 1
14 |
15 | printf 'export TCPCLIENT=1\n' >> \
16 | /services/urcd-torhubconnect-"$1:$2"/run || exit 1
17 |
18 | printf "exec tcpclient -H -R 127.0.0.1 9050 ./ucspi-socks4aclient $1 $2 ./urchubstream $3\n" >> \
19 | /services/urcd-torhubconnect-"$1:$2"/run || exit 1
20 |
21 | chmod +x /services/urcd-torhubconnect-"$1:$2"/run || exit 1
22 |
23 | test -L /services/urcd-torhubconnect-"$1:$2"/urchubstream || \
24 | ln -s `pwd`/urchubstream /services/urcd-torhubconnect-"$1:$2"/urchubstream || \
25 | exit 1
26 |
27 | test -L /service/urcd-torhubconnect-"$1:$2" || \
28 | ln -s /services/urcd-torhubconnect-"$1:$2" \
29 | /service/urcd-torhubconnect-"$1:$2" || \
30 | exit 1
31 |
--------------------------------------------------------------------------------
/scripts/add-torsend:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | [ -z $3 ] && \
3 | echo $0' ' 1>&2 && \
4 | exit 64
5 |
6 | mkdir -p /services/urcd-torsend-"$1:$2" || exit 1
7 |
8 | test -L /services/urcd-torsend-"$1:$2"/ucspi-socks4aclient || \
9 | ln -s `pwd`/ucspi-socks4aclient /services/urcd-torsend-"$1:$2"/ucspi-socks4aclient || exit 1
10 |
11 | printf '#!/bin/sh -e\n' > \
12 | /services/urcd-torsend-"$1:$2"/run || exit 1
13 |
14 | printf "exec tcpclient -H -R 127.0.0.1 9050 ./ucspi-socks4aclient $1 $2 ./urcsend $3\n" >> \
15 | /services/urcd-torsend-"$1:$2"/run || exit 1
16 |
17 | chmod +x /services/urcd-torsend-"$1:$2"/run || exit 1
18 |
19 | test -L /services/urcd-torsend-"$1:$2"/urcsend || \
20 | ln -s `pwd`/urcsend /services/urcd-torsend-"$1:$2"/urcsend || \
21 | exit 1
22 |
23 | test -L /service/urcd-torsend-"$1:$2" || \
24 | ln -s /services/urcd-torsend-"$1:$2" \
25 | /service/urcd-torsend-"$1:$2" || \
26 | exit 1
27 |
--------------------------------------------------------------------------------
/scripts/add-udprecv:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | [ -z $3 ] && \
3 | echo $0' ' 1>&2 && \
4 | exit 64
5 |
6 | mkdir -p /services/urcd-udprecv-"$1:$2" || exit 1
7 |
8 | printf '#!/bin/sh -e\n' > \
9 | /services/urcd-udprecv-"$1:$2"/run || exit 1
10 |
11 | printf "exec ./urc-udprecv $1 $2 $3\n" >> \
12 | /services/urcd-udprecv-"$1:$2"/run || exit 1
13 |
14 | chmod +x /services/urcd-udprecv-"$1:$2"/run || exit 1
15 |
16 | test -L /services/urcd-udprecv-"$1:$2"/urc-udprecv || \
17 | ln -s `pwd`/urc-udprecv /services/urcd-udprecv-"$1:$2"/urc-udprecv || \
18 | exit 1
19 |
20 | test -L /service/urcd-udprecv-"$1:$2" || \
21 | ln -s /services/urcd-udprecv-"$1:$2" \
22 | /service/urcd-udprecv-"$1:$2" || \
23 | exit 1
24 |
--------------------------------------------------------------------------------
/scripts/add-udpsend:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | [ -z $3 ] && \
3 | echo $0' ' 1>&2 && \
4 | exit 64
5 |
6 | mkdir -p /services/urcd-udpsend-"$1:$2" || exit 1
7 |
8 | printf '#!/bin/sh -e\n' > \
9 | /services/urcd-udpsend-"$1:$2"/run || exit 1
10 |
11 | printf "exec ./urc-udpsend $1 $2 $3\n" >> \
12 | /services/urcd-udpsend-"$1:$2"/run || exit 1
13 |
14 | chmod +x /services/urcd-udpsend-"$1:$2"/run || exit 1
15 |
16 | test -L /services/urcd-udpsend-"$1:$2"/urc-udpsend || \
17 | ln -s `pwd`/urc-udpsend /services/urcd-udpsend-"$1:$2"/urc-udpsend || \
18 | exit 1
19 |
20 | test -L /service/urcd-udpsend-"$1:$2" || \
21 | ln -s /services/urcd-udpsend-"$1:$2" \
22 | /service/urcd-udpsend-"$1:$2" || \
23 | exit 1
24 |
--------------------------------------------------------------------------------
/scripts/add-urchub:
--------------------------------------------------------------------------------
1 | #!/bin/sh -e
2 |
3 | n=`ls /services/ | grep urcd-hub | wc -l | sed 's/ //g'`
4 | mkdir -p /services/urcd-hub$n
5 | mkdir -p /services/urcd-hub$n/socket/
6 |
7 | chown urcd /services/urcd-hub$n/socket/
8 |
9 | echo '#!/bin/sh -e' > /services/urcd-hub$n/run
10 | echo 'ulimit -s 8192' >> /services/urcd-hub$n/run
11 | echo 'exec ./urchub ./urccache `pwd`/socket/' >> /services/urcd-hub$n/run
12 | chmod +x /services/urcd-hub$n/run
13 |
14 | test -L /services/urcd-hub$n/urchub || ln -s `pwd`/urchub /services/urcd-hub$n/urchub
15 | test -L /services/urcd-hub$n/urccache || ln -s `pwd`/urccache /services/urcd-hub$n/urccache
16 | test -L /service/urcd-hub$n || ln -s /services/urcd-hub$n /service/urcd-hub$n
17 |
18 | sleep 4
19 | svstat /service/urcd-hub$n
20 |
--------------------------------------------------------------------------------
/scripts/add-urcstream2hub:
--------------------------------------------------------------------------------
1 | #!/bin/sh -e
2 | [ -z $2 ] && \
3 | echo $0' ' 1>&2 && \
4 | exit 64
5 |
6 | n=`ls /services | grep urcd-stream2hub | wc -l`
7 |
8 | mkdir -p /services/urcd-stream2hub$n
9 | mkdir -p /services/urcd-stream2hub$n/env
10 |
11 | echo '0.0' > /services/urcd-stream2hub$n/env/LIMIT
12 |
13 | echo '#!/bin/sh -e' > /services/urcd-stream2hub$n/run
14 | echo "exec ./urcstream2hub $2 ./urcstream $1" >> /services/urcd-stream2hub$n/run
15 | chmod +x /services/urcd-stream2hub$n/run
16 |
17 | test -L /services/urcd-stream2hub$n/urcstream || \
18 | ln -s `pwd`/urcstream /services/urcd-stream2hub$n/urcstream
19 |
20 | test -L /services/urcd-stream2hub$n/urcstream2hub || \
21 | ln -s `pwd`/urcstream2hub /services/urcd-stream2hub$n/urcstream2hub
22 |
23 | test -L /service/urcd-stream2hub$n || \
24 | ln -s /services/urcd-stream2hub$n /service/urcd-stream2hub$n
25 |
26 | sleep 4
27 | svstat /service/urcd-stream2hub$n
28 |
--------------------------------------------------------------------------------
/scripts/scrubsocketdir:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | if [ -z "$1" ] || ! [ -e "$1" ]; then
3 | echo $0': '
4 | exit 64
5 | fi
6 | for i in `ls "$1"`; do
7 | [ "$i" == "hub" ] && continue
8 | [ -e "/proc/$i/" ] || setuidgid urcd rm "$1/$i"
9 | done
10 |
--------------------------------------------------------------------------------
/scripts/urcd.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | if [ $(id -u) != 0 ]; then
4 | echo 'fatal error: root privileges required' 1>&2
5 | exit 1
6 | fi
7 |
8 | path="`pwd`/socket/"
9 | mkdir -p "$path"
10 | chown urcd "$path"
11 |
12 | if ! pidof urchub 1>/dev/null ; then
13 | ./urchub ./urccache "$path" &
14 | fi
15 |
16 | if ! pidof urchubstream 1>/dev/null ; then
17 | addr=(db/urchub/tor/*)
18 | addr="${addr[RANDOM % ${#addr[@]}]}"
19 | port=`cat $addr/port`
20 | addr=`basename $addr`
21 | tcpclient -H -R 127.0.0.1 9050 ./ucspi-socks4aclient $addr $port ./urchubstream "$path"
22 | fi
23 |
24 | exec tcpserver -H -R -l `cat env/addr` `cat env/addr` `cat env/port` ./urcd `cat env/path`
25 |
--------------------------------------------------------------------------------
/src/base16.h:
--------------------------------------------------------------------------------
1 | int base16_encode(unsigned char *a, unsigned char *b, int blen)
2 | {
3 |
4 | int i = 0;
5 | int alen = 0;
6 |
7 | for(i=0;i> 4;
11 | if (a[alen] < 10) a[alen] += 48; else a[alen] += 87;
12 | ++alen;
13 |
14 | a[alen] = b[i] % 16;
15 | if (a[alen] < 10) a[alen] += 48; else a[alen] += 87;
16 | ++alen;
17 |
18 | }
19 |
20 | return alen;
21 |
22 | }
23 |
24 | int base16_decode(unsigned char *b, unsigned char *a, int alen)
25 | {
26 |
27 | int i = 0;
28 | int blen = 0;
29 |
30 | for(i=0;i 47) && (a[i]<58)) b[blen] = a[i] - 48 << 4;
34 | else if ((a[i] > 96) && (a[i] < 103)) b[blen] = a[i] - 87 << 4;
35 | else if ((a[i] > 64) && (a[i] < 71)) b[blen] = a[i] - 55 << 4;
36 | else return blen;
37 | if (++i == alen) return blen;
38 |
39 | if ((a[i] > 47) && (a[i]<58)) b[blen] += a[i] - 48;
40 | else if ((a[i] > 96) && (a[i] < 103)) b[blen] += a[i] - 87;
41 | else if ((a[i] > 64) && (a[i] < 71)) b[blen] += a[i] - 55;
42 | else return blen;
43 | ++blen;
44 |
45 | }
46 |
47 | return blen;
48 |
49 | }
50 |
--------------------------------------------------------------------------------
/src/check-nacl.h:
--------------------------------------------------------------------------------
1 | #include
2 |
--------------------------------------------------------------------------------
/src/check-sodium.h:
--------------------------------------------------------------------------------
1 | #include
2 |
--------------------------------------------------------------------------------
/src/check-taia.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #include
6 | #include
7 |
8 | #include "tai_dec.h"
9 | #include "tai_inc.h"
10 |
11 | main()
12 | {
13 |
14 | unsigned char slow[16] = {0};
15 | unsigned char norm[16] = {0};
16 | unsigned char fast[16] = {0};
17 |
18 | taia_now(norm);
19 |
20 | taia_pack(norm,norm);
21 |
22 | memcpy(slow,norm,16);
23 | memcpy(fast,norm,16);
24 |
25 | tai_dec(slow,slow,"\0\0\0\0\0\0\0\x80");
26 | tai_inc(fast,fast,"\0\0\0\0\0\0\0\x80");
27 |
28 | write(1,slow,16);
29 | write(1,norm,16);
30 | write(1,fast,16);
31 |
32 | int i;
33 |
34 | for (i=0;i<16;++i)
35 | {
36 | if (slow[i] < norm[i]) break;
37 | if (slow[i] > norm[i]) exit(1);
38 | } if (!crypto_verify_16(slow,norm)) exit(2);
39 |
40 | for (i=0;i<16;++i)
41 | {
42 | if (norm[i] < fast[i]) exit(0);
43 | if (norm[i] > fast[i]) exit(3);
44 | } if (!crypto_verify_16(norm,fast)) exit(4);
45 |
46 | }
47 |
--------------------------------------------------------------------------------
/src/cryptoserv.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 | #include
11 | #include
12 | #include
13 | #include
14 | #include
15 | #include
16 | #include
17 | #include
18 | #include
19 |
20 | #include "base16.h"
21 |
22 | #define USAGE "./cryptoserv /path/to/sockets/ /path/to/root/\n"
23 |
24 | #ifndef UNIX_PATH_MAX
25 | #ifdef __NetBSD__
26 | #define UNIX_PATH_MAX 104
27 | #else
28 | #define UNIX_PATH_MAX 108
29 | #endif
30 | #endif
31 |
32 | int itoa(char *s, int n, int slen)
33 | {
34 | if (snprintf(s,slen,"%d",n)<0) return -1;
35 | return 0;
36 | }
37 |
38 | void randombytes(char *bytes) {} // override: hack crypto_*_keypair functions
39 |
40 | void lower(
41 | unsigned char *buffer0,
42 | unsigned char *buffer1,
43 | int buffer1_len
44 | ) {
45 | int i;
46 | for(i=0;i64)&&(buffer1[i]<91)) {
48 | buffer0[i] = buffer1[i] + 32;
49 | }
50 | else buffer0[i] = buffer1[i];
51 | }
52 | }
53 |
54 | main(int argc, char *argv[])
55 | {
56 |
57 | if (argc<3) {
58 | write(2,USAGE,strlen(USAGE));
59 | exit(1);
60 | }
61 |
62 | struct passwd *urcd = getpwnam("urcd");
63 | struct sockaddr_un s;
64 | struct dirent *file;
65 | struct stat stats;
66 |
67 | DIR *directory;
68 |
69 | unsigned char buffer3[1024*2] = {0};
70 | unsigned char buffer2[1024*2] = {0};
71 | unsigned char buffer1[1024*2] = {0};
72 | unsigned char buffer0[1024*2] = {0};
73 | unsigned char identifiednick[256];
74 | unsigned char path[512];
75 | unsigned char hex[192];
76 | unsigned char pk0[32];
77 | unsigned char pk1[32];
78 | unsigned char sk[64];
79 |
80 | float LIMIT;
81 |
82 | long logintime;
83 | long starttime;
84 | long EXPIRY;
85 |
86 | int identifiednicklen;
87 | int loginattempts = 0;
88 | int identified = 0;
89 | int oldnicklen = 0;
90 | int informed = 0;
91 | int nicklen = 0;
92 | int identval=0;
93 | int sfd = -1;
94 | int NICKLEN;
95 | int fd;
96 | int i;
97 |
98 | fd = open("env/LIMIT",0);
99 | if (fd>0)
100 | {
101 | if (read(fd,buffer0,1024)>0) LIMIT = atof(buffer0);
102 | else LIMIT = 1.0;
103 | } else LIMIT = 1.0;
104 | close(fd);
105 |
106 | bzero(buffer0,1024);
107 |
108 | fd = open("env/EXPIRY",0);
109 | if (fd>0)
110 | {
111 | if (read(fd,buffer0,1024)>0) EXPIRY = atol(buffer0) * 24L * 60L * 60L;
112 | else EXPIRY = 32L * 24L * 60L * 60L;
113 | } else EXPIRY = 32L * 24L * 60L * 60L;
114 | close(fd);
115 |
116 | fd = open("env/NICKLEN",0);
117 | if (fd>0)
118 | {
119 | if (read(fd,buffer0,1024)>0) NICKLEN = atoi(buffer0) & 255;
120 | else NICKLEN = 32;
121 | } else NICKLEN = 32;
122 | close(fd);
123 |
124 | bzero(&s,sizeof(s));
125 | s.sun_family = AF_UNIX;
126 |
127 | if ((i=strlen(argv[1])) > UNIX_PATH_MAX) exit(2);
128 | memcpy(s.sun_path,argv[1],i);
129 |
130 | if (((sfd=socket(AF_UNIX,SOCK_DGRAM,0))<0)
131 | || (itoa(s.sun_path+i,getppid(),UNIX_PATH_MAX-i)<0)
132 | || (connect(sfd,(struct sockaddr *)&s,sizeof(s))<0)
133 | || (setsockopt(sfd,SOL_SOCKET,SO_REUSEADDR,&i,sizeof(i))<0))
134 | {
135 | write(2,USAGE,strlen(USAGE));
136 | exit(3);
137 | }
138 |
139 | if ((!urcd)
140 | || (chdir(argv[2]))
141 | || (chroot(argv[2]))
142 | || (setgroups(0,'\x00'))
143 | || (setgid(urcd->pw_gid))
144 | || (setuid(urcd->pw_uid)))
145 | {
146 | write(2,USAGE,strlen(USAGE));
147 | exit(4);
148 | }
149 |
150 | starttime = time((long *)0);
151 | logintime = starttime;
152 |
153 | fcntl(0,F_SETFL,fcntl(0,F_GETFL,0)&~O_NONBLOCK);
154 |
155 | memcpy(buffer2+2+12+4+8,":CryptoServ!URCD@service NOTICE ",32);
156 |
157 | if (EXPIRY) {
158 | memcpy(path,"urcsigndb/",10);
159 | if (!(directory=opendir("urcsigndb/"))) exit(5);
160 | while ((file=readdir(directory)))
161 | {
162 | if (file->d_name[0] == '.') continue;
163 | bzero(path+10,-10+512);
164 | memcpy(path+10,file->d_name,strlen(file->d_name));
165 | stat(path,(struct stat *)&stats);
166 | if (time((long *)0) - stats.st_atime >= EXPIRY) remove(path);
167 | } closedir(directory);
168 |
169 | memcpy(path,"urccryptoboxdir/",16);
170 | if (!(directory=opendir("urccryptoboxdir/"))) exit(6);
171 | while ((file=readdir(directory)))
172 | {
173 | if (file->d_name[0] == '.') continue;
174 | bzero(path+16,-16+512);
175 | memcpy(path+16,file->d_name,strlen(file->d_name));
176 | stat(path,(struct stat *)&stats);
177 | if (time((long *)0) - stats.st_atime >= EXPIRY) remove(path);
178 | } closedir(directory);
179 | /*
180 | memcpy(path,"urccryptoboxpfs/",16);
181 | if (!(directory=opendir("urccryptoboxpfs/"))) exit(6);
182 | while ((file=readdir(directory)))
183 | {
184 | if (file->d_name[0] == '.') continue;
185 | bzero(path+16,-16+512);
186 | memcpy(path+16,file->d_name,strlen(file->d_name));
187 | stat(path,(struct stat *)&stats);
188 | if (time((long *)0) - stats.st_atime >= EXPIRY) remove(path);
189 | } closedir(directory);*/
190 | }
191 |
192 | while (1)
193 | {
194 |
195 | for (i=0;i<1024;++i)
196 | {
197 | if (read(0,buffer0+i,1)<1) exit(7);
198 | if (buffer0[i] == '\r') --i;
199 | if (buffer0[i] == '\n') break;
200 | } if (buffer0[i] != '\n') continue;
201 | ++i;
202 |
203 | lower(buffer1,buffer0,i);
204 |
205 | if ((loginattempts)&&(time((long *)0)-logintime>256)) {
206 | logintime = time((long *)0);
207 | --loginattempts;
208 | }
209 |
210 | /// NICK
211 | if ((i>=7)&&(!memcmp("nick ",buffer1,5))) { /* not reliable */
212 | nicklen=-5+i-1;
213 | for (;nicklen>0;--nicklen) {
214 | if ((buffer1[5+nicklen] == '.') || (buffer1[5+nicklen] == '/')) {
215 | nicklen=oldnicklen;
216 | goto client_write;
217 | }
218 | }
219 | nicklen=-5+i-1;
220 | if (nicklen<=NICKLEN) {
221 | memcpy(buffer2+2+12+4+8+32,buffer1+5,nicklen);
222 | memcpy(buffer2+2+12+4+8+32+nicklen," :",2);
223 | oldnicklen = nicklen;
224 | }
225 | else nicklen = 0;
226 | } else if (nicklen) {
227 | if ((i>=20)&&(!memcmp("privmsg cryptoserv :",buffer1,20))) {
228 |
229 | usleep((int)(LIMIT*1000000));
230 |
231 | /// IDENTIFY
232 | if ((i>=20+5+1+1)&&(!memcmp("ident",buffer1+20,5))) {
233 | if ((i>=20+9+1+1)&&(!memcmp("identify ",buffer1+20,9))) identval=192;
234 | if ((i>=20+9+1+1)&&(!memcmp("identsig ",buffer1+20,9))) identval=128;
235 | if ((i>=20+9+1+1)&&(!memcmp("identenc ",buffer1+20,9))) identval=64;
236 | // if ((i>=20+9+1+1)&&(!memcmp("identoff ",buffer1+20,9))) identval=0;//dunno how to do this yet.
237 | if (identval == 0) continue;
238 |
239 | if (loginattempts == 4) goto invalid_passwd;
240 | ++loginattempts;
241 | bzero(path,512);
242 | memcpy(path,"urcsigndb/",10);
243 | memcpy(path+10,buffer2+2+12+4+8+32,nicklen);
244 | if (((fd=open(path,O_RDONLY))<0) || (read(fd,hex,64)<64) || (base16_decode(pk0,hex,64)<32)) {
245 | memcpy(buffer2+2+12+4+8+32+nicklen+2,"Account does not exist.\n",24);
246 | write(sfd,buffer2,2+12+4+8+32+nicklen+2+24);
247 | close(fd);
248 | continue;
249 | }close(fd);
250 | memcpy(buffer3,buffer0+20+9,-20-9+i-1);
251 | memcpy(buffer3-20-9+i-1,buffer2+2+12+4+8+32,nicklen);
252 | crypto_hash_sha512(sk,buffer3,-20-9+i-1+nicklen);
253 | crypto_sign_keypair(pk1,sk);
254 | if (memcmp(pk0,pk1,32)) {
255 | invalid_passwd:
256 | memcpy(buffer2+2+12+4+8+32+nicklen+2,"Invalid passwd.\n",16);
257 | write(sfd,buffer2,2+12+4+8+32+nicklen+2+16);
258 | continue;
259 | }
260 | bzero(path,512);
261 | memcpy(path,"urccryptoboxdir/",16);
262 | memcpy(path+16,buffer2+2+12+4+8+32,nicklen);
263 | if (((fd=open(path,O_RDONLY))<0) || (read(fd,hex,64)<64) || (base16_decode(pk0,hex,64)<32)) {
264 | memcpy(buffer2+2+12+4+8+32+nicklen+2,"Account does not exist.\n",24);
265 | write(sfd,buffer2,2+12+4+8+32+nicklen+2+24);
266 | close(fd);
267 | continue;
268 | }close(fd);
269 | crypto_scalarmult_curve25519_base(pk1,sk);
270 | if (memcmp(pk0,pk1,32)) {
271 | memcpy(buffer2+2+12+4+8+32+nicklen+2,"Invalid passwd.\n",16);
272 | write(sfd,buffer2,2+12+4+8+32+nicklen+2+16);
273 | continue;
274 | }
275 | base16_encode(hex,sk,32);
276 | base16_encode(hex+64,sk,64);
277 | memcpy(buffer0,"PASS ",5);
278 | memcpy(buffer0+5,hex+((identval==128)?64:0),identval);
279 | memcpy(buffer0+5+identval,"\n",1);
280 | if (write(1,buffer0,5+identval+1)<=0) exit(8);
281 | memcpy(buffer2+2+12+4+8+32+nicklen+2,"Success\n",8);
282 | write(sfd,buffer2,2+12+4+8+32+nicklen+2+8);
283 | memcpy(identifiednick,buffer2+2+12+4+8+32,nicklen);
284 | identifiednicklen = nicklen;
285 | loginattempts = 0;
286 | identified = 1;
287 | continue;
288 | }
289 |
290 | /// REGISTER
291 | if ((i>=20+9+1+1)&&(!memcmp("register ",buffer1+20,9))) {
292 | if ((identified) || (time((long *)0)-starttime<128)) goto HELP;
293 | memcpy(buffer3,buffer0+20+9,-20-9+i-1);
294 | memcpy(buffer3-20-9+i-1,buffer2+2+12+4+8+32,nicklen);
295 | crypto_hash_sha512(sk,buffer3,-20-9+i-1+nicklen);
296 | REGISTER:
297 | crypto_sign_keypair(pk0,sk);
298 | bzero(path,512);
299 | memcpy(path,"urcsigndb/",10);
300 | if (identified) memcpy(path+10,identifiednick,identifiednicklen);
301 | else memcpy(path+10,buffer2+2+12+4+8+32,nicklen);
302 | if ((!access(path,F_OK))&&(!identified)) {
303 | memcpy(buffer2+2+12+4+8+32+nicklen+2,"Account already exists.\n",24);
304 | write(sfd,buffer2,2+12+4+8+32+nicklen+2+24);
305 | continue;
306 | }
307 | if (((fd=open(path,O_CREAT|O_WRONLY))<0) || (fchmod(fd,S_IRUSR|S_IWUSR))<0) {
308 | memcpy(buffer2+2+12+4+8+32+nicklen+2,"Failure\n",8);
309 | write(sfd,buffer2,2+12+4+8+32+nicklen+2+8);
310 | close(fd);
311 | continue;
312 | }
313 | base16_encode(hex,pk0,32);
314 | if (write(fd,hex,64)<64) exit(9);
315 | close(fd);
316 | crypto_scalarmult_curve25519_base(pk0,sk);
317 | bzero(path,512);
318 | memcpy(path,"urccryptoboxdir/",16);
319 | if (identified) memcpy(path+16,identifiednick,identifiednicklen);
320 | else memcpy(path+16,buffer2+2+12+4+8+32,nicklen);
321 | if (((fd=open(path,O_CREAT|O_WRONLY))<0) || (fchmod(fd,S_IRUSR|S_IWUSR))<0) {
322 | memcpy(buffer2+2+12+4+8+32+nicklen+2,"Failure\n",8);
323 | write(sfd,buffer2,2+12+4+8+32+nicklen+2+8);
324 | close(fd);
325 | continue;
326 | }
327 | base16_encode(hex,pk0,32);
328 | if (write(fd,hex,64)<64) exit(10);
329 | close(fd);
330 | base16_encode(hex,sk,32);
331 | base16_encode(hex+64,sk,64);
332 | memcpy(buffer0,"PASS ",5);
333 | memcpy(buffer0+5,hex,192);
334 | memcpy(buffer0+5+192,"\n",1);
335 | if (write(1,buffer0,5+192+1)<=0) exit(11);
336 | memcpy(buffer2+2+12+4+8+32+nicklen+2,"Success\n",8);
337 | write(sfd,buffer2,2+12+4+8+32+nicklen+2+8);
338 | if (!identified) {
339 | memcpy(identifiednick,buffer2+2+12+4+8+32,nicklen);
340 | identifiednicklen = nicklen;
341 | identified = 1;
342 | }
343 | continue;
344 | }
345 |
346 | /// SET PASSWORD
347 | if ((i>=20+13+1+1)&&(!memcmp("set password ",buffer1+20,13))) {
348 | if (!identified) goto HELP;
349 | memcpy(buffer3,buffer0+20+13,-20-13+i-1);
350 | memcpy(buffer3-20-13+i-1,identifiednick,identifiednicklen);
351 | crypto_hash_sha512(sk,buffer3,-20-13+i-1+identifiednicklen);
352 | goto REGISTER;
353 | }
354 |
355 | /// SET PFS
356 | if ((i>=20+8+2+1)&&(!memcmp("set pfs ",buffer1+20,8))) {
357 | if (!identified) {
358 | memcpy(buffer2+2+12+4+8+32+nicklen+2,"You are not identified.\n",24);
359 | write(sfd,buffer2,2+12+4+8+32+nicklen+2+24);
360 | continue;
361 | }
362 | bzero(path,512);
363 | memcpy(path,"urccryptoboxpfs/",16);
364 | memcpy(path+16,identifiednick,identifiednicklen);
365 | if ((i>=20+8+3+1)&&(!memcmp("off",buffer1+20+8,3))) {
366 | if (remove(path)<0) {
367 | memcpy(buffer2+2+12+4+8+32+nicklen+2,"Failure\n",8);
368 | write(sfd,buffer2,2+12+4+8+32+nicklen+2+8);
369 | continue;
370 | }
371 | } else if ((i>=20+8+2+1)&&(!memcmp("on",buffer1+20+8,2))) {
372 | if ((fd=open(path,O_CREAT))<0) {
373 | memcpy(buffer2+2+12+4+8+32+nicklen+2,"Failure\n",8);
374 | write(sfd,buffer2,2+12+4+8+32+nicklen+2+8);
375 | close(fd);
376 | continue;
377 | }close(fd);
378 | } else {
379 | memcpy(buffer2+2+12+4+8+32+nicklen+2,"Invalid option.\n",16);
380 | write(sfd,buffer2,2+12+4+8+32+nicklen+2+16);
381 | continue;
382 | }
383 | memcpy(buffer2+2+12+4+8+32+nicklen+2,"Success\n",8);
384 | write(sfd,buffer2,2+12+4+8+32+nicklen+2+8);
385 | continue;
386 | }
387 |
388 | /// DROP
389 | if ((i>=20+4)&&(!memcmp("drop",buffer1+20,4))) {
390 | if (!identified) goto HELP;
391 | bzero(path,512);
392 | memcpy(path,"urccryptoboxdir/",16);
393 | memcpy(path+16,identifiednick,identifiednicklen);
394 | if (remove(path)<0) {
395 | memcpy(buffer2+2+12+4+8+32+nicklen+2,"Failure\n",8);
396 | write(sfd,buffer2,2+12+4+8+32+nicklen+2+8);
397 | }
398 | bzero(path,512);
399 | memcpy(path,"urcsigndb/",10);
400 | memcpy(path+10,identifiednick,identifiednicklen);
401 | if (remove(path)<0) {
402 | memcpy(buffer2+2+12+4+8+32+nicklen+2,"Failure\n",8);
403 | write(sfd,buffer2,2+12+4+8+32+nicklen+2+8);
404 | continue;
405 | }
406 | memcpy(buffer0,"PASS ",5);
407 | memcpy(buffer0+5+192,"\n",1);
408 | for (i=0;i<192;++i) buffer0[5+i]='0';
409 | if (write(1,buffer0,5+192+1)<=0) exit(12);
410 | memcpy(buffer2+2+12+4+8+32+nicklen+2,"Success\n",8);
411 | write(sfd,buffer2,2+12+4+8+32+nicklen+2+8);
412 | starttime = time((long *)0);
413 | identified = 0;
414 | continue;
415 | }
416 |
417 | /// LOGOUT
418 | if ((i>=20+6)&&(!memcmp("logout",buffer1+20,6))) {
419 | if (!identified) {
420 | memcpy(buffer2+2+12+4+8+32+nicklen+2,"You are not identified.\n",24);
421 | write(sfd,buffer2,2+12+4+8+32+nicklen+2+24);
422 | continue;
423 | }
424 | memcpy(buffer0,"PASS ",5);
425 | memcpy(buffer0+5+192,"\n",1);
426 | for (i=0;i<192;++i) buffer0[5+i]='0';
427 | if (write(1,buffer0,5+192+1)<=0) exit(13);
428 | memcpy(buffer2+2+12+4+8+32+nicklen+2,"Success\n",8);
429 | write(sfd,buffer2,2+12+4+8+32+nicklen+2+8);
430 | starttime = time((long *)0);
431 | identified = 0;
432 | continue;
433 | }
434 |
435 | /// HELP
436 | if ((i>=20+4)&&(!memcmp("help",buffer1+20,4))) {
437 | HELP:
438 | informed = 1;
439 | memcpy(buffer2+2+12+4+8+32+nicklen+2,"The following commands will most likely take effect when you and/or your peers /reconnect:\n",91);
440 | write(sfd,buffer2,2+12+4+8+32+nicklen+2+91);
441 | memcpy(buffer2+2+12+4+8+32+nicklen+2,"`REGISTER ' after 128 seconds to create an account.\n",60);
442 | write(sfd,buffer2,2+12+4+8+32+nicklen+2+60);
443 | memcpy(buffer2+2+12+4+8+32+nicklen+2,"`IDENTIFY ' to login to your account and activate URCSIGN and URCCRYPTOBOX.\n",84);
444 | write(sfd,buffer2,2+12+4+8+32+nicklen+2+84);
445 | memcpy(buffer2+2+12+4+8+32+nicklen+2,"`IDENTENC ' to login to your account and activate URCCRYPTOBOX.\n",72);
446 | write(sfd,buffer2,2+12+4+8+32+nicklen+2+72);
447 | memcpy(buffer2+2+12+4+8+32+nicklen+2,"`IDENTSIG ' to login to your account and activate URCSIGN.\n",67);
448 | write(sfd,buffer2,2+12+4+8+32+nicklen+2+67);
449 | memcpy(buffer2+2+12+4+8+32+nicklen+2,"`SET PASSWORD ' changes your password after you REGISTER/IDENTIFY.\n",75);
450 | write(sfd,buffer2,2+12+4+8+32+nicklen+2+75);
451 | memcpy(buffer2+2+12+4+8+32+nicklen+2,"`SET PFS ' toggles perfect forward secrecy for PM after /reconnect\n",76);
452 | write(sfd,buffer2,2+12+4+8+32+nicklen+2+76);
453 | memcpy(buffer2+2+12+4+8+32+nicklen+2,"`DROP' removes your account after you REGISTER/IDENTIFY.\n",57);
454 | write(sfd,buffer2,2+12+4+8+32+nicklen+2+57);
455 | memcpy(buffer2+2+12+4+8+32+nicklen+2,"`LOGOUT' deactivates URCSIGN and URCCRYPTOBOX.\n",47);
456 | write(sfd,buffer2,2+12+4+8+32+nicklen+2+47);
457 | }
458 |
459 | if (!informed) goto HELP;
460 | continue;
461 | }
462 | }
463 | client_write:
464 | if (write(1,buffer0,i)<=0) exit(14);
465 | if ((i>=4)&&(!memcmp("quit",buffer1,4))) {
466 | write(1,"",0); // send EOF
467 | exit(15);
468 | }
469 | }
470 | }
471 |
--------------------------------------------------------------------------------
/src/dprintf.h:
--------------------------------------------------------------------------------
1 | /* NetBSD workaround: (thanks epoch) */
2 | #ifdef HAVE_NBTOOL_CONFIG_H
3 | #include "nbtool_config.h"
4 | #endif
5 |
6 | #if !HAVE_DPRINTF
7 | #include
8 | #ifndef HAVE_NBTOOL_CONFIG_H
9 | #include
10 | #include
11 | #include
12 | #endif
13 |
14 | int dprintf(int fd, const char *format, ...) {
15 | FILE *f;
16 | int d;
17 | va_list ap;
18 | if ((d=dup(fd))==-1) return -1;
19 | if ((f=fdopen(d,"r+"))==NULL) {
20 | close(d);
21 | return -1;
22 | }
23 | va_start(ap,format);
24 | d=vfprintf(f,format,ap);
25 | va_end(ap);
26 | fclose(f);
27 | return d;
28 | }
29 |
30 | #endif
31 |
--------------------------------------------------------------------------------
/src/keypair.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | int main(){
5 | unsigned char pk [32];
6 | unsigned char sk [32];
7 | int i ;
8 |
9 | crypto_box_keypair(pk,sk);
10 |
11 | printf("PUBKEY: ");
12 | for (i=0;i<32;++i) printf("%02x",pk[i]);
13 | printf("\n");
14 |
15 | printf("SECKEY: ");
16 | for (i=0;i<32;++i) printf("%02x",sk[i]);
17 | printf("\n");}
18 | /*
19 | void randombytes(char *bytes) {
20 | read(0,bytes,32);}*/
21 |
--------------------------------------------------------------------------------
/src/liburc.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include "liburc.h"
4 |
5 | /* security: enforce compatibility and santize malicious configurations */
6 | #if crypto_sign_SECRETKEYBYTES != 64
7 | exit(255);
8 | #endif
9 | #if crypto_sign_PUBLICKEYBYTES != 32
10 | exit(255);
11 | #endif
12 | #if crypto_sign_BYTES != 64
13 | exit(255);
14 | #endif
15 |
16 | #define URC_MTU 1024
17 | #define IRC_MTU 512
18 |
19 | /* ImportError: workaround dummy init function (initliburc) */
20 | PyObject *pyliburc(PyObject *self) { return Py_BuildValue("i", 0); }
21 |
22 | PyObject *pyurc_jail(PyObject *self, PyObject *args, PyObject *kw) {
23 | char *path;
24 | Py_ssize_t pathsize = 0;
25 | static const char *kwlist[] = {"path",0};
26 | if (!PyArg_ParseTupleAndKeywords(
27 | args,
28 | kw,
29 | "|s#:urc_jail",
30 | (char **)kwlist,
31 | &path,
32 | &pathsize
33 | )) return Py_BuildValue("i", -1);
34 | return Py_BuildValue("i", urc_jail(path));
35 | }
36 |
37 | PyObject *pyrandombytes(PyObject *self, PyObject *args, PyObject *kw){
38 | PyObject *bytes;
39 | unsigned char *b;
40 | Py_ssize_t n = 0;
41 | static const char *kwlist[] = {"n",0};
42 | if (!PyArg_ParseTupleAndKeywords(args, kw,
43 | #if PY_VERSION_HEX < 0x02050000
44 | "|i:randombytes",
45 | #else
46 | "|n:randombytes",
47 | #endif
48 | (char **)kwlist,
49 | &n
50 | ))
51 | return PyBytes_FromStringAndSize("", 0);
52 | b = PyMem_Malloc(n);
53 | if (!b) return PyBytes_FromStringAndSize("", 0);
54 | randombytes(b,n);
55 | bytes = PyBytes_FromStringAndSize((char *)b, n);
56 | PyMem_Free(b);
57 | return bytes;
58 | }
59 |
60 | PyObject *pyurchub_fmt(PyObject *self, PyObject *args, PyObject *kw) {
61 | unsigned char p[1024*2];
62 | char *b;
63 | Py_ssize_t psize = 0;
64 | Py_ssize_t bsize = 0;
65 | static const char *kwlist[] = {"b",0};
66 | if (!PyArg_ParseTupleAndKeywords(
67 | args,
68 | kw,
69 | "|s#:urchub_fmt",
70 | (char **)kwlist,
71 | &b,
72 | &bsize
73 | )) return Py_BuildValue("i", -1);
74 | if (bsize > IRC_MTU) return Py_BuildValue("i", -1);
75 | if (urchub_fmt(p,&psize,b,bsize) == -1) return Py_BuildValue("i", -1);
76 | return PyBytes_FromStringAndSize((char *)p, psize);
77 | }
78 |
79 | PyObject *pyurcsign_fmt(PyObject *self, PyObject *args, PyObject *kw) {
80 | unsigned char p[1024*2];
81 | char *b;
82 | char *sk;
83 | Py_ssize_t psize = 0;
84 | Py_ssize_t bsize = 0;
85 | Py_ssize_t sksize = 0;
86 | static const char *kwlist[] = {"b","sk",0};
87 | if (!PyArg_ParseTupleAndKeywords(
88 | args,
89 | kw,
90 | "|s#s#:urcsign_fmt",
91 | (char **)kwlist,
92 | &b,
93 | &bsize,
94 | &sk,
95 | &sksize
96 | )) return Py_BuildValue("i", -1);
97 | if (sksize != 64) return Py_BuildValue("i", -1);
98 | if (bsize > IRC_MTU) return Py_BuildValue("i", -1);
99 | if (urcsign_fmt(p,&psize,b,bsize,sk) == -1) return Py_BuildValue("i", -1);
100 | return PyBytes_FromStringAndSize((char *)p, psize);
101 | }
102 |
103 | PyObject *pyurcsign_verify(PyObject *self, PyObject *args, PyObject *kw) {
104 | unsigned char *p;
105 | unsigned char *pk;
106 | Py_ssize_t psize = 0;
107 | Py_ssize_t pksize = 0;
108 | static const char *kwlist[] = {"p", "pk", 0};
109 | if (!PyArg_ParseTupleAndKeywords(
110 | args,
111 | kw,
112 | "|s#s#:urcsign_verify",
113 | (char **)kwlist,
114 | &p,
115 | &psize,
116 | &pk,
117 | &pksize
118 | )) return Py_BuildValue("i", -1);
119 | if (pksize != 32) return Py_BuildValue("i", -1);
120 | if (urcsign_verify(p,psize,pk) == -1) return Py_BuildValue("i", -1);
121 | return Py_BuildValue("i", 0);
122 | }
123 |
124 | PyObject *pyurcsecretbox_fmt(PyObject *self, PyObject *args, PyObject *kw) {
125 | unsigned char p[1024*2];
126 | char *b;
127 | char *sk;
128 | Py_ssize_t psize = 0;
129 | Py_ssize_t bsize = 0;
130 | Py_ssize_t sksize = 0;
131 | static const char *kwlist[] = {"b","sk",0};
132 | if (!PyArg_ParseTupleAndKeywords(
133 | args,
134 | kw,
135 | "|s#s#:urcsecretbox_fmt",
136 | (char **)kwlist,
137 | &b,
138 | &bsize,
139 | &sk,
140 | &sksize
141 | )) return Py_BuildValue("i", -1);
142 | if (sksize != 32) return Py_BuildValue("i", -1);
143 | if (bsize > IRC_MTU) return Py_BuildValue("i", -1);
144 | if (urcsecretbox_fmt(p,&psize,b,bsize,sk) == -1) return Py_BuildValue("i", -1);
145 | return PyBytes_FromStringAndSize((char *)p, psize);
146 | }
147 |
148 | PyObject *pyurcsecretbox_open(PyObject *self, PyObject *args, PyObject *kw) {
149 | unsigned char b[1024*2];
150 | char *p;
151 | char *sk;
152 | Py_ssize_t bsize = 0;
153 | Py_ssize_t psize = 0;
154 | Py_ssize_t sksize = 0;
155 | static const char *kwlist[] = {"p","sk",0};
156 | if (!PyArg_ParseTupleAndKeywords(
157 | args,
158 | kw,
159 | "|s#s#:urcsecretbox_open",
160 | (char **)kwlist,
161 | &p,
162 | &psize,
163 | &sk,
164 | &sksize
165 | )) return Py_BuildValue("i", -1);
166 | if (sksize != 32) return Py_BuildValue("i", -1);
167 | if (psize > URC_MTU) return Py_BuildValue("i", -1);
168 | if (urcsecretbox_open(b,&bsize,p,psize,sk) == -1) return Py_BuildValue("i", -1);
169 | return PyBytes_FromStringAndSize((char *)b, bsize);
170 | }
171 |
172 | PyObject *pyurcsignsecretbox_fmt(PyObject *self, PyObject *args, PyObject *kw) {
173 | unsigned char p[1024*2];
174 | char *b;
175 | char *ssk;
176 | char *csk;
177 | Py_ssize_t psize = 0;
178 | Py_ssize_t bsize = 0;
179 | Py_ssize_t ssksize = 0;
180 | Py_ssize_t csksize = 0;
181 | static const char *kwlist[] = {"b","ssk","csk",0};
182 | if (!PyArg_ParseTupleAndKeywords(
183 | args,
184 | kw,
185 | "|s#s#s#:urcsignsecretbox_fmt",
186 | (char **)kwlist,
187 | &b,
188 | &bsize,
189 | &ssk,
190 | &ssksize,
191 | &csk,
192 | &csksize
193 | )) return Py_BuildValue("i", -1);
194 | if (ssksize != 64) return Py_BuildValue("i", -1);
195 | if (csksize != 32) return Py_BuildValue("i", -1);
196 | if (bsize > IRC_MTU) return Py_BuildValue("i", -1);
197 | if (urcsignsecretbox_fmt(p,&psize,b,bsize,ssk,csk) == -1) return Py_BuildValue("i", -1);
198 | return PyBytes_FromStringAndSize((char *)p, psize);
199 | }
200 |
201 | PyObject *pyurcsignsecretbox_open(PyObject *self, PyObject *args, PyObject *kw) {
202 | unsigned char b[1024*2];
203 | char *p;
204 | char *csk;
205 | Py_ssize_t bsize = 0;
206 | Py_ssize_t psize = 0;
207 | Py_ssize_t csksize = 0;
208 | static const char *kwlist[] = {"p","csk",0};
209 | if (!PyArg_ParseTupleAndKeywords(
210 | args,
211 | kw,
212 | "|s#s#:urcsignsecretbox_open",
213 | (char **)kwlist,
214 | &p,
215 | &psize,
216 | &csk,
217 | &csksize
218 | )) return Py_BuildValue("i", -1);
219 | if (csksize != 32) return Py_BuildValue("i", -1);
220 | if (psize > URC_MTU) return Py_BuildValue("i", -1);
221 | if (urcsignsecretbox_open(b,&bsize,p,psize,csk) == -1) return Py_BuildValue("i", -1);
222 | return PyBytes_FromStringAndSize((char *)b, bsize);
223 | }
224 |
225 | PyObject *pyurcsignsecretbox_verify(PyObject *self, PyObject *args, PyObject *kw) {
226 | unsigned char *p;
227 | unsigned char *pk;
228 | Py_ssize_t psize = 0;
229 | Py_ssize_t pksize = 0;
230 | static const char *kwlist[] = {"p", "pk", 0};
231 | if (!PyArg_ParseTupleAndKeywords(
232 | args,
233 | kw,
234 | "|s#s#:urcsignsecretbox_verify",
235 | (char **)kwlist,
236 | &p,
237 | &psize,
238 | &pk,
239 | &pksize
240 | )) return Py_BuildValue("i", -1);
241 | if (pksize != 32) return Py_BuildValue("i", -1);
242 | if (urcsignsecretbox_verify(p,psize,pk) == -1) return Py_BuildValue("i", -1);
243 | return Py_BuildValue("i", 0);
244 | }
245 |
246 | PyObject *pyurccryptobox_fmt(PyObject *self, PyObject *args, PyObject *kw) {
247 | unsigned char p[1024*2];
248 | char *b;
249 | char *pk;
250 | char *sk;
251 | Py_ssize_t psize = 0;
252 | Py_ssize_t bsize = 0;
253 | Py_ssize_t pksize = 0;
254 | Py_ssize_t sksize = 0;
255 | static const char *kwlist[] = {"b","pk","sk",0};
256 | if (!PyArg_ParseTupleAndKeywords(
257 | args,
258 | kw,
259 | "|s#s#s#:urccryptobox_fmt",
260 | (char **)kwlist,
261 | &b,
262 | &bsize,
263 | &pk,
264 | &pksize,
265 | &sk,
266 | &sksize
267 | )) return Py_BuildValue("i", -1);
268 | if (pksize != 32) return Py_BuildValue("i", -1);
269 | if (sksize != 32) return Py_BuildValue("i", -1);
270 | if (bsize > IRC_MTU) return Py_BuildValue("i", -1);
271 | if (urccryptobox_fmt(p,&psize,b,bsize,pk,sk) == -1) return Py_BuildValue("i", -1);
272 | return PyBytes_FromStringAndSize((char *)p, psize);
273 | }
274 |
275 | PyObject *pyurccryptobox_open(PyObject *self, PyObject *args, PyObject *kw) {
276 | unsigned char b[1024*2];
277 | char *p;
278 | char *pk;
279 | char *sk;
280 | Py_ssize_t bsize = 0;
281 | Py_ssize_t psize = 0;
282 | Py_ssize_t pksize = 0;
283 | Py_ssize_t sksize = 0;
284 | static const char *kwlist[] = {"p","pk","sk",0};
285 | if (!PyArg_ParseTupleAndKeywords(
286 | args,
287 | kw,
288 | "|s#s#s#:urccryptobox_open",
289 | (char **)kwlist,
290 | &p,
291 | &psize,
292 | &pk,
293 | &pksize,
294 | &sk,
295 | &sksize
296 | )) return Py_BuildValue("i", -1);
297 | if (pksize != 32) return Py_BuildValue("i", -1);
298 | if (sksize != 32) return Py_BuildValue("i", -1);
299 | if (psize > URC_MTU) return Py_BuildValue("i", -1);
300 | if (urccryptobox_open(b,&bsize,p,psize,pk,sk) == -1) return Py_BuildValue("i", -1);
301 | return PyBytes_FromStringAndSize((char *)b, bsize);
302 | }
303 |
304 | PyObject *pyurccryptoboxpfs_fmt(PyObject *self, PyObject *args, PyObject *kw) {
305 | unsigned char p[1024*2];
306 | char *b;
307 | char *pk0;
308 | char *sk0;
309 | char *pk1;
310 | char *sk1;
311 | Py_ssize_t psize = 0;
312 | Py_ssize_t bsize = 0;
313 | Py_ssize_t pk0size = 0;
314 | Py_ssize_t sk0size = 0;
315 | Py_ssize_t pk1size = 0;
316 | Py_ssize_t sk1size = 0;
317 | static const char *kwlist[] = {"b","pk0","sk0","pk1","sk1",0};
318 | if (!PyArg_ParseTupleAndKeywords(
319 | args,
320 | kw,
321 | "|s#s#s#s#s#:urccryptoboxpfs_fmt",
322 | (char **)kwlist,
323 | &b,
324 | &bsize,
325 | &pk0,
326 | &pk0size,
327 | &sk0,
328 | &sk0size,
329 | &pk1,
330 | &pk1size,
331 | &sk1,
332 | &sk1size
333 | )) return Py_BuildValue("i", -1);
334 | if (pk0size != 32) return Py_BuildValue("i", -1);
335 | if (sk0size != 32) return Py_BuildValue("i", -1);
336 | if (pk1size != 32) return Py_BuildValue("i", -1);
337 | if (sk1size != 32) return Py_BuildValue("i", -1);
338 | if (bsize > IRC_MTU) return Py_BuildValue("i", -1);
339 | if (urccryptoboxpfs_fmt(p,&psize,b,bsize,pk0,sk0,pk1,sk1) == -1) return Py_BuildValue("i", -1);
340 | return PyBytes_FromStringAndSize((char *)p, psize);
341 | }
342 |
343 | PyObject *pyurccryptoboxpfs_open(PyObject *self, PyObject *args, PyObject *kw) {
344 | unsigned char b[1024*2];
345 | unsigned char pk0[32];
346 | unsigned char zk[32];
347 | char *p;
348 | char *sk0;
349 | char *pk1;
350 | char *sk1;
351 | Py_ssize_t bsize = 0;
352 | Py_ssize_t psize = 0;
353 | Py_ssize_t sk0size = 0;
354 | Py_ssize_t pk1size = 0;
355 | Py_ssize_t sk1size = 0;
356 | static const char *kwlist[] = {"p","sk0","pk1","sk1",0};
357 | if (!PyArg_ParseTupleAndKeywords(
358 | args,
359 | kw,
360 | "|s#s#s#s#:urccryptoboxpfs_open",
361 | (char **)kwlist,
362 | &p,
363 | &psize,
364 | &sk0,
365 | &sk0size,
366 | &pk1,
367 | &pk1size,
368 | &sk1,
369 | &sk1size
370 | )) return Py_BuildValue("i", -1);
371 | if (sk0size != 32) return Py_BuildValue("i", -1);
372 | if (pk1size != 32) return Py_BuildValue("i", -1);
373 | if (sk1size != 32) return Py_BuildValue("i", -1);
374 | if (psize > URC_MTU) return Py_BuildValue("i", -1);
375 | if (urccryptoboxpfs_open(b,&bsize,p,psize,pk0,sk0,pk1,sk1) == -1) {
376 | bzero(zk,32);
377 | if (crypto_verify_32(pk0,zk)) return Py_BuildValue("OO",
378 | PyBytes_FromStringAndSize((char *)pk0, 32),
379 | Py_BuildValue("i", -1)
380 | );
381 | return Py_BuildValue("OO",
382 | Py_BuildValue("i", -1),
383 | Py_BuildValue("i", -1)
384 | );
385 | }
386 | return Py_BuildValue("OO",
387 | PyBytes_FromStringAndSize((char *)pk0, 32),
388 | PyBytes_FromStringAndSize((char *)b, bsize)
389 | );
390 | }
391 |
392 | static PyMethodDef Module_methods[] = {
393 | { "liburc", pyliburc, METH_NOARGS },
394 | { "urc_jail", pyurc_jail, METH_VARARGS|METH_KEYWORDS},
395 | { "randombytes", pyrandombytes, METH_VARARGS|METH_KEYWORDS},
396 | { "urchub_fmt", pyurchub_fmt, METH_VARARGS|METH_KEYWORDS},
397 | { "urcsign_fmt", pyurcsign_fmt, METH_VARARGS|METH_KEYWORDS},
398 | { "urcsign_verify", pyurcsign_verify, METH_VARARGS|METH_KEYWORDS},
399 | { "urcsecretbox_fmt", pyurcsecretbox_fmt, METH_VARARGS|METH_KEYWORDS},
400 | { "urcsecretbox_open", pyurcsecretbox_open, METH_VARARGS|METH_KEYWORDS},
401 | { "urcsignsecretbox_fmt", pyurcsignsecretbox_fmt, METH_VARARGS|METH_KEYWORDS},
402 | { "urcsignsecretbox_open", pyurcsignsecretbox_open, METH_VARARGS|METH_KEYWORDS},
403 | { "urcsignsecretbox_verify", pyurcsignsecretbox_verify, METH_VARARGS|METH_KEYWORDS},
404 | { "urccryptobox_fmt", pyurccryptobox_fmt, METH_VARARGS|METH_KEYWORDS},
405 | { "urccryptobox_open", pyurccryptobox_open, METH_VARARGS|METH_KEYWORDS},
406 | { "urccryptoboxpfs_fmt", pyurccryptoboxpfs_fmt, METH_VARARGS|METH_KEYWORDS},
407 | { "urccryptoboxpfs_open", pyurccryptoboxpfs_open, METH_VARARGS|METH_KEYWORDS},
408 | { NULL, NULL}
409 | };
410 |
411 | void initliburc(){ (void) Py_InitModule("liburc", Module_methods); }
412 | void initurc_jail(){ (void) Py_InitModule("urc_jail", Module_methods); }
413 | void initrandombytes(){ (void) Py_InitModule("randombytes", Module_methods); }
414 | void initurchub_fmt(){ (void) Py_InitModule("urchub_fmt", Module_methods); }
415 | void initurcsign_fmt(){ (void) Py_InitModule("urcsign_fmt", Module_methods); }
416 | void initurcsign_verify(){ (void) Py_InitModule("urcsign_verify", Module_methods); }
417 | void initurcsecretbox_fmt(){ (void) Py_InitModule("urcsecretbox_fmt", Module_methods); }
418 | void initurcsecretbox_open(){ (void) Py_InitModule("urcsecretbox_open", Module_methods); }
419 | void initurccryptobox_fmt(){ (void) Py_InitModule("urccryptobox_fmt", Module_methods); }
420 | void initurccryptobox_open(){ (void) Py_InitModule("urccryptobox_open", Module_methods); }
421 | void initurcsignsecretbox_fmt(){ (void) Py_InitModule("urcsignsecretbox_fmt", Module_methods); }
422 | void initurcsignsecretbox_open(){ (void) Py_InitModule("urcsignsecretbox_open", Module_methods); }
423 | void initurccryptoboxpfs_fmt(){ (void) Py_InitModule("urccryptoboxpfs_fmt", Module_methods); }
424 | void initurccryptoboxpfs_open(){ (void) Py_InitModule("urccryptoboxpfs_open", Module_methods); }
425 |
--------------------------------------------------------------------------------
/src/liburc.h:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 | #include
11 | #include
12 | #include
13 | #include
14 | #include
15 | #include
16 |
17 | /* security: enforce compatibility and santize malicious configurations */
18 | #if crypto_secretbox_BOXZEROBYTES != 16
19 | exit(255);
20 | #endif
21 | #if crypto_secretbox_ZEROBYTES != 32
22 | exit(255);
23 | #endif
24 | #if crypto_sign_BYTES != 64
25 | exit(255);
26 | #endif
27 |
28 | #define URC_MTU 1024
29 | #define IRC_MTU 512
30 |
31 | int devurandomfd = -1;
32 | int procstatusfd = -1;
33 |
34 | int urc_jail(char *path) {
35 | if (procstatusfd == -1) procstatusfd = open("/proc/self/status",O_RDONLY);
36 | if (devurandomfd == -1) devurandomfd = open("/dev/arandom",O_RDONLY);
37 | if (devurandomfd == -1) devurandomfd = open("/dev/urandom",O_RDONLY);
38 | struct passwd *urcd = getpwnam("urcd");
39 | if ((!urcd)
40 | || (chdir(path))
41 | || (chroot(path))
42 | || (setgroups(0,'\x00'))
43 | || (setgid(urcd->pw_gid))
44 | || (setuid(urcd->pw_uid)))
45 | return -1;
46 | return 0;
47 | }
48 |
49 | void randombytes(unsigned char *d, int dlen) {
50 | unsigned char *b = malloc(64 * sizeof(unsigned char));
51 | static unsigned char buff[1024];
52 | static unsigned char a[64];
53 | unsigned char c[64];
54 | static struct timeval now;
55 | static int i;
56 | if (procstatusfd == -1) procstatusfd = open("/proc/self/status",O_RDONLY);
57 | if (devurandomfd == -1) devurandomfd = open("/dev/arandom",O_RDONLY);
58 | if (devurandomfd == -1) devurandomfd = open("/dev/urandom",O_RDONLY);
59 | if ((devurandomfd == -1) || (read(devurandomfd,a,64) != 64)) {
60 | if (procstatusfd != -1) {
61 | lseek(procstatusfd,0,SEEK_SET);
62 | if (read(procstatusfd,buff,1024) > 0) crypto_hash_sha512(a,buff,1024);
63 | }
64 | for (i=0;i<64;++i) {
65 | gettimeofday(&now,'\x00'); srand(now.tv_usec); a[i]^= (rand() & 255);
66 | if (b) a[i] ^= b[i];
67 | a[i] ^= c[i];
68 | }
69 | }
70 | crypto_hash_sha512(c,a,64);
71 | crypto_stream(d,dlen,c,c+24);
72 | if (b) free(b);
73 | }
74 |
75 | int setlen(unsigned char *b, int blen) {
76 | if (blen > URC_MTU) return -1;
77 | b[0] = blen / 256;
78 | b[1] = blen % 256;
79 | return 0;
80 | }
81 |
82 | void taia96n(unsigned char *ts) {
83 | static const long long offset[] = {
84 | -8LL, -7LL, -6LL, -5LL, -4LL, -3LL, -2LL, -1LL,
85 | 8LL, 7LL, 6LL, 5LL, 4LL, 3LL, 2LL, 1LL
86 | };
87 | static unsigned long long a;
88 | static unsigned char b[1+4];
89 | randombytes(b,1+4);
90 | tai_now(ts);
91 | a=0ULL;
92 | memcpy(&a,ts,8);
93 | a+=offset[b[0] & 15];
94 | memcpy(ts,&a,8);
95 | tai_pack(ts,ts);
96 | memcpy(ts+8,b+1,4);
97 | }
98 |
99 | int urchub_fmt(unsigned char *p, int *plen, unsigned char *b, int blen) {
100 | if (blen > IRC_MTU) return -1;
101 | if (setlen(p,blen) == -1) return -1;
102 | taia96n(p+2);
103 | p[14]=0;
104 | p[15]=0;
105 | p[16]=0;
106 | p[17]=0;
107 | randombytes(p+2+12+4,8);
108 | memmove(p+2+12+4+8,b,blen);
109 | *plen=2+12+4+8+blen;
110 | return 0;
111 | }
112 |
113 | int urcsign_fmt(unsigned char *p, int *plen, unsigned char *b, int blen, unsigned char *sk) {
114 | static unsigned long long smlen;
115 | static unsigned char sm[1024*2];
116 | if (blen > IRC_MTU) return -1;
117 | if (setlen(p,blen+64) == -1) return -1;
118 | taia96n(p+2);
119 | p[14]=1;
120 | p[15]=0;
121 | p[16]=0;
122 | p[17]=0;
123 | randombytes(p+2+12+4,8);
124 | memmove(p+2+12+4+8,b,blen);
125 | if (crypto_sign_edwards25519sha512batch(sm,&smlen,p,(unsigned long long)(2+12+4+8+blen),sk) == -1) return -1;
126 | memmove(p+2+12+4+8+blen,sm,32);
127 | memmove(p+2+12+4+8+blen+32,sm+smlen-32,32);
128 | *plen=2+12+4+8+blen+64;
129 | return 0;
130 | }
131 |
132 | int urcsign_verify(unsigned char *p, int plen, unsigned char *pk) {
133 | static unsigned char sm[1024*2];
134 | static unsigned char m[1024*2];
135 | static unsigned long long mlen;
136 | if (p[14] != 1) return -1;
137 | if (plen > URC_MTU) return -1;
138 | memmove(sm,p+plen-64,32);
139 | memmove(sm+32,p,plen-64);
140 | memmove(sm+32+plen-64,p+plen-32,32);
141 | return crypto_sign_edwards25519sha512batch_open(m,&mlen,(const unsigned char *)sm,(unsigned long long)plen,(const unsigned char *)pk);
142 | }
143 |
144 | int urcsecretbox_fmt(unsigned char *p, int *plen, unsigned char *b, int blen, unsigned char *sk) {
145 | static unsigned char m[1024*2];
146 | static unsigned char c[1024*2];
147 | static int zlen;
148 | if (blen > IRC_MTU) return -1;
149 | zlen = blen + (256 - blen % 256);
150 | bzero(m,32+zlen); /* http://nacl.cr.yp.to/secretbox.html */
151 | bzero(c,16);
152 | if (setlen(p,zlen+16) == -1) return -1;
153 | taia96n(p+2);
154 | p[14]=2;
155 | p[15]=0;
156 | p[16]=0;
157 | p[17]=0;
158 | randombytes(p+2+12+4,8);
159 | memmove(m+32,b,blen);
160 | if (crypto_secretbox(c,m,32+zlen,(const unsigned char *)p+2,(const unsigned char *)sk) == -1) return -1;
161 | memmove(p+2+12+4+8,c+16,zlen+16);
162 | *plen=2+12+4+8+zlen+16;
163 | return 0;
164 | }
165 |
166 | int urcsecretbox_open(unsigned char *b, int *blen, unsigned char *p, int plen, unsigned char *sk) {
167 | static unsigned char m[1024*2];
168 | static unsigned char c[1024*2];
169 | if (p[14] != 2) return -1;
170 | if (plen > URC_MTU) return -1;
171 | bzero(m,32); /* http://nacl.cr.yp.to/secretbox.html */
172 | bzero(c,16);
173 | memmove(c+16,p+2+12+4+8,-2-12-4-8+plen);
174 | if (crypto_secretbox_open(m,c,16-2-12-4-8+plen,(const unsigned char *)p+2,(const unsigned char *)sk) == -1) return -1;
175 | memmove(b,m+32,-2-12-4-8+plen-16);
176 | *blen=-2-12-4-8+plen-16;
177 | return 0;
178 | }
179 |
180 | int urcsignsecretbox_fmt(unsigned char *p, int *plen, unsigned char *b, int blen, unsigned char *ssk, unsigned char *csk) {
181 | static unsigned long long smlen;
182 | static unsigned char sm[1024*2];
183 | static unsigned char m[1024*2];
184 | static unsigned char c[1024*2];
185 | static int zlen;
186 | if (blen > IRC_MTU) return -1;
187 | zlen = blen + (256 - blen % 256);
188 | if (setlen(p,zlen+64+16) == -1) return -1;
189 | taia96n(p+2);
190 | p[14]=3;
191 | p[15]=0;
192 | p[16]=0;
193 | p[17]=0;
194 | randombytes(p+2+12+4,8);
195 | memmove(p+2+12+4+8,b,blen);
196 | bzero(p+2+12+4+8+blen,-blen+zlen);
197 | if (crypto_sign(sm,&smlen,p,2+12+4+8+zlen,ssk) == -1) return -1;
198 | memmove(p+2+12+4+8+zlen,sm,32);
199 | memmove(p+2+12+4+8+zlen+32,sm+smlen-32,32);
200 | bzero(m,32); /* http://nacl.cr.yp.to/secretbox.html */
201 | bzero(c,16);
202 | memmove(m+32,p+2+12+4+8,zlen+64);
203 | if (crypto_secretbox(c,m,32+zlen+64,(const unsigned char *)p+2,(const unsigned char *)csk) == -1) return -1;
204 | memmove(p+2+12+4+8,c+16,zlen+64+16);
205 | *plen=2+12+4+8+zlen+64+16;
206 | return 0;
207 | }
208 |
209 | int urcsignsecretbox_open(unsigned char *b, int *blen, unsigned char *p, int plen, unsigned char *sk) {
210 | static unsigned char m[1024*2];
211 | static unsigned char c[1024*2];
212 | if (p[14] != 3) return -1;
213 | if (plen > URC_MTU) return -1;
214 | bzero(m,32); /* http://nacl.cr.yp.to/secretbox.html */
215 | bzero(c,16);
216 | memmove(c+16,p+2+12+4+8,-2-12-4-8+plen);
217 | if (crypto_secretbox_open(m,c,16-2-12-4-8+plen,(const unsigned char *)p+2,(const unsigned char *)sk) == -1) return -1;
218 | memmove(b,p,2+12+4+8);
219 | memmove(b+2+12+4+8,m+32,-2-12-4-8+plen-16);
220 | *blen=plen-16;
221 | return 0;
222 | }
223 |
224 | int urcsignsecretbox_verify(unsigned char *p, int plen, unsigned char *pk) {
225 | static unsigned long long mlen;
226 | static unsigned char sm[1024*2];
227 | static unsigned char m[1024*2];
228 | if (p[14] != 3) return -1;
229 | if (plen > URC_MTU) return -1;
230 | memmove(sm,p+plen-64,32);
231 | memmove(sm+32,p,plen-64);
232 | memmove(sm+32+plen-64,p+plen-32,32);
233 | return crypto_sign_open(m,&mlen,(const unsigned char *)sm,plen,(const unsigned char *)pk);
234 | }
235 |
236 | int urccryptobox_fmt(unsigned char *p, int *plen, unsigned char *b, int blen, unsigned char *pk, unsigned char *sk) {
237 | static unsigned char m[1024*2];
238 | static unsigned char c[1024*2];
239 | static int zlen;
240 | if (blen > IRC_MTU) return -1;
241 | zlen = blen + (256 - blen % 256);
242 | bzero(m,32+zlen); /* http://nacl.cr.yp.to/box.html */
243 | bzero(c,16);
244 | if (setlen(p,zlen+16) == -1) return -1;
245 | taia96n(p+2);
246 | p[14]=4;
247 | p[15]=0;
248 | p[16]=0;
249 | p[17]=0;
250 | randombytes(p+2+12+4,8);
251 | memmove(m+32,b,blen);
252 | if (crypto_box(c,m,32+zlen,(const unsigned char *)p+2,(const unsigned char *)pk,(const unsigned char *)sk) == -1) return -1;
253 | memmove(p+2+12+4+8,c+16,zlen+16);
254 | *plen=2+12+4+8+zlen+16;
255 | return 0;
256 | }
257 |
258 | int urccryptobox_open(unsigned char *b, int *blen, unsigned char *p, int plen, unsigned char *pk, unsigned char *sk) {
259 | static unsigned char m[1024*2];
260 | static unsigned char c[1024*2];
261 | if (p[14] != 4) return -1;
262 | if (plen > URC_MTU) return -1;
263 | bzero(m,32); /* http://nacl.cr.yp.to/box.html */
264 | bzero(c,16);
265 | memmove(c+16,p+2+12+4+8,-2-12-4-8+plen);
266 | if (crypto_box_open(m,c,16-2-12-4-8+plen,(const unsigned char *)p+2,(const unsigned char *)pk,(const unsigned char *)sk) == -1) return -1;
267 | memmove(b,m+32,-2-12-4-8+plen-16);
268 | *blen=-2-12-4-8+plen-16;
269 | return 0;
270 | }
271 |
272 | int urccryptoboxpfs_fmt(unsigned char *p, int *plen, unsigned char *b, int blen, unsigned char *pk0, unsigned char *sk0, unsigned char *pk1, unsigned char *sk1) {
273 | static unsigned char m[1024*2];
274 | static unsigned char c[1024*2];
275 | static int zlen;
276 | if (blen > IRC_MTU) return -1;
277 | zlen = blen + (256 - blen % 256);
278 | bzero(m,32+zlen); /* http://nacl.cr.yp.to/box.html */
279 | bzero(c,16);
280 | if (setlen(p,32+zlen+16+16) == -1) return -1;
281 | taia96n(p+2);
282 | p[14]=5;
283 | p[15]=0;
284 | p[16]=0;
285 | p[17]=0;
286 | randombytes(p+2+12+4,8);
287 | memmove(m+32,b,blen);
288 | if (crypto_box(c,m,32+zlen,(const unsigned char *)p+2,(const unsigned char *)pk0,(const unsigned char *)sk0) == -1) return -1;
289 | crypto_scalarmult_curve25519_base(m+32,sk0);
290 | memmove(m+32+32,c+16,zlen+16);
291 | if (crypto_box(c,m,32+32+zlen+16,(const unsigned char *)p+2,(const unsigned char *)pk1,(const unsigned char *)sk1) == -1) return -1;
292 | memmove(p+2+12+4+8,c+16,32+zlen+16+16);
293 | *plen=2+12+4+8+32+zlen+16+16;
294 | return 0;
295 | }
296 |
297 | int urccryptoboxpfs_open(unsigned char *b, int *blen, unsigned char *p, int plen, unsigned char *pk0, unsigned char *sk0, unsigned char *pk1, unsigned char *sk1) {
298 | static unsigned char m[1024*2];
299 | static unsigned char c[1024*2];
300 | bzero(pk0,32);
301 | if (p[14] != 5) return -1;
302 | if (plen > URC_MTU) return -1;
303 | bzero(m,32); /* http://nacl.cr.yp.to/box.html */
304 | bzero(c,16);
305 | memmove(c+16,p+2+12+4+8,-2-12-4-8+plen);
306 | if (crypto_box_open(m,c,16-2-12-4-8+plen,(const unsigned char *)p+2,(const unsigned char *)pk1,(const unsigned char *)sk1) == -1) return -1;
307 | memmove(pk0,m+32,32);
308 | memmove(c+16,m+32+32,-2-12-4-8-32+plen-16);
309 | if (crypto_box_open(m,c,16-2-12-4-8-32+plen-16,(const unsigned char *)p+2,(const unsigned char *)pk0,(const unsigned char *)sk0) == -1) return -1;
310 | memmove(b,m+32,-2-12-4-8-32+plen-16-16);
311 | *blen=-2-12-4-8-32+plen-16-16;
312 | return 0;
313 | }
314 |
--------------------------------------------------------------------------------
/src/nacltaia.c:
--------------------------------------------------------------------------------
1 | /*
2 | this library will eventually be replaced with liburc
3 | */
4 |
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 | #include
11 | #include
12 |
13 | PyObject *pynacltaia(PyObject *self){ /* hack __init__ */
14 | return Py_BuildValue("i", 0);}
15 |
16 | PyObject *pytaia_now_pack(PyObject *self){
17 | PyObject *ret;
18 | unsigned char *tpad;
19 | tpad = PyMem_Malloc(16);
20 |
21 | if (!tpad)
22 | return PyErr_NoMemory();
23 |
24 | taia_now(tpad);
25 | taia_pack(tpad,tpad);
26 |
27 | ret = PyBytes_FromStringAndSize((char *)tpad,16);
28 | PyMem_Free(tpad);
29 | return ret;}
30 |
31 | PyObject *pytaia_okseconds(PyObject *self, PyObject *args, PyObject *kw){
32 | unsigned char *t;
33 | Py_ssize_t tsize=0, n=0;
34 | static const char *kwlist[] = {"n","t",0};
35 |
36 | if (!PyArg_ParseTupleAndKeywords(args, kw,
37 | #if PY_VERSION_HEX < 0x02050000
38 | "|is#:taia_okseconds",
39 | #else
40 | "|ns#:taia_okseconds",
41 | #endif
42 | (char **)kwlist, &n, &t, &tsize)){
43 | return (PyObject *)0;}
44 |
45 | if (tsize<8)
46 | return Py_BuildValue("i", -1);
47 |
48 | int l = 8, i;
49 | struct timeval now;
50 | gettimeofday(&now,(struct timezone *) 0);
51 | unsigned long long s1 = 4611686018427387914ULL + (unsigned long long) now.tv_sec;
52 | unsigned long long s2 = 0ULL; /* uint64 */
53 |
54 | for(i=0;i<8;++i)
55 | s2 += (unsigned long long)t[i] << (unsigned long long)(--l << 3);
56 |
57 | if (s1 > s2){
58 | if ((s1 - s2) > (unsigned long long)n)
59 | return Py_BuildValue("i", 0);}
60 | else {
61 | if ((s2 - s1) > (unsigned long long)n)
62 | return Py_BuildValue("i", 0);}
63 |
64 | return Py_BuildValue("i", 1);}
65 |
66 | PyObject *pytaia_new(PyObject *self, PyObject *args, PyObject *kw){
67 | unsigned char *t, *u;
68 | Py_ssize_t tsize=0, usize=0;
69 | static const char *kwlist[] = {"t", "u", 0};
70 |
71 | if (!PyArg_ParseTupleAndKeywords(args, kw, "|s#s#:taia_new", (char **)kwlist, &t, &tsize, &u, &usize)){
72 | return (PyObject *)0;}
73 |
74 | if ((tsize<16)||(usize<16))
75 | return Py_BuildValue("i", -1);
76 |
77 | int i;
78 |
79 | for(i=0;i<16;++i){ /* simple reverse implementation of taia_less */
80 | if (t[i]u[i])
83 | return Py_BuildValue("i", 1);}
84 |
85 | return Py_BuildValue("i", 0);}
86 |
87 | PyObject *pycrypto_box_keypair(PyObject *self){
88 | PyObject *pypk, *pysk, *pyret;
89 | unsigned char pk[crypto_box_PUBLICKEYBYTES];
90 | unsigned char sk[crypto_box_SECRETKEYBYTES];
91 |
92 | crypto_box_keypair(pk, sk);
93 |
94 | pypk = PyBytes_FromStringAndSize((char *)pk, crypto_box_PUBLICKEYBYTES);
95 |
96 | if (!pypk)
97 | return (PyObject *)0;
98 |
99 | pysk = PyBytes_FromStringAndSize((char *)sk, crypto_box_SECRETKEYBYTES);
100 |
101 | if (!pysk){
102 | Py_DECREF(pypk);
103 | return (PyObject *)0;}
104 |
105 | pyret = PyTuple_New(2);
106 |
107 | if (!pyret){
108 | Py_DECREF(pypk);
109 | Py_DECREF(pysk);
110 | return (PyObject *)0;}
111 |
112 | PyTuple_SET_ITEM(pyret, 0, pypk);
113 | PyTuple_SET_ITEM(pyret, 1, pysk);
114 | return pyret;}
115 |
116 | PyObject *pycrypto_box_beforenm(PyObject *self, PyObject *args, PyObject *kw){
117 | PyObject *ret;
118 | char *pk, *sk;
119 | Py_ssize_t pksize=0, sksize=0;
120 | static const char *kwlist[] = {"pk", "sk", 0};
121 | unsigned char rk[crypto_box_SECRETKEYBYTES];
122 |
123 | if (!PyArg_ParseTupleAndKeywords(args, kw, "|s#s#:crypto_box_beforenm", (char **) kwlist, &pk, &pksize, &sk, &sksize)){
124 | return (PyObject *)0;}
125 |
126 | if (pksize != crypto_box_PUBLICKEYBYTES) return Py_BuildValue("i", 0);
127 | if (sksize != crypto_box_SECRETKEYBYTES) return Py_BuildValue("i", 0);
128 | if (crypto_box_beforenm(rk,(const unsigned char *) pk,(const unsigned char *) sk)<0) return Py_BuildValue("i", 0);
129 | ret = PyBytes_FromStringAndSize((char *)rk,crypto_box_SECRETKEYBYTES);
130 | return ret;}
131 |
132 | PyObject *pycrypto_box(PyObject *self, PyObject *args, PyObject *kw){
133 | char *m, *n, *pk, *sk;
134 | Py_ssize_t msize=0, nsize=0, pksize=0, sksize=0;
135 | static const char *kwlist[] = {"m", "n", "pk", "sk", 0};
136 | unsigned int i;
137 | PyObject *ret;
138 | size_t mlen;
139 | unsigned char *mpad;
140 | unsigned char *cpad;
141 |
142 | if (!PyArg_ParseTupleAndKeywords(args, kw, "|s#s#s#s#:crypto_box", (char **) kwlist, &m, &msize, &n, &nsize, &pk, &pksize, &sk, &sksize)){
143 | return (PyObject *)0;}
144 |
145 | if (nsize != crypto_box_NONCEBYTES) return Py_BuildValue("i", 0);
146 | if (pksize != crypto_box_PUBLICKEYBYTES) return Py_BuildValue("i", 0);
147 | if (sksize != crypto_box_SECRETKEYBYTES) return Py_BuildValue("i", 0);
148 |
149 | mlen = msize + crypto_box_ZEROBYTES;
150 | mpad = PyMem_Malloc(mlen);
151 |
152 | if (!mpad)
153 | return PyErr_NoMemory();
154 |
155 | cpad = PyMem_Malloc(mlen);
156 |
157 | if (!cpad){
158 | PyMem_Free(mpad);
159 | return PyErr_NoMemory();}
160 |
161 | for (i = 0;i < crypto_box_ZEROBYTES;++i) mpad[i] = 0;
162 | for (i = crypto_box_ZEROBYTES;i < mlen;++i) mpad[i] = m[i - crypto_box_ZEROBYTES];
163 |
164 | crypto_box(cpad, mpad, mlen,(const unsigned char *) n,(const unsigned char *) pk,(const unsigned char *) sk);
165 |
166 | ret = PyBytes_FromStringAndSize((char *)cpad + crypto_box_BOXZEROBYTES,mlen - crypto_box_BOXZEROBYTES);
167 |
168 | PyMem_Free(mpad);
169 | PyMem_Free(cpad);
170 | return ret;}
171 |
172 | PyObject *pycrypto_box_open(PyObject *self, PyObject *args, PyObject *kw){
173 | char *c, *n, *pk, *sk;
174 | Py_ssize_t csize=0, nsize=0, pksize=0, sksize=0;
175 | static const char *kwlist[] = {"c", "n", "pk", "sk", 0};
176 | unsigned int i;
177 | PyObject *ret;
178 | size_t clen;
179 | unsigned char *mpad;
180 | unsigned char *cpad;
181 |
182 | if (!PyArg_ParseTupleAndKeywords(args, kw, "|s#s#s#s#:crypto_box_open", (char **) kwlist, &c, &csize, &n, &nsize, &pk, &pksize, &sk, &sksize)){
183 | return (PyObject *)0;}
184 |
185 | if (nsize != crypto_box_NONCEBYTES) return Py_BuildValue("i", 0);
186 | if (pksize != crypto_box_PUBLICKEYBYTES) return Py_BuildValue("i", 0);
187 | if (sksize != crypto_box_SECRETKEYBYTES) return Py_BuildValue("i", 0);
188 |
189 | clen = csize + crypto_box_BOXZEROBYTES;
190 | mpad = PyMem_Malloc(clen);
191 |
192 | if (!mpad)
193 | return PyErr_NoMemory();
194 |
195 | cpad = PyMem_Malloc(clen);
196 |
197 | if (!cpad){
198 | PyMem_Free(mpad);
199 | return PyErr_NoMemory();}
200 |
201 | for (i = 0;i < crypto_box_BOXZEROBYTES;++i) cpad[i] = 0;
202 | for (i = crypto_box_BOXZEROBYTES;i < clen;++i) cpad[i] = c[i - crypto_box_BOXZEROBYTES];
203 |
204 | if (crypto_box_open(mpad, cpad, clen, (const unsigned char *) n, (const unsigned char *) pk, (const unsigned char *) sk) != 0){
205 | PyMem_Free(mpad);
206 | PyMem_Free(cpad);
207 | return Py_BuildValue("i", 0);}
208 |
209 | if (clen < crypto_box_ZEROBYTES){
210 | PyMem_Free(mpad);
211 | PyMem_Free(cpad);
212 | return Py_BuildValue("i", 0);}
213 |
214 | ret = PyBytes_FromStringAndSize((char *)mpad + crypto_box_ZEROBYTES, clen - crypto_box_ZEROBYTES);
215 | PyMem_Free(mpad);
216 | PyMem_Free(cpad);
217 | return ret;}
218 |
219 | PyObject *pycrypto_secretbox(PyObject *self, PyObject *args, PyObject *kw){
220 | char *m, *n, *k;
221 | Py_ssize_t msize=0, nsize=0, ksize=0;
222 | static const char *kwlist[] = {"m", "n", "k", 0};
223 | unsigned int i;
224 | PyObject *ret;
225 | size_t mlen;
226 | unsigned char *mpad;
227 | unsigned char *cpad;
228 |
229 | if (!PyArg_ParseTupleAndKeywords(args, kw, "|s#s#s#:crypto_secretbox", (char **) kwlist, &m, &msize, &n, &nsize, &k, &ksize)){
230 | return (PyObject *)0;}
231 |
232 | if (nsize != crypto_secretbox_NONCEBYTES) return Py_BuildValue("i", 0);
233 | if (ksize != crypto_secretbox_KEYBYTES) return Py_BuildValue("i", 0);
234 |
235 | mlen = msize + crypto_secretbox_ZEROBYTES;
236 | mpad = PyMem_Malloc(mlen);
237 |
238 | if (!mpad)
239 | return PyErr_NoMemory();
240 |
241 | cpad = PyMem_Malloc(mlen);
242 |
243 | if (!cpad){
244 | PyMem_Free(mpad);
245 | return PyErr_NoMemory();}
246 |
247 | for (i = 0;i < crypto_secretbox_ZEROBYTES;++i) mpad[i] = 0;
248 | for (i = crypto_secretbox_ZEROBYTES;i < mlen;++i) mpad[i] = m[i - crypto_secretbox_ZEROBYTES];
249 |
250 | crypto_secretbox(cpad, mpad, mlen, (const unsigned char *) n, (const unsigned char *) k);
251 |
252 | ret = PyBytes_FromStringAndSize((char *)cpad + crypto_secretbox_BOXZEROBYTES, mlen - crypto_secretbox_BOXZEROBYTES);
253 |
254 | PyMem_Free(mpad);
255 | PyMem_Free(cpad);
256 | return ret;}
257 |
258 | PyObject *pycrypto_secretbox_open(PyObject *self, PyObject *args, PyObject *kw){
259 | char *c, *n, *k;
260 | Py_ssize_t csize=0, nsize=0, ksize=0;
261 | static const char *kwlist[] = {"c", "n", "k", 0};
262 | unsigned int i;
263 | PyObject *ret;
264 | size_t clen;
265 | unsigned char *mpad;
266 | unsigned char *cpad;
267 |
268 | if (!PyArg_ParseTupleAndKeywords(args, kw, "|s#s#s#:crypto_secretbox_open", (char **) kwlist, &c, &csize, &n, &nsize, &k, &ksize)){
269 | return (PyObject *)0;}
270 |
271 | if (nsize != crypto_secretbox_NONCEBYTES) return Py_BuildValue("i", 0);
272 | if (ksize != crypto_secretbox_KEYBYTES) return Py_BuildValue("i", 0);
273 |
274 | clen = csize + crypto_secretbox_BOXZEROBYTES;
275 | mpad = PyMem_Malloc(clen);
276 |
277 | if (!mpad)
278 | return PyErr_NoMemory();
279 |
280 | cpad = PyMem_Malloc(clen);
281 |
282 | if (!cpad){
283 | PyMem_Free(mpad);
284 | return PyErr_NoMemory();}
285 |
286 | for (i = 0;i < crypto_secretbox_BOXZEROBYTES;++i) cpad[i] = 0;
287 | for (i = crypto_secretbox_BOXZEROBYTES;i < clen;++i) cpad[i] = c[i - crypto_secretbox_BOXZEROBYTES];
288 |
289 | if (crypto_secretbox_open(mpad, cpad, clen, (const unsigned char *) n, (const unsigned char *) k) != 0){
290 | PyMem_Free(mpad);
291 | PyMem_Free(cpad);
292 | return Py_BuildValue("i", 0);}
293 |
294 | if (clen < crypto_secretbox_ZEROBYTES){
295 | PyMem_Free(mpad);
296 | PyMem_Free(cpad);
297 | return Py_BuildValue("i", 0);}
298 |
299 | ret = PyBytes_FromStringAndSize((char *)mpad + crypto_secretbox_ZEROBYTES, clen - crypto_secretbox_ZEROBYTES);
300 | PyMem_Free(mpad);
301 | PyMem_Free(cpad);
302 | return ret;}
303 |
304 | PyObject *pycrypto_sign_keypair(PyObject *self){
305 | PyObject *pypk, *pysk, *pyret;
306 | unsigned char pk[crypto_sign_PUBLICKEYBYTES];
307 | unsigned char sk[crypto_sign_SECRETKEYBYTES];
308 |
309 | crypto_sign_keypair(pk, sk);
310 |
311 | pypk = PyBytes_FromStringAndSize((char *)pk, crypto_sign_PUBLICKEYBYTES);
312 |
313 | if (!pypk)
314 | return (PyObject *)0;
315 |
316 | pysk = PyBytes_FromStringAndSize((char *)sk, crypto_sign_SECRETKEYBYTES);
317 |
318 | if (!pysk){
319 | Py_DECREF(pypk);
320 | return (PyObject *)0;}
321 |
322 | pyret = PyTuple_New(2);
323 |
324 | if (!pyret){
325 | Py_DECREF(pypk);
326 | Py_DECREF(pysk);
327 | return (PyObject *)0;}
328 |
329 | PyTuple_SET_ITEM(pyret, 0, pypk);
330 | PyTuple_SET_ITEM(pyret, 1, pysk);
331 | return pyret;}
332 |
333 | PyObject *pycrypto_sign(PyObject *self, PyObject *args, PyObject *kw){
334 | Py_ssize_t m_stringsize=0, sksize=0;
335 | const unsigned char *sk, *m_string;
336 | static const char *kwlist[] = {"m", "sk", 0};
337 | PyObject *ret;
338 | unsigned long long mlen, smlen;
339 | unsigned char *m;
340 |
341 | if (!PyArg_ParseTupleAndKeywords(args, kw, "|s#s#:crypto_sign", (char **) kwlist, (char **)&m_string, &m_stringsize, (char **)&sk, &sksize)){
342 | return (PyObject *)0;}
343 |
344 | if (sksize != crypto_sign_SECRETKEYBYTES){
345 | return Py_BuildValue("i", 0);}
346 |
347 | mlen = m_stringsize;
348 | m = PyMem_Malloc(mlen + crypto_sign_BYTES);
349 |
350 | if (!m)
351 | return PyErr_NoMemory();
352 |
353 | if (crypto_sign(m, &smlen, m_string, mlen, sk) != 0){
354 | PyMem_Free(m);
355 | return Py_BuildValue("i", 0);}
356 |
357 | ret = PyBytes_FromStringAndSize((char *)m, smlen);
358 | PyMem_Free(m);
359 | return ret;}
360 |
361 | PyObject *pycrypto_sign_open(PyObject *self, PyObject *args, PyObject *kw){
362 | const unsigned char *sm, *pk;
363 | Py_ssize_t smsize=0, pksize=0;
364 | static const char *kwlist[] = {"sm", "pk", 0};
365 | PyObject *ret;
366 | unsigned long long smlen, mlen;
367 | unsigned char *m;
368 |
369 | if (!PyArg_ParseTupleAndKeywords(args, kw, "|s#s#:crypto_sign_open", (char **)kwlist, (char **)&sm, &smsize, (char **)&pk, &pksize)){
370 | return (PyObject *)0;}
371 |
372 | if (pksize != crypto_sign_PUBLICKEYBYTES){
373 | return Py_BuildValue("i", 0);}
374 |
375 | smlen = smsize;
376 | m = PyMem_Malloc(smlen);
377 |
378 | if (!m)
379 | return PyErr_NoMemory();
380 |
381 | if (crypto_sign_open(m, &mlen, sm, smlen, pk) != 0){
382 | PyMem_Free(m);
383 | return Py_BuildValue("i", 0);}
384 |
385 | ret = PyBytes_FromStringAndSize((char *) m, mlen);
386 | PyMem_Free(m);
387 | return ret;}
388 |
389 | PyObject *pycrypto_hash_sha256(PyObject *self, PyObject *args, PyObject *kw){
390 | char *m;
391 | Py_ssize_t msize=0;
392 | unsigned char h[crypto_hash_sha256_BYTES];
393 | static const char *kwlist[] = {"m",0};
394 |
395 | if (!PyArg_ParseTupleAndKeywords(args, kw, "|s#:crypto_hash_sha256", (char **)kwlist, &m, &msize)){
396 | return (PyObject *)0;}
397 |
398 | crypto_hash_sha256(h, (const unsigned char *)m, msize);
399 |
400 | return PyBytes_FromStringAndSize((char *)h, crypto_hash_sha256_BYTES);}
401 |
402 | PyObject *pycrypto_hash_sha512(PyObject *self, PyObject *args, PyObject *kw){
403 | char *m;
404 | Py_ssize_t msize=0;
405 | unsigned char h[crypto_hash_sha512_BYTES];
406 | static const char *kwlist[] = {"m",0};
407 |
408 | if (!PyArg_ParseTupleAndKeywords(args, kw, "|s#:crypto_hash_sha512", (char **)kwlist, &m, &msize)){
409 | return (PyObject *)0;}
410 |
411 | crypto_hash_sha512(h, (const unsigned char *)m, msize);
412 |
413 | return PyBytes_FromStringAndSize((char *)h, crypto_hash_sha512_BYTES);}
414 |
415 | static PyMethodDef Module_methods[] = {
416 | {"nacltaia", pynacltaia, METH_NOARGS},
417 | {"taia_now_pack", pytaia_now_pack, METH_NOARGS},
418 | {"taia_new", pytaia_new, METH_VARARGS|METH_KEYWORDS},
419 | {"taia_okseconds", pytaia_okseconds, METH_VARARGS|METH_KEYWORDS},
420 | {"crypto_box", pycrypto_box, METH_VARARGS|METH_KEYWORDS},
421 | {"crypto_box_open", pycrypto_box_open, METH_VARARGS|METH_KEYWORDS},
422 | {"crypto_box_beforenm", pycrypto_box_beforenm, METH_VARARGS|METH_KEYWORDS},
423 | {"crypto_box_keypair", pycrypto_box_keypair, METH_NOARGS},
424 | {"crypto_sign", pycrypto_sign, METH_VARARGS|METH_KEYWORDS},
425 | {"crypto_sign_open", pycrypto_sign_open, METH_VARARGS|METH_KEYWORDS},
426 | {"crypto_sign_keypair", pycrypto_sign_keypair, METH_NOARGS},
427 | {"crypto_secretbox", pycrypto_secretbox, METH_VARARGS|METH_KEYWORDS},
428 | {"crypto_secretbox_open",pycrypto_secretbox_open,METH_VARARGS|METH_KEYWORDS},
429 | {"crypto_hash_sha256" ,pycrypto_hash_sha256 ,METH_VARARGS|METH_KEYWORDS},
430 | {"crypto_hash_sha512" ,pycrypto_hash_sha512 ,METH_VARARGS|METH_KEYWORDS},
431 | {NULL, NULL}};
432 |
433 | void initnacltaia(){
434 | (void) Py_InitModule("nacltaia", Module_methods);}
435 |
436 | void inittaia_now_pack(){
437 | (void) Py_InitModule("taia_now_pack", Module_methods);}
438 |
439 | void inittaia_new(){
440 | (void) Py_InitModule("taia_new", Module_methods);}
441 |
442 | void inittaia_okseconds(){
443 | (void) Py_InitModule("taia_okseconds", Module_methods);}
444 |
445 | void initcrypto_box(){
446 | (void) Py_InitModule("crypto_box", Module_methods);}
447 |
448 | void initcrypto_box_open(){
449 | (void) Py_InitModule("crypto_box_open", Module_methods);}
450 |
451 | void initcrypto_box_beforenm(){
452 | (void) Py_InitModule("crypto_box_beforenm", Module_methods);}
453 |
454 | void initcrypto_box_keypair(){
455 | (void) Py_InitModule("crypto_box_keypair", Module_methods);}
456 |
457 | void initcrypto_sign(){
458 | (void) Py_InitModule("crypto_sign", Module_methods);}
459 |
460 | void initcrypto_sign_open(){
461 | (void) Py_InitModule("crypto_sign_open", Module_methods);}
462 |
463 | void initcrypto_sign_keypair(){
464 | (void) Py_InitModule("crypto_sign_keypair", Module_methods);}
465 |
466 | void initcrypto_secretbox(){
467 | (void) Py_InitModule("crypto_secretbox", Module_methods);}
468 |
469 | void initcrypto_secretbox_open(){
470 | (void) Py_InitModule("crypto_secretbox_open", Module_methods);}
471 |
472 | void initcrypto_hash_sha256(){
473 | (void) Py_InitModule("crypto_hash_sha256", Module_methods);}
474 |
475 | void initcrypto_hash_sha512(){
476 | (void) Py_InitModule("crypto_hash_sha512", Module_methods);}
477 |
--------------------------------------------------------------------------------
/src/sign_keypair.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | int main(){
5 | unsigned char pk [32];
6 | unsigned char sk [64];
7 | int i ;
8 |
9 | crypto_sign_keypair(pk,sk);
10 |
11 | printf("PUBKEY: ");
12 | for (i=0;i<32;++i) printf("%02x",pk[i]);
13 | printf("\n");
14 |
15 | printf("SECKEY: ");
16 | for (i=0;i<64;++i) printf("%02x",sk[i]);
17 | printf("\n");}
18 | /*
19 | void randombytes(char *bytes) {
20 | read(0,bytes,64);}*/
21 |
--------------------------------------------------------------------------------
/src/socket_bind.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #include "socket.h"
6 | #include "byte.h"
7 |
8 | int socket_bind(int fd,const unsigned char *ip,const unsigned char *port)
9 | {
10 | struct sockaddr_in sa;
11 | byte_zero(&sa,sizeof sa);
12 | byte_copy(&sa.sin_addr,4,ip);
13 | byte_copy(&sa.sin_port,2,port);
14 |
15 | /* AF_UNSPEC EAFNOSUPPORT -- d3v11 */
16 | if (bind(fd,(struct sockaddr *) &sa,sizeof sa) < 0)
17 | {
18 | sa.sin_family = AF_INET;
19 | return bind(fd,(struct sockaddr *) &sa,sizeof sa);
20 | }
21 | return 0;
22 | }
23 |
--------------------------------------------------------------------------------
/src/tai_dec.h:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | tai_dec(unsigned char *t, unsigned char *u, unsigned char *v)
4 | {
5 |
6 | static int i;
7 |
8 | memmove(t,u,8);
9 |
10 | for (i=7;i>-1;--i)
11 | {
12 |
13 | if ((t[i] >= v[i]) | (!i)){ t[i] -= v[i]; continue; } t[i] -= v[i];
14 | if ((t[i-1]) | (!i-1)){ --t[i-1]; continue; } --t[i-1];
15 | if ((t[i-2]) | (!i-2)){ --t[i-2]; continue; } --t[i-2];
16 | if ((t[i-3]) | (!i-3)){ --t[i-3]; continue; } --t[i-3];
17 | if ((t[i-4]) | (!i-4)){ --t[i-4]; continue; } --t[i-4];
18 | if ((t[i-5]) | (!i-5)){ --t[i-5]; continue; } --t[i-5];
19 | if ((t[i-6]) | (!i-6)){ --t[i-6]; continue; } --t[i-6];
20 | --t[i-7];
21 |
22 | }
23 |
24 | }
25 |
--------------------------------------------------------------------------------
/src/tai_inc.h:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | tai_inc(unsigned char *t, unsigned char *u, unsigned char *v)
4 | {
5 |
6 | static int i;
7 |
8 | memmove(t,u,8);
9 |
10 | for (i=7;i>-1;--i)
11 | {
12 |
13 | if (!v[i]) continue;
14 | if ((t[i] + v[i] < 256) | (!i)){ t[i] += v[i]; continue; } t[i] += v[i];
15 | if ((++t[i-1]) | (!i-1)) continue;
16 | if ((++t[i-2]) | (!i-2)) continue;
17 | if ((++t[i-3]) | (!i-3)) continue;
18 | if ((++t[i-4]) | (!i-4)) continue;
19 | if ((++t[i-5]) | (!i-5)) continue;
20 | if ((++t[i-6]) | (!i-6)) continue;
21 | ++t[i-7];
22 |
23 | }
24 |
25 | }
26 |
--------------------------------------------------------------------------------
/src/taia96n.pyx:
--------------------------------------------------------------------------------
1 | #/usr/bin/env python
2 | from random import randrange
3 | from time import time
4 |
5 | def taia96n_now():
6 | now = time()
7 | return {
8 | 'sec':4611686018427387914L+long(now)+randrange(-8,8),
9 | 'nano':randrange(0,4294967295L),
10 |
11 | # uncomment if you need nano second accuracy. i left
12 | # this optional to avoid clockskew leaks (thanks chi)
13 | #
14 | # 'sec':4611686018427387914L+long(now),
15 | # 'nano':long(1000000000*(now%1)+randrange(0,512)),
16 |
17 | # uncomment for djb style taia96n, with nano second
18 | # precision
19 | #
20 | # 'sec':4611686018427387914L+long(now),
21 | # 'nano':long(1000000000*(now%1)+500),
22 |
23 | }
24 |
25 | def tai_pack(s): return str(
26 | chr(s['sec']>>56&255) +
27 | chr(s['sec']>>48&255) +
28 | chr(s['sec']>>40&255) +
29 | chr(s['sec']>>32&255) +
30 | chr(s['sec']>>24&255) +
31 | chr(s['sec']>>16&255) +
32 | chr(s['sec']>>8&255) +
33 | chr(s['sec']&255)
34 | )
35 |
36 | def taia96n_pack(s): return str(
37 | tai_pack(s)+
38 | chr(s['nano']>>24&255)+
39 | chr(s['nano']>>16&255)+
40 | chr(s['nano']>>8&255)+
41 | chr(s['nano']&255)
42 | )
43 |
--------------------------------------------------------------------------------
/src/ucspi-client2server.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #define USAGE "Usage: ucspi-client2server prog [args]\n"
4 | int main (int argc, char **argv) {
5 | if (argc>2) {
6 | dup2(6,0);
7 | dup2(7,1);
8 | execvp(argv[1],argv+1);
9 | }
10 | write(2,USAGE,strlen(USAGE));
11 | return 255;
12 | }
13 |
--------------------------------------------------------------------------------
/src/ucspi-server2client.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #define USAGE "Usage: ucspi-server2client prog [args]\n"
4 | int main (int argc, char **argv) {
5 | if (argc>2) {
6 | dup2(0,6);
7 | dup2(1,7);
8 | execvp(argv[1],argv+1);
9 | }
10 | write(2,USAGE,strlen(USAGE));
11 | return 255;
12 | }
13 |
--------------------------------------------------------------------------------
/src/ucspi-socks4aclient.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #define USAGE "Usage: ucspi-socks4aclient addr port prog [args]\n"
4 | int main(int argc, char **argv){
5 |
6 | if ((argc<4)||(strlen(argv[1])>256)||(atoi(argv[2])<0)||(atoi(argv[2])>65535)){
7 | write(2,USAGE,strlen(USAGE));
8 | return 64;}
9 |
10 | unsigned char packet[512]={0};
11 | packet[ 0] = '\x04';
12 | packet[ 1] = '\x01';
13 | packet[ 2] = atoi(argv[2])/256;
14 | packet[ 3] = atoi(argv[2])%256;
15 | packet[ 7] = '\x01';
16 | packet[ 8] = 'u';
17 | packet[ 9] = 'c';
18 | packet[10] = 's';
19 | packet[11] = 'p';
20 | packet[12] = 'i';
21 |
22 | memmove(&packet[14],argv[1],strlen(argv[1])+1);
23 | if (write(7,packet,14+strlen(argv[1])+1)<14+strlen(argv[1])+1) return 128+111;
24 | bzero(packet,512);
25 | if (read(6,packet,8)<8) return 128+32;
26 | if ((packet[0]!=0)||(packet[1]!=90)) return 128+111;
27 | execvp(argv[3],argv+3);}
28 |
--------------------------------------------------------------------------------
/src/ucspi-stream.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | int main(){
5 |
6 | fcntl(0,4,2050); fcntl(1,4,2050);
7 | fcntl(6,4,2050); fcntl(7,4,2050);
8 |
9 | struct pollfd fds[4];
10 | fds[0].fd=0; fds[0].events=3;
11 | fds[1].fd=6; fds[1].events=3;
12 | fds[2].fd=1; fds[2].events=4;
13 | fds[3].fd=7; fds[3].events=4;
14 |
15 | unsigned char client_buffer[1024]={0};
16 | unsigned char server_buffer[1024]={0};
17 |
18 | int client_eagain=0;
19 | int server_eagain=0;
20 |
21 | int in=0, out=0;
22 |
23 | while (1){
24 |
25 | poll(fds,2,-1);
26 | poll(fds+2,2,0);
27 |
28 | if ((server_eagain)||(fds[0].revents)){
29 | if (fds[3].revents){
30 | if (server_eagain<1024){
31 | in=read(0,&server_buffer[server_eagain],1024-server_eagain);
32 | if (in<1) break;}
33 | else in=0;
34 | out=write(7,server_buffer,server_eagain+in);
35 | if (out<0) break;
36 | if (out
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 | #include
11 | #include
12 | #include
13 |
14 | #ifndef UNIX_PATH_MAX
15 | #ifdef __NetBSD__
16 | #define UNIX_PATH_MAX 104
17 | #else
18 | #define UNIX_PATH_MAX 108
19 | #endif
20 | #endif
21 |
22 | int itoa(char *s, int n, int slen)
23 | {
24 | if (snprintf(s,slen,"%d",n)<0) return -1;
25 | return 0;
26 | }
27 |
28 | main(int argc, char **argv)
29 | {
30 |
31 | int udpfd;
32 | struct sockaddr_in udp;
33 | bzero(&udp,sizeof(udp));
34 | udp.sin_family = AF_INET;
35 |
36 | unsigned char buffer[1024] = {0};
37 |
38 | int BROADCAST;
39 | int n = open("env/BROADCAST",0);
40 | if (n>0)
41 | {
42 | if (read(n,buffer,1024)>0) BROADCAST = atoi(buffer);
43 | else BROADCAST = 0;
44 | } else BROADCAST = 0;
45 | close(n);
46 |
47 | if (
48 | (argc<4)
49 | || (!(udp.sin_port=htons(atoi(argv[2]))))
50 | || (!inet_pton(AF_INET,argv[1],&udp.sin_addr))
51 | || ((udpfd=socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP))<0)
52 | || (setsockopt(udpfd,SOL_SOCKET,SO_REUSEADDR,(int[]){1},sizeof(int)))
53 | || ((BROADCAST) && (setsockopt(udpfd,SOL_SOCKET,SO_BROADCAST,(int[]){1},sizeof(int))))
54 | || (bind(udpfd,(struct sockaddr *)&udp,sizeof(udp))<0)
55 | )
56 | {
57 | write(2,USAGE,strlen(USAGE));
58 | exit(64);
59 | }
60 |
61 | float LIMIT;
62 | n = open("env/LIMIT",0);
63 | if (n>0)
64 | {
65 | if (read(n,buffer,1024)>0) LIMIT = atof(buffer);
66 | else LIMIT = 1.0;
67 | } else LIMIT = 1.0;
68 | close(n);
69 |
70 | struct passwd *urcd = getpwnam("urcd");
71 |
72 | if ((!urcd)
73 | || (chdir(argv[3]))
74 | || (chroot(argv[3]))
75 | || (setgroups(0,'\x00'))
76 | || (setgid(urcd->pw_gid))
77 | || (setuid(urcd->pw_uid))) exit(64);
78 |
79 | int sockfd;
80 | struct sockaddr_un sock;
81 | bzero(&sock,sizeof(sock));
82 | sock.sun_family = AF_UNIX;
83 |
84 | if ((sockfd=socket(AF_UNIX,SOCK_DGRAM,0))<0) exit(1);
85 | if (setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&n,sizeof(n=1))<0) exit(2);
86 | if (fcntl(sockfd,F_SETFL,O_NONBLOCK)<0) exit(3);
87 |
88 | struct sockaddr_un hub;
89 | bzero(&hub,sizeof(hub));
90 | hub.sun_family = AF_UNIX;
91 | memcpy(&hub.sun_path,"hub\0",4);
92 |
93 | while (1)
94 | {
95 | usleep((int)(LIMIT*1000000));
96 | if (
97 | ((n=read(udpfd,buffer,1024))<2+12+4+8)
98 | || (n!=2+12+4+8+buffer[0]*256+buffer[1])
99 | ) continue;
100 | if (sendto(sockfd,buffer,n,MSG_DONTWAIT,(struct sockaddr *)&hub,sizeof(hub))<0) usleep(262144);
101 | }
102 | }
103 |
--------------------------------------------------------------------------------
/src/urc-udpsend.c:
--------------------------------------------------------------------------------
1 | #define USAGE "Usage: urc-udpsend addr port /path/to/sockets/\n"
2 | #include
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 | #include
11 | #include
12 | #include
13 | #include
14 |
15 | #ifndef UNIX_PATH_MAX
16 | #ifdef __NetBSD__
17 | #define UNIX_PATH_MAX 104
18 | #else
19 | #define UNIX_PATH_MAX 108
20 | #endif
21 | #endif
22 |
23 | int itoa(char *s, int n, int slen)
24 | {
25 | if (snprintf(s,slen,"%d",n)<0) return -1;
26 | return 0;
27 | }
28 |
29 | main(int argc, char **argv)
30 | {
31 |
32 | int udpfd;
33 | struct sockaddr_in udp;
34 | bzero(&udp,sizeof(udp));
35 | udp.sin_family = AF_INET;
36 |
37 | unsigned char buffer[1024] = {0};
38 |
39 | int BROADCAST;
40 | int n = open("env/BROADCAST",0);
41 | if (n>0)
42 | {
43 | if (read(n,buffer,1024)>0) BROADCAST = atoi(buffer);
44 | else BROADCAST = 0;
45 | } else BROADCAST = 0;
46 | close(n);
47 |
48 | if (
49 | (argc<4)
50 | || (!(udp.sin_port=htons(atoi(argv[2]))))
51 | || (!inet_pton(AF_INET,argv[1],&udp.sin_addr))
52 | || ((udpfd=socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP))<0)
53 | || (setsockopt(udpfd,SOL_SOCKET,SO_REUSEADDR,(int[]){1},sizeof(int)))
54 | || ((BROADCAST) && (setsockopt(udpfd,SOL_SOCKET,SO_BROADCAST,(int[]){1},sizeof(int))))
55 | || (connect(udpfd,(struct sockaddr *)&udp,sizeof(udp))<0)
56 | )
57 | {
58 | write(2,USAGE,strlen(USAGE));
59 | exit(64);
60 | }
61 |
62 | int devurandomfd = open("/dev/urandom",O_RDONLY);
63 | if (devurandomfd<0) exit(255);
64 | unsigned char byte[1];
65 |
66 | char user[UNIX_PATH_MAX] = {0};
67 | if (itoa(user,getpid(),UNIX_PATH_MAX)<0) exit(1);
68 |
69 | struct passwd *urcd = getpwnam("urcd");
70 |
71 | if ((!urcd)
72 | || (chdir(argv[3]))
73 | || (chroot(argv[3]))
74 | || (setgroups(0,'\x00'))
75 | || (setgid(urcd->pw_gid))
76 | || (setuid(urcd->pw_uid))) exit(64);
77 |
78 | int sockfd;
79 | struct sockaddr_un sock;
80 | bzero(&sock,sizeof(sock));
81 | sock.sun_family = AF_UNIX;
82 |
83 | void sock_close(int signum)
84 | {
85 | unlink(sock.sun_path);
86 | exit(signum);
87 | } signal(SIGINT,sock_close);
88 | signal(SIGHUP,sock_close);
89 | signal(SIGTERM,sock_close);
90 |
91 | if ((sockfd=socket(AF_UNIX,SOCK_DGRAM,0))<0) exit(2);
92 | if (setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&n,sizeof(n=1))<0) exit(3);
93 | n = strlen(user);
94 | if (n > UNIX_PATH_MAX) exit(4);
95 | memcpy(&sock.sun_path,user,n);
96 | unlink(sock.sun_path);
97 | if (bind(sockfd,(struct sockaddr *)&sock,sizeof(sock))<0) exit(5);
98 |
99 | struct sockaddr_un path;
100 | path.sun_family = AF_UNIX;
101 | socklen_t path_len = sizeof(struct sockaddr_un);
102 |
103 | struct pollfd fds[1];
104 | fds[0].fd = sockfd;
105 | fds[0].events = POLLIN | POLLPRI;
106 |
107 | while (1)
108 | {
109 | bzero(path.sun_path,UNIX_PATH_MAX);
110 | n = recvfrom(sockfd,buffer,1024,0,(struct sockaddr *)&path,&path_len);
111 | if (!n) continue;
112 | if (n<0) sock_close(6);
113 | if (!path_len) continue;
114 | if (buffer[n-1] != '\n') continue;
115 | if (read(devurandomfd,byte,1)<1) sock_close(7);
116 | poll(fds,1,byte[0]<<4);
117 | write(udpfd,buffer,n);
118 | }
119 | }
120 |
--------------------------------------------------------------------------------
/src/urc2sd.pyx:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 | USAGE='''\
4 | urc2sd: help: This NOTICE can be disabled if env/HELP is set \
5 | to 0. /INVITE adds temporary relay if env/INVITE is set to 1. \
6 | Contact the urc2sd admin for permenance. ChanOp BAN/EXCEPT \
7 | masks also filter relay traffic. \
8 | Thanks for supporting URC, the anonymous decentralized \
9 | alternative to IRC.\n'''
10 |
11 | from binascii import hexlify
12 | from nacltaia import *
13 | from taia96n import *
14 | import unicodedata
15 | import collections
16 | import subprocess
17 | import codecs
18 | import select
19 | import socket
20 | import signal
21 | import time
22 | import pwd
23 | import sys
24 | import re
25 | import os
26 |
27 | RE = 'a-zA-Z0-9^(\)\-_{\}[\]|\\\\'
28 | re_USER = re.compile('!\S+@',re.IGNORECASE).sub
29 | re_SPLIT = re.compile(' +',re.IGNORECASE).split
30 | re_CLIENT_HELP = re.compile('^:['+RE+']+![~:#'+RE+'.]+@[:#'+RE+'.]+ PRIVMSG [#&!+]['+RE+']+ :['+RE+']+[:,]? help$',re.IGNORECASE).search
31 | re_CLIENT_PRIVMSG_NOTICE_TOPIC = re.compile('^:['+RE+']+![~:#'+RE+'.]+@[:#'+RE+'.]+ ((PRIVMSG)|(NOTICE)|(TOPIC)) [#&!+]['+RE+']+ :.*$',re.IGNORECASE).search
32 | re_CLIENT_PART = re.compile('^:['+RE+']+![~:#'+RE+'.]+@[:#'+RE+'.]+ PART [#&!+]['+RE+']+( :)?',re.IGNORECASE).search
33 | re_CLIENT_QUIT = re.compile('^:['+RE+']+![~:#'+RE+'.]+@[:#'+RE+'.]+ QUIT( :)?',re.IGNORECASE).search
34 | re_CLIENT_PING = re.compile('^PING :?.+$',re.IGNORECASE).search
35 | re_CLIENT_JOIN = re.compile('^:['+RE+']+![~:#'+RE+'.]+@[:#'+RE+'.]+ JOIN :[#&!+]['+RE+']+$',re.IGNORECASE).search
36 | re_CLIENT_KICK = re.compile('^:.+ KICK [#&!+]['+RE+']+ ['+RE+']+',re.IGNORECASE).search
37 | re_CLIENT_CHANMODE = re.compile('^:['+RE+']+![~:#'+RE+'.]+@[:#'+RE+'.]+ MODE [#&!+]['+RE+']+ [-+][be] \S+ ?',re.IGNORECASE).search
38 | re_CLIENT_BAN_EXCEPT = re.compile('^:['+RE+'!@~.]+ ((367)|(348)) ['+RE+']+ [#&!+]['+RE+']+ \S+ ',re.IGNORECASE).search
39 | re_BUFFER_CTCP_DCC = re.compile('\x01(ACTION )?',re.IGNORECASE).sub
40 | re_BUFFER_COLOUR = re.compile('(\x03[0-9][0-9]?((?<=[0-9]),[0-9]?[0-9]?)?)|[\x02\x03\x0f\x1d\x1f]',re.IGNORECASE).sub
41 | re_SERVER_PRIVMSG_NOTICE_TOPIC = re.compile('^:['+RE+']+![~:#'+RE+'.]+@[:#'+RE+'.]{1,256} ((PRIVMSG)|(NOTICE)|(TOPIC)) [#&!+]['+RE+']+ :.*$',re.IGNORECASE).search
42 |
43 | ### some operating systems do not set atime reliably ###
44 | if os.path.exists('env/HELP') \
45 | and time.time() - os.stat('env/HELP')[7] >= 2048 \
46 | and int(open('env/HELP','rb').read().split('\n')[0]):
47 | os.utime('env/HELP',(time.time(),time.time()))
48 | HELP = 1
49 | else: HELP = 0
50 |
51 | LIMIT = float(open('env/LIMIT','rb').read().split('\n')[0]) if os.path.exists('env/LIMIT') else 1
52 | INVITE = int(open('env/INVITE','rb').read().split('\n')[0]) if os.path.exists('env/INVITE') else 0
53 | COLOUR = int(open('env/COLOUR','rb').read().split('\n')[0]) if os.path.exists('env/COLOUR') else 0
54 | UNICODE = int(open('env/UNICODE','rb').read().split('\n')[0]) if os.path.exists('env/UNICODE') else 0
55 | TIMEOUT = int(open('env/TIMEOUT','rb').read().split('\n')[0]) if os.path.exists('env/TIMEOUT') else 128
56 | PRESENCE = int(open('env/PRESENCE','rb').read().split('\n')[0]) if os.path.exists('env/PRESENCE') else 0
57 | URCSIGNDB = open('env/URCSIGNDB','rb').read().split('\n')[0] if os.path.exists('env/URCSIGNDB') else str()
58 | CHANLIMIT = int(open('env/CHANLIMIT','rb').read().split('\n')[0]) if os.path.exists('env/CHANLIMIT') else 16
59 | URCSIGNPUBKEYDIR = open('env/URCSIGNPUBKEYDIR','rb').read().split('\n')[0] if os.path.exists('env/URCSIGNPUBKEYDIR') else str()
60 |
61 | ### nacl-20110221's randombytes() not compatible with chroot ###
62 | devurandomfd = os.open("/dev/urandom",os.O_RDONLY)
63 | def randombytes(n): return try_read(devurandomfd,n)
64 |
65 | if URCSIGNDB or URCSIGNPUBKEYDIR:
66 |
67 | ### NaCl's crypto_sign / crypto_sign_open API sucks ###
68 | def _crypto_sign(m,sk):
69 | s = crypto_sign(m,sk)
70 | return s[:32]+s[-32:]
71 |
72 | def _crypto_sign_open(m,s,pk):
73 | return 1 if crypto_sign_open(s[:32]+m+s[32:],pk) != 0 else 0
74 |
75 | if URCSIGNPUBKEYDIR:
76 | urcsignpubkeydb = dict()
77 | for dst in os.listdir(URCSIGNPUBKEYDIR):
78 | dst = dst.lower()
79 | urcsignpubkeydb[dst] = dict()
80 | for src in os.listdir(URCSIGNPUBKEYDIR+'/'+dst):
81 | urcsignpubkeydb[dst][src.lower()] = open(URCSIGNPUBKEYDIR+'/'+dst+'/'+src,'rb').read(64).decode('hex')
82 |
83 | if URCSIGNDB:
84 | urcsigndb = dict()
85 | for src in os.listdir(URCSIGNDB):
86 | urcsigndb[src.lower()] = open(URCSIGNDB+'/'+src,'rb').read(64).decode('hex')
87 |
88 | BAN = dict()
89 | EXCEPT = dict()
90 | seen = time.time()
91 | ping = time.time()
92 | user = str(os.getpid())
93 | bytes = [(chr(i),i) for i in xrange(0,256)]
94 | nick = open('nick','rb').read().split('\n')[0]
95 |
96 | channels = collections.deque([],CHANLIMIT)
97 | for dst in open('channels','rb').read().lower().split('\n'):
98 | if dst: channels.append(dst)
99 |
100 | auto_cmd = list()
101 | for cmd in open('auto_cmd','rb').read().split('\n'):
102 | if cmd: auto_cmd.append(cmd)
103 |
104 | def sock_close(sn,sf):
105 | try: os.remove(str(os.getpid()))
106 | except: pass
107 | if sn: sys.exit(sn&255)
108 |
109 | signal.signal(signal.SIGHUP,sock_close)
110 | signal.signal(signal.SIGINT,sock_close)
111 | signal.signal(signal.SIGTERM,sock_close)
112 | signal.signal(signal.SIGCHLD,sock_close)
113 |
114 | rd = 0
115 | """
116 | if os.access('stdin',os.X_OK):
117 | p = subprocess.Popen(['./stdin'],stdout=subprocess.PIPE)
118 | rd = p.stdout.fileno()
119 | del p
120 |
121 | if os.access('stdout',os.X_OK):
122 | p = subprocess.Popen(['./stdout'],stdin=subprocess.PIPE,stdout=subprocess.PIPE)
123 | pipefd = ( p.stdout.fileno(), p.stdin.fileno() )
124 | del p
125 | else: pipefd = os.pipe()
126 | """
127 |
128 | ### nacl-20110221's randombytes() not compatible with chroot ###
129 | devurandomfd = os.open("/dev/urandom",os.O_RDONLY)
130 | def randombytes(n): return try_read(devurandomfd,n)
131 |
132 | uid, gid = pwd.getpwnam('urcd')[2:4]
133 | os.chdir(sys.argv[1])
134 | os.chroot(os.getcwd())
135 | os.setgroups(list())
136 | os.setgid(gid)
137 | os.setuid(uid)
138 | root = os.getcwd()
139 | del uid, gid
140 |
141 | sock=socket.socket(socket.AF_UNIX,socket.SOCK_DGRAM)
142 | sock_close(0,0)
143 | sock.bind(str(os.getpid()))
144 | sock.setblocking(0)
145 | sd=sock.fileno()
146 |
147 | poll=select.poll()
148 | poll.register(rd,select.POLLIN|select.POLLPRI)
149 | """poll.register(pipefd[0],select.POLLIN)"""
150 | poll.register(sd,select.POLLIN)
151 | poll=poll.poll
152 |
153 | client_revents=select.poll()
154 | client_revents.register(rd,select.POLLIN|select.POLLPRI)
155 | client_revents=client_revents.poll
156 |
157 | """
158 | pipe_revents=select.poll()
159 | pipe_revents.register(pipefd[0],select.POLLIN)
160 | pipe_revents=pipe_revents.poll
161 | """
162 |
163 | server_revents=select.poll()
164 | server_revents.register(sd,select.POLLIN)
165 | server_revents=server_revents.poll
166 |
167 | def try_read(fd,buffer_len):
168 | try: return os.read(fd,buffer_len)
169 | except: sock_close(1,0)
170 |
171 | def try_write(fd,buffer):
172 | try: return os.write(fd,buffer)
173 | except: sock_close(2,0)
174 |
175 | def sock_write(buffer):
176 | buflen = len(buffer)
177 | buffer = chr(buflen>>8)+chr(buflen%256)+taia96n_pack(taia96n_now())+'\x00\x00\x00\x00'+randombytes(8)+buffer
178 | try: sock.sendto(buffer,'hub')
179 | except: pass
180 |
181 | try_write(1,'USER '+nick+' '+nick+' '+nick+' :'+nick+'\nNICK '+nick+'\n')
182 |
183 | def INIT():
184 | if client_revents(8192): return
185 | global INIT, auto_cmd, channels
186 | INIT = 0
187 | for cmd in auto_cmd:
188 | time.sleep(LIMIT)
189 | try_write(1,cmd+'\n')
190 | for dst in channels:
191 | time.sleep(LIMIT)
192 | try_write(1,'JOIN '+dst+'\n')
193 | if HELP:
194 | time.sleep(LIMIT)
195 | try_write(1,'NOTICE '+dst+' :'+USAGE)
196 | channels = collections.deque([],CHANLIMIT)
197 | del auto_cmd
198 |
199 | while 1:
200 |
201 | if poll(TIMEOUT<<10) and not INIT: time.sleep(LIMIT)
202 | now = time.time()
203 |
204 | if not client_revents(0):
205 | if now - seen >= TIMEOUT: sock_close(3,0)
206 | if now - ping >= TIMEOUT >> 4:
207 | try_write(1,'PING :LAG\n')
208 | ping = now
209 |
210 | else:
211 | buffer, seen, ping = str(), now, now
212 | while 1:
213 | byte = try_read(rd,1)
214 | if byte == '': sock_close(4,0)
215 | if byte == '\n': break
216 | if byte != '\r' and len(buffer)<768: buffer += byte
217 |
218 | if re_CLIENT_HELP(buffer): try_write(1,'NOTICE '+re_SPLIT(buffer,3)[2]+' :'+USAGE)
219 |
220 | if re_CLIENT_PRIVMSG_NOTICE_TOPIC(buffer):
221 | if buffer[1:].split('!',1)[0] != nick: sock_write(buffer+'\n')
222 |
223 | elif PRESENCE and re_CLIENT_PART(buffer):
224 | if len(buffer.split(' :'))<2: buffer += ' :'
225 | sock_write(buffer+'\n')
226 |
227 | elif PRESENCE and re_CLIENT_QUIT(buffer):
228 | if len(buffer.split(' :'))<2: buffer += ' :'
229 | sock_write(buffer+'\n')
230 |
231 | elif re_CLIENT_PING(buffer): try_write(1,'PONG '+re_SPLIT(buffer,1)[1]+'\n')
232 |
233 | elif re_CLIENT_JOIN(buffer):
234 | if PRESENCE: sock_write(buffer+'\n')
235 | dst = buffer.split(' :')[1].lower()
236 | if not dst in channels:
237 | if len(channels) - 1 < CHANLIMIT:
238 | BAN[dst], EXCEPT[dst] = list(), list()
239 | channels.append(dst)
240 | try_write(1,'MODE '+dst+' b\n')
241 | time.sleep(LIMIT)
242 | try_write(1,'MODE '+dst+' e\n')
243 | else: try_write(1,'PART '+dst+' :CHANLIMIT\n')
244 |
245 | elif re.search('^:'+re.escape(nick).upper()+'!.+ NICK ',buffer.upper()):
246 | nick = re_SPLIT(buffer)[2]
247 | re_CLIENT_HELP = re.compile('^:['+RE+']+![~:#'+RE+'.]+@[:#'+RE+'.]+ PRIVMSG [#&!+]['+RE+']+ :['+re.escape(nick)+']+[:,]? help$',re.IGNORECASE).search
248 |
249 | elif re.search('^:.+ 433 .+ '+re.escape(nick),buffer):
250 | nick+='_'
251 | try_write(1,'NICK '+nick+'\n')
252 |
253 | elif re_CLIENT_KICK(buffer):
254 | if len(buffer.split(' :'))<2: buffer += ' :'
255 | sock_write(buffer+'\n')
256 | if re_SPLIT(buffer,4)[3].lower() == nick.lower():
257 | try_write(1,'JOIN '+re_SPLIT(buffer,4)[2]+'\n')
258 | del EXCEPT[dst], BAN[dst]
259 | channels.remove(dst)
260 |
261 | elif INVITE and len(channels) < CHANLIMIT and re.search('^:['+RE+']+![~'+RE+'.]+@['+RE+'.]+ INVITE '+re.escape(nick).upper()+' :[#&!+]['+RE+']+$',buffer.upper()):
262 | dst = buffer[1:].split(':',1)[1].lower()
263 | if not dst in channels: try_write(1,'JOIN '+dst+'\n')
264 |
265 | elif re_CLIENT_CHANMODE(buffer):
266 | try:
267 | src, cmd, dst = re_SPLIT(buffer,5)[2:5]
268 | dst = re.compile('^'+re.escape(dst).replace('\\*','.*')+'$',re.IGNORECASE).search
269 | src = src.lower()
270 | if cmd[1] == 'b':
271 | BAN[src].append(dst) if cmd[0] == '+' and not dst in BAN[src] else BAN[src].remove(dst)
272 | elif cmd[1] == 'e':
273 | EXCEPT[src].append(dst) if cmd[0] == '+' and not dst in EXCEPT[src] else EXCEPT[src].remove(dst)
274 | except: pass
275 |
276 | elif re_CLIENT_BAN_EXCEPT(buffer):
277 | try:
278 | cmd, src, dst, msg = re_SPLIT(buffer,5)[1:5]
279 | msg = re.compile('^'+re.escape(msg).replace('\\*','.*')+'$',re.IGNORECASE).search
280 | dst = dst.lower()
281 | if cmd == '367':
282 | if not msg in BAN[dst]: BAN[dst].append(msg)
283 | elif cmd == '348':
284 | if not msg in EXCEPT[dst]: EXCEPT.append(msg)
285 | except: pass
286 |
287 | if INIT:
288 | INIT()
289 | continue
290 |
291 | if server_revents(0):
292 | buffer = try_read(sd,2+12+4+8+1024)
293 |
294 | ### URCSIGN ###
295 | if buffer[2+12:2+12+4] == '\x01\x00\x00\x00':
296 | buflen = len(buffer)
297 | try:
298 | src, cmd, dst = re_SPLIT(buffer[2+12+4+8+1:].lower(),3)[:3]
299 | src = src.split('!',1)[0]
300 | except: src, cmd, dst = buffer[2+12+4+8+1:].split('!',1)[0].lower(), str(), str()
301 |
302 | if URCSIGNPUBKEYDIR \
303 | and dst in urcsignpubkeydb.keys() \
304 | and src in urcsignpubkeydb[dst].keys():
305 | try:
306 | if _crypto_sign_open(buffer[:buflen-64],buffer[-64:],urcsignpubkeydb[dst][src]):
307 | buffer = re_USER('!sign@',buffer[2+12+4+8:].split('\n',1)[0],1)
308 | else: buffer = re_USER('!urcd@',buffer[2+12+4+8:].split('\n',1)[0],1)
309 | except: buffer = re_USER('!urcd@',buffer[2+12+4+8:].split('\n',1)[0],1)
310 | elif URCSIGNDB:
311 | try:
312 | if _crypto_sign_open(buffer[:buflen-64],buffer[-64:],urcsigndb[src]):
313 | buffer = re_USER('!sign@',buffer[2+12+4+8:].split('\n',1)[0],1)
314 | else: buffer = re_USER('!urcd@',buffer[2+12+4+8:].split('\n',1)[0],1)
315 | except: buffer = re_USER('!urcd@',buffer[2+12+4+8:].split('\n',1)[0],1)
316 | else: buffer = re_USER('!urcd@',buffer[2+12+4+8:].split('\n',1)[0],1)
317 |
318 | ### URCHUB ###
319 | else: buffer = re_USER('!urcd@',buffer[2+12+4+8:].split('\n',1)[0],1)
320 |
321 | """
322 | if buffer: try_write(pipefd[1],buffer+'\n')
323 |
324 | if pipe_revents(0):
325 |
326 | buffer = str()
327 | while 1:
328 | byte = try_read(pipefd[0],1)
329 | if byte == '': sock_close(5,0)
330 | if byte == '\n': break
331 | if byte != '\r' and len(buffer)<768: buffer += byte
332 | """
333 |
334 | action, buffer = (1, re_BUFFER_CTCP_DCC('',buffer) + '\x01') if '\x01ACTION ' in buffer.upper() else (0, re_BUFFER_CTCP_DCC('',buffer))
335 | if not COLOUR: buffer = re_BUFFER_COLOUR('',buffer)
336 | if not UNICODE:
337 | buffer = codecs.ascii_encode(unicodedata.normalize('NFKD',unicode(buffer,'utf-8','replace')),'ignore')[0]
338 | buffer = ''.join(byte for byte in buffer if 127 > ord(byte) > 31 or byte in ['\x01','\x02','\x03','\x0f','\x1d','\x1f'])
339 | buffer += '\n'
340 |
341 | poll(ord(randombytes(1))<<4) ### may reduce some side channels ###
342 |
343 | if re_SERVER_PRIVMSG_NOTICE_TOPIC(buffer):
344 | dst = re_SPLIT(buffer,3)[2].lower()
345 | if dst in channels:
346 | cmd, src = 1, re_SPLIT(buffer[1:],1)[0]
347 | if buffer.split('!',1)[1].split('@')[0] == 'sign': src = src.split('!',1)[0] + '!*@verified'
348 | else: src = src.split('!',1)[0] + '!*@' + hexlify(crypto_hash_sha256(src.split('@',1)[1])[:4])
349 | for cmd in EXCEPT[dst]:
350 | if cmd(src):
351 | cmd = 0
352 | break
353 | if cmd:
354 | for cmd in BAN[dst]:
355 | if cmd(src):
356 | cmd = 0
357 | break
358 | if cmd == 0: continue
359 | cmd = re_SPLIT(buffer,3)[1].upper()
360 | src = src.replace('!*@','@',1) + '> '
361 | if COLOUR and buffer.split('!',1)[1].split('@')[0] == 'sign':
362 | src = '\x03' + str(ord(hexlify(crypto_hash_sha256(src)[0])[:2].decode('hex'))%16) + src.replace('@','\x0f@',1)
363 | if cmd == 'TOPIC':
364 | try_write(1,'NOTICE '+dst+' :'+src+'/TOPIC\n')
365 | time.sleep(LIMIT)
366 | src = str()
367 | if action: src = '\x01ACTION ' + src
368 | msg = buffer.split(' :',1)[1]
369 | buffer = cmd + ' ' + dst + ' :' + src + msg + '\n'
370 | try_write(1,buffer)
371 |
--------------------------------------------------------------------------------
/src/urccache-failover.c:
--------------------------------------------------------------------------------
1 | #define USAGE "Usage: urccache /path/to/root/\n"
2 | #include
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 |
10 | main(int argc, char **argv)
11 | {
12 |
13 | if (argc<2)
14 | {
15 | write(2,USAGE,strlen(USAGE));
16 | exit(64);
17 | }
18 |
19 | unsigned char cache[131072*32]={0};
20 |
21 | struct passwd *urcd = getpwnam("urcd");
22 |
23 | if ((!urcd)
24 | || (chdir(argv[1]))
25 | || (chroot(argv[1]))
26 | || (setgroups(0,'\x00'))
27 | || (setgid(urcd->pw_gid))
28 | || (setuid(urcd->pw_uid))) exit(64);
29 |
30 | unsigned char buffer[16+8+65536+32];
31 | unsigned char hash[32];
32 | int i, n, l;
33 |
34 | while (1)
35 | {
36 |
37 | readbuffer: if (read(0,buffer,2)<2) exit(1);
38 |
39 | n = 0;
40 | l = 16 + 8 + buffer[0] * 256 + buffer[1];
41 |
42 | while (n-32;i-=32) if (!crypto_verify_32(hash,cache+i))
52 | {
53 | if (write(1,"\1",1)<1) exit(3);
54 | goto readbuffer;
55 | }
56 |
57 | memcpy(cache,cache+32,131072*32-32);
58 | memcpy(cache+131072*32-32,hash,32);
59 |
60 | if (write(1,"\0",1)<1) exit(4);
61 |
62 | }
63 |
64 | }
65 |
--------------------------------------------------------------------------------
/src/urccache.c:
--------------------------------------------------------------------------------
1 | #define USAGE "Usage: urccache /path/to/root/\n"
2 | #include
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 | #include
11 | #include
12 | #include
13 |
14 | #include "tai_dec.h"
15 | #include "tai_inc.h"
16 |
17 | main(int argc, char **argv) {
18 |
19 | if (argc<2)
20 | {
21 | write(2,USAGE,strlen(USAGE));
22 | exit(64);
23 | }
24 |
25 | unsigned char cache[256][16384]={0};
26 | unsigned char buffer[65536*2];
27 | unsigned char salt[32];
28 | unsigned char hash[32];
29 | unsigned char ts[16];
30 | unsigned char st[16];
31 | unsigned char ret[1];
32 |
33 | unsigned long timecached[256];
34 | float cached[256];
35 | int i, n, l;
36 |
37 | randombytes(salt,32);
38 |
39 | taia_now(st);
40 | taia_pack(st,st);
41 | tai_inc(st,st,"\0\0\0\0\0\0\0\x20");
42 |
43 | bzero(cached,sizeof(cached));
44 | for (i=0;i<256;++i) timecached[i] = time(0L);
45 |
46 | struct passwd *urcd = getpwnam("urcd");
47 |
48 | if ((!urcd)
49 | || (chdir(argv[1]))
50 | || (chroot(argv[1]))
51 | || (setgroups(0,'\x00'))
52 | || (setgid(urcd->pw_gid))
53 | || (setuid(urcd->pw_uid))) exit(64);
54 |
55 | while (1) {
56 |
57 | readbuffer: if (read(0,buffer,2)<2) exit(1);
58 |
59 | n = 0;
60 | l = 12 + 4 + 8 + buffer[0] * 256 + buffer[1];
61 |
62 | while (n buffer[i])
73 | {
74 | if (write(1,"\4",1)<1) exit(3);
75 | goto readbuffer;
76 | }
77 | }
78 | }
79 |
80 | taia_now(ts);
81 | taia_pack(ts,ts);
82 |
83 | tai_dec(ts,ts,"\0\0\0\0\0\0\0\x80");
84 |
85 | for (i=0;i<12;++i)
86 | {
87 | if (ts[i] < buffer[i]) break;
88 | if (ts[i] > buffer[i])
89 | {
90 | if (write(1,"\3",1)<1) exit(4);
91 | goto readbuffer;
92 | }
93 | }
94 |
95 | tai_inc(ts,ts,"\0\0\0\0\0\0\x01\0");
96 |
97 | for (i=0;i<12;++i)
98 | {
99 | if (ts[i] > buffer[i]) break;
100 | if (ts[i] < buffer[i])
101 | {
102 | if (write(1,"\2",1)<1) exit(5);
103 | goto readbuffer;
104 | }
105 | }
106 |
107 | memcpy(buffer+l,salt,32);
108 | crypto_hash_sha256(hash,buffer,l+32);
109 |
110 | for (i=16384-32;i>-32;i-=32) if (!crypto_verify_32(hash,cache[hash[0]]+i))
111 | {
112 | if (write(1,"\1",1)<1) exit(6);
113 | goto readbuffer;
114 | }
115 |
116 | memcpy(cache[hash[0]],cache[hash[0]]+32,16384-32);
117 | memcpy(cache[hash[0]]+16384-32,hash,32);
118 |
119 | if (write(1,"\0",1)<1) exit(7);
120 |
121 | if (cached[hash[0]] == 512.0) cached[hash[0]] = 0.0;
122 | if (time(0L) - timecached[hash[0]] >= 256)
123 | {
124 | timecached[hash[0]] = time(0L);
125 | cached[hash[0]] = 0.0;
126 | } ++cached[hash[0]];
127 |
128 | usleep((int) (cached[hash[0]] / 512.0 * 1000000.0));
129 |
130 | }
131 | }
132 |
--------------------------------------------------------------------------------
/src/urchub.c:
--------------------------------------------------------------------------------
1 | #define USAGE "Usage: urchub ./urccache /path/to/sockets/\n"
2 | #include
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 | #include
11 | #include
12 | #include
13 | #include
14 | #include
15 | #include
16 |
17 | #ifndef UNIX_PATH_MAX
18 | #ifdef __NetBSD__
19 | #define UNIX_PATH_MAX 104
20 | #else
21 | #define UNIX_PATH_MAX 108
22 | #endif
23 | #endif
24 |
25 | main(int argc, char **argv)
26 | {
27 |
28 | if (argc<3)
29 | {
30 | write(2,USAGE,strlen(USAGE));
31 | exit(64);
32 | }
33 |
34 | int cache_pid;
35 | unsigned char ret[1];
36 | int cachein[2], cacheout[2];
37 |
38 | if ((pipe(cachein)<0) || (pipe(cacheout)<0)) exit(1);
39 | cache_pid = fork();
40 | if (!cache_pid)
41 | {
42 | close(0);
43 | close(1);
44 | dup(cachein[0]);
45 | dup(cacheout[1]);
46 | close(cachein[1]);
47 | close(cacheout[0]);
48 | execvp(argv[1],argv+1);
49 | } else {
50 | if (cache_pid<0) exit(2);
51 | } close(cachein[0]); close(cacheout[1]);
52 |
53 | struct passwd *urcd = getpwnam("urcd");
54 |
55 | if ((!urcd)
56 | || (chdir(argv[2]))
57 | || (chroot(argv[2]))
58 | || (setgroups(0,'\x00'))
59 | || (setgid(urcd->pw_gid))
60 | || (setuid(urcd->pw_uid))) exit(64);
61 |
62 | unsigned char buffer[2+16+8+65536];
63 | char user[] = "hub\0";
64 | int sockfd;
65 |
66 | struct sockaddr_un sock;
67 | bzero(&sock,sizeof(sock));
68 | sock.sun_family = AF_UNIX;
69 |
70 | void sock_close(int signum)
71 | {
72 | unlink(sock.sun_path);
73 | exit(signum);
74 | } signal(SIGINT,sock_close);
75 | signal(SIGHUP,sock_close);
76 | signal(SIGTERM,sock_close);
77 | signal(SIGCHLD,sock_close);
78 |
79 | sockfd = socket(AF_UNIX,SOCK_DGRAM,0);
80 | if (sockfd<0) exit(3);
81 | int n = 1;
82 | if (setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&n,sizeof(n))<0) exit(4);
83 | int userlen = strlen(user);
84 | if (userlen > UNIX_PATH_MAX) exit(5);
85 | memcpy(&sock.sun_path,user,userlen);
86 | unlink(sock.sun_path);
87 | if (bind(sockfd,(struct sockaddr *)&sock,sizeof(sock))<0) exit(6);
88 |
89 | int strlen_recvpath;
90 | struct sockaddr_un recvpath;
91 | recvpath.sun_family = AF_UNIX;
92 | socklen_t recvpath_len = sizeof(struct sockaddr_un);
93 |
94 | DIR *root;
95 | int sendpath_len;
96 | struct dirent *sendpath;
97 | struct sockaddr_un sendpaths;
98 | sendpaths.sun_family = AF_UNIX;
99 |
100 | while (1)
101 | {
102 | recvpath_len = sizeof(recvpath); // must be initialized each recvfrom call
103 | bzero(&recvpath.sun_path,UNIX_PATH_MAX);
104 | n = recvfrom(sockfd,buffer,65536,0,(struct sockaddr *)&recvpath,&recvpath_len);
105 | if (!n) continue;
106 | if (n<0) sock_close(7);
107 | if (n!=2+16+8+buffer[0]*256+buffer[1]) continue;
108 | if (write(cachein[1],buffer,n)<0) sock_close(8);
109 | if (read(cacheout[0],ret,1)<1) sock_close(9);
110 | if (ret[0]) continue;
111 |
112 | root = opendir("/");
113 | if (!root) sock_close(10);
114 | strlen_recvpath = strlen(recvpath.sun_path);
115 | while ((sendpath = readdir(root)))
116 | {
117 | if (sendpath->d_name[0] == '.') continue;
118 | sendpath_len = strlen(sendpath->d_name);
119 | if (sendpath_len > UNIX_PATH_MAX) continue;
120 | if ((sendpath_len == userlen) && (!memcmp(sendpath->d_name,user,userlen))) continue;
121 | if ((sendpath_len == strlen_recvpath) && (!memcmp(sendpath->d_name,recvpath.sun_path,strlen_recvpath))) continue;
122 | bzero(sendpaths.sun_path,UNIX_PATH_MAX);
123 | memcpy(&sendpaths.sun_path,sendpath->d_name,sendpath_len);
124 | sendto(sockfd,buffer,n,MSG_DONTWAIT,(struct sockaddr *)&sendpaths,sizeof(sendpaths));
125 | } closedir(root);
126 | }
127 | }
128 |
--------------------------------------------------------------------------------
/src/urchubstream.c:
--------------------------------------------------------------------------------
1 | #define USAGE "Usage: urchubstream /path/to/sockets/\n"
2 | #include
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 | #include
11 | #include
12 | #include
13 |
14 | #ifndef UNIX_PATH_MAX
15 | #ifdef __NetBSD__
16 | #define UNIX_PATH_MAX 104
17 | #else
18 | #define UNIX_PATH_MAX 108
19 | #endif
20 | #endif
21 |
22 | int itoa(char *s, int n, int slen)
23 | {
24 | if (snprintf(s,slen,"%d",n)<0) return -1;
25 | return 0;
26 | }
27 |
28 | main(int argc, char **argv)
29 | {
30 |
31 | if (argc<2)
32 | {
33 | write(2,USAGE,strlen(USAGE));
34 | exit(64);
35 | }
36 |
37 | int devurandomfd = open("/dev/urandom",O_RDONLY);
38 | if (devurandomfd<0) exit(255);
39 | unsigned char byte[1];
40 |
41 | int i, n, l;
42 | unsigned char buffer[2+16+8+1024] = {0};
43 | int rd = 0, wr = 1, sd = -1;
44 | if (getenv("TCPCLIENT")){ rd = 6; wr = 7; }
45 |
46 | float LIMIT;
47 | n = open("env/LIMIT",0);
48 | if (n>0)
49 | {
50 | if (read(n,buffer,1024)>0) LIMIT = atof(buffer);
51 | else LIMIT = 1.0;
52 | } else LIMIT = 1.0;
53 | close(n);
54 |
55 | char user[UNIX_PATH_MAX] = {0};
56 | if (itoa(user,getpid(),UNIX_PATH_MAX)<0) exit(1);
57 |
58 | struct passwd *urcd = getpwnam("urcd");
59 |
60 | if ((!urcd)
61 | || (chdir(argv[1]))
62 | || (chroot(argv[1]))
63 | || (setgroups(0,'\x00'))
64 | || (setgid(urcd->pw_gid))
65 | || (setuid(urcd->pw_uid))) exit(64);
66 |
67 | struct sockaddr_un sock;
68 | bzero(&sock,sizeof(sock));
69 | sock.sun_family = AF_UNIX;
70 |
71 | void sock_close(int signum)
72 | {
73 | unlink(sock.sun_path);
74 | exit(signum);
75 | } signal(SIGINT,sock_close);
76 | signal(SIGHUP,sock_close);
77 | signal(SIGTERM,sock_close);
78 |
79 | if ((sd=socket(AF_UNIX,SOCK_DGRAM,0))<0) exit(2);
80 | n = 1;
81 | if (setsockopt(sd,SOL_SOCKET,SO_REUSEADDR,&n,sizeof(n))<0) exit(3);
82 | int userlen = strlen(user);
83 | if (userlen > UNIX_PATH_MAX) exit(4);
84 | memcpy(&sock.sun_path,user,userlen);
85 | unlink(sock.sun_path);
86 | if (bind(sd,(struct sockaddr *)&sock,sizeof(sock))<0) exit(5);
87 |
88 | struct pollfd fds[2];
89 | fds[0].fd = rd; fds[0].events = POLLIN | POLLPRI;
90 | fds[1].fd = sd; fds[1].events = POLLIN;
91 |
92 | struct sockaddr_un hub;
93 | bzero(&hub,sizeof(hub));
94 | hub.sun_family = AF_UNIX;
95 | memcpy(&hub.sun_path,"hub\0",4);
96 |
97 | while (1) {
98 |
99 | poll(fds,2,-1);
100 |
101 | if (fds[0].revents)
102 | {
103 | if (read(rd,buffer,2)<2) sock_close(7);
104 | n = 2;
105 | l = 2+16+8+buffer[0]*256+buffer[1];
106 | if (l>2+16+8+1024) sock_close(8);
107 |
108 | while (n
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 | #include
11 | #include
12 | #include
13 | #include
14 |
15 | #ifndef UNIX_PATH_MAX
16 | #ifdef __NetBSD__
17 | #define UNIX_PATH_MAX 104
18 | #else
19 | #define UNIX_PATH_MAX 108
20 | #endif
21 | #endif
22 |
23 | main(int argc, char **argv)
24 | {
25 |
26 | if (argc<2)
27 | {
28 | write(2,USAGE,strlen(USAGE));
29 | exit(64);
30 | }
31 |
32 | char buffer[1024] = {0};
33 |
34 | int n;
35 | float LIMIT;
36 | n = open("env/LIMIT",0);
37 | if (n>0)
38 | {
39 | if (read(n,buffer,1024)>0) LIMIT = atof(buffer);
40 | else LIMIT = 1.0;
41 | } else LIMIT = 1.0;
42 | close(n);
43 |
44 | struct passwd *urcd = getpwnam("urcd");
45 |
46 | if ((!urcd)
47 | || (chdir(argv[1]))
48 | || (chroot(argv[1]))
49 | || (setgroups(0,'\x00'))
50 | || (setgid(urcd->pw_gid))
51 | || (setuid(urcd->pw_uid))) exit(64);
52 |
53 | int sockfd;
54 | struct sockaddr_un sock;
55 | bzero(&sock,sizeof(sock));
56 | sock.sun_family = AF_UNIX;
57 |
58 | if ((sockfd=socket(AF_UNIX,SOCK_DGRAM,0))<0) exit(1);
59 | n = 1;
60 | if (setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&n,sizeof(n))<0) exit(2);
61 | if (fcntl(sockfd,F_SETFL,O_NONBLOCK)<0) exit(3);
62 |
63 | struct pollfd fds[1];
64 | fds[0].fd = 0;
65 | fds[0].events = POLLIN | POLLPRI;
66 |
67 | DIR *root;
68 | int pathlen;
69 | struct dirent *path;
70 | struct sockaddr_un paths;
71 | paths.sun_family = AF_UNIX;
72 |
73 | while (1)
74 | {
75 |
76 | poll(fds,1,-1);
77 |
78 | usleep((int)(LIMIT*1000000));
79 |
80 | for (n=0;n<1024;++n)
81 | {
82 | if (read(0,buffer+n,1)<1) exit(4);
83 | if (buffer[n] == '\n') break;
84 | } if (buffer[n] != '\n') continue;
85 | ++n;
86 |
87 | root = opendir("/");
88 | if (!root) exit(5);
89 |
90 | while ((path = readdir(root)))
91 | {
92 | if (path->d_name[0] == '.') continue;
93 | pathlen = strlen(path->d_name);
94 | if (pathlen > UNIX_PATH_MAX) continue;
95 | bzero(paths.sun_path,UNIX_PATH_MAX);
96 | memcpy(&paths.sun_path,path->d_name,pathlen);
97 | sendto(sockfd,buffer,n,0,(struct sockaddr *)&paths,sizeof(paths));
98 | } closedir(root);
99 |
100 | }
101 | }
102 |
--------------------------------------------------------------------------------
/src/urcrecv.pyx:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | import socket
3 | import time
4 | import pwd
5 | import sys
6 | import os
7 |
8 | LIMIT = float(open('env/LIMIT','rb').read().split('\n')[0]) if os.path.exists('env/LIMIT') else 1
9 |
10 | uid, gid = pwd.getpwnam('urcd')[2:4]
11 | os.chdir(sys.argv[1])
12 | os.chroot(os.getcwd())
13 | os.setgid(gid)
14 | os.setuid(uid)
15 | root = os.getcwd()
16 | del uid, gid
17 |
18 | sock=socket.socket(1,2)
19 | sock.setblocking(0)
20 |
21 | while 1:
22 |
23 | buffer = str()
24 |
25 | while 1:
26 | byte = os.read(0,1)
27 | if not byte: sys.exit(0)
28 | elif byte == '\n':
29 | buffer+=byte
30 | break
31 | elif len(buffer)<1024: buffer+=byte
32 |
33 | time.sleep(LIMIT)
34 |
35 | for path in os.listdir(root):
36 | try: sock.sendto(buffer,path)
37 | except: pass
38 |
--------------------------------------------------------------------------------
/src/urcsend.c:
--------------------------------------------------------------------------------
1 | #define USAGE "Usage: urcsend /path/to/sockets/\n"
2 | #include
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 | #include
11 | #include
12 | #include
13 | #include
14 |
15 | #ifndef UNIX_PATH_MAX
16 | #ifdef __NetBSD__
17 | #define UNIX_PATH_MAX 104
18 | #else
19 | #define UNIX_PATH_MAX 108
20 | #endif
21 | #endif
22 |
23 | int itoa(char *s, int n, int slen)
24 | {
25 | if (snprintf(s,slen,"%d",n)<0) return -1;
26 | return 0;
27 | }
28 |
29 | main(int argc, char **argv)
30 | {
31 |
32 | if (argc<2)
33 | {
34 | write(2,USAGE,strlen(USAGE));
35 | exit(64);
36 | }
37 |
38 | char buffer[1024] = {0};
39 | char user[UNIX_PATH_MAX] = {0};
40 | if (itoa(user,getpid(),UNIX_PATH_MAX)<0) exit(1);
41 |
42 | struct passwd *urcd = getpwnam("urcd");
43 |
44 | if ((!urcd)
45 | || (chdir(argv[1]))
46 | || (chroot(argv[1]))
47 | || (setgroups(0,'\x00'))
48 | || (setgid(urcd->pw_gid))
49 | || (setuid(urcd->pw_uid))) exit(64);
50 |
51 | int sockfd;
52 | struct sockaddr_un sock;
53 | bzero(&sock,sizeof(sock));
54 | sock.sun_family = AF_UNIX;
55 |
56 | void sock_close(int signum)
57 | {
58 | unlink(sock.sun_path);
59 | exit(signum);
60 | } signal(SIGINT,sock_close);
61 | signal(SIGHUP,sock_close);
62 | signal(SIGTERM,sock_close);
63 |
64 | if ((sockfd=socket(AF_UNIX,SOCK_DGRAM,0))<0) exit(2);
65 | int n = 1;
66 | if (setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&n,sizeof(n))<0) exit(3);
67 | n = strlen(user);
68 | if (n > UNIX_PATH_MAX) exit(4);
69 | memcpy(&sock.sun_path,user,n);
70 | unlink(sock.sun_path);
71 | if (bind(sockfd,(struct sockaddr *)&sock,sizeof(sock))<0) exit(5);
72 |
73 | struct sockaddr_un path;
74 | path.sun_family = AF_UNIX;
75 | socklen_t path_len = sizeof(struct sockaddr_un);
76 |
77 | while (1)
78 | {
79 | bzero(path.sun_path,UNIX_PATH_MAX);
80 | n = recvfrom(sockfd,buffer,1024,0,(struct sockaddr *)&path,&path_len);
81 | if (!n) continue;
82 | if (n<0) sock_close(6);
83 | if (!path_len) continue;
84 | if (buffer[n-1] != '\n') continue;
85 | if (write(7,buffer,n)<0) sock_close(7);
86 | }
87 | }
88 |
--------------------------------------------------------------------------------
/src/urcsend.pyx:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | import socket
3 | import signal
4 | import pwd
5 | import sys
6 | import os
7 |
8 | fd = int(os.getenv('CURVECPCLIENT',7))
9 |
10 | def sock_close(sn,sf):
11 | try: os.remove(str(os.getpid()))
12 | except: pass
13 | if sn: sys.exit(0)
14 |
15 | signal.signal(1 ,sock_close)
16 | signal.signal(2 ,sock_close)
17 | signal.signal(15,sock_close)
18 |
19 | uid, gid = pwd.getpwnam('urcd')[2:4]
20 | os.chdir(sys.argv[1])
21 | os.chroot(os.getcwd())
22 | os.setgid(gid)
23 | os.setuid(uid)
24 | root = os.getcwd()
25 | del uid, gid
26 |
27 | sock=socket.socket(1,2)
28 | sock_close(0,0)
29 | sock.bind(str(os.getpid()))
30 |
31 | while 1:
32 |
33 | buffer, path = sock.recvfrom(1024)
34 | if not path or buffer[len(buffer)-1:] != '\n': continue
35 |
36 | try:
37 | if not os.write(fd,buffer): sock_close(15,0)
38 | except: sock_close(15,0)
39 |
--------------------------------------------------------------------------------
/src/urcstream.c:
--------------------------------------------------------------------------------
1 | #define USAGE "Usage: urcstream /path/to/sockets/\n"
2 | #include
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 | #include
11 | #include
12 | #include
13 | #include
14 |
15 | #ifndef UNIX_PATH_MAX
16 | #ifdef __NetBSD__
17 | #define UNIX_PATH_MAX 104
18 | #else
19 | #define UNIX_PATH_MAX 108
20 | #endif
21 | #endif
22 |
23 | int itoa(char *s, int n, int slen)
24 | {
25 | if (snprintf(s,slen,"%d",n)<0) return -1;
26 | return 0;
27 | }
28 |
29 | main(int argc, char **argv)
30 | {
31 |
32 | if (argc<2)
33 | {
34 | write(2,USAGE,strlen(USAGE));
35 | exit(64);
36 | }
37 |
38 | int rd = 0, wr = 1;
39 | if (getenv("TCPCLIENT")){ rd = 6; wr = 7; }
40 |
41 | char buffer[1024] = {0};
42 | char user[UNIX_PATH_MAX] = {0};
43 | if (itoa(user,getpid(),UNIX_PATH_MAX)<0) exit(1);
44 |
45 | int n;
46 | float LIMIT;
47 | n = open("env/LIMIT",0);
48 | if (n>0)
49 | {
50 | if (read(n,buffer,1024)>0) LIMIT = atof(buffer);
51 | else LIMIT = 1.0;
52 | } else LIMIT = 1.0;
53 | close(n);
54 |
55 | struct passwd *urcd = getpwnam("urcd");
56 |
57 | if ((!urcd)
58 | || (chdir(argv[1]))
59 | || (chroot(argv[1]))
60 | || (setgroups(0,'\x00'))
61 | || (setgid(urcd->pw_gid))
62 | || (setuid(urcd->pw_uid))) exit(64);
63 |
64 | int sockfd;
65 | struct sockaddr_un sock;
66 | bzero(&sock,sizeof(sock));
67 | sock.sun_family = AF_UNIX;
68 |
69 | void sock_close(int signum)
70 | {
71 | unlink(sock.sun_path);
72 | exit(signum);
73 | } signal(SIGINT,sock_close);
74 | signal(SIGHUP,sock_close);
75 | signal(SIGTERM,sock_close);
76 |
77 | if ((sockfd=socket(AF_UNIX,SOCK_DGRAM,0))<0) exit(2);
78 | n = 1;
79 | if (setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&n,sizeof(n))<0) exit(3);
80 | int userlen = strlen(user);
81 | if (userlen > UNIX_PATH_MAX) exit(4);
82 | memcpy(&sock.sun_path,user,userlen);
83 | unlink(sock.sun_path);
84 | if (bind(sockfd,(struct sockaddr *)&sock,sizeof(sock))<0) exit(5);
85 |
86 | struct pollfd fds[2];
87 | fds[0].fd = rd; fds[0].events = POLLIN | POLLPRI;
88 | fds[1].fd = sockfd; fds[1].events = POLLIN;
89 |
90 | DIR *root;
91 | int pathlen;
92 | struct dirent *path;
93 | struct sockaddr_un paths;
94 | paths.sun_family = AF_UNIX;
95 |
96 | while (1) {
97 |
98 | poll(fds,2,-1);
99 |
100 | if (fds[0].revents) {
101 |
102 | usleep((int)(LIMIT*1000000));
103 |
104 | for (n=0;n<1024;++n)
105 | {
106 | if (read(rd,buffer+n,1)<1) sock_close(6);
107 | if (buffer[n] == '\n') break;
108 | } if (buffer[n] != '\n') goto urcwrite;
109 | ++n;
110 |
111 | root = opendir("/");
112 | if (!root) sock_close(7);
113 | while ((path = readdir(root)))
114 | {
115 | if (path->d_name[0] == '.') continue;
116 | pathlen = strlen(path->d_name);
117 | if (pathlen > UNIX_PATH_MAX) continue;
118 | if ((pathlen == userlen) && (!memcmp(path->d_name,user,userlen))) continue;
119 | bzero(paths.sun_path,UNIX_PATH_MAX);
120 | memcpy(&paths.sun_path,path->d_name,pathlen);
121 | sendto(sockfd,buffer,n,MSG_DONTWAIT,(struct sockaddr *)&paths,sizeof(paths));
122 | } closedir(root);
123 | }
124 |
125 | urcwrite: while (poll(fds+1,1,0))
126 | {
127 | n = read(sockfd,buffer,1024);
128 | if (!n) continue;
129 | if (n<0) sock_close(8);
130 | if (buffer[n-1] != '\n') continue;
131 | if (write(wr,buffer,n)<0) sock_close(9);
132 | }
133 | }
134 | }
135 |
--------------------------------------------------------------------------------
/src/urcstream.pyx:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | import socket
3 | import select
4 | import signal
5 | import time
6 | import pwd
7 | import sys
8 | import os
9 |
10 | user = str(os.getpid())
11 | LIMIT = float(open('env/LIMIT','rb').read().split('\n')[0]) if os.path.exists('env/LIMIT') else 1
12 |
13 | wr = 1
14 | if int(os.getenv('TCPCLIENT',0)):
15 | wr += 6
16 | rd = wr - 1
17 |
18 | def sock_close(sn,sf):
19 | try:
20 | os.remove(str(os.getpid()))
21 | except:
22 | pass
23 | if sn:
24 | sys.exit(0)
25 |
26 | signal.signal(1 ,sock_close)
27 | signal.signal(2 ,sock_close)
28 | signal.signal(15,sock_close)
29 |
30 | uid, gid = pwd.getpwnam('urcd')[2:4]
31 | os.chdir(sys.argv[1])
32 | os.chroot(os.getcwd())
33 | os.setgid(gid)
34 | os.setuid(uid)
35 | root = os.getcwd()
36 | del uid, gid
37 |
38 | sock=socket.socket(1,2)
39 | sock_close(0,0)
40 | sock.bind(str(os.getpid()))
41 | sock.setblocking(0)
42 | sd=sock.fileno()
43 |
44 | client_POLLIN=select.poll()
45 | client_POLLIN.register(rd,3)
46 |
47 | server_POLLIN=select.poll()
48 | server_POLLIN.register(sd,3)
49 |
50 | now = time.time()
51 | def limit():
52 | if ((time.time() - now) > LIMIT):
53 | global now
54 | now = time.time()
55 | return 0
56 | return 1
57 |
58 | def client_poll():
59 | return len( client_POLLIN.poll(256-
60 | (256*len( server_POLLIN.poll(0)))
61 | ))
62 |
63 | def server_poll():
64 | return len( server_POLLIN.poll(256-
65 | (256*len( client_POLLIN.poll(0)))
66 | ))
67 |
68 | while 1:
69 | if (client_poll() and limit()):
70 |
71 | buffer = str()
72 |
73 | while 1:
74 | byte = os.read(rd,1)
75 | if not byte: sock_close(15,0)
76 | elif byte == '\n':
77 | buffer+=byte
78 | break
79 | elif len(buffer)<1024: buffer+=byte
80 |
81 | for path in os.listdir(root):
82 | try:
83 | if path != user:
84 | sock.sendto(buffer,path)
85 | except:
86 | pass
87 |
88 | while server_poll():
89 | buffer = os.read(sd,1024)
90 | if buffer[len(buffer)-1:] != '\n': continue
91 | try:
92 | if not os.write(wr,buffer):
93 | sock_close(15,0)
94 | except:
95 | sock_close(15,0)
96 |
--------------------------------------------------------------------------------
/src/urcstream2hub.c:
--------------------------------------------------------------------------------
1 | #define USAGE "Usage: urcstream2hub /path/to/hub/sockets/ ./urcstream /path/to/sockets/\n"
2 | #include
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 | #include
11 | #include
12 | #include
13 | #include
14 | #include
15 |
16 | #ifndef UNIX_PATH_MAX
17 | #ifdef __NetBSD__
18 | #define UNIX_PATH_MAX 104
19 | #else
20 | #define UNIX_PATH_MAX 108
21 | #endif
22 | #endif
23 |
24 | int itoa(char *s, int n, int slen)
25 | {
26 | if (snprintf(s,slen,"%d",n)<0) return -1;
27 | return 0;
28 | }
29 |
30 | main(int argc, char **argv)
31 | {
32 |
33 | if (argc<4)
34 | {
35 | write(2,USAGE,strlen(USAGE));
36 | exit(64);
37 | }
38 |
39 | int urcstream_pid;
40 | int urcstreamin[2], urcstreamout[2];
41 |
42 | if ((pipe(urcstreamin)<0) || (pipe(urcstreamout)<0)) exit(1);
43 | urcstream_pid = fork();
44 | if (!urcstream_pid)
45 | {
46 | close(0);
47 | close(1);
48 | dup(urcstreamin[0]);
49 | dup(urcstreamout[1]);
50 | close(urcstreamin[1]);
51 | close(urcstreamout[0]);
52 | execvp(argv[2],argv+2);
53 | } else {
54 | if (urcstream_pid<0) exit(2);
55 | } close(urcstreamin[0]); close(urcstreamout[1]);
56 |
57 | int devurandom = open("/dev/urandom",O_RDONLY);
58 | if (devurandom<0) exit(3);
59 |
60 | if (chdir(argv[1])) exit(64);
61 | struct passwd *urcd = getpwnam("urcd");
62 | if ((!urcd) || ((chroot(argv[1])) || (setgroups(0,'\x00')) || (setgid(urcd->pw_gid)) || (setuid(urcd->pw_uid)))) exit(64);
63 |
64 | char user[UNIX_PATH_MAX] = {0};
65 | if (itoa(user,getpid(),UNIX_PATH_MAX)<0) exit(4);
66 |
67 | int sockfd;
68 | struct sockaddr_un sock;
69 | bzero(&sock,sizeof(sock));
70 | sock.sun_family = AF_UNIX;
71 |
72 | void sock_close(int signum)
73 | {
74 | unlink(sock.sun_path);
75 | exit(signum);
76 | } signal(SIGINT,sock_close); signal(SIGHUP,sock_close); signal(SIGTERM,sock_close); signal(SIGCHLD,sock_close);
77 |
78 | sockfd = socket(AF_UNIX,SOCK_DGRAM,0);
79 | if (sockfd<0) exit(5);
80 | int n = 1;
81 | if (setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&n,sizeof(n))<0) exit(6);
82 | int userlen = strlen(user);
83 | if (userlen > UNIX_PATH_MAX) exit(7);
84 | memcpy(&sock.sun_path,user,userlen+1);
85 | unlink(sock.sun_path);
86 | if (bind(sockfd,(struct sockaddr *)&sock,sizeof(sock.sun_family)+userlen)<0) exit(8);
87 |
88 | struct pollfd fds[2];
89 | fds[0].fd = urcstreamout[0]; fds[0].events = POLLIN | POLLPRI;
90 | fds[1].fd = sockfd; fds[1].events = POLLIN;
91 |
92 | struct sockaddr_un hub;
93 | bzero(&hub,sizeof(hub));
94 | hub.sun_family = AF_UNIX;
95 | memcpy(&hub.sun_path,"hub\0",4);
96 |
97 | unsigned char buffer[2+16+8+1024] = {0};
98 |
99 | while (1) {
100 |
101 | poll(fds,2,-1);
102 |
103 | if (fds[0].revents)
104 | {
105 | for (n=0;n<1024;++n)
106 | {
107 | if (read(urcstreamout[0],buffer+2+16+8+n,1)<1) sock_close(9);
108 | if (buffer[2+16+8+n] == '\n') break;
109 | } if (buffer[2+16+8+n] != '\n') goto urcwrite;
110 | ++n;
111 | buffer[0] = n / 256;
112 | buffer[1] = n % 256;
113 | taia_now(buffer+2);
114 | taia_pack(buffer+2,buffer+2);
115 | if (read(devurandom,buffer+2+16,8)<8) sock_close(10);
116 | if (sendto(sockfd,buffer,2+16+8+n,MSG_DONTWAIT,(struct sockaddr *)&hub,sizeof(hub))<0) usleep(250000);
117 | }
118 |
119 | urcwrite: while (poll(fds+1,1,0))
120 | {
121 | n = read(sockfd,buffer,2+16+8+1024);
122 | if (!n) continue;
123 | if (n<0) sock_close(11);
124 | if (buffer[n-1] != '\n') continue;
125 | if (n!=2+16+8+buffer[0]*256+buffer[1]) continue;
126 | if (write(urcstreamin[1],buffer+2+16+8,-2-16-8+n)<0) sock_close(12);
127 | }
128 | }
129 | }
130 |
--------------------------------------------------------------------------------
/stdin.cryptoserv:
--------------------------------------------------------------------------------
1 | #!/bin/sh -e
2 |
3 | mkdir -p cryptoservroot/
4 | mkdir -p cryptoservroot/urcsigndb/
5 | mkdir -p cryptoservroot/urccryptoboxdir/
6 | mkdir -p cryptoservroot/urccryptoboxpfs/
7 |
8 | test -e cryptoservroot/.git/ || (
9 | cd cryptoservroot/
10 | git init
11 | )
12 |
13 | echo "`pwd`"/cryptoservroot/urcsigndb > env/URCSIGNDB
14 | echo "`pwd`"/cryptoservroot/urccryptoboxdir > env/URCCRYPTOBOXDIR
15 | echo "`pwd`"/cryptoservroot/urccryptoboxpfs > env/URCCRYPTOBOXPFS
16 |
17 | chown urcd cryptoservroot/*
18 |
19 | # expiry cleanup (hackaround)
20 | for i in `ls cryptoservroot/urccryptoboxpfs/`; do
21 | # test -e cryptoservroot/urcsigndb/$i || rm -rf cryptoservroot/urccryptoboxpfs/$i
22 | test -e cryptoservroot/urccryptoboxdir/$i || rm -rf cryptoservroot/urccryptoboxpfs/$i
23 | done
24 |
25 | exec ./cryptoserv "`cat env/path`" "`pwd`"/cryptoservroot/
26 |
--------------------------------------------------------------------------------