This commit was manufactured by cvs2svn to create tag

'tor-0_0_8pre1'.

svn:r2121
This commit is contained in:
(no author)
2004-07-23 06:28:41 +00:00
parent 48a7547c42
commit 69211f1e2a
128 changed files with 43097 additions and 0 deletions
+20
View File
@@ -0,0 +1,20 @@
Makefile
Makefile.in
aclocal.m4
autom4te.cache
configure
orconfig.h
orconfig.h.in
config.cache
config.log
config.status
config.guess
config.sub
conftest*
stamp-h
stamp-h1
tor.sh
depcomp
install-sh
missing
mkinstalldirs
+34
View File
@@ -0,0 +1,34 @@
Main authors:
-------------
Roger Dingledine <arma@freehaven.net> overhauled all of the code, did
a bunch of new design work, etc.
Nick Mathewson <nickm@freehaven.net> wrote lots of stuff too, in
particular the router and descriptor parsing, and the crypto and tls
wrappers.
Matej Pfajfar <badbytes@freehaven.net> wrote the first version of the code
(called OR) in 2001-2002.
Contributors:
-------------
John Bashinski <jbash@velvet.com> contributed the initial rpm spec file.
Christian Grothoff <grothoff@cs.purdue.edu> contributed better daemonizing
behavior.
Steven Hazel <sah@thalassocracy.org> made 'make install' do the right
thing.
Jason Holt <jason@lunkwill.org> contributed patches to the instructions
and the man page.
Peter Palfrader <peter@palfrader.org> maintains everything that's
debian-specific.
Aaron Turner <aturner@netscreen.com> contributed the first version of
the tor.sh initscripts shell script.
+575
View File
@@ -0,0 +1,575 @@
Release notes in progress for 0.0.8:
pre1:
o Bugfixes:
- Made our unit tests compile again on OpenBSD 3.5, and tor
itself compile again on OpenBSD on a sparc64.
- We were neglecting milliseconds when logging on win32, so
everything appeared to happen at the beginning of each second.
o Protocol changes:
- 'Extend' relay cell payloads now include the digest of the
intended next hop's identity key. Now we can verify that we're
extending to the right router, and also extend to routers we
hadn't heard of before.
o Features:
- Tor nodes can now act as relays (with an advertised ORPort)
without being manually verified by the dirserver operators.
- Uploaded descriptors of unverified routers are now accepted
by the dirservers, and included in the directory.
- Verified routers are listed by nickname in the running-routers
list; unverified routers are listed as "$<fingerprint>".
- We now use hash-of-identity-key in most places rather than
nickname or addr:port, for improved security/flexibility.
- To avoid Sybil attacks, paths still use only verified servers.
But now we have a chance to play around with hybrid approaches.
- Nodes track bandwidth usage to estimate capacity (not used yet).
- ClientOnly option for nodes that never want to become servers.
- Directory caching.
- "AuthoritativeDir 1" option for the official dirservers.
- Now other nodes (clients and servers) will cache the latest
directory they've pulled down.
- They can enable their DirPort to serve it to others.
- Clients will pull down a directory from any node with an open
DirPort, and check the signature/timestamp correctly.
- Authoritative dirservers now fetch directories from other
authdirservers, to stay better synced.
- Running-routers list tells who's down also, along with noting
if they're verified (listed by nickname) or unverified (listed
by hash-of-key).
- Allow dirservers to serve running-router list separately.
This isn't used yet.
- ORs connect-on-demand to other ORs
- If you get an extend cell to an OR you're not connected to,
connect, handshake, and forward the create cell.
- The authoritative dirservers stay connected to everybody,
and everybody stays connected to 0.0.7 servers, but otherwise
clients/servers expire unused connections after 5 minutes.
- When servers get a sigint, they delay 30 seconds (refusing new
connections) then exit. A second sigint causes immediate exit.
- File and name management:
- Look for .torrc if no CONFDIR "torrc" is found.
- If no datadir is defined, then choose, make, and secure ~/.tor
as datadir.
- If torrc not found, exitpolicy reject *:*.
- Expands ~/ in filenames to $HOME/ (but doesn't yet expand ~arma).
- If no nickname is defined, derive default from hostname.
- Rename secret key files, e.g. identity.key -> secret_id_key,
to discourage people from mailing their identity key to tor-ops.
- Refuse to build a circuit before the directory has arrived --
it won't work anyway, since you won't know the right onion keys
to use.
- Try other dirservers immediately if the one you try is down. This
should tolerate down dirservers better now.
- Parse tor version numbers so we can do an is-newer-than check
rather than an is-in-the-list check.
- New socks command 'resolve', to let us shim gethostbyname()
locally.
- A 'tor_resolve' script to access the socks resolve functionality.
- A new socks-extensions.txt doc file to describe our
interpretation and extensions to the socks protocols.
- Add a ContactInfo option, which gets published in descriptor.
- Publish OR uptime in descriptor (and thus in directory) too.
- Write tor version at the top of each log file
- New docs in the tarball:
- tor-doc.html.
- Document that you should proxy your SSL traffic too.
Changes in version 0.0.7.2 - 2004-07-07
o A better fix for the 0.0.0.0 problem, that will hopefully
eliminate the remaining related assertion failures.
Changes in version 0.0.7.1 - 2004-07-04
o When an address resolves to 0.0.0.0, treat it as a failed resolve,
since internally we use 0.0.0.0 to signify "not yet resolved".
Changes in version 0.0.7 - 2004-06-07
o Fixes for crashes and other obnoxious bugs:
- Fix an epipe bug: sometimes when directory connections failed
to connect, we would give them a chance to flush before closing
them.
- When we detached from a circuit because of resolvefailed, we
would immediately try the same circuit twice more, and then
give up on the resolve thinking we'd tried three different
exit nodes.
- Limit the number of intro circuits we'll attempt to build for a
hidden service per 15-minute period.
- Check recommended-software string *early*, before actually parsing
the directory. Thus we can detect an obsolete version and exit,
even if the new directory format doesn't parse.
o Fixes for security bugs:
- Remember which nodes are dirservers when you startup, and if a
random OR enables his dirport, don't automatically assume he's
a trusted dirserver.
o Other bugfixes:
- Directory connections were asking the wrong poll socket to
start writing, and not asking themselves to start writing.
- When we detached from a circuit because we sent a begin but
didn't get a connected, we would use it again the first time;
but after that we would correctly switch to a different one.
- Stop warning when the first onion decrypt attempt fails; they
will sometimes legitimately fail now that we rotate keys.
- Override unaligned-access-ok check when $host_cpu is ia64 or
arm. Apparently they allow it but the kernel whines.
- Dirservers try to reconnect periodically too, in case connections
have failed.
- Fix some memory leaks in directory servers.
- Allow backslash in Win32 filenames.
- Made Tor build complain-free on FreeBSD, hopefully without
breaking other BSD builds. We'll see.
- Check directory signatures based on name of signer, not on whom
we got the directory from. This will let us cache directories more
easily.
- Rotate dnsworkers and cpuworkers on SIGHUP, so they get new config
settings too.
o Features:
- Doxygen markup on all functions and global variables.
- Make directory functions update routerlist, not replace it. So
now directory disagreements are not so critical a problem.
- Remove the upper limit on number of descriptors in a dirserver's
directory (not that we were anywhere close).
- Allow multiple logfiles at different severity ranges.
- Allow *BindAddress to specify ":port" rather than setting *Port
separately. Allow multiple instances of each BindAddress config
option, so you can bind to multiple interfaces if you want.
- Allow multiple exit policy lines, which are processed in order.
Now we don't need that huge line with all the commas in it.
- Enable accept/reject policies on SOCKS connections, so you can bind
to 0.0.0.0 but still control who can use your OP.
- Updated the man page to reflect these features.
Changes in version 0.0.6.2 - 2004-05-16
o Our integrity-checking digest was checking only the most recent cell,
not the previous cells like we'd thought.
Thanks to Stefan Mark for finding the flaw!
Changes in version 0.0.6.1 - 2004-05-06
o Fix two bugs in our AES counter-mode implementation (this affected
onion-level stream encryption, but not TLS-level). It turns
out we were doing something much more akin to a 16-character
polyalphabetic cipher. Oops.
Thanks to Stefan Mark for finding the flaw!
o Retire moria3 as a directory server, and add tor26 as a directory
server.
Changes in version 0.0.6 - 2004-05-02
o Features:
- Hidden services and rendezvous points are implemented. Go to
http://6sxoyfb3h2nvok2d.onion/ for an index of currently available
hidden services. (This only works via a socks4a proxy such as
Privoxy, and currently it's quite slow.)
- We now rotate link (tls context) keys and onion keys.
- CREATE cells now include oaep padding, so you can tell
if you decrypted them correctly.
- Retry stream correctly when we fail to connect because of
exit-policy-reject (should try another) or can't-resolve-address.
- When we hup a dirserver and we've *removed* a server from the
approved-routers list, now we remove that server from the
in-memory directories too.
- Add bandwidthburst to server descriptor.
- Directories now say which dirserver signed them.
- Use a tor_assert macro that logs failed assertions too.
- Since we don't support truncateds much, don't bother sending them;
just close the circ.
- Fetch randomness from /dev/urandom better (not via fopen/fread)
- Better debugging for tls errors
- Set Content-Type on the directory and hidserv descriptor.
- Remove IVs from cipher code, since AES-ctr has none.
o Bugfixes:
- Fix an assert trigger for exit nodes that's been plaguing us since
the days of 0.0.2prexx (thanks weasel!)
- Fix a bug where we were closing tls connections intermittently.
It turns out openssl keeps its errors around -- so if an error
happens, and you don't ask about it, and then another openssl
operation happens and succeeds, and you ask if there was an error,
it tells you about the first error.
- Fix a bug that's been lurking since 27 may 03 (!)
When passing back a destroy cell, we would use the wrong circ id.
- Don't crash if a conn that sent a begin has suddenly lost its circuit.
- Some versions of openssl have an SSL_pending function that erroneously
returns bytes when there is a non-application record pending.
- Win32 fixes. Tor now compiles on win32 with no warnings/errors.
o We were using an array of length zero in a few places.
o Win32's gethostbyname can't resolve an IP to an IP.
o Win32's close can't close a socket.
o Handle windows socket errors correctly.
o Portability:
- check for <sys/limits.h> so we build on FreeBSD again, and
<machine/limits.h> for NetBSD.
Changes in version 0.0.5 - 2004-03-30
o Install torrc as torrc.sample -- we no longer clobber your
torrc. (Woo!)
o Fix mangled-state bug in directory fetching (was causing sigpipes).
o Only build circuits after we've fetched the directory: clients were
using only the directory servers before they'd fetched a directory.
This also means longer startup time; so it goes.
o Fix an assert trigger where an OP would fail to handshake, and we'd
expect it to have a nickname.
o Work around a tsocks bug: do a socks reject when AP connection dies
early, else tsocks goes into an infinite loop.
o Hold socks connection open until reply is flushed (if possible)
o Make exit nodes resolve IPs to IPs immediately, rather than asking
the dns farm to do it.
o Fix c99 aliasing warnings in rephist.c
o Don't include server descriptors that are older than 24 hours in the
directory.
o Give socks 'reject' replies their whole 15s to attempt to flush,
rather than seeing the 60s timeout and assuming the flush had failed.
o Clean automake droppings from the cvs repository
o Add in a 'notice' log level for things the operator should hear
but that aren't warnings
Changes in version 0.0.4 - 2004-03-26
o When connecting to a dirserver or OR and the network is down,
we would crash.
Changes in version 0.0.3 - 2004-03-26
o Warn and fail if server chose a nickname with illegal characters
o Port to Solaris and Sparc:
- include missing header fcntl.h
- have autoconf find -lsocket -lnsl automatically
- deal with hardware word alignment
- make uname() work (solaris has a different return convention)
- switch from using signal() to sigaction()
o Preliminary work on reputation system:
- Keep statistics on success/fail of connect attempts; they're published
by kill -USR1 currently.
- Add a RunTesting option to try to learn link state by creating test
circuits, even when SocksPort is off.
- Remove unused open circuits when there are too many.
Changes in version 0.0.2 - 2004-03-19
- Include strlcpy and strlcat for safer string ops
- define INADDR_NONE so we compile (but still not run) on solaris
Changes in version 0.0.2pre27 - 2004-03-14
o Bugfixes:
- Allow internal tor networks (we were rejecting internal IPs,
now we allow them if they're set explicitly).
- And fix a few endian issues.
Changes in version 0.0.2pre26 - 2004-03-14
o New features:
- If a stream times out after 15s without a connected cell, don't
try that circuit again: try a new one.
- Retry streams at most 4 times. Then give up.
- When a dirserver gets a descriptor from an unknown router, it
logs its fingerprint (so the dirserver operator can choose to
accept it even without mail from the server operator).
- Inform unapproved servers when we reject their descriptors.
- Make tor build on Windows again. It works as a client, who knows
about as a server.
- Clearer instructions in the torrc for how to set up a server.
- Be more efficient about reading fd's when our global token bucket
(used for rate limiting) becomes empty.
o Bugfixes:
- Stop asserting that computers always go forward in time. It's
simply not true.
- When we sent a cell (e.g. destroy) and then marked an OR connection
expired, we might close it before finishing a flush if the other
side isn't reading right then.
- Don't allow dirservers to start if they haven't defined
RecommendedVersions
- We were caching transient dns failures. Oops.
- Prevent servers from publishing an internal IP as their address.
- Address a strcat vulnerability in circuit.c
Changes in version 0.0.2pre25 - 2004-03-04
o New features:
- Put the OR's IP in its router descriptor, not its fqdn. That way
we'll stop being stalled by gethostbyname for nodes with flaky dns,
e.g. poblano.
o Bugfixes:
- If the user typed in an address that didn't resolve, the server
crashed.
Changes in version 0.0.2pre24 - 2004-03-03
o Bugfixes:
- Fix an assertion failure in dns.c, where we were trying to dequeue
a pending dns resolve even if it wasn't pending
- Fix a spurious socks5 warning about still trying to write after the
connection is finished.
- Hold certain marked_for_close connections open until they're finished
flushing, rather than losing bytes by closing them too early.
- Correctly report the reason for ending a stream
- Remove some duplicate calls to connection_mark_for_close
- Put switch_id and start_daemon earlier in the boot sequence, so it
will actually try to chdir() to options.DataDirectory
- Make 'make test' exit(1) if a test fails; fix some unit tests
- Make tor fail when you use a config option it doesn't know about,
rather than warn and continue.
- Make --version work
- Bugfixes on the rpm spec file and tor.sh, so it's more up to date
Changes in version 0.0.2pre23 - 2004-02-29
o New features:
- Print a statement when the first circ is finished, so the user
knows it's working.
- If a relay cell is unrecognized at the end of the circuit,
send back a destroy. (So attacks to mutate cells are more
clearly thwarted.)
- New config option 'excludenodes' to avoid certain nodes for circuits.
- When it daemonizes, it chdir's to the DataDirectory rather than "/",
so you can collect coredumps there.
o Bugfixes:
- Fix a bug in tls flushing where sometimes data got wedged and
didn't flush until more data got sent. Hopefully this bug was
a big factor in the random delays we were seeing.
- Make 'connected' cells include the resolved IP, so the client
dns cache actually gets populated.
- Disallow changing from ORPort=0 to ORPort>0 on hup.
- When we time-out on a stream and detach from the circuit, send an
end cell down it first.
- Only warn about an unknown router (in exitnodes, entrynodes,
excludenodes) after we've fetched a directory.
Changes in version 0.0.2pre22 - 2004-02-26
o New features:
- Servers publish less revealing uname information in descriptors.
- More memory tracking and assertions, to crash more usefully when
errors happen.
- If the default torrc isn't there, just use some default defaults.
Plus provide an internal dirservers file if they don't have one.
- When the user tries to use Tor as an http proxy, give them an http
501 failure explaining that we're a socks proxy.
- Dump a new router.desc on hup, to help confused people who change
their exit policies and then wonder why router.desc doesn't reflect
it.
- Clean up the generic tor.sh init script that we ship with.
o Bugfixes:
- If the exit stream is pending on the resolve, and a destroy arrives,
then the stream wasn't getting removed from the pending list. I
think this was the one causing recent server crashes.
- Use a more robust poll on OSX 10.3, since their poll is flaky.
- When it couldn't resolve any dirservers, it was useless from then on.
Now it reloads the RouterFile (or default dirservers) if it has no
dirservers.
- Move the 'tor' binary back to /usr/local/bin/ -- it turns out
many users don't even *have* a /usr/local/sbin/.
Changes in version 0.0.2pre21 - 2004-02-18
o New features:
- There's a ChangeLog file that actually reflects the changelog.
- There's a 'torify' wrapper script, with an accompanying
tor-tsocks.conf, that simplifies the process of using tsocks for
tor. It even has a man page.
- The tor binary gets installed to sbin rather than bin now.
- Retry streams where the connected cell hasn't arrived in 15 seconds
- Clean up exit policy handling -- get the default out of the torrc,
so we can update it without forcing each server operator to fix
his/her torrc.
- Allow imaps and pop3s in default exit policy
o Bugfixes:
- Prevent picking middleman nodes as the last node in the circuit
Changes in version 0.0.2pre20 - 2004-01-30
o New features:
- We now have a deb package, and it's in debian unstable. Go to
it, apt-getters. :)
- I've split the TotalBandwidth option into BandwidthRate (how many
bytes per second you want to allow, long-term) and
BandwidthBurst (how many bytes you will allow at once before the cap
kicks in). This better token bucket approach lets you, say, set
BandwidthRate to 10KB/s and BandwidthBurst to 10MB, allowing good
performance while not exceeding your monthly bandwidth quota.
- Push out a tls record's worth of data once you've got it, rather
than waiting until you've read everything waiting to be read. This
may improve performance by pipelining better. We'll see.
- Add an AP_CONN_STATE_CONNECTING state, to allow streams to detach
from failed circuits (if they haven't been connected yet) and attach
to new ones.
- Expire old streams that haven't managed to connect. Some day we'll
have them reattach to new circuits instead.
o Bugfixes:
- Fix several memory leaks that were causing servers to become bloated
after a while.
- Fix a few very rare assert triggers. A few more remain.
- Setuid to User _before_ complaining about running as root.
Changes in version 0.0.2pre19 - 2004-01-07
o Bugfixes:
- Fix deadlock condition in dns farm. We were telling a child to die by
closing the parent's file descriptor to him. But newer children were
inheriting the open file descriptor from the parent, and since they
weren't closing it, the socket never closed, so the child never read
eof, so he never knew to exit. Similarly, dns workers were holding
open other sockets, leading to all sorts of chaos.
- New cleaner daemon() code for forking and backgrounding.
- If you log to a file, it now prints an entry at the top of the
logfile so you know it's working.
- The onionskin challenge length was 30 bytes longer than necessary.
- Started to patch up the spec so it's not quite so out of date.
Changes in version 0.0.2pre18 - 2004-01-02
o Bugfixes:
- Fix endian issues with the 'integrity' field in the relay header.
- Fix a potential bug where connections in state
AP_CONN_STATE_CIRCUIT_WAIT might unexpectedly ask to write.
Changes in version 0.0.2pre17 - 2003-12-30
o Bugfixes:
- Made --debuglogfile (or any second log file, actually) work.
- Resolved an edge case in get_unique_circ_id_by_conn where a smart
adversary could force us into an infinite loop.
o Features:
- Each onionskin handshake now includes a hash of the computed key,
to prove the server's identity and help perfect forward secrecy.
- Changed cell size from 256 to 512 bytes (working toward compatibility
with MorphMix).
- Changed cell length to 2 bytes, and moved it to the relay header.
- Implemented end-to-end integrity checking for the payloads of
relay cells.
- Separated streamid from 'recognized' (otherwise circuits will get
messed up when we try to have streams exit from the middle). We
use the integrity-checking to confirm that a cell is addressed to
this hop.
- Randomize the initial circid and streamid values, so an adversary who
breaks into a node can't learn how many circuits or streams have
been made so far.
Changes in version 0.0.2pre16 - 2003-12-14
o Bugfixes:
- Fixed a bug that made HUP trigger an assert
- Fixed a bug where a circuit that immediately failed wasn't being
counted as a failed circuit in counting retries.
o Features:
- Now we close the circuit when we get a truncated cell: otherwise we're
open to an anonymity attack where a bad node in the path truncates
the circuit and then we open streams at him.
- Add port ranges to exit policies
- Add a conservative default exit policy
- Warn if you're running tor as root
- on HUP, retry OR connections and close/rebind listeners
- options.EntryNodes: try these nodes first when picking the first node
- options.ExitNodes: if your best choices happen to include any of
your preferred exit nodes, you choose among just those preferred
exit nodes.
- options.ExcludedNodes: nodes that are never picked in path building
Changes in version 0.0.2pre15 - 2003-12-03
o Robustness and bugfixes:
- Sometimes clients would cache incorrect DNS resolves, which would
really screw things up.
- An OP that goes offline would slowly leak all its sockets and stop
working.
- A wide variety of bugfixes in exit node selection, exit policy
handling, and processing pending streams when a new circuit is
established.
- Pick nodes for a path only from those the directory says are up
- Choose randomly from all running dirservers, not always the first one
- Increase allowed http header size for directory fetch.
- Stop writing to stderr (if we're daemonized it will be closed).
- Enable -g always, so cores will be more useful to me.
- Switch "-lcrypto -lssl" to "-lssl -lcrypto" for broken distributions.
o Documentation:
- Wrote a man page. It lists commonly used options.
o Configuration:
- Change default loglevel to warn.
- Make PidFile default to null rather than littering in your CWD.
- OnionRouter config option is now obsolete. Instead it just checks
ORPort>0.
- Moved to a single unified torrc file for both clients and servers.
Changes in version 0.0.2pre14 - 2003-11-29
o Robustness and bugfixes:
- Force the admin to make the DataDirectory himself
- to get ownership/permissions right
- so clients no longer make a DataDirectory and then never use it
- fix bug where a client who was offline for 45 minutes would never
pull down a directory again
- fix (or at least hide really well) the dns assert bug that was
causing server crashes
- warnings and improved robustness wrt clockskew for certs
- use the native daemon(3) to daemonize, when available
- exit if bind() fails
- exit if neither socksport nor orport is defined
- include our own tor_timegm (Win32 doesn't have its own)
- bugfix for win32 with lots of connections
- fix minor bias in PRNG
- make dirserver more robust to corrupt cached directory
o Documentation:
- Wrote the design document (woo)
o Circuit building and exit policies:
- Circuits no longer try to use nodes that the directory has told them
are down.
- Exit policies now support bitmasks (18.0.0.0/255.0.0.0) and
bitcounts (18.0.0.0/8).
- Make AP connections standby for a circuit if no suitable circuit
exists, rather than failing
- Circuits choose exit node based on addr/port, exit policies, and
which AP connections are standing by
- Bump min pathlen from 2 to 3
- Relay end cells have a payload to describe why the stream ended.
- If the stream failed because of exit policy, try again with a new
circuit.
- Clients have a dns cache to remember resolved addresses.
- Notice more quickly when we have no working circuits
o Configuration:
- APPort is now called SocksPort
- SocksBindAddress, ORBindAddress, DirBindAddress let you configure
where to bind
- RecommendedVersions is now a config variable rather than
hardcoded (for dirservers)
- Reloads config on HUP
- Usage info on -h or --help
- If you set User and Group config vars, it'll setu/gid to them.
Changes in version 0.0.2pre13 - 2003-10-19
o General stability:
- SSL_write no longer fails when it returns WANTWRITE and the number
of bytes in the buf has changed by the next SSL_write call.
- Fix segfault fetching directory when network is down
- Fix a variety of minor memory leaks
- Dirservers reload the fingerprints file on HUP, so I don't have
to take down the network when I approve a new router
- Default server config file has explicit Address line to specify fqdn
o Buffers:
- Buffers grow and shrink as needed (Cut process size from 20M to 2M)
- Make listener connections not ever alloc bufs
o Autoconf improvements:
- don't clobber an external CFLAGS in ./configure
- Make install now works
- create var/lib/tor on make install
- autocreate a tor.sh initscript to help distribs
- autocreate the torrc and sample-server-torrc with correct paths
o Log files and Daemonizing now work:
- If --DebugLogFile is specified, log to it at -l debug
- If --LogFile is specified, use it instead of commandline
- If --RunAsDaemon is set, tor forks and backgrounds on startup
+996
View File
@@ -0,0 +1,996 @@
# $Id$
# Doxyfile 1.2.18
# This file describes the settings to be used by the documentation system
# doxygen (www.doxygen.org) for a project
#
# All text after a hash (#) is considered a comment and will be ignored
# The format is:
# TAG = value [value, ...]
# For lists items can also be appended using:
# TAG += value [value, ...]
# Values that contain spaces should be placed between quotes (" ")
#---------------------------------------------------------------------------
# General configuration options
#---------------------------------------------------------------------------
# The PROJECT_NAME tag is a single word (or a sequence of words surrounded
# by quotes) that should identify the project.
PROJECT_NAME = tor
# The PROJECT_NUMBER tag can be used to enter a project or revision number.
# This could be handy for archiving the generated documentation or
# if some version control system is used.
PROJECT_NUMBER = 0.0.7pre1
# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
# base path where the generated documentation will be put.
# If a relative path is entered, it will be relative to the location
# where doxygen was started. If left blank the current directory will be used.
OUTPUT_DIRECTORY = ./doc/doxygen
# The OUTPUT_LANGUAGE tag is used to specify the language in which all
# documentation generated by doxygen is written. Doxygen will use this
# information to generate all constant output in the proper language.
# The default language is English, other supported languages are:
# Brazilian, Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish, Dutch,
# Finnish, French, German, Greek, Hungarian, Italian, Japanese, Japanese-en
# (Japanese with english messages), Korean, Norwegian, Polish, Portuguese,
# Romanian, Russian, Serbian, Slovak, Slovene, Spanish, Swedish and Ukrainian.
OUTPUT_LANGUAGE = English
# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in
# documentation are documented, even if no documentation was available.
# Private class members and static file members will be hidden unless
# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
EXTRACT_ALL = NO
# If the EXTRACT_PRIVATE tag is set to YES all private members of a class
# will be included in the documentation.
EXTRACT_PRIVATE = NO
# If the EXTRACT_STATIC tag is set to YES all static members of a file
# will be included in the documentation.
EXTRACT_STATIC = YES
# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs)
# defined locally in source files will be included in the documentation.
# If set to NO only classes defined in header files are included.
EXTRACT_LOCAL_CLASSES = YES
# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all
# undocumented members of documented classes, files or namespaces.
# If set to NO (the default) these members will be included in the
# various overviews, but no documentation section is generated.
# This option has no effect if EXTRACT_ALL is enabled.
HIDE_UNDOC_MEMBERS = NO
# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all
# undocumented classes that are normally visible in the class hierarchy.
# If set to NO (the default) these class will be included in the various
# overviews. This option has no effect if EXTRACT_ALL is enabled.
HIDE_UNDOC_CLASSES = NO
# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all
# friend (class|struct|union) declarations.
# If set to NO (the default) these declarations will be included in the
# documentation.
HIDE_FRIEND_COMPOUNDS = NO
# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will
# include brief member descriptions after the members that are listed in
# the file and class documentation (similar to JavaDoc).
# Set to NO to disable this.
#changed
BRIEF_MEMBER_DESC = NO
# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend
# the brief description of a member or function before the detailed description.
# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
# brief descriptions will be completely suppressed.
REPEAT_BRIEF = YES
# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
# Doxygen will generate a detailed section even if there is only a brief
# description.
ALWAYS_DETAILED_SEC = NO
# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all inherited
# members of a class in the documentation of that class as if those members were
# ordinary class members. Constructors, destructors and assignment operators of
# the base classes will not be shown.
INLINE_INHERITED_MEMB = NO
# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full
# path before files name in the file list and in the header files. If set
# to NO the shortest path that makes the file name unique will be used.
FULL_PATH_NAMES = NO
# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag
# can be used to strip a user defined part of the path. Stripping is
# only done if one of the specified strings matches the left-hand part of
# the path. It is allowed to use relative paths in the argument list.
STRIP_FROM_PATH =
# The INTERNAL_DOCS tag determines if documentation
# that is typed after a \internal command is included. If the tag is set
# to NO (the default) then the documentation will be excluded.
# Set it to YES to include the internal documentation.
INTERNAL_DOCS = NO
# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct
# doxygen to hide any special comment blocks from generated source code
# fragments. Normal C and C++ comments will always remain visible.
STRIP_CODE_COMMENTS = YES
# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate
# file names in lower case letters. If set to YES upper case letters are also
# allowed. This is useful if you have classes or files whose names only differ
# in case and if your file system supports case sensitive file names. Windows
# users are adviced to set this option to NO.
CASE_SENSE_NAMES = YES
# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter
# (but less readable) file names. This can be useful is your file systems
# doesn't support long names like on DOS, Mac, or CD-ROM.
SHORT_NAMES = NO
# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen
# will show members with their full class and namespace scopes in the
# documentation. If set to YES the scope will be hidden.
HIDE_SCOPE_NAMES = NO
# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen
# will generate a verbatim copy of the header file for each class for
# which an include is specified. Set to NO to disable this.
VERBATIM_HEADERS = YES
# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen
# will put list of the files that are included by a file in the documentation
# of that file.
SHOW_INCLUDE_FILES = YES
# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen
# will interpret the first line (until the first dot) of a JavaDoc-style
# comment as the brief description. If set to NO, the JavaDoc
# comments will behave just like the Qt-style comments (thus requiring an
# explict @brief command for a brief description.
JAVADOC_AUTOBRIEF = NO
# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen
# treat a multi-line C++ special comment block (i.e. a block of //! or ///
# comments) as a brief description. This used to be the default behaviour.
# The new default is to treat a multi-line C++ comment block as a detailed
# description. Set this tag to YES if you prefer the old behaviour instead.
MULTILINE_CPP_IS_BRIEF = NO
# If the DETAILS_AT_TOP tag is set to YES then Doxygen
# will output the detailed description near the top, like JavaDoc.
# If set to NO, the detailed description appears after the member
# documentation.
DETAILS_AT_TOP = NO
# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented
# member inherits the documentation from any documented member that it
# reimplements.
INHERIT_DOCS = YES
# If the INLINE_INFO tag is set to YES (the default) then a tag [inline]
# is inserted in the documentation for inline members.
INLINE_INFO = YES
# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen
# will sort the (detailed) documentation of file and class members
# alphabetically by member name. If set to NO the members will appear in
# declaration order.
SORT_MEMBER_DOCS = YES
# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
# tag is set to YES, then doxygen will reuse the documentation of the first
# member in the group (if any) for the other members of the group. By default
# all members of a group must be documented explicitly.
DISTRIBUTE_GROUP_DOC = NO
# The TAB_SIZE tag can be used to set the number of spaces in a tab.
# Doxygen uses this value to replace tabs by spaces in code fragments.
TAB_SIZE = 8
# The GENERATE_TODOLIST tag can be used to enable (YES) or
# disable (NO) the todo list. This list is created by putting \todo
# commands in the documentation.
GENERATE_TODOLIST = YES
# The GENERATE_TESTLIST tag can be used to enable (YES) or
# disable (NO) the test list. This list is created by putting \test
# commands in the documentation.
GENERATE_TESTLIST = YES
# The GENERATE_BUGLIST tag can be used to enable (YES) or
# disable (NO) the bug list. This list is created by putting \bug
# commands in the documentation.
GENERATE_BUGLIST = YES
# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or
# disable (NO) the deprecated list. This list is created by putting \deprecated commands in the documentation.
GENERATE_DEPRECATEDLIST= YES
# This tag can be used to specify a number of aliases that acts
# as commands in the documentation. An alias has the form "name=value".
# For example adding "sideeffect=\par Side Effects:\n" will allow you to
# put the command \sideeffect (or @sideeffect) in the documentation, which
# will result in a user defined paragraph with heading "Side Effects:".
# You can put \n's in the value part of an alias to insert newlines.
ALIASES =
# The ENABLED_SECTIONS tag can be used to enable conditional
# documentation sections, marked by \if sectionname ... \endif.
ENABLED_SECTIONS =
# The MAX_INITIALIZER_LINES tag determines the maximum number of lines
# the initial value of a variable or define consist of for it to appear in
# the documentation. If the initializer consists of more lines than specified
# here it will be hidden. Use a value of 0 to hide initializers completely.
# The appearance of the initializer of individual variables and defines in the
# documentation can be controlled using \showinitializer or \hideinitializer
# command in the documentation regardless of this setting.
MAX_INITIALIZER_LINES = 30
# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources
# only. Doxygen will then generate output that is more tailored for C.
# For instance some of the names that are used will be different. The list
# of all members will be omitted, etc.
OPTIMIZE_OUTPUT_FOR_C = YES
# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java sources
# only. Doxygen will then generate output that is more tailored for Java.
# For instance namespaces will be presented as packages, qualified scopes
# will look different, etc.
OPTIMIZE_OUTPUT_JAVA = NO
# Set the SHOW_USED_FILES tag to NO to disable the list of files generated
# at the bottom of the documentation of classes and structs. If set to YES the
# list will mention the files that were used to generate the documentation.
SHOW_USED_FILES = YES
#---------------------------------------------------------------------------
# configuration options related to warning and progress messages
#---------------------------------------------------------------------------
# The QUIET tag can be used to turn on/off the messages that are generated
# by doxygen. Possible values are YES and NO. If left blank NO is used.
QUIET = NO
# The WARNINGS tag can be used to turn on/off the warning messages that are
# generated by doxygen. Possible values are YES and NO. If left blank
# NO is used.
WARNINGS = YES
# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings
# for undocumented members. If EXTRACT_ALL is set to YES then this flag will
# automatically be disabled.
WARN_IF_UNDOCUMENTED = YES
# The WARN_FORMAT tag determines the format of the warning messages that
# doxygen can produce. The string should contain the $file, $line, and $text
# tags, which will be replaced by the file and line number from which the
# warning originated and the warning text.
WARN_FORMAT = "$file:$line: $text"
# The WARN_LOGFILE tag can be used to specify a file to which warning
# and error messages should be written. If left blank the output is written
# to stderr.
WARN_LOGFILE =
#---------------------------------------------------------------------------
# configuration options related to the input files
#---------------------------------------------------------------------------
# The INPUT tag can be used to specify the files and/or directories that contain
# documented source files. You may enter file names like "myfile.cpp" or
# directories like "/usr/src/myproject". Separate the files or directories
# with spaces.
INPUT = src/common src/or
# If the value of the INPUT tag contains directories, you can use the
# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
# and *.h) to filter out the source-files in the directories. If left
# blank the following patterns are tested:
# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx *.hpp
# *.h++ *.idl *.odl
FILE_PATTERNS = *.c *.h
# The RECURSIVE tag can be used to turn specify whether or not subdirectories
# should be searched for input files as well. Possible values are YES and NO.
# If left blank NO is used.
RECURSIVE = NO
# The EXCLUDE tag can be used to specify files and/or directories that should
# excluded from the INPUT source files. This way you can easily exclude a
# subdirectory from a directory tree whose root is specified with the INPUT tag.
EXCLUDE = tree.h
# The EXCLUDE_SYMLINKS tag can be used select whether or not files or directories
# that are symbolic links (a Unix filesystem feature) are excluded from the input.
EXCLUDE_SYMLINKS = NO
# If the value of the INPUT tag contains directories, you can use the
# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
# certain files from those directories.
EXCLUDE_PATTERNS =
# The EXAMPLE_PATH tag can be used to specify one or more files or
# directories that contain example code fragments that are included (see
# the \include command).
EXAMPLE_PATH =
# If the value of the EXAMPLE_PATH tag contains directories, you can use the
# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
# and *.h) to filter out the source-files in the directories. If left
# blank all files are included.
EXAMPLE_PATTERNS =
# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
# searched for input files to be used with the \include or \dontinclude
# commands irrespective of the value of the RECURSIVE tag.
# Possible values are YES and NO. If left blank NO is used.
EXAMPLE_RECURSIVE = NO
# The IMAGE_PATH tag can be used to specify one or more files or
# directories that contain image that are included in the documentation (see
# the \image command).
IMAGE_PATH =
# The INPUT_FILTER tag can be used to specify a program that doxygen should
# invoke to filter for each input file. Doxygen will invoke the filter program
# by executing (via popen()) the command <filter> <input-file>, where <filter>
# is the value of the INPUT_FILTER tag, and <input-file> is the name of an
# input file. Doxygen will then use the output that the filter program writes
# to standard output.
INPUT_FILTER =
# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
# INPUT_FILTER) will be used to filter the input files when producing source
# files to browse (i.e. when SOURCE_BROWSER is set to YES).
FILTER_SOURCE_FILES = NO
#---------------------------------------------------------------------------
# configuration options related to source browsing
#---------------------------------------------------------------------------
# If the SOURCE_BROWSER tag is set to YES then a list of source files will
# be generated. Documented entities will be cross-referenced with these sources.
SOURCE_BROWSER = NO
# Setting the INLINE_SOURCES tag to YES will include the body
# of functions and classes directly in the documentation.
INLINE_SOURCES = NO
# If the REFERENCED_BY_RELATION tag is set to YES (the default)
# then for each documented function all documented
# functions referencing it will be listed.
REFERENCED_BY_RELATION = YES
# If the REFERENCES_RELATION tag is set to YES (the default)
# then for each documented function all documented entities
# called/used by that function will be listed.
REFERENCES_RELATION = YES
#---------------------------------------------------------------------------
# configuration options related to the alphabetical class index
#---------------------------------------------------------------------------
# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index
# of all compounds will be generated. Enable this if the project
# contains a lot of classes, structs, unions or interfaces.
ALPHABETICAL_INDEX = NO
# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then
# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns
# in which this list will be split (can be a number in the range [1..20])
COLS_IN_ALPHA_INDEX = 5
# In case all classes in a project start with a common prefix, all
# classes will be put under the same header in the alphabetical index.
# The IGNORE_PREFIX tag can be used to specify one or more prefixes that
# should be ignored while generating the index headers.
IGNORE_PREFIX =
#---------------------------------------------------------------------------
# configuration options related to the HTML output
#---------------------------------------------------------------------------
# If the GENERATE_HTML tag is set to YES (the default) Doxygen will
# generate HTML output.
GENERATE_HTML = YES
# The HTML_OUTPUT tag is used to specify where the HTML docs will be put.
# If a relative path is entered the value of OUTPUT_DIRECTORY will be
# put in front of it. If left blank `html' will be used as the default path.
HTML_OUTPUT = html
# The HTML_FILE_EXTENSION tag can be used to specify the file extension for
# each generated HTML page (for example: .htm,.php,.asp). If it is left blank
# doxygen will generate files with .html extension.
HTML_FILE_EXTENSION = .html
# The HTML_HEADER tag can be used to specify a personal HTML header for
# each generated HTML page. If it is left blank doxygen will generate a
# standard header.
HTML_HEADER =
# The HTML_FOOTER tag can be used to specify a personal HTML footer for
# each generated HTML page. If it is left blank doxygen will generate a
# standard footer.
HTML_FOOTER =
# The HTML_STYLESHEET tag can be used to specify a user defined cascading
# style sheet that is used by each HTML page. It can be used to
# fine-tune the look of the HTML output. If the tag is left blank doxygen
# will generate a default style sheet
HTML_STYLESHEET =
# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes,
# files or namespaces will be aligned in HTML using tables. If set to
# NO a bullet list will be used.
HTML_ALIGN_MEMBERS = YES
# If the GENERATE_HTMLHELP tag is set to YES, additional index files
# will be generated that can be used as input for tools like the
# Microsoft HTML help workshop to generate a compressed HTML help file (.chm)
# of the generated HTML documentation.
GENERATE_HTMLHELP = NO
# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can
# be used to specify the file name of the resulting .chm file. You
# can add a path in front of the file if the result should not be
# written to the html output dir.
CHM_FILE =
# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can
# be used to specify the location (absolute path including file name) of
# the HTML help compiler (hhc.exe). If non empty doxygen will try to run
# the html help compiler on the generated index.hhp.
HHC_LOCATION =
# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag
# controls if a separate .chi index file is generated (YES) or that
# it should be included in the master .chm file (NO).
GENERATE_CHI = NO
# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag
# controls whether a binary table of contents is generated (YES) or a
# normal table of contents (NO) in the .chm file.
BINARY_TOC = NO
# The TOC_EXPAND flag can be set to YES to add extra items for group members
# to the contents of the Html help documentation and to the tree view.
TOC_EXPAND = NO
# The DISABLE_INDEX tag can be used to turn on/off the condensed index at
# top of each HTML page. The value NO (the default) enables the index and
# the value YES disables it.
DISABLE_INDEX = NO
# This tag can be used to set the number of enum values (range [1..20])
# that doxygen will group on one line in the generated HTML documentation.
ENUM_VALUES_PER_LINE = 4
# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be
# generated containing a tree-like index structure (just like the one that
# is generated for HTML Help). For this to work a browser that supports
# JavaScript and frames is required (for instance Mozilla, Netscape 4.0+,
# or Internet explorer 4.0+). Note that for large projects the tree generation
# can take a very long time. In such cases it is better to disable this feature.
# Windows users are probably better off using the HTML help feature.
GENERATE_TREEVIEW = NO
# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be
# used to set the initial width (in pixels) of the frame in which the tree
# is shown.
TREEVIEW_WIDTH = 250
#---------------------------------------------------------------------------
# configuration options related to the LaTeX output
#---------------------------------------------------------------------------
# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will
# generate Latex output.
GENERATE_LATEX = YES
# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put.
# If a relative path is entered the value of OUTPUT_DIRECTORY will be
# put in front of it. If left blank `latex' will be used as the default path.
LATEX_OUTPUT = latex
# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be invoked. If left blank `latex' will be used as the default command name.
LATEX_CMD_NAME = latex
# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to
# generate index for LaTeX. If left blank `makeindex' will be used as the
# default command name.
MAKEINDEX_CMD_NAME = makeindex
# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact
# LaTeX documents. This may be useful for small projects and may help to
# save some trees in general.
COMPACT_LATEX = NO
# The PAPER_TYPE tag can be used to set the paper type that is used
# by the printer. Possible values are: a4, a4wide, letter, legal and
# executive. If left blank a4wide will be used.
PAPER_TYPE = a4wide
# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX
# packages that should be included in the LaTeX output.
EXTRA_PACKAGES =
# The LATEX_HEADER tag can be used to specify a personal LaTeX header for
# the generated latex document. The header should contain everything until
# the first chapter. If it is left blank doxygen will generate a
# standard header. Notice: only use this tag if you know what you are doing!
LATEX_HEADER =
# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated
# is prepared for conversion to pdf (using ps2pdf). The pdf file will
# contain links (just like the HTML output) instead of page references
# This makes the output suitable for online browsing using a pdf viewer.
PDF_HYPERLINKS = NO
# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of
# plain latex in the generated Makefile. Set this option to YES to get a
# higher quality PDF documentation.
USE_PDFLATEX = NO
# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode.
# command to the generated LaTeX files. This will instruct LaTeX to keep
# running if errors occur, instead of asking the user for help.
# This option is also used when generating formulas in HTML.
LATEX_BATCHMODE = NO
#---------------------------------------------------------------------------
# configuration options related to the RTF output
#---------------------------------------------------------------------------
# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output
# The RTF output is optimised for Word 97 and may not look very pretty with
# other RTF readers or editors.
GENERATE_RTF = NO
# The RTF_OUTPUT tag is used to specify where the RTF docs will be put.
# If a relative path is entered the value of OUTPUT_DIRECTORY will be
# put in front of it. If left blank `rtf' will be used as the default path.
RTF_OUTPUT = rtf
# If the COMPACT_RTF tag is set to YES Doxygen generates more compact
# RTF documents. This may be useful for small projects and may help to
# save some trees in general.
COMPACT_RTF = NO
# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated
# will contain hyperlink fields. The RTF file will
# contain links (just like the HTML output) instead of page references.
# This makes the output suitable for online browsing using WORD or other
# programs which support those fields.
# Note: wordpad (write) and others do not support links.
RTF_HYPERLINKS = NO
# Load stylesheet definitions from file. Syntax is similar to doxygen's
# config file, i.e. a series of assigments. You only have to provide
# replacements, missing definitions are set to their default value.
RTF_STYLESHEET_FILE =
# Set optional variables used in the generation of an rtf document.
# Syntax is similar to doxygen's config file.
RTF_EXTENSIONS_FILE =
#---------------------------------------------------------------------------
# configuration options related to the man page output
#---------------------------------------------------------------------------
# If the GENERATE_MAN tag is set to YES (the default) Doxygen will
# generate man pages
GENERATE_MAN = NO
# The MAN_OUTPUT tag is used to specify where the man pages will be put.
# If a relative path is entered the value of OUTPUT_DIRECTORY will be
# put in front of it. If left blank `man' will be used as the default path.
MAN_OUTPUT = man
# The MAN_EXTENSION tag determines the extension that is added to
# the generated man pages (default is the subroutine's section .3)
MAN_EXTENSION = .3
# If the MAN_LINKS tag is set to YES and Doxygen generates man output,
# then it will generate one additional man file for each entity
# documented in the real man page(s). These additional files
# only source the real man page, but without them the man command
# would be unable to find the correct page. The default is NO.
MAN_LINKS = NO
#---------------------------------------------------------------------------
# configuration options related to the XML output
#---------------------------------------------------------------------------
# If the GENERATE_XML tag is set to YES Doxygen will
# generate an XML file that captures the structure of
# the code including all documentation. Note that this
# feature is still experimental and incomplete at the
# moment.
GENERATE_XML = NO
# The XML_SCHEMA tag can be used to specify an XML schema,
# which can be used by a validating XML parser to check the
# syntax of the XML files.
XML_SCHEMA =
# The XML_DTD tag can be used to specify an XML DTD,
# which can be used by a validating XML parser to check the
# syntax of the XML files.
XML_DTD =
#---------------------------------------------------------------------------
# configuration options for the AutoGen Definitions output
#---------------------------------------------------------------------------
# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will
# generate an AutoGen Definitions (see autogen.sf.net) file
# that captures the structure of the code including all
# documentation. Note that this feature is still experimental
# and incomplete at the moment.
GENERATE_AUTOGEN_DEF = NO
#---------------------------------------------------------------------------
# Configuration options related to the preprocessor
#---------------------------------------------------------------------------
# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will
# evaluate all C-preprocessor directives found in the sources and include
# files.
ENABLE_PREPROCESSING = YES
# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro
# names in the source code. If set to NO (the default) only conditional
# compilation will be performed. Macro expansion can be done in a controlled
# way by setting EXPAND_ONLY_PREDEF to YES.
MACRO_EXPANSION = NO
# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES
# then the macro expansion is limited to the macros specified with the
# PREDEFINED and EXPAND_AS_PREDEFINED tags.
EXPAND_ONLY_PREDEF = NO
# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files
# in the INCLUDE_PATH (see below) will be search if a #include is found.
SEARCH_INCLUDES = YES
# The INCLUDE_PATH tag can be used to specify one or more directories that
# contain include files that are not input files but should be processed by
# the preprocessor.
INCLUDE_PATH =
# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
# patterns (like *.h and *.hpp) to filter out the header-files in the
# directories. If left blank, the patterns specified with FILE_PATTERNS will
# be used.
INCLUDE_FILE_PATTERNS =
# The PREDEFINED tag can be used to specify one or more macro names that
# are defined before the preprocessor is started (similar to the -D option of
# gcc). The argument of the tag is a list of macros of the form: name
# or name=definition (no spaces). If the definition and the = are
# omitted =1 is assumed.
PREDEFINED =
# If the MACRO_EXPANSION and EXPAND_PREDEF_ONLY tags are set to YES then
# this tag can be used to specify a list of macro names that should be expanded.
# The macro definition that is found in the sources will be used.
# Use the PREDEFINED tag if you want to use a different macro definition.
EXPAND_AS_DEFINED =
# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then
# doxygen's preprocessor will remove all function-like macros that are alone
# on a line, have an all uppercase name, and do not end with a semicolon. Such
# function macros are typically used for boiler-plate code, and will confuse the
# parser if not removed.
SKIP_FUNCTION_MACROS = YES
#---------------------------------------------------------------------------
# Configuration::addtions related to external references
#---------------------------------------------------------------------------
# The TAGFILES tag can be used to specify one or more tagfiles.
TAGFILES =
# When a file name is specified after GENERATE_TAGFILE, doxygen will create
# a tag file that is based on the input files it reads.
GENERATE_TAGFILE =
# If the ALLEXTERNALS tag is set to YES all external classes will be listed
# in the class index. If set to NO only the inherited external classes
# will be listed.
ALLEXTERNALS = NO
# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed
# in the modules index. If set to NO, only the current project's groups will
# be listed.
EXTERNAL_GROUPS = YES
# The PERL_PATH should be the absolute path and name of the perl script
# interpreter (i.e. the result of `which perl').
PERL_PATH = /usr/bin/perl
#---------------------------------------------------------------------------
# Configuration options related to the dot tool
#---------------------------------------------------------------------------
# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will
# generate a inheritance diagram (in Html, RTF and LaTeX) for classes with base or
# super classes. Setting the tag to NO turns the diagrams off. Note that this
# option is superceded by the HAVE_DOT option below. This is only a fallback. It is
# recommended to install and use dot, since it yield more powerful graphs.
CLASS_DIAGRAMS = YES
# If set to YES, the inheritance and collaboration graphs will hide
# inheritance and usage relations if the target is undocumented
# or is not a class.
HIDE_UNDOC_RELATIONS = YES
# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
# available from the path. This tool is part of Graphviz, a graph visualization
# toolkit from AT&T and Lucent Bell Labs. The other options in this section
# have no effect if this option is set to NO (the default)
HAVE_DOT = NO
# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen
# will generate a graph for each documented class showing the direct and
# indirect inheritance relations. Setting this tag to YES will force the
# the CLASS_DIAGRAMS tag to NO.
CLASS_GRAPH = YES
# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen
# will generate a graph for each documented class showing the direct and
# indirect implementation dependencies (inheritance, containment, and
# class references variables) of the class with other documented classes.
COLLABORATION_GRAPH = YES
# If set to YES, the inheritance and collaboration graphs will show the
# relations between templates and their instances.
TEMPLATE_RELATIONS = YES
# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT
# tags are set to YES then doxygen will generate a graph for each documented
# file showing the direct and indirect include dependencies of the file with
# other documented files.
INCLUDE_GRAPH = YES
# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and
# HAVE_DOT tags are set to YES then doxygen will generate a graph for each
# documented header file showing the documented files that directly or
# indirectly include this file.
INCLUDED_BY_GRAPH = YES
# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen
# will graphical hierarchy of all classes instead of a textual one.
GRAPHICAL_HIERARCHY = YES
# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
# generated by dot. Possible values are png, jpg, or gif
# If left blank png will be used.
DOT_IMAGE_FORMAT = png
# The tag DOT_PATH can be used to specify the path where the dot tool can be
# found. If left blank, it is assumed the dot tool can be found on the path.
DOT_PATH =
# The DOTFILE_DIRS tag can be used to specify one or more directories that
# contain dot files that are included in the documentation (see the
# \dotfile command).
DOTFILE_DIRS =
# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width
# (in pixels) of the graphs generated by dot. If a graph becomes larger than
# this value, doxygen will try to truncate the graph, so that it fits within
# the specified constraint. Beware that most browsers cannot cope with very
# large images.
MAX_DOT_GRAPH_WIDTH = 1024
# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height
# (in pixels) of the graphs generated by dot. If a graph becomes larger than
# this value, doxygen will try to truncate the graph, so that it fits within
# the specified constraint. Beware that most browsers cannot cope with very
# large images.
MAX_DOT_GRAPH_HEIGHT = 1024
# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will
# generate a legend page explaining the meaning of the various boxes and
# arrows in the dot generated graphs.
GENERATE_LEGEND = YES
# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will
# remove the intermedate dot files that are used to generate
# the various graphs.
DOT_CLEANUP = YES
#---------------------------------------------------------------------------
# Configuration::addtions related to the search engine
#---------------------------------------------------------------------------
# The SEARCHENGINE tag specifies whether or not a search engine should be
# used. If set to NO the values of all tags below this one will be ignored.
SEARCHENGINE = NO
# The CGI_NAME tag should be the name of the CGI script that
# starts the search engine (doxysearch) with the correct parameters.
# A script with this name will be generated by doxygen.
CGI_NAME = search.cgi
# The CGI_URL tag should be the absolute URL to the directory where the
# cgi binaries are located. See the documentation of your http daemon for
# details.
CGI_URL =
# The DOC_URL tag should be the absolute URL to the directory where the
# documentation is located. If left blank the absolute path to the
# documentation, with file:// prepended to it, will be used.
DOC_URL =
# The DOC_ABSPATH tag should be the absolute path to the directory where the
# documentation is located. If left blank the directory on the local machine
# will be used.
DOC_ABSPATH =
# The BIN_ABSPATH tag must point to the directory where the doxysearch binary
# is installed.
BIN_ABSPATH = /usr/local/bin/
# The EXT_DOC_PATHS tag can be used to specify one or more paths to
# documentation generated for other projects. This allows doxysearch to search
# the documentation for these projects as well.
EXT_DOC_PATHS =
+54
View File
@@ -0,0 +1,54 @@
Quickstart version for users:
0) Download the absolute newest version. No, really.
http://freehaven.net/tor/dist/
1) tar xvf it, and then cd into the directory.
2) ./configure
3) make
4) make install (as root if necessary)
5) tor (if it doesn't work, give it the whole path or fix your path)
You don't need to run this as root, and you probably shouldn't.
(If you're having problems, try running it with "-l info" to get
more details.)
6) point your browser to socks4 or socks5 proxy at localhost port
9050. In mozilla, this is in edit|preferences|advanced|proxies. This
allows you to test to make sure tor is installed correctly.
(If you have a personal firewall, be sure to allow local connections
to port 9050.)
(If your firewall blocks outgoing connections, punch a hole so it
can connect to TCP *:9001-9004 and *:9031-9033)
(If you're using Safari as your browser, keep in mind that OS X before
10.3 claims to support socks but does not. You must do step 8.)
7) make sure you've set it up correctly: go to
http://www.junkbusters.com/cgi-bin/privacy and see what IP it says
you're coming from. If it works, you should probably go on to step 8,
to get better privacy.
8) Optionally, install privoxy (www.privoxy.org), and add the line
"forward-socks4a / localhost:9050 ." (without the quotes -- don't forget
the dot) to its config file. Then change your mozilla to http proxy
at localhost port 8118 (and no socks proxy). You should also set your
SSL proxy to the same thing, to hide your https traffic. Using privoxy
will give you good html scrubbing as well.
(See doc/CLIENTS for why direct socks gives you less anonymity.)
*****If this works for you, you can stop reading here******
If you got the source from cvs:
Run "./autogen.sh", which will run the various auto* programs and then
run ./configure for you. From there, start at step 3 in the quickstart
list above.
If the quickstart doesn't work for you:
If you have problems finding libraries, try
CPPFLAGS="-I/usr/local/include" LDFLAGS="-L/usr/local/lib" \
./configure
rather than simply ./configure.
Check out the list archives at http://archives.seul.org/or/dev/ and see
if somebody else has reported your problem. If not, please subscribe
and let us know what you did to fix it, or give us the details and
we'll see what we can do.
+29
View File
@@ -0,0 +1,29 @@
Copyright (c) 2001-2004, Roger Dingledine
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.
* Neither the names of the copyright owners nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+24
View File
@@ -0,0 +1,24 @@
AUTOMAKE_OPTIONS = foreign
# else it keeps trying to put COPYING back in
SUBDIRS = src doc contrib
DIST_SUBDIRS = src doc contrib
EXTRA_DIST = INSTALL README AUTHORS LICENSE ChangeLog
#install-data-local:
# $(INSTALL) -m 755 -d $(LOCALSTATEDIR)/lib/tor
dist-rpm: dist
rm -rf /tmp/tor-rpm-build
mkdir /tmp/tor-rpm-build
for subdir in BUILD RPMS SOURCES SPECS SRPMS; do \
mkdir /tmp/tor-rpm-build/$$subdir; \
done
cp tor-$(VERSION).tar.gz /tmp/tor-rpm-build/SOURCES
rpmbuild -ba --define '_topdir /tmp/tor-rpm-build' contrib/tor.spec
mv /tmp/tor-rpm-build/*RPMS/* .
doxygen:
doxygen && cd doc/doxygen/latex && make
+63
View File
@@ -0,0 +1,63 @@
'tor' is an implementation of The Onion Routing system, as
described in a bit more detail at http://www.onion-router.net/. You
can read list archives, and subscribe to the mailing list, at
http://archives.seul.org/or/dev/.
Is your question in the FAQ? Should it be?
**************************************************************************
See the INSTALL file for a quickstart. That is all you will probably need.
**************************************************************************
**************************************************************************
You only need to look beyond this point if the quickstart in the INSTALL
doesn't work for you.
**************************************************************************
Do you want to run a tor server?
We're looking for people with reasonably reliable Internet connections,
that have at least 768kbit each way. Currently we don't use all of that,
but we want it available for burst traffic.
First, copy torrc.sample to torrc (by default it's in
/usr/local/etc/tor/), and edit the middle part. Create the
DataDirectory, and make sure it's owned by whoever will be running
tor. Fix your system clock so it's not too far off. Make sure name
resolution works.
Then run tor to generate keys. One of the files generated
in your DataDirectory is your 'fingerprint' file. Mail it to
tor-ops@freehaven.net.
Please also tell us in that mail who you are, so we know whom to contact
if there's any problem. Also describe what kind of connectivity the new
server will have. If possible PGP sign your mail.
NOTE: You won't be able to use tor as a client or server
in this configuration until you've been added to the directory
and can authenticate to the other nodes.
Do you want to run a hidden service?
Copy torrc.sample to torrc (by default it's in /usr/local/etc/tor/), and
edit the bottom part. Then run Tor. It will create each HiddenServiceDir
you have configured, and it will create a 'hostname' file which
specifies the url (xyz.onion) for that service. You can tell people
the url, and they can connect to it via their Tor client.
Configuring tsocks:
If you want to use Tor for protocols that can't use Privoxy, or
with applications that are not socksified, then download tsocks
(tsocks.sourceforge.net) and configure it to talk to localhost:9050
as a socks4 server. My /etc/tsocks.conf simply has:
server_port = 9050
server = 127.0.0.1
(I had to "cd /usr/lib; ln -s /lib/libtsocks.so" to get the tsocks
library working after install, since my libpath didn't include /lib.)
Then you can do "tsocks ssh arma@moria.mit.edu". But note that if
ssh is suid root, you either need to do this as root, or cp a local
version of ssh that isn't suid.
+266
View File
@@ -0,0 +1,266 @@
# Microsoft Developer Studio Project File - Name="or" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Console Application" 0x0103
CFG=or - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "or.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "or.mak" CFG="or - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "or - Win32 Release" (based on "Win32 (x86) Console Application")
!MESSAGE "or - Win32 Debug" (based on "Win32 (x86) Console Application")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
RSC=rc.exe
!IF "$(CFG)" == "or - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD CPP /nologo /MT /W3 /GX /O2 /I "d:\openssl\include ..\win32" /I "..\win32" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib libeay32.lib ssleay32.lib /nologo /subsystem:console /machine:I386 /libpath:"d:\openssl\lib\vc"
!ELSEIF "$(CFG)" == "or - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "..\..\src\win32" /I "D:\openssl\include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FR /YX /FD /GZ /c
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib libeay32.lib ssleay32.lib /nologo /subsystem:console /debug /machine:I386 /out:"Debug/tor.exe" /pdbtype:sept /libpath:"d:\openssl\lib\vc"
!ENDIF
# Begin Target
# Name "or - Win32 Release"
# Name "or - Win32 Debug"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File
SOURCE=..\..\src\common\aes.c
# End Source File
# Begin Source File
SOURCE=..\..\src\or\buffers.c
# End Source File
# Begin Source File
SOURCE=..\..\src\or\circuitbuild.c
# End Source File
# Begin Source File
SOURCE=..\..\src\or\circuitlist.c
# End Source File
# Begin Source File
SOURCE=..\..\src\or\circuituse.c
# End Source File
# Begin Source File
SOURCE=..\..\src\or\command.c
# End Source File
# Begin Source File
SOURCE=..\..\src\or\config.c
# End Source File
# Begin Source File
SOURCE=..\..\src\or\connection.c
# End Source File
# Begin Source File
SOURCE=..\..\src\or\connection_edge.c
# End Source File
# Begin Source File
SOURCE=..\..\src\or\connection_or.c
# End Source File
# Begin Source File
SOURCE=..\..\src\or\cpuworker.c
# End Source File
# Begin Source File
SOURCE=..\..\src\common\crypto.c
# End Source File
# Begin Source File
SOURCE=..\..\src\or\directory.c
# End Source File
# Begin Source File
SOURCE=..\..\src\or\dirserv.c
# End Source File
# Begin Source File
SOURCE=..\..\src\or\dns.c
# End Source File
# Begin Source File
SOURCE=..\..\src\common\fakepoll.c
# End Source File
# Begin Source File
SOURCE=..\..\src\common\log.c
# End Source File
# Begin Source File
SOURCE=..\..\src\or\main.c
# End Source File
# Begin Source File
SOURCE=..\..\src\or\onion.c
# End Source File
# Begin Source File
SOURCE=..\..\src\or\relay.c
# End Source File
# Begin Source File
SOURCE=..\..\src\or\rendclient.c
# End Source File
# Begin Source File
SOURCE=..\..\src\or\rendcommon.c
# End Source File
# Begin Source File
SOURCE=..\..\src\or\rendmid.c
# End Source File
# Begin Source File
SOURCE=..\..\src\or\rendservice.c
# End Source File
# Begin Source File
SOURCE=..\..\src\or\rephist.c
# End Source File
# Begin Source File
SOURCE=..\..\src\or\router.c
# End Source File
# Begin Source File
SOURCE=..\..\src\or\routerlist.c
# End Source File
# Begin Source File
SOURCE=..\..\src\or\routerparse.c
# End Source File
# Begin Source File
SOURCE=..\..\src\or\tor_main.c
# End Source File
# Begin Source File
SOURCE=..\..\src\common\tortls.c
# End Source File
# Begin Source File
SOURCE=..\..\src\common\util.c
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl"
# Begin Source File
SOURCE=..\..\src\common\aes.h
# End Source File
# Begin Source File
SOURCE=..\..\src\common\crypto.h
# End Source File
# Begin Source File
SOURCE=..\..\src\common\fakepoll.h
# End Source File
# Begin Source File
SOURCE=..\..\src\common\log.h
# End Source File
# Begin Source File
SOURCE=..\..\src\or\or.h
# End Source File
# Begin Source File
SOURCE=..\..\src\win32\orconfig.h
# End Source File
# Begin Source File
SOURCE=..\..\src\common\test.h
# End Source File
# Begin Source File
SOURCE=..\..\src\common\torint.h
# End Source File
# Begin Source File
SOURCE=..\..\src\common\tortls.h
# End Source File
# Begin Source File
SOURCE=..\..\src\or\tree.h
# End Source File
# Begin Source File
SOURCE=..\..\src\common\util.h
# End Source File
# End Group
# Begin Group "Resource Files"
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
# End Group
# End Target
# End Project
+29
View File
@@ -0,0 +1,29 @@
Microsoft Developer Studio Workspace File, Format Version 6.00
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
###############################################################################
Project: "or"=".\or.dsp" - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
}}}
###############################################################################
Global:
Package=<5>
{{{
}}}
Package=<3>
{{{
}}}
###############################################################################
+29
View File
@@ -0,0 +1,29 @@
Microsoft Developer Studio Workspace File, Format Version 6.00
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
###############################################################################
Project: "or"="..\or\or.dsp" - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
}}}
###############################################################################
Global:
Package=<5>
{{{
}}}
Package=<3>
{{{
}}}
###############################################################################
+8
View File
@@ -0,0 +1,8 @@
#!/bin/sh
# Run this to generate all the initial makefiles, etc.
aclocal &&
autoheader &&
autoconf &&
automake --add-missing --copy
./configure
+222
View File
@@ -0,0 +1,222 @@
AC_INIT
AM_INIT_AUTOMAKE(tor, 0.0.8pre1)
AM_CONFIG_HEADER(orconfig.h)
AC_CANONICAL_HOST
CFLAGS="$CFLAGS -Wall -g -O2"
if test -f /etc/redhat-release; then
CFLAGS="$CFLAGS -I/usr/kerberos/include"
fi
AC_ARG_ENABLE(debug,
[ --enable-debug compiles with debugging info],
[if test x$enableval = xyes; then
CFLAGS="$CFLAGS -g"
fi])
AC_PROG_CC
AC_PROG_MAKE_SET
AC_PROG_RANLIB
# The big search for OpenSSL
# copied from openssh's configure.ac
AC_ARG_WITH(ssl-dir,
[ --with-ssl-dir=PATH Specify path to OpenSSL installation ],
[
if test "x$withval" != "xno" ; then
tryssldir=$withval
fi
]
)
AC_SEARCH_LIBS(socket, [socket])
AC_SEARCH_LIBS(gethostbyname, [nsl])
saved_LIBS="$LIBS"
saved_LDFLAGS="$LDFLAGS"
saved_CPPFLAGS="$CPPFLAGS"
if test "x$prefix" != "xNONE" ; then
tryssldir="$tryssldir $prefix"
fi
AC_CACHE_CHECK([for OpenSSL directory], ac_cv_openssldir, [
for ssldir in $tryssldir "" /usr/local/openssl /usr/lib/openssl /usr/local/ssl /usr/lib/ssl /usr/local /usr/pkg /opt /opt/openssl ; do
CPPFLAGS="$saved_CPPFLAGS"
LDFLAGS="$saved_LDFLAGS"
LIBS="$saved_LIBS -lssl -lcrypto"
# Skip directories if they don't exist
if test ! -z "$ssldir" -a ! -d "$ssldir" ; then
continue;
fi
if test ! -z "$ssldir" -a "x$ssldir" != "x/usr"; then
# Try to use $ssldir/lib if it exists, otherwise
# $ssldir
if test -d "$ssldir/lib" ; then
LDFLAGS="-L$ssldir/lib $saved_LDFLAGS"
if test ! -z "$need_dash_r" ; then
LDFLAGS="-R$ssldir/lib $LDFLAGS"
fi
else
LDFLAGS="-L$ssldir $saved_LDFLAGS"
if test ! -z "$need_dash_r" ; then
LDFLAGS="-R$ssldir $LDFLAGS"
fi
fi
# Try to use $ssldir/include if it exists, otherwise
# $ssldir
if test -d "$ssldir/include" ; then
CPPFLAGS="-I$ssldir/include $saved_CPPFLAGS"
else
CPPFLAGS="-I$ssldir $saved_CPPFLAGS"
fi
fi
# Basic test to check for compatible version and correct linking
# *does not* test for RSA - that comes later.
AC_TRY_RUN(
[
#include <string.h>
#include <openssl/rand.h>
int main(void)
{
char a[2048];
memset(a, 0, sizeof(a));
RAND_add(a, sizeof(a), sizeof(a));
return(RAND_status() <= 0);
}
],
[
found_crypto=1
break;
], []
)
if test ! -z "$found_crypto" ; then
break;
fi
done
if test -z "$found_crypto" ; then
AC_MSG_ERROR([Could not find working OpenSSL library, please install or check config.log])
fi
if test -z "$ssldir" ; then
ssldir="(system)"
fi
ac_cv_openssldir=$ssldir
])
if (test ! -z "$ac_cv_openssldir" && test "x$ac_cv_openssldir" != "x(system)") ;
then
dnl Need to recover ssldir - test above runs in subshell
ssldir=$ac_cv_openssldir
if test ! -z "$ssldir" -a "x$ssldir" != "x/usr"; then
# Try to use $ssldir/lib if it exists, otherwise
# $ssldir
if test -d "$ssldir/lib" ; then
LDFLAGS="-L$ssldir/lib $saved_LDFLAGS"
if test ! -z "$need_dash_r" ; then
LDFLAGS="-R$ssldir/lib $LDFLAGS"
fi
else
LDFLAGS="-L$ssldir $saved_LDFLAGS"
if test ! -z "$need_dash_r" ; then
LDFLAGS="-R$ssldir $LDFLAGS"
fi
fi
# Try to use $ssldir/include if it exists, otherwise
# $ssldir
if test -d "$ssldir/include" ; then
CPPFLAGS="-I$ssldir/include $saved_CPPFLAGS"
else
CPPFLAGS="-I$ssldir $saved_CPPFLAGS"
fi
fi
fi
LIBS="$saved_LIBS -lssl -lcrypto"
dnl The warning message here is no longer strictly accurate.
AC_CHECK_HEADERS(unistd.h string.h signal.h netdb.h ctype.h poll.h sys/stat.h sys/poll.h sys/types.h fcntl.h sys/fcntl.h sys/ioctl.h sys/socket.h sys/time.h netinet/in.h arpa/inet.h errno.h assert.h time.h pwd.h grp.h, , AC_MSG_WARN(some headers were not found, compilation may fail))
dnl These headers are not essential
AC_CHECK_HEADERS(stdint.h sys/types.h inttypes.h sys/param.h sys/wait.h sys/limits.h netinet/in.h arpa/inet.h machine/limits.h)
AC_CHECK_FUNCS(gettimeofday ftime socketpair uname inet_aton strptime)
AC_REPLACE_FUNCS(strlcat strlcpy)
dnl In case we aren't given a working stdint.h, we'll need to grow our own.
dnl Watch out.
AC_CHECK_SIZEOF(int8_t)
AC_CHECK_SIZEOF(int16_t)
AC_CHECK_SIZEOF(int32_t)
AC_CHECK_SIZEOF(int64_t)
AC_CHECK_SIZEOF(uint8_t)
AC_CHECK_SIZEOF(uint16_t)
AC_CHECK_SIZEOF(uint32_t)
AC_CHECK_SIZEOF(uint64_t)
AC_CHECK_SIZEOF(intptr_t)
AC_CHECK_SIZEOF(uintptr_t)
dnl AC_CHECK_TYPES([int8_t, int16_t, int32_t, int64_t, uint8_t, uint16_t, uint32_t, uint64_t, intptr_t, uintptr_t])
AC_CHECK_SIZEOF(char)
AC_CHECK_SIZEOF(short)
AC_CHECK_SIZEOF(int)
AC_CHECK_SIZEOF(long)
AC_CHECK_SIZEOF(long long)
AC_CHECK_SIZEOF(__int64)
AC_CHECK_SIZEOF(void *)
# Now, let's see about alignment requirements. On some platforms, we override
# the default.
case $host in
ia64-*-* | arm-*-* )
tor_cv_unaligned_ok=no
;;
*)
AC_CACHE_CHECK([whether unaligned int access is allowed], tor_cv_unaligned_ok,
[AC_RUN_IFELSE([AC_LANG_SOURCE(
[[int main () { char s[] = "A\x00\x00\x00\x00\x00\x00\x00";
return *(int*)(&s[1]); }]])],
[tor_cv_unaligned_ok=yes],
[tor_cv_unaligned_ok=no],
[tor_cv_unaligned_ok=cross])])
esac
if test $tor_cv_unaligned_ok = yes; then
AC_DEFINE([UNALIGNED_INT_ACCESS_OK], 1,
[Define to 1 iff unaligned int access is allowed])
fi
# $prefix stores the value of the --prefix command line option, or
# NONE if the option wasn't set. In the case that it wasn't set, make
# it be the default, so that we can use it to expand directories now.
if test "x$prefix" = "xNONE"; then
prefix=$ac_default_prefix
fi
# and similarly for $exec_prefix
if test "x$exec_prefix" = "xNONE"; then
exec_prefix=$prefix
fi
CONFDIR=`eval echo $sysconfdir/tor`
AC_SUBST(CONFDIR)
AC_DEFINE_UNQUOTED(CONFDIR,"$CONFDIR")
AC_DEFINE([CONFDIR], [], [tor's configuration directory])
BINDIR=`eval echo $bindir`
AC_SUBST(BINDIR)
LOCALSTATEDIR=`eval echo $localstatedir`
AC_SUBST(LOCALSTATEDIR)
echo "confdir: $CONFDIR"
AC_OUTPUT(Makefile contrib/tor.sh contrib/torify contrib/Makefile src/config/torrc.sample doc/tor.1 src/Makefile doc/Makefile src/config/Makefile src/common/Makefile src/or/Makefile)
+4
View File
@@ -0,0 +1,4 @@
Makefile
Makefile.in
tor.sh
torify
+9
View File
@@ -0,0 +1,9 @@
confdir = $(sysconfdir)/tor
EXTRA_DIST = tor-tsocks.conf torify.1 tor.spec tor-resolve
conf_DATA = tor-tsocks.conf
bin_SCRIPTS = torify tor-resolve
man_MANS = torify.1
+171
View File
@@ -0,0 +1,171 @@
#!/usr/bin/env python2.3
import re, sys
import textwrap
files = sys.argv[1:]
funcDeclaredIn = {}
fileDeclares = {}
functionCalls = {}
funcCalledByFile = {}
funcCalledByFunc = {}
cpp_re = re.compile(r'//.*$')
c_re = re.compile(r'/[*]+(?:[^*]+|[*]+[^/*])*[*]+/', re.M|re.S)
for fname in files:
f = open(fname, 'r')
curFunc = "???"
functionCalls.setdefault(curFunc,{})
lineno = 0
body = f.read()
body = cpp_re.sub(" ",body)
body = c_re.sub(" ",body)
#if fname == 'dns.c': print body
for line in body.split("\n"):
lineno += 1
m = re.match(r'^[^\s/].*\s(\w+)\([^;]*$', line)
if m:
#print line, "->", m.group(1)
curFunc = m.group(1)
if curFunc[0] == '_': curFunc = curFunc[1:]
functionCalls.setdefault(curFunc,{})
funcDeclaredIn[m.group(1)] = fname
fileDeclares.setdefault(fname, {})[m.group(1)] = 1
continue
m = re.match(r'^(\w+)\([^;]', line)
if m:
#print line, "->", m.group(1)
curFunc = m.group(1)
if curFunc[0] == '_': curFunc = curFunc[1:]
functionCalls.setdefault(curFunc,{})
funcDeclaredIn[m.group(1)] = fname
fileDeclares.setdefault(fname, {})[m.group(1)] = 1
continue
while line:
m = re.search(r'(\w+)\(', line)
if not m: break
#print fname, line, curFunc, "->", m.group(1)
fn = m.group(1)
if fn[0] == '_':
fn = fn[1:]
functionCalls[curFunc][m.group(1)] = 1
#if curFunc == "???":
# print ">>!!!!! at %s:%s"%(fname,lineno)
funcCalledByFunc.setdefault(m.group(1), {})[curFunc]=1
funcCalledByFile.setdefault(m.group(1), {})[fname]=1
line = line[m.end():]
f.close()
fileUsers = {}
fileUses = {}
for fname in files:
print "%s:"%fname
users = {}
for func in fileDeclares[fname]:
cb = funcCalledByFile.get(func,{}).keys()
for f in cb: users[f] = 1
#print "users[%s] = %s"%(f,users[f])
users = users.keys()
users.sort()
fileUsers[fname] = users
for user in users:
fileUses.setdefault(user,[]).append(fname)
if user == fname: continue
print " from %s:"%user
for func in fileDeclares[fname]:
if funcCalledByFile.get(func,{}).get(user,0):
print " %s()"%func
def wrap(s, pre):
return textwrap.fill(s,
width=77, initial_indent=pre,
subsequent_indent=" "*len(pre))
for fname in files:
print
print "===== %s"%fname
print wrap(" ".join(fileUses[fname]),
" Calls: ")
print wrap(" ".join(fileUsers[fname]),
" Called by: ")
print "=============================="
funcnames = functionCalls.keys()
funcnames.sort()
if 1:
for func in funcnames:
print "===== %s"%func
callers = [c for c in funcCalledByFunc.get(func,{}).keys()
if c != "???"]
callers.sort()
called = [c for c in functionCalls[func].keys() if c != "???" and
c in funcnames]
called.sort()
print wrap(" ".join(callers),
" Called by:")
print wrap(" ".join(called),
" Calls:")
# simple topological sort.
functionDepth = {}
while 1:
BIG = 1000000
any = 0
for func in funcnames:
if functionDepth.has_key(func):
continue
called = [c for c in functionCalls[func] if c != func and
functionCalls.has_key(c)]
if len(called) == 0:
functionDepth[func] = 0
#print "Depth(%s)=%s"%(func,0)
any = 1
continue
calledDepths = [ functionDepth.get(c,BIG) for c in called ]
if max(calledDepths) < BIG:
d = functionDepth[func] = max(calledDepths)+1
#print "Depth(%s)=%s"%(func,d)
any = 1
continue
if not any:
break
# compute lexical closure.
cycCalls = {}
for func in funcnames:
if not functionDepth.has_key(func):
calls = [ c for c in functionCalls[func] if c != func and
functionCalls.has_key(c) and not functionDepth.has_key(c)]
cycCalls[func] = d = {}
for c in calls:
d[c]=1
cycNames = cycCalls.keys()
while 1:
any = 0
for func in cycNames:
L = len(cycCalls[func])
for called in cycCalls[func].keys():
cycCalls[func].update(cycCalls[called])
if L != len(cycCalls[func]):
any = 1
if not any:
break
depthList = [ (v,k) for k,v in functionDepth.items() ]
depthList.sort()
cycList = [ (len(v),k) for k,v in cycCalls.items() ]
cycList.sort()
for depth,name in depthList:
print "Depth[%s]=%s"%(name,depth)
for bredth,name in cycList:
print "Width[%s]=%s"%(name,bredth)
print "Sorted %s / %s"%(len(functionDepth),len(funcnames))
+126
View File
@@ -0,0 +1,126 @@
#!/usr/bin/python
#$Id$
import socket
import struct
import sys
def socks4AResolveRequest(hostname):
version = 4
command = 0xF0
port = 0
addr = 0x0000001
username = ""
reqheader = struct.pack("!BBHL", version, command, port, addr)
return "%s%s\x00%s\x00"%(reqheader,username,hostname)
def socks4AParseResponse(response):
RESPONSE_LEN = 8
if len(response) < RESPONSE_LEN:
print "return none", len(response)
return None
assert len(response) >= RESPONSE_LEN
version,status,port = struct.unpack("!BBH",response[:4])
assert version == 0
assert port == 0
if status == 90:
return "%d.%d.%d.%d"%tuple(map(ord, response[4:]))
else:
return "ERROR (status %d)"%status
def socks5Hello():
return "\x05\x01\x00"
def socks5ParseHello(response):
if response != "\x05\x00":
raise ValueError("Bizarre socks5 response")
def socks5ResolveRequest(hostname):
version = 5
command = 0xF0
rsv = 0
port = 0
atype = 0x03
reqheader = struct.pack("!BBBB",version, command, rsv, atype)
portstr = struct.pach("!H",port)
return "%s%s\0%s"%(reqheader,hostname,port)
def socks5ParseResponse(r):
if len(r)<8: return None
version, reply, rsv, atype = struct.unpack("!BBBB",r[:4])
assert version==5
assert rsv==0
if reply != 0x00:
return "ERROR"
assert atype in (0x01,0x04)
expected_len = 4 + ({1:4,4:16}[atype]) + 2
if len(r) < expected_len:
return None
elif len(r) > expected_len:
raise ValueError("Overlong socks5 reply!")
addr = r[4:-2]
if atype == 0x01:
return "%d.%d.%d.%d"%tuple(map(ord,addr))
else:
# not really the right way to format IPv6
return "IPv6: %s"%(":".join([hex(ord(c)) for c in addr]))
def parseHostAndPort(h):
host, port = "localhost", 9050
if ":" in h:
i = h.index(":")
host = h[:i]
try:
port = int(h[i+1:])
except ValueError:
print "Bad hostname %r"%h
sys.exit(1)
elif h:
try:
port = int(h)
except ValueError:
host = h
return host, port
def resolve(hostname, sockshost, socksport, socksver=4):
assert socksver in (4,5)
if socksver == 4:
fmt = socks4AResolveRequest
parse = socks4AParseResponse
else:
fmt = socks5ResolveRequest
parse = socks5ParseResponse
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((sockshost,socksport))
if socksver == 5:
s.send(socks5Hello())
socksParseHello(s.recv(2))
s.send(fmt(hostname))
answer = s.recv(8)
result = parse(answer)
while result is None:
more = s.recv(1)
if not more:
print "Connection closed; dying."
return None
answer += more
result = parse(answer)
print "Got answer",result
m = s.recv(1)
if m:
print "Got extra data too! Ick."
return result
if __name__ == '__main__':
if len(sys.argv) not in (2,3,4):
print "Syntax: resolve.py [-4|-5] hostname [sockshost:socksport]"
sys.exit(0)
if sys.argv[1] in ("-4", "-5"):
socksver = int(sys.argv[1][1])
del sys.argv[1]
if len(sys.argv) == 4:
print "Syntax: resolve.py [-4|-5] hostname [sockshost:socksport]"
sys.exit(0)
if len(sys.argv) == 3:
sh,sp = parseHostAndPort(sys.argv[2])
else:
sh,sp = parseHostAndPort("")
resolve(sys.argv[1], sh, sp)
@@ -0,0 +1,7 @@
# This is the configuration for libtsocks (transparent socks) for use
# with tor, which is providing a socks server on port 9050 by default.
#
# See tsocks.conf(5) and torify(1) manpages.
server = 127.0.0.1
server_port = 9050
+112
View File
@@ -0,0 +1,112 @@
#!/bin/sh
#
#tor The Onion Router
#
# chkconfig: 2345 90 10
# description: Onion Router
TORUSER=
TORGROUP=
TORBIN=@BINDIR@/tor
TORPID=@LOCALSTATEDIR@/run/tor/tor.pid
TORLOG=@LOCALSTATEDIR@/log/tor/tor.log
TORCONF=@CONFDIR@/torrc
# Strictly speaking, we don't need to su if we have --user and --group.
# "Belt and suspenders," says jbash.
TORARGS="--pidfile $TORPID --logfile $TORLOG --runasdaemon 1"
if [ "x$TORUSER" != "x" ]; then
TORARGS="$TORARGS --user $TORUSER"
fi
if [ "x$TORGROUP" != "x" ]; then
TORARGS="$TORARGS --group $TORGROUP"
fi
RETVAL=0
case "$1" in
start)
if [ -f $TORPID ]; then
echo "tor appears to be already running (pid file exists)"
echo "Maybe you should run: $0 restart ?"
RETVAL=1
else
echo -n "Starting tor..."
if [ "x$TORUSER" = "x" ]; then
$TORBIN -f $TORCONF $TORARGS
else
/bin/su -c "$TORBIN -f $TORCONF $TORARGS" $TORUSER
fi
RETVAL=$?
if [ $RETVAL -eq 0 ]; then
echo " ok"
else
echo " ERROR!"
fi
fi
;;
stop)
if [ -f $TORPID ]; then
echo -n "Killing tor..."
kill `cat $TORPID`
RETVAL=$?
if [ $RETVAL -eq 0 ]; then
echo " ok"
else
echo " ERROR!"
fi
else
echo "Unable to kill tor: $TORPID does not exist"
RETVAL=1
fi
;;
reload)
if [ -f $TORPID ]; then
echo -n "Sending HUP to tor..."
kill -HUP `cat $TORPID`
RETVAL=$?
if [ $RETVAL -eq 0 ]; then
echo " ok"
else
echo " ERROR!"
fi
else
echo "Unable to kill tor: $TORPID does not exist"
RETVAL=1
fi
;;
restart)
$0 stop
if [ -f $TORPID ]; then
rm -f $TORPID
fi
$0 start
;;
status)
PID=`cat $TORPID 2>/dev/null`
if [ "$PID" != "" ]; then
torstat=`ps -p $PID | grep -c "^$PID"`
if [ $torstat ]; then
echo "tor is running ($PID)"
else
echo "tor is not running (looks like it crashed, look for core? $PID)"
fi
else
echo "tor is not running (exited gracefully)"
fi
;;
log)
cat $TORLOG
;;
*)
echo "Usage: $0 (start|stop|restart|status|log)"
exit 1
esac
exit $RETVAL
+150
View File
@@ -0,0 +1,150 @@
# TODO:
# Add /etc/logrotate.d/tor
#
%define blddate %(date -u +"%Y%m%d%H%M")
%define version 0.0.7
%define version_extra rc2
%define vepoch 0.1
%define tor_version %{version}%{version_extra}
# not quite right XXXXX
%define release 0.std.%{vepoch}.%{version_extra}
Name: tor
Version: %{version}
Release: %{release}
Summary: Anonymizing overlay network for TCP
Vendor: R. Dingledine <arma@seul.org>
Packager: Nick Mathewson <nickm@seul.org>
License: BSD-like
Group: Applications/Internet
URL: http://freehaven.net/tor/
Source0: http://freehaven.net/tor/dist/tor-%{tor_version}.tar.gz
Requires: openssl >= 0.9.6
BuildRequires: openssl-devel >= 0.9.6
Requires(pre): shadow-utils, /usr/bin/id, /bin/date, /bin/sh
Requires(pre): %{_sbindir}/useradd, %{_sbindir}/groupadd
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
%description
Tor is a connection-based low-latency anonymous communication system which
addresses many flaws in the original onion routing design.
In brief, Onion Routing is a connection-oriented anonymizing communication
service. Users choose a source-routed path through a set of nodes, and
negotiate a "virtual circuit" through the network, in which each node
knows its predecessor and successor, but no others. Traffic flowing down
the circuit is unwrapped by a symmetric key at each node, which reveals
the downstream node.
Basically Tor provides a distributed network of servers ("onion
routers"). Users bounce their tcp streams (web traffic, ftp, ssh, etc)
around the routers, and recipients, observers, and even the routers
themselves have difficulty tracking the source of the stream.
Note that Tor does no protocol cleaning. That means there is a danger that
application protocols and associated programs can be induced to reveal
information about the initiator. Tor depends on Privoxy and similar protocol
cleaners to solve this problem.
Client applications can use the Tor network by connecting to the local
onion proxy. If the application itself does not come with socks support
you can use a socks client such as tsocks. Some web browsers like mozilla
and web proxies like privoxy come with socks support, so you don't need an
extra socks client if you want to use Tor with them.
Remember that this is alpha code, and the network is very small -- Tor will
not provide anonymity currently.
This package provides the "tor" program, which serves as both a client
and a relay node. Scripts will automatically create a "tor" user and
group, set tor up to run as a daemon, and automatically start it at
installation time.
%prep
%setup -q -n tor-%{tor_version}
# Patch the startup script to use the right user and group IDs. Force
# the use of /bin/sh as the shell for the "tor" account.
ed -s contrib/tor.sh.in << '/EOF/' > /dev/null
,s/^TORUSER=$/TORUSER=tor/
,s/^TORGROUP=$/TORGROUP=tor/
,s:/bin/su:/bin/su -s /bin/sh:
#
# Save and exit ed
w
q
/EOF/
%build
%configure
%__make
%install
%makeinstall
# Install init script.
%__mkdir_p ${RPM_BUILD_ROOT}%{_initrddir}
%__install -p -m 755 contrib/tor.sh ${RPM_BUILD_ROOT}%{_initrddir}/tor
# Directories that don't have any preinstalled files
%__mkdir_p -m 700 ${RPM_BUILD_ROOT}%{_localstatedir}/lib/tor
%__mkdir_p -m 755 ${RPM_BUILD_ROOT}%{_localstatedir}/run/tor
%__mkdir_p -m 755 ${RPM_BUILD_ROOT}%{_localstatedir}/log/tor
%clean
[ "${RPM_BUILD_ROOT}" != "/" ] && rm -rf ${RPM_BUILD_ROOT}
%pre
[ -f %{_initrddir}/tor ] && /sbin/service tor stop
if [ ! -n "`/usr/bin/id -g tor 2>/dev/null`" ]; then
# One would like to default the GID, but doing that properly would
# require thought.
%{_sbindir}/groupadd tor 2> /dev/null
fi
if [ ! -n "`/usr/bin/id -u tor 2>/dev/null`" ]; then
# One would also like to default the UID, but doing that properly would
# also require thought.
if [ -x /sbin/nologin ]; then
%{_sbindir}/useradd -r -g tor -d / -s /sbin/nologin tor 2> /dev/null
else
%{_sbindir}/useradd -r -g tor -d / -s /bin/false tor 2> /dev/null
fi
fi
%post
/sbin/chkconfig --add tor
/sbin/chkconfig tor && /sbin/service tor start
%preun
/sbin/chkconfig tor && /sbin/service tor stop
/sbin/chkconfig --del tor
%files
%defattr(-,root,root)
%doc AUTHORS INSTALL LICENSE README ChangeLog doc/HACKING doc/TODO doc/FAQ
#%{_mandir}/man1/tor.1.gz
#%{_mandir}/man1/torify.1.gz
%{_mandir}/man*/*
%{_bindir}/tor
%{_bindir}/torify
%config %{_initrddir}/tor
%dir %{_sysconfdir}/tor/
%config(noreplace) %{_sysconfdir}/tor/torrc.sample
%config(noreplace) %{_sysconfdir}/tor/dirservers
%config(noreplace) %{_sysconfdir}/tor/tor-tsocks.conf
%attr(0700,tor,tor) %dir %{_localstatedir}/lib/tor
%attr(0755,tor,tor) %dir %{_localstatedir}/run/tor
%attr(0755,tor,tor) %dir %{_localstatedir}/log/tor
%changelog
* Mon Jun 06 2004 Nick Mathewson <nickm@freehaven.net> 0.0.7-0.std.0.1.rc2
- Make spec file more happy with fc2 packaging
* Sat Jan 17 2004 John Bashinski <jbash@velvet.com>
- Basic spec file; tested with Red Hat 9.
+23
View File
@@ -0,0 +1,23 @@
.TH torify 1 "" Feb-2004 ""
.\" manual page by Peter Palfrader
.SH NAME
.LP
torify \- wrapper for tsocks and tor
.SH SYNOPSIS
\fBtorify\fP\ \fIapplication\fP\ [\fIapplication's\ arguments\fP]
.SH DESCRIPTION
\fBtorify\fR is a simple wrapper that calls tsocks with a tor specific
configuration file.
Tsocks itself is wrapper between the tsocks library and the application what
you would like to run socksified.
Please note that since tsocks uses LD_PRELOAD this cannot be applied to suid
binaries.
.SH SEE ALSO
.BR tor (1),
.BR tsocks (1),
.BR tsocks.conf (5).
+7
View File
@@ -0,0 +1,7 @@
#! /bin/sh
# Wrapper script for use of the tsocks(8) transparent socksification library
# See the tsocks(1) and torify(1) manpages.
TSOCKS_CONF_FILE=@CONFDIR@/tor-tsocks.conf
export TSOCKS_CONF_FILE
exec tsocks "$@"
+18
View File
@@ -0,0 +1,18 @@
Tor only provides TCP layer anonymity. It does not do any protocol
cleaning, so if you are going to browse the web you still give away a
lot of information to servers.
The privoxy package provides a privacy enhancing HTTP proxy, which
is good at filtering headers, cookies, and much more. To view the
description of the Debian privoxy package just run "apt-cache show
privoxy". Please refer to the privoxy documentation for more details.
In order to use privoxy over tor, add the following line to your
privoxy configuration file:
forward-socks4a / localhost:9050 .
(the dot is important)
Then configure your browser to use privoxy as its HTTP proxy.
--
Peter Palfrader <weasel@debian.org>, Tue, 17 Feb 2004 02:15:36 +0100
+9
View File
@@ -0,0 +1,9 @@
Legend:
- Not done
* Top priority
. Partially done
o Done
D Deferred
X Abandoned
- strip debugging symbols when tor is more mature
+196
View File
@@ -0,0 +1,196 @@
tor (0.0.7.2-1) unstable; urgency=medium
* New upstream release.
Fixes another instance of that remote crash bug.
* Mention another reason why stop/reload may fail in the init script.
-- Peter Palfrader <weasel@debian.org> Thu, 8 Jul 2004 03:21:32 +0200
tor (0.0.7.1-1) unstable; urgency=medium
* New upstream release.
Fixes a bug that allows a remote crash on exit nodes.
* Logrotate var/log/tor/*log instead of just var/log/tor/log, in
case the admin wants several logs.
-- Peter Palfrader <weasel@debian.org> Mon, 5 Jul 2004 19:18:12 +0200
tor (0.0.7-1) unstable; urgency=low
* New upstream version
closes: #249893: FTBFS on ia64
-- Peter Palfrader <weasel@debian.org> Mon, 7 Jun 2004 21:46:08 +0200
tor (0.0.6.2-1) unstable; urgency=medium
* New upstream release (breaks backwards compatibility yet again).
* Recommend socat.
* Since tor is in /usr/sbin, the manpage should be in section 8, not
in section 1. Move it there, including updating the section in
the manpage itself and the reference in torify(1).
* Update debian/copyright file.
-- Peter Palfrader <weasel@debian.org> Sun, 16 May 2004 10:47:20 +0200
tor (0.0.6.1-1) unstable; urgency=medium
* New upstream release (breaks backwards compatibility).
-- Peter Palfrader <weasel@debian.org> Fri, 7 May 2004 00:24:49 +0200
tor (0.0.6-1) unstable; urgency=low
* New upstream release (breaks backwards compatibility).
-- Peter Palfrader <weasel@debian.org> Sun, 2 May 2004 23:58:36 +0200
tor (0.0.5+0.0.6rc4-1) unstable; urgency=low
* New upstream release candidate.
-- Peter Palfrader <weasel@debian.org> Sun, 2 May 2004 14:36:59 +0200
tor (0.0.5+0.0.6rc3-1) unstable; urgency=low
* New upstream release candidate.
-- Peter Palfrader <weasel@debian.org> Thu, 29 Apr 2004 11:52:07 +0200
tor (0.0.5+0.0.6rc2-1) unstable; urgency=low
* New upstream release candidate.
* Mention upstream website and mailinglist archives in long
description.
-- Peter Palfrader <weasel@debian.org> Mon, 26 Apr 2004 12:23:20 +0200
tor (0.0.5-1) unstable; urgency=low
* New upstream release.
* Upstream installs a torrc.sample file now, rather than torrc.
Keep using torrc as dpkg handles conffile upgrades.
-- Peter Palfrader <weasel@debian.org> Tue, 30 Mar 2004 20:54:00 +0200
tor (0.0.4-1) unstable; urgency=low
* New upstream release (how the version numbers fly by :).
-- Peter Palfrader <weasel@debian.org> Fri, 26 Mar 2004 23:46:09 +0100
tor (0.0.3-1) unstable; urgency=low
* New upstream release.
* Also mention that tree.h is by Niels Provos in debian/copyright.
-- Peter Palfrader <weasel@debian.org> Fri, 26 Mar 2004 20:36:08 +0100
tor (0.0.2-1) unstable; urgency=low
* New upstream release.
* Uses strlcpy and strlcat by Todd C. Miller, mention him in
debian/copyright.
-- Peter Palfrader <weasel@debian.org> Fri, 19 Mar 2004 12:37:17 +0100
tor (0.0.1+0.0.2pre27-1) unstable; urgency=low
* New upstream release.
-- Peter Palfrader <weasel@debian.org> Mon, 15 Mar 2004 05:19:16 +0100
tor (0.0.1+0.0.2pre26-1) unstable; urgency=low
* New upstream release.
* Mention log and pidfile location in tor.1.
-- Peter Palfrader <weasel@debian.org> Mon, 15 Mar 2004 02:21:29 +0100
tor (0.0.1+0.0.2pre25-1) unstable; urgency=low
* New upstream release.
-- Peter Palfrader <weasel@debian.org> Thu, 4 Mar 2004 23:05:38 +0100
tor (0.0.1+0.0.2pre24-1) unstable; urgency=low
* New upstream release.
* Do not strip binaries for now.
* Add "# ulimit -c unlimited" to tor.default
* Always enable DataDirectory.
* Actually use dpatch now (to modify upstream torrc.in)
* Wait for tor to die in init stop. Let the user know if it doesn't.
-- Peter Palfrader <weasel@debian.org> Wed, 3 Mar 2004 14:10:25 +0100
tor (0.0.1+0.0.2pre23-1) unstable; urgency=low
* New upstream release.
* The one test that always failed has been fixed: removed comment from
rules file.
-- Peter Palfrader <weasel@debian.org> Sun, 29 Feb 2004 12:36:33 +0100
tor (0.0.1+0.0.2pre22-1) unstable; urgency=low
* New upstream release.
* Upstream has moved tor back to usr/bin, but we will keep it in
usr/sbin. That's the right place and it doesn't break my tab
completion there.
-- Peter Palfrader <weasel@debian.org> Fri, 27 Feb 2004 01:59:09 +0100
tor (0.0.1+0.0.2pre21-1) unstable; urgency=low
* New upstream release.
* 0.0.2pre20-2 removed the Recommends: on privoxy rather
than tsocks (which is now required) by mistake. Fix that.
* package description: Mention that the package starts the OP by default and
that OR can be enabled in the config.
* tor moved to sbin, updating init script.
-- Peter Palfrader <weasel@debian.org> Wed, 18 Feb 2004 10:08:12 +0100
tor (0.0.1+0.0.2pre20-2) unstable; urgency=low
* Add torify script, documentation, and config file. Means we also
depend on tsocks now rather than just recommending it. Right now
we install it in debian/rules, but upcoming versions might install
it in upstream's make install target.
* There's an upstream ChangeLog file now. Enjoy!
* Add a README.privoxy file that explains how to setup privoxy to
go over tor.
* As is the case too often, the INSTALL file not only covers
installation, but also basic usage and configuration. Therefore
include it in the docs dir.
* Add a lintian override for the INSTALL file.
-- Peter Palfrader <weasel@debian.org> Tue, 17 Feb 2004 02:32:00 +0100
tor (0.0.1+0.0.2pre20-1) unstable; urgency=low
* New upstream version.
- various design paper updates
- resolve cygwin warnings
- split the token bucket into "rate" and "burst" params
- try to resolve discrepency between bytes transmitted over TLS and actual
bandwidth use
- setuid to user _before_ complaining about running as root
- fix several memleaks and double frees
- minor logging fixes
- add more debugging for logs.
- various documentation fixes and improvements
- for perforcmance testing, paths are always 3 hops, not "3 or more"
(this will go away at a later date again)
* Add dependency on adduser which was previously missing.
* Change short description to a nicer one.
-- Peter Palfrader <weasel@debian.org> Sat, 31 Jan 2004 10:10:45 +0100
tor (0.0.1+0.0.2pre19-1) unstable; urgency=low
* Initial Release (closes: #216611).
-- Peter Palfrader <weasel@debian.org> Sat, 10 Jan 2004 11:20:06 +0100
+1
View File
@@ -0,0 +1 @@
4
+48
View File
@@ -0,0 +1,48 @@
Source: tor
Section: comm
Priority: optional
Maintainer: Peter Palfrader <weasel@debian.org>
Build-Depends: debhelper (>= 4.1.65), libssl-dev, dpatch
Standards-Version: 3.6.1
Package: tor
Architecture: any
Depends: ${shlibs:Depends}, adduser, tsocks
Recommends: privoxy, socat
Suggests: mixmaster, mixminion, anon-proxy
Description: anonymizing overlay network for TCP
Tor is a connection-based low-latency anonymous communication system which
addresses many flaws in the original onion routing design.
.
In brief, Onion Routing is a connection-oriented anonymizing communication
service. Users choose a source-routed path through a set of nodes, and
negotiate a "virtual circuit" through the network, in which each node
knows its predecessor and successor, but no others. Traffic flowing down
the circuit is unwrapped by a symmetric key at each node, which reveals
the downstream node.
.
Basically Tor provides a distributed network of servers ("onion
routers"). Users bounce their tcp streams (web traffic, ftp, ssh, etc)
around the routers, and recipients, observers, and even the routers
themselves have difficulty tracking the source of the stream.
.
Note that Tor does no protocol cleaning. That means there is a danger that
application protocols and associated programs can be induced to reveal
information about the initiator. Tor depends on Privoxy and similar protocol
cleaners to solve this problem.
.
Client applications can use the Tor network by connecting to the local
onion proxy. If the application itself does not come with socks support
you can use a socks client such as tsocks. Some web browsers like mozilla
and web proxies like privoxy come with socks support, so you don't need an
extra socks client if you want to use Tor with them.
.
This package enables only the onion proxy by default, but it can be configured
as a relay (server) node.
.
Remember that this is alpha code, and the network is very small -- Tor will
not provide anonymity currently.
.
The latest information can be found at http://freehaven.net/tor/, or on the
mailing lists, archived at http://archives.seul.org/or/dev/ or
http://archives.seul.org/or/announce/.
+102
View File
@@ -0,0 +1,102 @@
This package was debianized by Peter Palfrader <weasel@debian.org> on
Sat, 10 Jan 2004 11:20:06 +0100.
It was downloaded from http://freehaven.net/tor/
Upstream Authors: Roger Dingledine <arma@freehaven.net>
Nick Mathewson <nickm@freehaven.net>
Matej Pfajfar <badbytes@freehaven.net>
Copyright (c) 2001-2004 Roger Dingledine
Copyright (c) 2002,2003 Nick Mathewson
Copyright (c) 2001-2003 Matej Pfajfar
strlcat, strlcpy: Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
tree.h: Copyright (c) 2002 Niels Provos <provos@citi.umich.edu>
Modifications for Debian: Copyright (c) 2004 Peter Palfrader <weasel@debian.org>
The tor code is under this license:
===============================================================================
Copyright (c) 2001-2004, Roger Dingledine
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.
* Neither the names of the copyright owners nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
===============================================================================
tree.h by Niels Provos is licensed as follows:
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
===============================================================================
strlcat and strlcpy by Todd C. Miller are licensed under the following license:
* Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+3
View File
@@ -0,0 +1,3 @@
01_uncomment_datadirectory.dpatch
02_add_debian_files_in_manpage.dpatch
03_tor_manpage_in_section_8.dpatch
@@ -0,0 +1,37 @@
#! /bin/sh -e
## 01_uncomment_datadirectory.dpatch by <weasel@debian.org>
##
## All lines beginning with `## DP:' are a description of the patch.
## DP: No description.
if [ $# -lt 1 ]; then
echo "`basename $0`: script expects -patch|-unpatch as argument" >&2
exit 1
fi
[ -f debian/patches/00patch-opts ] && . debian/patches/00patch-opts
patch_opts="${patch_opts:--f --no-backup-if-mismatch} ${2:+-d $2}"
case "$1" in
-patch) patch -p1 ${patch_opts} < $0;;
-unpatch) patch -R -p1 ${patch_opts} < $0;;
*)
echo "`basename $0`: script expects -patch|-unpatch as argument" >&2
exit 1;;
esac
exit 0
@DPATCH@
diff -urNad /home/weasel/projects/tor/cvs/src/config/torrc.sample.in cvs/src/config/torrc.sample.in
--- /home/weasel/projects/tor/cvs/src/config/torrc.sample.in 2004-03-01 23:41:26.000000000 +0100
+++ cvs/src/config/torrc.sample.in 2004-03-03 13:47:25.000000000 +0100
@@ -11,7 +11,7 @@
##################### Below is just for servers #####################
## The directory for keeping all the keys/etc for this server
-#DataDirectory @LOCALSTATEDIR@/lib/tor
+DataDirectory @LOCALSTATEDIR@/lib/tor
#Nickname moria # A unique handle for this server
#Address moria.seul.org # The fqdn for this server
@@ -0,0 +1,41 @@
#! /bin/sh -e
## 02_add_debian_files_in_manpage.dpatch by <weasel@debian.org>
##
## All lines beginning with `## DP:' are a description of the patch.
## DP: No description.
if [ $# -lt 1 ]; then
echo "`basename $0`: script expects -patch|-unpatch as argument" >&2
exit 1
fi
[ -f debian/patches/00patch-opts ] && . debian/patches/00patch-opts
patch_opts="${patch_opts:--f --no-backup-if-mismatch} ${2:+-d $2}"
case "$1" in
-patch) patch -p1 ${patch_opts} < $0;;
-unpatch) patch -R -p1 ${patch_opts} < $0;;
*)
echo "`basename $0`: script expects -patch|-unpatch as argument" >&2
exit 1;;
esac
exit 0
@DPATCH@
diff -urNad /home/weasel/projects/tor/cvs/doc/tor.1.in cvs/doc/tor.1.in
--- /home/weasel/projects/tor/cvs/doc/tor.1.in 2004-03-01 23:41:25.000000000 +0100
+++ cvs/doc/tor.1.in 2004-03-10 16:30:49.000000000 +0100
@@ -137,6 +137,12 @@
.TP
.I @LOCALSTATEDIR@/lib/tor/
The tor server stores keys/etc here.
+.TP
+.I /var/log/tor/log
+The tor server logs to this file.
+.TP
+.I /var/run/tor/tor.pid
+The PID of the tor (master) process is stored in this file.
.SH SEE ALSO
.BR privoxy (1),
@@ -0,0 +1,45 @@
#! /bin/sh -e
## 02_tor_manpage_in_section_8.dpatch by <weasel@debian.org>
##
## All lines beginning with `## DP:' are a description of the patch.
## DP: No description.
if [ $# -lt 1 ]; then
echo "`basename $0`: script expects -patch|-unpatch as argument" >&2
exit 1
fi
[ -f debian/patches/00patch-opts ] && . debian/patches/00patch-opts
patch_opts="${patch_opts:--f --no-backup-if-mismatch} ${2:+-d $2}"
case "$1" in
-patch) patch -p1 ${patch_opts} < $0;;
-unpatch) patch -R -p1 ${patch_opts} < $0;;
*)
echo "`basename $0`: script expects -patch|-unpatch as argument" >&2
exit 1;;
esac
exit 0
@DPATCH@
diff -urNad /home/weasel/projects/tor/cvs/contrib/torify.1 cvs/contrib/torify.1
--- /home/weasel/projects/tor/cvs/contrib/torify.1 2004-02-17 01:45:25.000000000 +0100
+++ cvs/contrib/torify.1 2004-05-07 01:12:57.000000000 +0200
@@ -18,6 +18,6 @@
binaries.
.SH SEE ALSO
-.BR tor (1),
+.BR tor (8),
.BR tsocks (1),
.BR tsocks.conf (5).
diff -urNad /home/weasel/projects/tor/cvs/doc/tor.1.in cvs/doc/tor.1.in
--- /home/weasel/projects/tor/cvs/doc/tor.1.in 2004-04-18 20:40:42.000000000 +0200
+++ cvs/doc/tor.1.in 2004-05-07 01:12:12.000000000 +0200
@@ -1,4 +1,4 @@
-.TH TOR 1 "November 2003" "TOR"
+.TH TOR 8 "November 2003" "TOR"
.SH NAME
tor \- The second-generation onion router
.SH SYNOPSIS
+113
View File
@@ -0,0 +1,113 @@
#!/usr/bin/make -f
# -*- makefile -*-
# Sample debian/rules that uses debhelper.
# GNU copyright 1997 to 1999 by Joey Hess.
# Uncomment this to turn on verbose mode.
#export DH_VERBOSE=1
# These are used for cross-compiling and for saving the configure script
# from having to guess our platform (since we know it already)
DEB_HOST_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_HOST_GNU_TYPE)
DEB_BUILD_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_BUILD_GNU_TYPE)
CFLAGS = -Wall -g
export PACKAGE=tor
include /usr/share/dpatch/dpatch.make
ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS)))
CFLAGS += -O0
else
CFLAGS += -O2
endif
#ifeq (,$(findstring nostrip,$(DEB_BUILD_OPTIONS)))
# INSTALL_PROGRAM += -s
#endif
configure: patch-stamp
config.status: configure
dh_testdir
CFLAGS="$(CFLAGS)" ./configure \
--host=$(DEB_HOST_GNU_TYPE) \
--build=$(DEB_BUILD_GNU_TYPE) \
--prefix=/usr \
--mandir=\$${prefix}/share/man \
--infodir=\$${prefix}/share/info \
--localstatedir=/var \
--sysconfdir=/etc
build: build-stamp
build-stamp: config.status
dh_testdir
$(MAKE)
@echo
@echo
src/or/test
@echo
touch build-stamp
clean: unpatch
dh_testdir
dh_testroot
rm -f build-stamp
-$(MAKE) distclean
dh_clean
install: build
dh_testdir
dh_testroot
dh_clean -k
dh_installdirs
$(MAKE) install DESTDIR=$(CURDIR)/debian/tor
# move tor to where it belongs
mv $(CURDIR)/debian/tor/etc/tor/torrc.sample $(CURDIR)/debian/tor/etc/tor/torrc
mv $(CURDIR)/debian/tor/usr/bin/tor $(CURDIR)/debian/tor/usr/sbin/tor
install -d $(CURDIR)/debian/tor/usr/share/man/man8
mv $(CURDIR)/debian/tor/usr/share/man/man1/tor.1 $(CURDIR)/debian/tor/usr/share/man/man8/tor.8
install -m 755 contrib/torify $(CURDIR)/debian/tor/usr/bin
install -m 644 contrib/torify.1 $(CURDIR)/debian/tor/usr/share/man/man1
install -m 644 contrib/tor-tsocks.conf $(CURDIR)/debian/tor/etc/tor
install -m 644 debian/tor.lintian-override $(CURDIR)/debian/tor/usr/share/lintian/overrides/tor
# Build architecture-independent files here.
binary-indep: build install
# We have nothing to do by default.
# Build architecture-dependent files here.
binary-arch: build install
dh_testdir
dh_testroot
dh_installchangelogs ChangeLog
dh_installdocs
dh_installexamples
# dh_install
# dh_installdebconf
dh_installlogrotate
# dh_installemacsen
# dh_installmime
dh_installinit
# dh_installcron
dh_installman
dh_link
#dh_strip
dh_compress
dh_fixperms
dh_installdeb
dh_shlibdeps
dh_gencontrol
dh_md5sums
dh_builddeb
binary: binary-indep binary-arch
.PHONY: build clean binary-indep binary-arch binary install
+13
View File
@@ -0,0 +1,13 @@
# Defaults for tor initscript
# sourced by /etc/init.d/tor
# installed at /etc/default/tor by the maintainer scripts
#
# This is a POSIX shell fragment
#
RUN_DAEMON="yes"
#
# Uncomment this if you want to get coredumps
#
# ulimit -c unlimited
+7
View File
@@ -0,0 +1,7 @@
etc/tor
var/lib/tor
var/log/tor
var/run/tor
usr/share/lintian/overrides
usr/bin
usr/sbin
+3
View File
@@ -0,0 +1,3 @@
README
INSTALL
debian/README.privoxy
+104
View File
@@ -0,0 +1,104 @@
#! /bin/sh
set -e
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
DAEMON=/usr/sbin/tor
NAME=tor
DESC="tor daemon"
TORLOG=/var/log/tor/log
TORPID=/var/run/tor/tor.pid
DEFAULTSFILE=/etc/default/$NAME
WAITFORDAEMON=10
ARGS="--pidfile $TORPID --logfile $TORLOG --runasdaemon 1"
test -x $DAEMON || exit 0
# Include tor defaults if available
if [ -f $DEFAULTSFILE ] ; then
. $DEFAULTSFILE
fi
wait_for_deaddaemon () {
pid=$1
sleep 1
if test -n "$pid"
then
if kill -0 $pid 2>/dev/null
then
echo -n "."
cnt=0
while kill -0 $pid 2>/dev/null
do
cnt=`expr $cnt + 1`
if [ $cnt -gt $WAITFORDAEMON ]
then
echo " FAILED."
return 1
fi
sleep 1
echo -n "."
done
fi
fi
return 0
}
case "$1" in
start)
if [ "$RUN_DAEMON" != "yes" ]; then
echo "Not starting $DESC (Disabled in $DEFAULTSFILE)."
else
echo -n "Starting $DESC: "
start-stop-daemon --start --quiet --oknodo \
--chuid debian-tor:debian-tor \
--pidfile $TORPID \
--exec $DAEMON -- $ARGS
echo "$NAME."
fi
;;
stop)
echo -n "Stopping $DESC: "
pid=`cat $TORPID 2>/dev/null` || true
if test ! -f $TORPID -o -z "$pid"
then
echo "not running (there is no $TORPID)."
elif start-stop-daemon --stop --quiet --pidfile $TORPID --exec $DAEMON
then
wait_for_deaddaemon $pid
echo "$NAME."
elif kill -0 $pid 2>/dev/null
then
echo "FAILED (Is $pid not $NAME? Is $DAEMON a different binary now?)."
else
echo "FAILED ($DAEMON died: process $pid not running; or permission denied)."
fi
;;
reload|force-reload)
echo -n "Reloading $DESC configuration: "
pid=`cat $TORPID 2>/dev/null` || true
if test ! -f $TORPID -o -z "$pid"
then
echo "not running (there is no $TORPID)."
elif start-stop-daemon --stop --signal 1 --quiet --pidfile $TORPID --exec $DAEMON
then
echo "$NAME."
elif kill -0 $pid 2>/dev/null
then
echo "FAILED (Is $pid not $NAME? Is $DAEMON a different binary now?)."
else
echo "FAILED ($DAEMON died: process $pid not running; or permission denied)."
fi
;;
restart)
$0 stop
sleep 1
$0 start
;;
*)
echo "Usage: $0 {start|stop|restart|reload|force-reload}" >&2
exit 1
;;
esac
exit 0
@@ -0,0 +1 @@
tor: package-contains-upstream-install-documentation
+11
View File
@@ -0,0 +1,11 @@
/var/log/tor/*log {
daily
rotate 5
compress
delaycompress
missingok
notifempty
postrotate
/etc/init.d/tor reload > /dev/null
endscript
}
+54
View File
@@ -0,0 +1,54 @@
#!/bin/sh -e
# checking debian-tor account
uid=`getent passwd debian-tor | cut -d ":" -f 3`
home=`getent passwd debian-tor | cut -d ":" -f 6`
# if there is the uid the account is there and we can do
# the sanit(ar)y checks otherwise we can safely create it.
if [ "$uid" ]; then
# guess??? the checks!!!
if [ $uid -ge 100 ] && [ $uid -le 999 ]; then
echo "debian-tor uid check: ok"
else
echo "ERROR: debian-tor account has a non-system uid!"
echo "Please check /usr/share/doc/tor/README.Debian on how to"
echo "correct this problem"
exit 1
fi
if [ "$home" = "/var/lib/tor" ]; then
echo "debian-tor homedir check: ok"
else
echo "ERROR: debian-tor account has an invalid home directory!"
echo "Please check /usr/share/doc/tor/README.Debian on how to"
echo "correct this problem"
exit 1
fi
else
# what this might mean?? oh creating a system l^Huser!
adduser --quiet \
--system \
--disabled-password \
--home /var/lib/tor \
--no-create-home \
--shell /bin/bash \
--group \
debian-tor
fi
# ch{owning,moding} things around
# We will do nothing across upgrades.
if [ "$2" = "" ]; then
for i in lib log run; do
chown -R debian-tor:debian-tor /var/$i/tor
chmod -R 700 /var/$i/tor
find /var/$i/tor -type f -exec chmod 600 '{}' ';'
done
fi
#DEBHELPER#
exit 0
+11
View File
@@ -0,0 +1,11 @@
#!/bin/sh -e
if [ "$1" = "purge" ]; then
# logs have to be removed according to policy.
rm -rf /var/log/tor/
rm -rf /var/lib/tor/
fi
#DEBHELPER#
exit 0
+8
View File
@@ -0,0 +1,8 @@
Makefile
Makefile.in
tor.1
*.aux
*.dvi
*.blg
*.bbl
*.log
+66
View File
@@ -0,0 +1,66 @@
Part one: Overview and explanation
Because tor is an application-level proxy, it needs client-side support
from every client program that wants to use it. (This is different from
systems like Freedom, which used a single client-side program to capture
all packets and redirect them to the Freedom network.) Client applications
need two general classes of modifications to be compatible with tor:
1) Whenever they call connect(), they instead should connect() to the
local onion proxy and tell it "address and port". The onion proxy will
itself make a connection to "address and port", and then the client
application can talk through that socket as if it's directly connected. To
support as many applications as possible, tor uses the common "socks"
protocol which does exactly the above. So applications with socks support
will support tor without needing any modifications.
2) Applications must not call gethostbyname() to resolve an address
they intend to later connect() to via onion routing. gethostbyname()
contacts the dns server of the target machine -- thus giving away the
fact that you intend to make an anonymous connection to it.
To clarify, I need to explain more about the socks protocol. Socks
comes in three flavors: 4, 4a, and 5. The socks4 protocol basically
uses IP and port -- so it is unsuitable because of the gethostbyname()
issue above. Socks4a is a slight modification to the socks4 protocol,
whereby you can specify an IP of 0.0.0.x to signal the socks server
that you will instead be sending a hostname (fqdn). So applications with
socks4a support are all set. Socks5, on the other hand, allows the client
to specify "address type" and then an address -- so some applications
choose to supply an IP and others choose to supply a hostname. If the
application uses socks5 you must investigate further to decide whether
it's leaking anonymity.
Part two: using tsocks to transparently replace library calls
tsocks (available from http://tsocks.sourceforge.net/ or from your
favorite apt-get equivalent) allows you to run a program as normal,
but it replaces the system calls for connect() to connect to the socks
server first and then pass it your destination info. In our case the
socks server is a tor process (running either locally or elsewhere).
In general this works quite well for command-line processes like finger,
ssh, etc. But there are a couple of catches: A) tsocks doesn't intercept
calls to gethostbyname. So unless you specify an IP rather than hostname,
you'll be giving yourself away. B) Programs which are suid don't let you
intercept the system calls -- ssh falls into this category. But you can
make a local copy of ssh and use that. C) Probably tsocks doesn't behave
well for behemoths like Mozilla.
Part three: applications which support tor correctly
[this section is outdated and wrong. we should tie it into the main
tor-doc.html one day.]
http: Mozilla: set your socks4 proxy to be the onion proxy (but see above)
privoxy: set your socks4a proxy to be the onion proxy
wget: run privoxy, and then add the line
"http_proxy=http://localhost:8118" to your ~/.wgetrc.
ssh: tsocks ssh arma@18.244.0.188
ftp: tsocks wget ftp://18.244.0.188/quux.tar --passive
Mozilla: set your socks4 proxy to be the onion proxy
+121
View File
@@ -0,0 +1,121 @@
The Onion Routing (TOR) Frequently Asked Questions
--------------------------------------------------
1. General.
1.1. What is Tor?
Tor is an implementation of version 2 of Onion Routing.
Go read the tor-design.pdf for the details.
In brief, Onion Routing is a connection-oriented anonymizing communication
service. Users choose a source-routed path through a set of nodes, and
negotiate a "virtual circuit" through the network, in which each node
knows its predecessor and successor, but no others. Traffic flowing down
the circuit is unwrapped by a symmetric key at each node, which reveals
the downstream node.
Basically Tor provides a distributed network of servers ("onion
routers"). Users bounce their tcp streams (web traffic, ftp, ssh, etc)
around the routers, and recipients, observers, and even the routers
themselves have difficulty tracking the source of the stream.
1.2. Why's it called Tor?
Because Tor is the onion routing system. I kept telling people I was
working on onion routing, and they said "Neat. Which one?" Even if onion
routing has become a standard household term, this is the actual onion
routing project, started out of the Naval Research Lab.
(Theories about recursive acronyms are ok too. It's also got a fine
translation into German.)
1.3 Is there a backdoor in Tor?
Not right now, but if this answer changes we probably won't be allowed
to tell you. You should always check the source (or at least the diffs
since the last release) for suspicious things; and if we don't give you
source, that's a sure sign something funny could be going on.
2. Compiling and installing.
[Read the README file for now; check back here once we've got packages/etc
for you.]
3. Running Tor.
3.1. What kind of server should I run?
The same executable functions as both client and server, depending on
which ports are specified in the configuration file. You can specify:
* SocksPort: client applications (eg privoxy, Mozilla) can speak socks to
this port.
* ORPort: other onion routers connect to this port
* DirPort: onion proxies and onion routers speak http to this port, to
pull down a directory of which nodes are currently available.
3.2. So I can just run a full onion router and join the network?
No. Users should run just an onion proxy. If you start up a full onion
router, the rest of the routers in the system won't recognize you,
so they will reject your handshake attempts.
3.3. How do I join the network then?
If you just want to use the onion routing network, you can run a proxy
and you're all set. If you want to run a router, you must convince
the directory server operators (currently arma@mit.edu) that you're a
trustworthy and reliable person. From there, the operators add you to
the directory, which propagates out to the rest of the network. All
nodes will know about you within a half hour.
3.4. I want to run a directory server too.
If you run a very reliable node, you plan to be around for a long time,
and you want to spend some time ensuring that router operators are
people we know and like, we may want you to run a directory server
too. We must manually add you to the 'dirservers' file that's part of
the distribution; users will only know about you when they upgrade to
a new version. Of course, you can always just start up your router as a
directory server too --- but users won't know to ask you for directories,
and more importantly, you'll never learn from the real directory servers
about recently joined routers.
4. Development.
4.1. Who's doing this?
4.2. Can I help?
4.3. I've got a bug.
5. Anonymity.
5.1. So I'm totally anonymous if I use Tor?
5.2. Where can I learn more about anonymity?
5.3. What attacks remain against onion routing?
6. Comparison to related projects.
6.1. Onion Routing.
Tor *is* onion routing.
6.2. Freedom.
7. Protocol and application support.
7.1. http? ftp? udp? socks? mozilla?
+580
View File
@@ -0,0 +1,580 @@
Guide to Hacking Tor
(As of 8 October 2003, this was all accurate. If you're reading this in
the distant future, stuff may have changed.)
0. Intro and required reading
Onion Routing is still very much in development stages. This document
aims to get you started in the right direction if you want to understand
the code, add features, fix bugs, etc.
Read the README file first, so you can get familiar with the basics of
installing and running an onion router.
Then, skim some of the introductory materials in tor-design.pdf,
tor-spec.txt, and the Tor FAQ to learn more about how the Tor protocol
is supposed to work. This document will assume you know about Cells,
Circuits, Streams, Connections, Onion Routers, and Onion Proxies.
1. Code organization
1.1. The modules
The code is divided into two directories: ./src/common and ./src/or.
The "common" directory contains general purpose utility functions not
specific to onion routing. The "or" directory implements all
onion-routing and onion-proxy specific functionality.
Files in ./src/common:
aes.[ch] -- Implements the AES cipher (with 128-bit keys and blocks),
and a counter-mode stream cipher on top of AES. This code is
taken from the main Rijndael distribution. (We include this
because many people are running older versions of OpenSSL without
AES support.)
crypto.[ch] -- Wrapper functions to present a consistent interface to
public-key and symmetric cryptography operations from OpenSSL.
fakepoll.[ch] -- Used on systems that don't have a poll() system call;
reimplements() poll using the select() system call.
log.[ch] -- Tor's logging subsystem.
test.h -- Macros used by unit tests.
torint.h -- Provides missing [u]int*_t types for environments that
don't have stdint.h.
tortls.[ch] -- Wrapper functions to present a consistent interface to
TLS, SSL, and X.509 functions from OpenSSL.
util.[ch] -- Miscellaneous portability and convenience functions.
Files in ./src/or:
[General-purpose modules]
or.h -- Common header file: include everything, define everything.
buffers.c -- Implements a generic buffer interface. Buffers are
fairly opaque string holders that can read to or flush from:
memory, file descriptors, or TLS connections.
Also implements parsing functions to read HTTP and SOCKS commands
from buffers.
tree.h -- A splay tree implementation by Niels Provos. Used by
dns.c for dns caching at exits, and by connection_edge.c for dns
caching at clients.
config.c -- Code to parse and validate the configuration file.
[Background processing modules]
cpuworker.c -- Implements a farm of 'CPU worker' processes to perform
CPU-intensive tasks in the background, so as not interrupt the
onion router. (OR only)
dns.c -- Implements a farm of 'DNS worker' processes to perform DNS
lookups for onion routers and cache the results. [This needs to
be done in the background because of the lack of a good,
ubiquitous asynchronous DNS implementation.] (OR only)
[Directory-related functionality.]
directory.c -- Code to send and fetch directories and router
descriptors via HTTP. Directories use dirserv.c to generate the
results; clients use routers.c to parse them.
dirserv.c -- Code to manage directory contents and generate
directories. [Directory server only]
routers.c -- Code to parse directories and router descriptors; and to
generate a router descriptor corresponding to this OR's
capabilities. Also presents some high-level interfaces for
managing an OR or OP's view of the directory.
[Circuit-related modules.]
circuit.c -- Code to create circuits, manage circuits, and route
relay cells along circuits.
onion.c -- Code to generate and respond to "onion skins".
[Core protocol implementation.]
connection.c -- Code used in common by all connection types. See
1.2. below for more general information about connections.
connection_edge.c -- Code used only by edge connections.
command.c -- Code to handle specific cell types.
connection_or.c -- Code to implement cell-speaking connections.
[Toplevel modules.]
main.c -- Toplevel module. Initializes keys, handles signals,
multiplexes between connections, implements main loop, and drives
scheduled events.
tor_main.c -- Stub module containing a main() function. Allows unit
test binary to link against main.c
[Unit tests]
test.c -- Contains unit tests for many pieces of the lower level Tor
modules.
1.2. All about connections
All sockets in Tor are handled as different types of nonblocking
'connections'. (What the Tor spec calls a "Connection", the code refers
to as a "Cell-speaking" or "OR" connection.)
Connections are implemented by the connection_t struct, defined in or.h.
Not every kind of connection uses all the fields in connection_t; see
the comments in or.h and the assertions in assert_connection_ok() for
more information.
Every connection has a type and a state. Connections never change their
type, but can go through many state changes in their lifetime.
The connection types break down as follows:
[Cell-speaking connections]
CONN_TYPE_OR -- A bidirectional TLS connection transmitting a
sequence of cells. May be from an OR to an OR, or from an OP to
an OR.
[Edge connections]
CONN_TYPE_EXIT -- A TCP connection from an onion router to a
Stream's destination. [OR only]
CONN_TYPE_AP -- A SOCKS proxy connection from the end user
application to the onion proxy. [OP only]
[Listeners]
CONN_TYPE_OR_LISTENER [OR only]
CONN_TYPE_AP_LISTENER [OP only]
CONN_TYPE_DIR_LISTENER [Directory server only]
-- Bound network sockets, waiting for incoming connections.
[Internal]
CONN_TYPE_DNSWORKER -- Connection from the main process to a DNS
worker process. [OR only]
CONN_TYPE_CPUWORKER -- Connection from the main process to a CPU
worker process. [OR only]
Connection states are documented in or.h.
Every connection has two associated input and output buffers.
Listeners don't use them. For non-listener connections, incoming
data is appended to conn->inbuf, and outgoing data is taken from the
front of conn->outbuf. Connections differ primarily in the functions
called to fill and drain these buffers.
1.3. All about circuits.
A circuit_t structure fills two roles. First, a circuit_t links two
connections together: either an edge connection and an OR connection,
or two OR connections. (When joined to an OR connection, a circuit_t
affects only cells sent to a particular circID on that connection. When
joined to an edge connection, a circuit_t affects all data.)
Second, a circuit_t holds the cipher keys and state for sending data
along a given circuit. At the OP, it has a sequence of ciphers, each
of which is shared with a single OR along the circuit. Separate
ciphers are used for data going "forward" (away from the OP) and
"backward" (towards the OP). At the OR, a circuit has only two stream
ciphers: one for data going forward, and one for data going backward.
1.4. Asynchronous IO and the main loop.
Tor uses the poll(2) system call (or it wraps select(2) to act like
poll, if poll is not available) to handle nonblocking (asynchronous)
IO. If you're not familiar with nonblocking IO, check out the links
at the end of this document.
All asynchronous logic is handled in main.c. The functions
'connection_add', 'connection_set_poll_socket', and 'connection_remove'
manage an array of connection_t*, and keep in synch with the array of
struct pollfd required by poll(2). (This array of connection_t* is
accessible via get_connection_array, but users should generally call
one of the 'connection_get_by_*' functions in connection.c to look up
individual connections.)
To trap read and write events, connections call the functions
'connection_{is|stop|start}_{reading|writing}'. If you want
to completely reset the events you're watching for, use
'connection_watch_events'.
Every time poll() finishes, main.c calls conn_read and conn_write on
every connection. These functions dispatch events that have something
to read to connection_handle_read, and events that have something to
write to connection_handle_write, respectively.
When connections need to be closed, they can respond in two ways. Most
simply, they can make connection_handle_* return an error (-1),
which will make conn_{read|write} close them. But if it's not
convenient to return -1 (for example, processing one connection causes
you to realize that a second one should close), then you can also
mark a connection to close by setting conn->marked_for_close. Marked
connections will be closed at the end of the current iteration of
the main loop.
The main loop handles several other operations: First, it checks
whether any signals have been received that require a response (HUP,
KILL, USR1, CHLD). Second, it calls prepare_for_poll to handle recurring
tasks and compute the necessary poll timeout. These recurring tasks
include periodically fetching the directory, timing out unused
circuits, incrementing flow control windows and re-enabling connections
that were blocking for more bandwidth, and maintaining statistics.
A word about TLS: Using TLS on OR connections complicates matters in
two ways.
First, a TLS stream has its own read buffer independent of the
connection's read buffer. (TLS needs to read an entire frame from
the network before it can decrypt any data. Thus, trying to read 1
byte from TLS can require that several KB be read from the network
and decrypted. The extra data is stored in TLS's decrypt buffer.)
Because the data hasn't been read by tor (it's still inside the TLS),
this means that sometimes a connection "has stuff to read" even when
poll() didn't return POLLIN. The tor_tls_get_pending_bytes function is
used in main.c to detect TLS objects with non-empty internal buffers.
Second, the TLS stream's events do not correspond directly to network
events: sometimes, before a TLS stream can read, the network must be
ready to write -- or vice versa.
1.5. How data flows (An illustration.)
Suppose an OR receives 256 bytes along an OR connection. These 256
bytes turn out to be a data relay cell, which gets decrypted and
delivered to an edge connection. Here we give a possible call sequence
for the delivery of this data.
(This may be outdated quickly.)
do_main_loop -- Calls poll(2), receives a POLLIN event on a struct
pollfd, then calls:
conn_read -- Looks up the corresponding connection_t, and calls:
connection_handle_read -- Calls:
connection_read_to_buf -- Notices that it has an OR connection so:
read_to_buf_tls -- Pulls data from the TLS stream onto conn->inbuf.
connection_process_inbuf -- Notices that it has an OR connection so:
connection_or_process_inbuf -- Checks whether conn is open, and calls:
connection_process_cell_from_inbuf -- Notices it has enough data for
a cell, then calls:
connection_fetch_from_buf -- Pulls the cell from the buffer.
cell_unpack -- Decodes the raw cell into a cell_t
command_process_cell -- Notices it is a relay cell, so calls:
command_process_relay_cell -- Looks up the circuit for the cell,
makes sure the circuit is live, then passes the cell to:
circuit_deliver_relay_cell -- Passes the cell to each of:
relay_crypt -- Strips a layer of encryption from the cell and
notices that the cell is for local delivery.
connection_edge_process_relay_cell -- extracts the cell's
relay command, and makes sure the edge connection is
open. Since it has a DATA cell and an open connection,
calls:
circuit_consider_sending_sendme -- check if the total number
of cells received by all streams on this circuit is
enough that we should send back an acknowledgement
(requesting that more cells be sent to any stream).
connection_write_to_buf -- To place the data on the outgoing
buffer of the correct edge connection, by calling:
connection_start_writing -- To tell the main poll loop about
the pending data.
write_to_buf -- To actually place the outgoing data on the
edge connection.
connection_consider_sending_sendme -- if the outbuf waiting
to flush to the exit connection is not too full, check
if the total number of cells received on this stream
is enough that we should send back an acknowledgement
(requesting that more cells be sent to this stream).
In a subsequent iteration, main notices that the edge connection is
ready for writing:
do_main_loop -- Calls poll(2), receives a POLLOUT event on a struct
pollfd, then calls:
conn_write -- Looks up the corresponding connection_t, and calls:
connection_handle_write -- This isn't a TLS connection, so calls:
flush_buf -- Delivers data from the edge connection's outbuf to the
network.
connection_wants_to_flush -- Reports that all data has been flushed.
connection_finished_flushing -- Notices the connection is an exit,
and calls:
connection_edge_finished_flushing -- The connection is open, so it
calls:
connection_stop_writing -- Tells the main poll loop that this
connection has no more data to write.
connection_consider_sending_sendme -- now that the outbuf
is empty, check again if the total number of cells
received on this stream is enough that we should send
back an acknowledgement (requesting that more cells be
sent to this stream).
1.6. Routers, descriptors, and directories
All Tor processes need to keep track of a list of onion routers, for
several reasons:
- OPs need to establish connections and circuits to ORs.
- ORs need to establish connections to other ORs.
- OPs and ORs need to fetch directories from a directory server.
- ORs need to upload their descriptors to directory servers.
- Directory servers need to know which ORs are allowed onto the
network, what the descriptors are for those ORs, and which of
those ORs are currently live.
Thus, every Tor process keeps track of a list of all the ORs it knows
in a static variable 'directory' in the routers.c module. This
variable contains a routerinfo_t object for each known OR. On startup,
the directory is initialized to a list of known directory servers (via
router_get_list_from_file()). Later, the directory is updated via
router_get_dir_from_string(). (OPs and ORs retrieve fresh directories
from directory servers; directory servers generate their own.)
Every OR must periodically regenerate a router descriptor for itself.
The descriptor and the corresponding routerinfo_t are stored in the
'desc_routerinfo' and 'descriptor' static variables in routers.c.
Additionally, a directory server keeps track of a list of the
router descriptors it knows in a separate list in dirserv.c. It
uses this list, checking which OR connections are open, to build
directories.
1.7. Data model
[XXX]
1.8. Flow control
[XXX]
2. Coding conventions
2.1. Details
Use tor_malloc, tor_strdup, and tor_gettimeofday instead of their
generic equivalents. (They always succeed or exit.)
Use INLINE instead of 'inline', so that we work properly on windows.
2.2. Calling and naming conventions
Whenever possible, functions should return -1 on error and and 0 on
success.
For multi-word identifiers, use lowercase words combined with
underscores. (e.g., "multi_word_identifier"). Use ALL_CAPS for macros and
constants.
Typenames should end with "_t".
Function names should be prefixed with a module name or object name. (In
general, code to manipulate an object should be a module with the same
name as the object, so it's hard to tell which convention is used.)
Functions that do things should have imperative-verb names
(e.g. buffer_clear, buffer_resize); functions that return booleans should
have predicate names (e.g. buffer_is_empty, buffer_needs_resizing).
2.3. What To Optimize
Don't optimize anything if it's not in the critical path. Right now,
the critical path seems to be AES, logging, and the network itself.
Feel free to do your own profiling to determine otherwise.
2.4. Log conventions
Log convention: use only these four log severities.
ERR is if something fatal just happened.
WARN if something bad happened, but we're still running. The
bad thing is either a bug in the code, an attack or buggy
protocol/implementation of the remote peer, etc. The operator should
examine the bad thing and try to correct it.
NOTICE if it's something the operator will want to know about.
(No error or warning messages should be expected during normal OR or OP
operation. I expect most people to run on -l notice eventually. If a
library function is currently called such that failure always means
ERR, then the library function should log WARN and let the caller
log ERR.)
INFO means something happened (maybe bad, maybe ok), but there's nothing
you need to (or can) do about it.
DEBUG is for everything louder than INFO.
[XXX Proposed convention: every messages of severity INFO or higher should
either (A) be intelligible to end-users who don't know the Tor source; or
(B) somehow inform the end-users that they aren't expected to understand
the message (perhaps with a string like "internal error"). Option (A) is
to be preferred to option (B). -NM]
2.5. Doxygen
We use the 'doxygen' utility to generate documentation from our source code.
Here's how to use it:
1. Begin every file that should be documented with
/**
* \file filename.c
* \brief Short desccription of the file
*/
(Doxygen will recognize any comment beginning with /** as special.)
2. Before any function, structure, #define, or variable you want to
document, add a comment of the form:
/** Describe the function's actions in imperative sentences.
*
* Use blank lines for paragraph breaks
* - and
* - hyphens
* - for
* - lists.
*
* Write <b>argument_names</b> in boldface.
*
* \code
* place_example_code();
* between_code_and_endcode_commands();
* \endcode
*/
3. Make sure to escape the characters "<", ">", "\", "%" and "#" as "\<",
"\>", "\\", "\%", and "\#".
4. To document structure members, you can use two forms:
struct foo {
/** You can put the comment before an element; */
int a;
int b; /**< Or use the less-than symbol to put the comment after the element. */
};
5. See the Doxygen manual for more information; this summary just scratches
the surface.
3. References
About Tor
See http://freehaven.net/tor/
http://freehaven.net/tor/cvs/doc/tor-spec.txt
http://freehaven.net/tor/cvs/doc/tor-design.tex
http://freehaven.net/tor/cvs/doc/FAQ
About anonymity
See http://freehaven.net/anonbib/
About nonblocking IO
[XXX insert references]
# ======================================================================
# Old HACKING document; merge into the above, move into tor-design.tex,
# or delete.
# ======================================================================
The pieces.
Routers. Onion routers, as far as the 'tor' program is concerned,
are a bunch of data items that are loaded into the router_array when
the program starts. Periodically it downloads a new set of routers
from a directory server, and updates the router_array. When a new OR
connection is started (see below), the relevant information is copied
from the router struct to the connection struct.
Connections. A connection is a long-standing tcp socket between
nodes. A connection is named based on what it's connected to -- an "OR
connection" has an onion router on the other end, an "OP connection" has
an onion proxy on the other end, an "exit connection" has a website or
other server on the other end, and an "AP connection" has an application
proxy (and thus a user) on the other end.
Circuits. A circuit is a path over the onion routing
network. Applications can connect to one end of the circuit, and can
create exit connections at the other end of the circuit. AP and exit
connections have only one circuit associated with them (and thus these
connection types are closed when the circuit is closed), whereas OP and
OR connections multiplex many circuits at once, and stay standing even
when there are no circuits running over them.
Streams. Streams are specific conversations between an AP and an exit.
Streams are multiplexed over circuits.
Cells. Some connections, specifically OR and OP connections, speak
"cells". This means that data over that connection is bundled into 256
byte packets (8 bytes of header and 248 bytes of payload). Each cell has
a type, or "command", which indicates what it's for.
Robustness features.
[XXX no longer up to date]
Bandwidth throttling. Each cell-speaking connection has a maximum
bandwidth it can use, as specified in the routers.or file. Bandwidth
throttling can occur on both the sender side and the receiving side. If
the LinkPadding option is on, the sending side sends cells at regularly
spaced intervals (e.g., a connection with a bandwidth of 25600B/s would
queue a cell every 10ms). The receiving side protects against misbehaving
servers that send cells more frequently, by using a simple token bucket:
Each connection has a token bucket with a specified capacity. Tokens are
added to the bucket each second (when the bucket is full, new tokens
are discarded.) Each token represents permission to receive one byte
from the network --- to receive a byte, the connection must remove a
token from the bucket. Thus if the bucket is empty, that connection must
wait until more tokens arrive. The number of tokens we add enforces a
longterm average rate of incoming bytes, yet we still permit short-term
bursts above the allowed bandwidth. Currently bucket sizes are set to
ten seconds worth of traffic.
The bandwidth throttling uses TCP to push back when we stop reading.
We extend it with token buckets to allow more flexibility for traffic
bursts.
Data congestion control. Even with the above bandwidth throttling,
we still need to worry about congestion, either accidental or intentional.
If a lot of people make circuits into same node, and they all come out
through the same connection, then that connection may become saturated
(be unable to send out data cells as quickly as it wants to). An adversary
can make a 'put' request through the onion routing network to a webserver
he owns, and then refuse to read any of the bytes at the webserver end
of the circuit. These bottlenecks can propagate back through the entire
network, mucking up everything.
(See the tor-spec.txt document for details of how congestion control
works.)
In practice, all the nodes in the circuit maintain a receive window
close to maximum except the exit node, which stays around 0, periodically
receiving a sendme and reading more data cells from the webserver.
In this way we can use pretty much all of the available bandwidth for
data, but gracefully back off when faced with multiple circuits (a new
sendme arrives only after some cells have traversed the entire network),
stalled network connections, or attacks.
We don't need to reimplement full tcp windows, with sequence numbers,
the ability to drop cells when we're full etc, because the tcp streams
already guarantee in-order delivery of each cell. Rather than trying
to build some sort of tcp-on-tcp scheme, we implement this minimal data
congestion control; so far it's enough.
Router twins. In many cases when we ask for a router with a given
address and port, we really mean a router who knows a given key. Router
twins are two or more routers that share the same private key. We thus
give routers extra flexibility in choosing the next hop in the circuit: if
some of the twins are down or slow, it can choose the more available ones.
Currently the code tries for the primary router first, and if it's down,
chooses the first available twin.
+4
View File
@@ -0,0 +1,4 @@
EXTRA_DIST = tor-spec.txt CLIENTS FAQ HACKING rend-spec.txt tor-design.tex tor-doc.html tor-doc.css
man_MANS = tor.1
+300
View File
@@ -0,0 +1,300 @@
Legend:
SPEC!! - Not specified
SPEC - Spec not finalized
NICK - nick claims
ARMA - arma claims
- Not done
* Top priority
. Partially done
o Done
D Deferred
X Abandoned
For scalability:
- Slightly smarter bandwidth management: use link capacity
intelligently.
- Handle full buffers without totally borking
For 0.0.8:
milestone 1:
o make all ORs serve the directory too.
o "AuthoritativeDir 1" for dirservers
o non-authorative servers with dirport publish opt dircacheport
o make clients read that and use it.
o make clients able to read a normal dirport from non-trusted OR too
o make ORs parse-and-keep-and-serve the directory they pull down
o authoritativedirservers should pull down directories from
other authdirservers, to merge descriptors.
. allow dirservers to serve running-router list separately.
o "get /running-routers" will fetch just this.
o actually make the clients use this sometimes.
o distinguish directory-is-dirty from runninglist-is-dirty
- ORs keep this too, and serve it
o Design: do we need running and non-running lists?
o tor remembers descriptor-lists across reboots.
. Packages define datadir as /var/lib/tor/. If no datadir is defined,
then choose, make, and secure ~/.tor as datadir.
o Adjust tor
o Change torrc.sample
D Change packages (not till 0.0.8 packages!)
o Look in ~/.torrc if no */etc/torrc is found.
NICK - Possible to get autoconf to easily install things into ~/.tor?
o Contact info, pgp fingerprint, comments in router desc.
o Add a ContactInfo line to torrc, which gets published in
descriptor (as opt)
o write tor version at the top of each log file
milestone 2:
. refer to things by key:
o extend cells need ip:port:identitykeyhash.
o Lookup routers and connections by key digest; accept hex
key digest in place of nicknames.
o Audit all uses of lookup-by-hostname and lookup-by-addr-port
to search by digest when appropriate.
o make sure to use addr/port in cpuworker tasks, because
OPs don't have keys.
o and fix the function comments in rephist
o Rep-hist functions need to store info by keyid
- also use this in intro points and rendezvous points, and
hidserv descs. [XXXX This isn't enough.]
- figure out what to do about ip:port:differentkey
o ORs connect on demand. attach circuits to new connections, keep
create cells around somewhere, send destroy if fail.
o nickname defaults to first piece of hostname
o running-routers list refers to nickname if verified, else
hash-base64'ed.
o Mark routers as verified or unverified based on whether
running-routers list includes nickname or id hash.
o put OR uptime in descriptor
o name the secret-key directory something to discourage people
from mailing their identity key to tor-ops
milestone 3:
- users can set their bandwidth, or we auto-detect it:
- advertised bandwidth defaults to 10KB
o advertised bandwidth is the min of max seen in each direction
in the past N seconds.
o calculate this
o not counting "local" connections
- round detected bandwidth up to nearest 10KB
- client software not upload descriptor until:
- you've been running for an hour
- it's sufficiently satisfied with its bandwidth
- it decides it is reachable
- start counting again if your IP ever changes.
- never regenerate identity keys, for now.
- you can set a bit for not-being-an-OR.
NICK - Reputation info needs to give better weight to recent events than
very old ones.
- Have clients and dirservers preserve reputation info over
reboots.
- clients choose nodes proportional to advertised bandwidth
o authdirserver includes descriptor.
- and lists as running iff:
- he can connect to you
- he has successfully extended to you
- he has sufficient mean-time-between-failures
- Don't accept ORs with nicknames same as verified ORs' nicknames.
- add new "Middleman 1" config variable?
o if torrc not found, exitpolicy reject *:*
o change if(options.ORPort) to what we really mean.
o same with socksport.
o get contrib/tor_resolve into the tarball and installed
- and working
for pre1:
o 0.0.8 ORs should use identity key for 0.0.7 ORs sometimes but
not always?
o we should publish advertised_bandwidth in descriptor
o bug: 0.0.8 OPs can't extend from an 0.0.7 OR to an 0.0.8 OR
post pre1:
- when we sigint tor, the dns/cpuworkers don't intercept sigint?
- "AcceptOnlyVerifiedRouters" config option?
- why does common/util.c build-depend on or/or.h ?
- ORs use uniquer default nicknames
- Tors deal appropriately when a newly-verified router has the
same nickname as another router they know about
X 007 can't extend to unverified 008. they will never be able to.
- if a begin failed due to exit policy, but we believe the IP
should have been allowed, switch that router to exitpolicy
reject *:* until we get our next directory.
- make advertised_server_mode() ORs fetch dirs more often.
- should the running-routers list put unverified routers at the
end?
- tor-resolve needs a man page
- tor-resolve should make use of cached answers?
ongoing:
. rename/rearrange functions for what file they're in
- generalize our transport: add transport.c in preparation for
http, airhook, etc transport.
For September:
NICK . Windows port
o works as client
- deal with pollhup / reached_eof on all platforms
. robust as a client
. works as server
- can be configured
- robust as a server
. Usable as NT service
- docs for building in win
- installer
- Docs
- FAQ
o overview of tor. how does it work, what's it do, pros and
cons of using it, why should I use it, etc.
- a howto tutorial with examples
o tutorial: how to set up your own tor network
- (need to not hardcode dirservers file in config.c)
. correct, update, polish spec
- document the exposed function api?
- document what we mean by socks.
NICK . packages
. rpm
- find a long-term rpm maintainer
- code
- better warn/info messages
o let tor do resolves.
o extend socks4 to do resolves?
o make script to ask tor for resolves
- tsocks
- gather patches, submit to maintainer
- intercept gethostbyname and others, do resolve via tor
- redesign and thorough code revamp, with particular eye toward:
- support half-open tcp connections
- conn key rotation
- other transports -- http, airhook
- modular introduction mechanism
- allow non-clique topology
Other details and small and hard things:
- tor should be able to have a pool of outgoing IP addresses
that it is able to rotate through. (maybe)
- tie into squid
- buffer size pool, to let a few buffers grow huge or many buffers
grow a bit
- hidserv offerers shouldn't need to define a SocksPort
- when the client fails to pick an intro point for a hidserv,
it should refetch the hidserv desc.
. should maybe make clients exit(1) when bad things happen?
e.g. clock skew.
- should retry exitpolicy end streams even if the end cell didn't
resolve the address for you
- Add '[...truncated]' or similar to truncated log entries (like the directory
in connection_dir_process_inbuf()).
. Make logs handle it better when writing to them fails.
o Dirserver shouldn't put you in running-routers list if you haven't
uploaded a descriptor recently
. Refactor: add own routerinfo to routerlist. Right now, only
router_get_by_nickname knows about 'this router', as a hack to
get circuit_launch_new to do the right thing.
. Scrubbing proxies
- Find an smtp proxy?
. Get socks4a support into Mozilla
- Extend by hostname, not by IP.
- Need a relay teardown cell, separate from one-way ends.
- Make it harder to circumvent bandwidth caps: look at number of bytes
sent across sockets, not number sent inside TLS stream.
- fix router_get_by_* functions so they can get ourselves too,
and audit everything to make sure rend and intro points are
just as likely to be us as not.
***************************Future tasks:****************************
Rendezvous and hidden services:
make it fast:
- preemptively build and start rendezvous circs.
- preemptively build n-1 hops of intro circs?
- cannibalize general circs?
make it reliable:
- standby/hotswap/redundant services.
- store stuff to disk? dirservers forget service descriptors when
they restart; nodes offering hidden services forget their chosen
intro points when they restart.
make it robust:
- auth mechanisms to let midpoint and bob selectively choose
connection requests.
make it scalable:
- right now the hidserv store/lookup system is run by the dirservers;
this won't scale.
Tor scalability:
Relax clique assumptions.
Redesign how directories are handled.
- Separate running-routers lookup from descriptor list lookup.
- Resolve directory agreement somehow.
- Cache directory on all servers.
Find and remove bottlenecks
- Address linear searches on e.g. circuit and connection lists.
Reputation/memory system, so dirservers can measure people,
and so other people can verify their measurements.
- Need to measure via relay, so it's not distinguishable.
Bandwidth-aware path selection. So people with T3's are picked
more often than people with DSL.
Reliability-aware node selection. So people who are stable are
preferred for long-term circuits such as intro and rend circs,
and general circs for irc, aim, ssh, etc.
Let dissidents get to Tor servers via Tor users. ("Backbone model")
Anonymity improvements:
Is abandoning the circuit the only option when an extend fails, or
can we do something without impacting anonymity too much?
Is exiting from the middle of the circuit always a bad idea?
Helper nodes. Decide how to use them to improve safety.
DNS resolution: need to make tor support resolve requests. Need to write
a script and an interface (including an extension to the socks
protocol) so we can ask it to do resolve requests. Need to patch
tsocks to intercept gethostbyname, else we'll continue leaking it.
Improve path selection algorithms based on routing-zones paper. Be sure
to start and end circuits in different ASs. Ideally, consider AS of
source and destination -- maybe even enter and exit via nearby AS.
Intermediate model, with some delays and mixing.
Add defensive dropping regime?
Make it more correct:
Handle half-open connections: right now we don't support all TCP
streams, at least according to the protocol. But we handle all that
we've seen in the wild.
Support IPv6.
Efficiency/speed/robustness:
Congestion control. Is our current design sufficient once we have heavy
use? Need to measure and tweak, or maybe overhaul.
Allow small cells and large cells on the same network?
Cell buffering and resending. This will allow us to handle broken
circuits as long as the endpoints don't break, plus will allow
connection (tls session key) rotation.
Implement Morphmix, so we can compare its behavior, complexity, etc.
Use cpuworker for more heavy lifting.
- Signing (and verifying) hidserv descriptors
- Signing (and verifying) intro/rend requests
- Signing (and verifying) router descriptors
- Signing (and verifying) directories
- Doing TLS handshake (this is very hard to separate out, though)
Buffer size pool: allocate a maximum size for all buffers, not
a maximum size for each buffer. So we don't have to give up as
quickly (and kill the thickpipe!) when there's congestion.
Exit node caching: tie into squid or other caching web proxy.
Other transport. HTTP, udp, rdp, airhook, etc. May have to do our own
link crypto, unless we can bully openssl into it.
P2P Tor:
Do all the scalability stuff above, first.
Incentives to relay. Not so hard.
Incentives to allow exit. Possibly quite hard.
Sybil defenses without having a human bottleneck.
How to gather random sample of nodes.
How to handle nodelist recommendations.
Consider incremental switches: a p2p tor with only 50 users has
different anonymity properties than one with 10k users, and should
be treated differently.
+189
View File
@@ -0,0 +1,189 @@
%!PS-Adobe-2.0 EPSF-2.0
%%Title: cell-struct.fig
%%Creator: fig2dev Version 3.2 Patchlevel 4
%%CreationDate: Mon May 17 00:04:58 2004
%%For: root@localhost.localdomain (root)
%%BoundingBox: 0 0 254 73
%%Magnification: 1.0000
%%EndComments
/$F2psDict 200 dict def
$F2psDict begin
$F2psDict /mtrx matrix put
/col-1 {0 setgray} bind def
/col0 {0.000 0.000 0.000 srgb} bind def
/col1 {0.000 0.000 1.000 srgb} bind def
/col2 {0.000 1.000 0.000 srgb} bind def
/col3 {0.000 1.000 1.000 srgb} bind def
/col4 {1.000 0.000 0.000 srgb} bind def
/col5 {1.000 0.000 1.000 srgb} bind def
/col6 {1.000 1.000 0.000 srgb} bind def
/col7 {1.000 1.000 1.000 srgb} bind def
/col8 {0.000 0.000 0.560 srgb} bind def
/col9 {0.000 0.000 0.690 srgb} bind def
/col10 {0.000 0.000 0.820 srgb} bind def
/col11 {0.530 0.810 1.000 srgb} bind def
/col12 {0.000 0.560 0.000 srgb} bind def
/col13 {0.000 0.690 0.000 srgb} bind def
/col14 {0.000 0.820 0.000 srgb} bind def
/col15 {0.000 0.560 0.560 srgb} bind def
/col16 {0.000 0.690 0.690 srgb} bind def
/col17 {0.000 0.820 0.820 srgb} bind def
/col18 {0.560 0.000 0.000 srgb} bind def
/col19 {0.690 0.000 0.000 srgb} bind def
/col20 {0.820 0.000 0.000 srgb} bind def
/col21 {0.560 0.000 0.560 srgb} bind def
/col22 {0.690 0.000 0.690 srgb} bind def
/col23 {0.820 0.000 0.820 srgb} bind def
/col24 {0.500 0.190 0.000 srgb} bind def
/col25 {0.630 0.250 0.000 srgb} bind def
/col26 {0.750 0.380 0.000 srgb} bind def
/col27 {1.000 0.500 0.500 srgb} bind def
/col28 {1.000 0.630 0.630 srgb} bind def
/col29 {1.000 0.750 0.750 srgb} bind def
/col30 {1.000 0.880 0.880 srgb} bind def
/col31 {1.000 0.840 0.000 srgb} bind def
end
save
newpath 0 73 moveto 0 0 lineto 254 0 lineto 254 73 lineto closepath clip newpath
-35.3 77.2 translate
1 -1 scale
/cp {closepath} bind def
/ef {eofill} bind def
/gr {grestore} bind def
/gs {gsave} bind def
/sa {save} bind def
/rs {restore} bind def
/l {lineto} bind def
/m {moveto} bind def
/rm {rmoveto} bind def
/n {newpath} bind def
/s {stroke} bind def
/sh {show} bind def
/slc {setlinecap} bind def
/slj {setlinejoin} bind def
/slw {setlinewidth} bind def
/srgb {setrgbcolor} bind def
/rot {rotate} bind def
/sc {scale} bind def
/sd {setdash} bind def
/ff {findfont} bind def
/sf {setfont} bind def
/scf {scalefont} bind def
/sw {stringwidth} bind def
/tr {translate} bind def
/tnt {dup dup currentrgbcolor
4 -2 roll dup 1 exch sub 3 -1 roll mul add
4 -2 roll dup 1 exch sub 3 -1 roll mul add
4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb}
bind def
/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul
4 -2 roll mul srgb} bind def
/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def
/$F2psEnd {$F2psEnteredState restore end} def
$F2psBegin
10 setmiterlimit
0 slj 0 slc
0.06000 0.06000 sc
%
% Fig objects follow
%
%
% here starts figure with depth 50
% Polyline
7.500 slw
n 1200 975 m
1200 1275 l gs col0 s gr
% Polyline
n 1725 975 m
1725 1275 l gs col0 s gr
% Polyline
n 600 975 m 4800 975 l 4800 1275 l 600 1275 l
cp gs col0 s gr
% Polyline
n 1200 300 m
1200 600 l gs col0 s gr
% Polyline
n 1725 300 m
1725 600 l gs col0 s gr
% Polyline
n 600 300 m 4800 300 l 4800 600 l 600 600 l
cp gs col0 s gr
% Polyline
n 2550 975 m
2550 1275 l gs col0 s gr
% Polyline
n 3150 975 m
3150 1275 l gs col0 s gr
% Polyline
n 3450 975 m
3450 1275 l gs col0 s gr
% Polyline
n 3900 975 m
3900 1275 l gs col0 s gr
/Times-Roman ff 180.00 scf sf
675 1200 m
gs 1 -1 sc (CircID) col0 sh gr
/Times-Roman ff 180.00 scf sf
900 900 m
gs 1 -1 sc (2) col0 sh gr
/Times-Roman ff 180.00 scf sf
1275 1200 m
gs 1 -1 sc (Relay) col0 sh gr
/Times-Roman ff 180.00 scf sf
1800 1200 m
gs 1 -1 sc (StreamID) col0 sh gr
/Times-Roman ff 180.00 scf sf
2625 1200 m
gs 1 -1 sc (Digest) col0 sh gr
/Times-Roman ff 180.00 scf sf
3150 1200 m
gs 1 -1 sc (Len) col0 sh gr
/Times-Roman ff 180.00 scf sf
4200 1200 m
gs 1 -1 sc (DATA) col0 sh gr
/Times-Roman ff 180.00 scf sf
675 525 m
gs 1 -1 sc (CircID) col0 sh gr
/Times-Roman ff 180.00 scf sf
1275 525 m
gs 1 -1 sc (CMD) col0 sh gr
/Times-Roman ff 180.00 scf sf
900 225 m
gs 1 -1 sc (2) col0 sh gr
/Times-Roman ff 180.00 scf sf
1425 225 m
gs 1 -1 sc (1) col0 sh gr
/Times-Roman ff 180.00 scf sf
3225 525 m
gs 1 -1 sc (DATA) col0 sh gr
/Times-Roman ff 180.00 scf sf
3225 900 m
gs 1 -1 sc (2) col0 sh gr
/Times-Roman ff 180.00 scf sf
3450 1200 m
gs 1 -1 sc (CMD) col0 sh gr
/Times-Roman ff 180.00 scf sf
3600 900 m
gs 1 -1 sc (1) col0 sh gr
/Times-Roman ff 180.00 scf sf
3300 225 m
gs 1 -1 sc (509 bytes) col0 sh gr
/Times-Roman ff 180.00 scf sf
1425 900 m
gs 1 -1 sc (1) col0 sh gr
/Times-Roman ff 180.00 scf sf
2100 900 m
gs 1 -1 sc (2) col0 sh gr
/Times-Roman ff 180.00 scf sf
2850 900 m
gs 1 -1 sc (6) col0 sh gr
/Times-Roman ff 180.00 scf sf
4350 900 m
gs 1 -1 sc (498) col0 sh gr
% here ends figure;
$F2psEnd
rs
showpage
+49
View File
@@ -0,0 +1,49 @@
#FIG 3.2
Landscape
Center
Inches
Letter
100.00
Single
-2
1200 2
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
1200 975 1200 1275
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
1725 975 1725 1275
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
600 975 4800 975 4800 1275 600 1275 600 975
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
1200 300 1200 600
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
1725 300 1725 600
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
600 300 4800 300 4800 600 600 600 600 300
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
2550 975 2550 1275
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
3150 975 3150 1275
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
3450 975 3450 1275
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
3900 975 3900 1275
4 0 0 50 -1 0 12 0.0000 4 135 510 675 1200 CircID\001
4 0 0 50 -1 0 12 0.0000 4 135 90 900 900 2\001
4 0 0 50 -1 0 12 0.0000 4 180 435 1275 1200 Relay\001
4 0 0 50 -1 0 12 0.0000 4 135 735 1800 1200 StreamID\001
4 0 0 50 -1 0 12 0.0000 4 180 510 2625 1200 Digest\001
4 0 0 50 -1 0 12 0.0000 4 135 285 3150 1200 Len\001
4 0 0 50 -1 0 12 0.0000 4 135 510 4200 1200 DATA\001
4 0 0 50 -1 0 12 0.0000 4 135 510 675 525 CircID\001
4 0 0 50 -1 0 12 0.0000 4 135 420 1275 525 CMD\001
4 0 0 50 -1 0 12 0.0000 4 135 90 900 225 2\001
4 0 0 50 -1 0 12 0.0000 4 135 90 1425 225 1\001
4 0 0 50 -1 0 12 0.0000 4 135 510 3225 525 DATA\001
4 0 0 50 -1 0 12 0.0000 4 135 90 3225 900 2\001
4 0 0 50 -1 0 12 0.0000 4 135 420 3450 1200 CMD\001
4 0 0 50 -1 0 12 0.0000 4 135 90 3600 900 1\001
4 0 0 50 -1 0 12 0.0000 4 180 735 3300 225 509 bytes\001
4 0 0 50 -1 0 12 0.0000 4 135 90 1425 900 1\001
4 0 0 50 -1 0 12 0.0000 4 135 90 2100 900 2\001
4 0 0 50 -1 0 12 0.0000 4 135 90 2850 900 6\001
4 0 0 50 -1 0 12 0.0000 4 135 270 4350 900 498\001
Binary file not shown.
Binary file not shown.
+357
View File
@@ -0,0 +1,357 @@
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%deffont "standard" xfont "comic sans ms-medium-r"
%%deffont "thick" xfont "arial black-medium-r"
%%deffont "typewriter" xfont "courier new-bold-r"
%%deffont "type2writer" xfont "arial narrow-bold-r"
%%deffont "standard" tfont "standard.ttf", tmfont "kochi-mincho.ttf"
%%deffont "thick" tfont "thick.ttf", tmfont "goth.ttf"
%%deffont "typewriter" tfont "typewriter.ttf", tmfont "goth.ttf"
%deffont "standard" xfont "helvetica-medium-r", tfont "arial.ttf", tmfont "times.ttf"
%deffont "thick" xfont "helvetica-bold-r", tfont "arialbd.ttf", tmfont "hoso6.ttf"
%deffont "italic" xfont "helvetica-italic-r", tfont "ariali.ttf", tmfont "hoso6.ttf"
%deffont "typewriter" xfont "courier-medium-r", tfont "typewriter.ttf", tmfont "hoso6.ttf"
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
%% Default settings per each line numbers.
%%
%default 1 leftfill, size 8, fore "black", back "white", font "thick", hgap 1
%default 2 size 8, vgap 10, prefix " ", ccolor "black"
%default 3 size 6, bar "gray70", vgap 0
%default 4 size 6, fore "black", vgap 0, prefix " ", font "standard"
%%
%%default 1 area 90 90, leftfill, size 9, fore "yellow", back "blue", font "thick"
%%default 2 size 9, vgap 10, prefix " "
%%default 3 size 7, bar "gray70", vgap 10
%%default 4 size 7, vgap 30, prefix " ", font "standard"
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
%% Default settings that are applied to TAB-indented lines.
%%
%tab 1 size 5, vgap 40, prefix " ", icon arc "red" 50
%tab 2 size 4, vgap 35, prefix " ", icon delta3 "blue" 40
%tab 3 size 3, vgap 35, prefix " ", icon dia "DarkViolet" 40
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%page
%nodefault
%center, size 9, font "thick", back "white", fore "black"
Tor:
%size 8
Next-generation Onion Routing
%size 7
Roger Dingledine
Nick Mathewson
Paul Syverson
The Free Haven Project
%font "typewriter", fore "blue"
http://freehaven.net/
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%page
Low-latency anonymity system
%leftfill
Deployed: 20 nodes, hundreds (?) of users
Many improvements on earlier design
Free software -- modified BSD license
Design is not covered by earlier onion routing
patent
Uses SOCKS to interface with client apps
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%page
We have working code
(14 kloc of C)
and a design document,
and a byte-level specification,
and a Debian package (in Unstable)
Works on Linux, BSD, OSX, Cygwin, ...
User-space, doesn't need kernel mods or root
%size 9
http://freehaven.net/tor/
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%page
%%
%%Talk Overview
%%
%%A bit about Onion Routing
%%
%%Improvements we've made
%%
%%Some related work
%%
%%Ask me questions
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%page
Anonymity: Who needs it?
Private citizens
advocacy, counseling, whistleblowing, reporting, ...
%size 6
Higher-level protocols
voting, e-cash, auctions
%size 6
Government applications
research, law enforcement
%size 6
Business applications
%size 5
(hide relationships and volumes of communication)
Who is visiting job sites?
Which groups are talking to patent lawyers?
Who are your suppliers and customers?
Is the CEO talking to a buyout partner?
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%page
Anonymity is a network effect
Systems need traffic (many low-sensitivity users) to attract the high-sensitivity users
Most users do not value anonymity much
Weak security (fast system) can mean more users
which can mean
%cont, font "italic"
stronger
%cont, font "standard"
anonymity
High-sensitivity agents have incentive to run nodes
so they can be certain first node in their path is good
to attract traffic for their messages
There can be an optimal level of free-riding
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%page
Onion Routing is...
An overlay network
Users build virtual circuits through the network
One layer of encryption at each hop
Fixed-size cells
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%page
Tor's goals
Conservative design
minimize new design work needed
%size 6
Support testing of future research
Design for deployment; deploy for use
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%page
Threat model -- what we aim for
Protect against somebody watching Alice
Protect against curious Bob
Protect against `some' curious nodes in the middle
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%page
Differences / limitations
We're TCP-only, not all IP (but we're user-space and very portable)
Not as strong as high-latency systems (Mixmaster, Mixminion)
Not peer-to-peer
No protocol normalization
Not unobservable (no steg, etc)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%page
Perfect forward secrecy
Telescoping circuit
negotiates keys at each hop
no more need for replay detection
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%page
No mixing, padding, traffic shaping (yet)
Please show us they're worth the usability tradeoff
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%page
%%
%%Many TCP streams can share one circuit
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%page
Many TCP streams share a circuit
Previous designs built a new circuit for each stream
lots of public key ops per request
plus anonymity dangers from making so many circuits
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%page
Leaky-pipe circuit topology
Alice can direct cells to any node in her circuit
So we can support long-range padding,
have multiple streams exiting at different places in the circuit
etc
%size 6
Unclear whether this is dangerous or useful
More research needed
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%page
Congestion control
Simple rate limiting
Plus have to keep internal nodes from overflowing
(Can't use global state or inter-node control)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%page
Directory servers
To solve the `introduction' problem
Approve new servers
Tell clients who's up right now
plus their keys, location, etc
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%page
Variable exit policies
Each server allows different outgoing connections
E.g. no servers allow outgoing mail currently
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%page
End-to-end integrity checking
In previous onion routing, an insider could change
the text being transmitted:
"dir" => "rm *"
Even an external adversary could do this!
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%page
Rendezvous points
allow hidden services
don't need (brittle) reply onions
Access-controlled: Bob can control who he talks to
Robust: Bob's service is available even when some Tor nodes go down
Smear-resistant: Evil service can't frame a rendezvous router
Application-transparent: Don't need to modify Bob's apache
%size 6
(Not implemented yet)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%page
How do we compare security?
Assume adversary owns c of n nodes
can choose which
%size 6
What's the chance for a random Alice and Bob that he wins?
Freedom, Tor: (c/n)^2
Peekabooty, six-four, etc: c/n
Jap (if no padding): 1 if c>1
Anonymizer: 1 if c>0
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%page
Future work
Threshold directory agreement
Scalability: Morphmix/p2p extensions?
Restricted-route (non-clique topology)
Non-TCP transport
Implement rendezvous points
Make it work better
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%page
We have working code
Plus a design document,
and a byte-level specification
and a Debian package (in Unstable)
%size 9
http://freehaven.net/tor/
%size 6
Privacy Enhancing Technologies workshop
%size 9
http://petworkshop.org/
+463
View File
@@ -0,0 +1,463 @@
%!PS-Adobe-2.0 EPSF-2.0
%%Title: interaction.fig
%%Creator: fig2dev Version 3.2 Patchlevel 3d
%%CreationDate: Sat Jan 31 05:25:23 2004
%%For: nickm@totoro.wangafu.net ()
%%BoundingBox: 0 0 449 235
%%Magnification: 1.0000
%%EndComments
/$F2psDict 200 dict def
$F2psDict begin
$F2psDict /mtrx matrix put
/col-1 {0 setgray} bind def
/col0 {0.000 0.000 0.000 srgb} bind def
/col1 {0.000 0.000 1.000 srgb} bind def
/col2 {0.000 1.000 0.000 srgb} bind def
/col3 {0.000 1.000 1.000 srgb} bind def
/col4 {1.000 0.000 0.000 srgb} bind def
/col5 {1.000 0.000 1.000 srgb} bind def
/col6 {1.000 1.000 0.000 srgb} bind def
/col7 {1.000 1.000 1.000 srgb} bind def
/col8 {0.000 0.000 0.560 srgb} bind def
/col9 {0.000 0.000 0.690 srgb} bind def
/col10 {0.000 0.000 0.820 srgb} bind def
/col11 {0.530 0.810 1.000 srgb} bind def
/col12 {0.000 0.560 0.000 srgb} bind def
/col13 {0.000 0.690 0.000 srgb} bind def
/col14 {0.000 0.820 0.000 srgb} bind def
/col15 {0.000 0.560 0.560 srgb} bind def
/col16 {0.000 0.690 0.690 srgb} bind def
/col17 {0.000 0.820 0.820 srgb} bind def
/col18 {0.560 0.000 0.000 srgb} bind def
/col19 {0.690 0.000 0.000 srgb} bind def
/col20 {0.820 0.000 0.000 srgb} bind def
/col21 {0.560 0.000 0.560 srgb} bind def
/col22 {0.690 0.000 0.690 srgb} bind def
/col23 {0.820 0.000 0.820 srgb} bind def
/col24 {0.500 0.190 0.000 srgb} bind def
/col25 {0.630 0.250 0.000 srgb} bind def
/col26 {0.750 0.380 0.000 srgb} bind def
/col27 {1.000 0.500 0.500 srgb} bind def
/col28 {1.000 0.630 0.630 srgb} bind def
/col29 {1.000 0.750 0.750 srgb} bind def
/col30 {1.000 0.880 0.880 srgb} bind def
/col31 {1.000 0.840 0.000 srgb} bind def
end
save
newpath 0 235 moveto 0 0 lineto 449 0 lineto 449 235 lineto closepath clip newpath
-62.3 239.8 translate
1 -1 scale
/cp {closepath} bind def
/ef {eofill} bind def
/gr {grestore} bind def
/gs {gsave} bind def
/sa {save} bind def
/rs {restore} bind def
/l {lineto} bind def
/m {moveto} bind def
/rm {rmoveto} bind def
/n {newpath} bind def
/s {stroke} bind def
/sh {show} bind def
/slc {setlinecap} bind def
/slj {setlinejoin} bind def
/slw {setlinewidth} bind def
/srgb {setrgbcolor} bind def
/rot {rotate} bind def
/sc {scale} bind def
/sd {setdash} bind def
/ff {findfont} bind def
/sf {setfont} bind def
/scf {scalefont} bind def
/sw {stringwidth} bind def
/tr {translate} bind def
/tnt {dup dup currentrgbcolor
4 -2 roll dup 1 exch sub 3 -1 roll mul add
4 -2 roll dup 1 exch sub 3 -1 roll mul add
4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb}
bind def
/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul
4 -2 roll mul srgb} bind def
/reencdict 12 dict def /ReEncode { reencdict begin
/newcodesandnames exch def /newfontname exch def /basefontname exch def
/basefontdict basefontname findfont def /newfont basefontdict maxlength dict def
basefontdict { exch dup /FID ne { dup /Encoding eq
{ exch dup length array copy newfont 3 1 roll put }
{ exch newfont 3 1 roll put } ifelse } { pop pop } ifelse } forall
newfont /FontName newfontname put newcodesandnames aload pop
128 1 255 { newfont /Encoding get exch /.notdef put } for
newcodesandnames length 2 idiv { newfont /Encoding get 3 1 roll put } repeat
newfontname newfont definefont pop end } def
/isovec [
8#055 /minus 8#200 /grave 8#201 /acute 8#202 /circumflex 8#203 /tilde
8#204 /macron 8#205 /breve 8#206 /dotaccent 8#207 /dieresis
8#210 /ring 8#211 /cedilla 8#212 /hungarumlaut 8#213 /ogonek 8#214 /caron
8#220 /dotlessi 8#230 /oe 8#231 /OE
8#240 /space 8#241 /exclamdown 8#242 /cent 8#243 /sterling
8#244 /currency 8#245 /yen 8#246 /brokenbar 8#247 /section 8#250 /dieresis
8#251 /copyright 8#252 /ordfeminine 8#253 /guillemotleft 8#254 /logicalnot
8#255 /hyphen 8#256 /registered 8#257 /macron 8#260 /degree 8#261 /plusminus
8#262 /twosuperior 8#263 /threesuperior 8#264 /acute 8#265 /mu 8#266 /paragraph
8#267 /periodcentered 8#270 /cedilla 8#271 /onesuperior 8#272 /ordmasculine
8#273 /guillemotright 8#274 /onequarter 8#275 /onehalf
8#276 /threequarters 8#277 /questiondown 8#300 /Agrave 8#301 /Aacute
8#302 /Acircumflex 8#303 /Atilde 8#304 /Adieresis 8#305 /Aring
8#306 /AE 8#307 /Ccedilla 8#310 /Egrave 8#311 /Eacute
8#312 /Ecircumflex 8#313 /Edieresis 8#314 /Igrave 8#315 /Iacute
8#316 /Icircumflex 8#317 /Idieresis 8#320 /Eth 8#321 /Ntilde 8#322 /Ograve
8#323 /Oacute 8#324 /Ocircumflex 8#325 /Otilde 8#326 /Odieresis 8#327 /multiply
8#330 /Oslash 8#331 /Ugrave 8#332 /Uacute 8#333 /Ucircumflex
8#334 /Udieresis 8#335 /Yacute 8#336 /Thorn 8#337 /germandbls 8#340 /agrave
8#341 /aacute 8#342 /acircumflex 8#343 /atilde 8#344 /adieresis 8#345 /aring
8#346 /ae 8#347 /ccedilla 8#350 /egrave 8#351 /eacute
8#352 /ecircumflex 8#353 /edieresis 8#354 /igrave 8#355 /iacute
8#356 /icircumflex 8#357 /idieresis 8#360 /eth 8#361 /ntilde 8#362 /ograve
8#363 /oacute 8#364 /ocircumflex 8#365 /otilde 8#366 /odieresis 8#367 /divide
8#370 /oslash 8#371 /ugrave 8#372 /uacute 8#373 /ucircumflex
8#374 /udieresis 8#375 /yacute 8#376 /thorn 8#377 /ydieresis] def
/Times-Bold /Times-Bold-iso isovec ReEncode
/Times-Roman /Times-Roman-iso isovec ReEncode
/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def
/$F2psEnd {$F2psEnteredState restore end} def
$F2psBegin
10 setmiterlimit
0.06000 0.06000 sc
%
% Fig objects follow
%
% Polyline
15.000 slw
n 6000 300 m
6000 3975 l gs col0 s gr
% Polyline
7.500 slw
gs clippath
3615 555 m 3615 495 l 3464 495 l 3584 525 l 3464 555 l cp
eoclip
n 1200 525 m
3600 525 l gs col0 s gr gr
% arrowhead
n 3464 555 m 3584 525 l 3464 495 l 3464 555 l cp gs 0.00 setgray ef gr col0 s
% Polyline
gs clippath
1185 795 m 1185 855 l 1336 855 l 1216 825 l 1336 795 l cp
eoclip
n 3600 825 m
1200 825 l gs col0 s gr gr
% arrowhead
n 1336 795 m 1216 825 l 1336 855 l 1336 795 l cp gs 0.00 setgray ef gr col0 s
% Polyline
15.000 slw
n 1200 300 m
1200 3975 l gs col0 s gr
% Polyline
7.500 slw
gs clippath
3615 1155 m 3615 1095 l 3464 1095 l 3584 1125 l 3464 1155 l cp
eoclip
n 1200 1125 m
3600 1125 l gs col0 s gr gr
% arrowhead
n 3464 1155 m 3584 1125 l 3464 1095 l 3464 1155 l cp gs 0.00 setgray ef gr col0 s
% Polyline
15.000 slw
n 3600 300 m
3600 3975 l gs col0 s gr
% Polyline
7.500 slw
gs clippath
6015 1230 m 6015 1170 l 5864 1170 l 5984 1200 l 5864 1230 l cp
eoclip
n 3600 1200 m
6000 1200 l gs col0 s gr gr
% arrowhead
n 5864 1230 m 5984 1200 l 5864 1170 l 5864 1230 l cp gs 0.00 setgray ef gr col0 s
% Polyline
gs clippath
3585 1470 m 3585 1530 l 3736 1530 l 3616 1500 l 3736 1470 l cp
eoclip
n 6000 1500 m
3600 1500 l gs col0 s gr gr
% arrowhead
n 3736 1470 m 3616 1500 l 3736 1530 l 3736 1470 l cp gs 0.00 setgray ef gr col0 s
% Polyline
gs clippath
1185 1545 m 1185 1605 l 1336 1605 l 1216 1575 l 1336 1545 l cp
eoclip
n 3600 1575 m
1200 1575 l gs col0 s gr gr
% arrowhead
n 1336 1545 m 1216 1575 l 1336 1605 l 1336 1545 l cp gs 0.00 setgray ef gr col0 s
% Polyline
[15 45] 45 sd
n 1050 1800 m
8325 1800 l gs col0 s gr [] 0 sd
% Polyline
gs clippath
3615 2130 m 3615 2070 l 3464 2070 l 3584 2100 l 3464 2130 l cp
eoclip
n 1200 2100 m
3600 2100 l gs col0 s gr gr
% arrowhead
n 3464 2130 m 3584 2100 l 3464 2070 l 3464 2130 l cp gs 0.00 setgray ef gr col0 s
% Polyline
gs clippath
6015 2205 m 6015 2145 l 5864 2145 l 5984 2175 l 5864 2205 l cp
eoclip
n 3600 2175 m
6000 2175 l gs col0 s gr gr
% arrowhead
n 5864 2205 m 5984 2175 l 5864 2145 l 5864 2205 l cp gs 0.00 setgray ef gr col0 s
% Polyline
[60] 0 sd
gs clippath
8190 2430 m 8190 2370 l 8039 2370 l 8159 2400 l 8039 2430 l cp
5985 2370 m 5985 2430 l 6136 2430 l 6016 2400 l 6136 2370 l cp
eoclip
n 6000 2400 m
8175 2400 l gs col0 s gr gr
[] 0 sd
% arrowhead
n 6136 2370 m 6016 2400 l 6136 2430 l 6136 2370 l cp gs 0.00 setgray ef gr col0 s
% arrowhead
n 8039 2430 m 8159 2400 l 8039 2370 l 8039 2430 l cp gs 0.00 setgray ef gr col0 s
% Polyline
gs clippath
3585 2520 m 3585 2580 l 3736 2580 l 3616 2550 l 3736 2520 l cp
eoclip
n 6000 2550 m
3600 2550 l gs col0 s gr gr
% arrowhead
n 3736 2520 m 3616 2550 l 3736 2580 l 3736 2520 l cp gs 0.00 setgray ef gr col0 s
% Polyline
gs clippath
1185 2595 m 1185 2655 l 1336 2655 l 1216 2625 l 1336 2595 l cp
eoclip
n 3600 2625 m
1200 2625 l gs col0 s gr gr
% arrowhead
n 1336 2595 m 1216 2625 l 1336 2655 l 1336 2595 l cp gs 0.00 setgray ef gr col0 s
% Polyline
gs clippath
3615 3030 m 3615 2970 l 3464 2970 l 3584 3000 l 3464 3030 l cp
eoclip
n 1200 3000 m
3600 3000 l gs col0 s gr gr
% arrowhead
n 3464 3030 m 3584 3000 l 3464 2970 l 3464 3030 l cp gs 0.00 setgray ef gr col0 s
% Polyline
gs clippath
6015 3105 m 6015 3045 l 5864 3045 l 5984 3075 l 5864 3105 l cp
eoclip
n 3600 3075 m
6000 3075 l gs col0 s gr gr
% arrowhead
n 5864 3105 m 5984 3075 l 5864 3045 l 5864 3105 l cp gs 0.00 setgray ef gr col0 s
% Polyline
gs clippath
8190 3180 m 8190 3120 l 8039 3120 l 8159 3150 l 8039 3180 l cp
eoclip
n 6000 3150 m
8175 3150 l gs col0 s gr gr
% arrowhead
n 8039 3180 m 8159 3150 l 8039 3120 l 8039 3180 l cp gs 0.00 setgray ef gr col0 s
% Polyline
gs clippath
5985 3420 m 5985 3480 l 6136 3480 l 6016 3450 l 6136 3420 l cp
eoclip
n 8175 3450 m
6000 3450 l gs col0 s gr gr
% arrowhead
n 6136 3420 m 6016 3450 l 6136 3480 l 6136 3420 l cp gs 0.00 setgray ef gr col0 s
% Polyline
gs clippath
5985 3495 m 5985 3555 l 6136 3555 l 6016 3525 l 6136 3495 l cp
eoclip
n 8175 3525 m
6000 3525 l gs col0 s gr gr
% arrowhead
n 6136 3495 m 6016 3525 l 6136 3555 l 6136 3495 l cp gs 0.00 setgray ef gr col0 s
% Polyline
gs clippath
5985 3570 m 5985 3630 l 6136 3630 l 6016 3600 l 6136 3570 l cp
eoclip
n 8175 3600 m
6000 3600 l gs col0 s gr gr
% arrowhead
n 6136 3570 m 6016 3600 l 6136 3630 l 6136 3570 l cp gs 0.00 setgray ef gr col0 s
% Polyline
gs clippath
3585 3495 m 3585 3555 l 3736 3555 l 3616 3525 l 3736 3495 l cp
eoclip
n 6000 3525 m
3600 3525 l gs col0 s gr gr
% arrowhead
n 3736 3495 m 3616 3525 l 3736 3555 l 3736 3495 l cp gs 0.00 setgray ef gr col0 s
% Polyline
gs clippath
3585 3645 m 3585 3705 l 3736 3705 l 3616 3675 l 3736 3645 l cp
eoclip
n 6000 3675 m
3600 3675 l gs col0 s gr gr
% arrowhead
n 3736 3645 m 3616 3675 l 3736 3705 l 3736 3645 l cp gs 0.00 setgray ef gr col0 s
% Polyline
gs clippath
3585 3570 m 3585 3630 l 3736 3630 l 3616 3600 l 3736 3570 l cp
eoclip
n 6000 3600 m
3600 3600 l gs col0 s gr gr
% arrowhead
n 3736 3570 m 3616 3600 l 3736 3630 l 3736 3570 l cp gs 0.00 setgray ef gr col0 s
% Polyline
gs clippath
1185 3645 m 1185 3705 l 1336 3705 l 1216 3675 l 1336 3645 l cp
eoclip
n 3600 3675 m
1200 3675 l gs col0 s gr gr
% arrowhead
n 1336 3645 m 1216 3675 l 1336 3705 l 1336 3645 l cp gs 0.00 setgray ef gr col0 s
% Polyline
gs clippath
1185 3720 m 1185 3780 l 1336 3780 l 1216 3750 l 1336 3720 l cp
eoclip
n 3600 3750 m
1200 3750 l gs col0 s gr gr
% arrowhead
n 1336 3720 m 1216 3750 l 1336 3780 l 1336 3720 l cp gs 0.00 setgray ef gr col0 s
% Polyline
gs clippath
1185 3795 m 1185 3855 l 1336 3855 l 1216 3825 l 1336 3795 l cp
eoclip
n 3600 3825 m
1200 3825 l gs col0 s gr gr
% arrowhead
n 1336 3795 m 1216 3825 l 1336 3855 l 1336 3795 l cp gs 0.00 setgray ef gr col0 s
% Polyline
15.000 slw
n 8175 300 m
8175 3975 l gs col0 s gr
% Polyline
7.500 slw
n 6300 825 m 7950 825 l 7950 1725 l 6300 1725 l
cp gs col7 1.00 shd ef gr gs col0 s gr
/Times-Bold-iso ff 180.00 scf sf
3375 225 m
gs 1 -1 sc (OR 1) col0 sh gr
/Times-Bold-iso ff 180.00 scf sf
1050 225 m
gs 1 -1 sc (Alice) col0 sh gr
/Times-Bold-iso ff 180.00 scf sf
5775 225 m
gs 1 -1 sc (OR 2) col0 sh gr
/Times-Roman-iso ff 150.00 scf sf
6075 3075 m
gs 1 -1 sc ("HTTP GET...") col0 sh gr
/Times-Roman-iso ff 150.00 scf sf
4800 3975 m
gs 1 -1 sc (. . .) dup sw pop 2 div neg 0 rm col0 sh gr
/Times-Roman-iso ff 150.00 scf sf
7125 3975 m
gs 1 -1 sc (. . .) dup sw pop 2 div neg 0 rm col0 sh gr
/Times-Roman-iso ff 150.00 scf sf
2400 3975 m
gs 1 -1 sc (. . .) dup sw pop 2 div neg 0 rm col0 sh gr
/Times-Roman-iso ff 150.00 scf sf
7125 2325 m
gs 1 -1 sc (\(TCP handshake\)) dup sw pop 2 div neg 0 rm col0 sh gr
/Times-Bold-iso ff 180.00 scf sf
7875 225 m
gs 1 -1 sc (website) col0 sh gr
/Times-Roman-iso ff 150.00 scf sf
7125 1425 m
gs 1 -1 sc ({X}--AES encryption) dup sw pop 2 div neg 0 rm col0 sh gr
/Times-Roman-iso ff 150.00 scf sf
7125 1200 m
gs 1 -1 sc (E\(x\)--RSA encryption) dup sw pop 2 div neg 0 rm col0 sh gr
/Times-Roman-iso ff 150.00 scf sf
7125 975 m
gs 1 -1 sc (Legend:) dup sw pop 2 div neg 0 rm col0 sh gr
/Times-Roman-iso ff 150.00 scf sf
2400 225 m
gs 1 -1 sc (\(link is TLS-encrypted\)) dup sw pop 2 div neg 0 rm col0 sh gr
/Times-Roman-iso ff 150.00 scf sf
1275 1050 m
gs 1 -1 sc (Relay c1{Extend, OR2, E\(g^x2\)}) col0 sh gr
/Times-Roman-iso ff 150.00 scf sf
1275 2025 m
gs 1 -1 sc (Relay c1{{Begin <website>:80}}) col0 sh gr
/Times-Roman-iso ff 150.00 scf sf
3525 1500 m
gs 1 -1 sc (Relay c1{Extended, g^y2, H\(K2\)}) dup sw pop neg 0 rm col0 sh gr
/Times-Roman-iso ff 150.00 scf sf
3675 2100 m
gs 1 -1 sc (Relay c2{Begin <website>:80}) col0 sh gr
/Times-Roman-iso ff 150.00 scf sf
3525 2550 m
gs 1 -1 sc (Relay c1{{Connected}}) dup sw pop neg 0 rm col0 sh gr
/Times-Roman-iso ff 150.00 scf sf
5925 2475 m
gs 1 -1 sc (Relay c2{Connected}) dup sw pop neg 0 rm col0 sh gr
/Times-Roman-iso ff 150.00 scf sf
1275 2925 m
gs 1 -1 sc (Relay c1{{Data, "HTTP GET..."}}) col0 sh gr
/Times-Roman-iso ff 150.00 scf sf
3675 3000 m
gs 1 -1 sc (Relay c2{Data, "HTTP GET..."}) col0 sh gr
/Times-Roman-iso ff 150.00 scf sf
4800 225 m
gs 1 -1 sc (\(link is TLS-encryped\)) dup sw pop 2 div neg 0 rm col0 sh gr
/Times-Roman-iso ff 150.00 scf sf
7050 225 m
gs 1 -1 sc (\(unencrypted\)) dup sw pop 2 div neg 0 rm col0 sh gr
/Times-Roman-iso ff 150.00 scf sf
7125 1650 m
gs 1 -1 sc (cN--a circID) dup sw pop 2 div neg 0 rm col0 sh gr
/Times-Roman-iso ff 150.00 scf sf
3525 3600 m
gs 1 -1 sc (Relay c1{{Data, \(response\)}}) dup sw pop neg 0 rm col0 sh gr
/Times-Roman-iso ff 150.00 scf sf
8100 3375 m
gs 1 -1 sc (\(response\)) dup sw pop neg 0 rm col0 sh gr
/Times-Roman-iso ff 150.00 scf sf
5925 3450 m
gs 1 -1 sc (Relay c2{Data, \(response\)}) dup sw pop neg 0 rm col0 sh gr
/Times-Roman-iso ff 150.00 scf sf
5925 1425 m
gs 1 -1 sc (Created c2, g^y2, H\(K2\)) dup sw pop neg 0 rm col0 sh gr
/Times-Roman-iso ff 150.00 scf sf
3675 1125 m
gs 1 -1 sc (Create c2, E\(g^x2\)) col0 sh gr
/Times-Roman-iso ff 150.00 scf sf
1275 450 m
gs 1 -1 sc (Create c1, E\(g^x1\)) col0 sh gr
/Times-Roman-iso ff 150.00 scf sf
3525 750 m
gs 1 -1 sc (Created c1, g^y1, H\(K1\)) dup sw pop neg 0 rm col0 sh gr
$F2psEnd
rs
+122
View File
@@ -0,0 +1,122 @@
#FIG 3.2
Landscape
Center
Inches
Letter
100.00
Single
-2
1200 2
2 1 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 2
6000 300 6000 3975
2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2
1 1 1.00 60.00 120.00
1200 525 3600 525
2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2
1 1 1.00 60.00 120.00
3600 825 1200 825
2 1 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 2
1200 300 1200 3975
2 1 0 1 0 7 50 0 -1 3.000 0 0 -1 1 0 2
1 1 1.00 60.00 120.00
1200 1125 3600 1125
2 1 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 2
3600 300 3600 3975
2 1 0 1 0 7 50 0 -1 3.000 0 0 -1 1 0 2
1 1 1.00 60.00 120.00
3600 1200 6000 1200
2 1 0 1 0 7 50 0 -1 3.000 0 0 -1 1 0 2
1 1 1.00 60.00 120.00
6000 1500 3600 1500
2 1 0 1 0 7 50 0 -1 3.000 0 0 -1 1 0 2
1 1 1.00 60.00 120.00
3600 1575 1200 1575
2 1 2 1 0 7 50 0 -1 3.000 0 0 -1 0 0 2
1050 1800 8325 1800
2 1 0 1 0 7 50 0 -1 3.000 0 0 -1 1 0 2
1 1 1.00 60.00 120.00
1200 2100 3600 2100
2 1 0 1 0 7 50 0 -1 3.000 0 0 -1 1 0 2
1 1 1.00 60.00 120.00
3600 2175 6000 2175
2 1 1 1 0 7 50 0 -1 4.000 0 0 -1 1 1 2
1 1 1.00 60.00 120.00
1 1 1.00 60.00 120.00
6000 2400 8175 2400
2 1 0 1 0 7 50 0 -1 3.000 0 0 -1 1 0 2
1 1 1.00 60.00 120.00
6000 2550 3600 2550
2 1 0 1 0 7 50 0 -1 3.000 0 0 -1 1 0 2
1 1 1.00 60.00 120.00
3600 2625 1200 2625
2 1 0 1 0 7 50 0 -1 3.000 0 0 -1 1 0 2
1 1 1.00 60.00 120.00
1200 3000 3600 3000
2 1 0 1 0 7 50 0 -1 3.000 0 0 -1 1 0 2
1 1 1.00 60.00 120.00
3600 3075 6000 3075
2 1 0 1 0 7 50 0 -1 3.000 0 0 -1 1 0 2
1 1 1.00 60.00 120.00
6000 3150 8175 3150
2 1 0 1 0 7 50 0 -1 3.000 0 0 -1 1 0 2
1 1 1.00 60.00 120.00
8175 3450 6000 3450
2 1 0 1 0 7 50 0 -1 3.000 0 0 -1 1 0 2
1 1 1.00 60.00 120.00
8175 3525 6000 3525
2 1 0 1 0 7 50 0 -1 3.000 0 0 -1 1 0 2
1 1 1.00 60.00 120.00
8175 3600 6000 3600
2 1 0 1 0 7 50 0 -1 3.000 0 0 -1 1 0 2
1 1 1.00 60.00 120.00
6000 3525 3600 3525
2 1 0 1 0 7 50 0 -1 3.000 0 0 -1 1 0 2
1 1 1.00 60.00 120.00
6000 3675 3600 3675
2 1 0 1 0 7 50 0 -1 3.000 0 0 -1 1 0 2
1 1 1.00 60.00 120.00
6000 3600 3600 3600
2 1 0 1 0 7 50 0 -1 3.000 0 0 -1 1 0 2
1 1 1.00 60.00 120.00
3600 3675 1200 3675
2 1 0 1 0 7 50 0 -1 3.000 0 0 -1 1 0 2
1 1 1.00 60.00 120.00
3600 3750 1200 3750
2 1 0 1 0 7 50 0 -1 3.000 0 0 -1 1 0 2
1 1 1.00 60.00 120.00
3600 3825 1200 3825
2 1 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 2
8175 300 8175 3975
2 2 0 1 0 7 50 0 20 3.000 0 0 -1 0 0 5
6300 825 7950 825 7950 1725 6300 1725 6300 825
4 0 0 50 0 2 12 0.0000 4 135 450 3375 225 OR 1\001
4 0 0 50 0 2 12 0.0000 4 135 420 1050 225 Alice\001
4 0 0 50 0 2 12 0.0000 4 135 450 5775 225 OR 2\001
4 0 0 50 0 0 10 0.0000 4 105 960 6075 3075 "HTTP GET..."\001
4 1 0 50 0 0 10 0.0000 4 15 135 4800 3975 . . .\001
4 1 0 50 0 0 10 0.0000 4 15 135 7125 3975 . . .\001
4 1 0 50 0 0 10 0.0000 4 15 135 2400 3975 . . .\001
4 1 0 50 0 0 10 0.0000 4 135 1050 7125 2325 (TCP handshake)\001
4 0 0 50 0 2 12 0.0000 4 135 630 7875 225 website\001
4 1 0 50 0 0 10 0.0000 4 135 1335 7125 1425 {X}--AES encryption\001
4 1 0 50 0 0 10 0.0000 4 135 1410 7125 1200 E(x)--RSA encryption\001
4 1 0 50 0 0 10 0.0000 4 135 480 7125 975 Legend:\001
4 1 0 50 0 0 10 0.0000 4 135 1455 2400 225 (link is TLS-encrypted)\001
4 0 0 50 0 0 10 0.0000 4 135 2085 1275 1050 Relay c1{Extend, OR2, E(g^x2)}\001
4 0 0 50 0 0 10 0.0000 4 135 1965 1275 2025 Relay c1{{Begin <website>:80}}\001
4 2 0 50 0 0 10 0.0000 4 135 2190 3525 1500 Relay c1{Extended, g^y2, H(K2)}\001
4 0 0 50 0 0 10 0.0000 4 135 1845 3675 2100 Relay c2{Begin <website>:80}\001
4 2 0 50 0 0 10 0.0000 4 135 1410 3525 2550 Relay c1{{Connected}}\001
4 2 0 50 0 0 10 0.0000 4 135 1290 5925 2475 Relay c2{Connected}\001
4 0 0 50 0 0 10 0.0000 4 135 2085 1275 2925 Relay c1{{Data, "HTTP GET..."}}\001
4 0 0 50 0 0 10 0.0000 4 135 1965 3675 3000 Relay c2{Data, "HTTP GET..."}\001
4 1 0 50 0 0 10 0.0000 4 135 1365 4800 225 (link is TLS-encryped)\001
4 1 0 50 0 0 10 0.0000 4 135 870 7050 225 (unencrypted)\001
4 1 0 50 0 0 10 0.0000 4 105 780 7125 1650 cN--a circID\001
4 2 0 50 0 0 10 0.0000 4 135 1860 3525 3600 Relay c1{{Data, (response)}}\001
4 2 0 50 0 0 10 0.0000 4 135 645 8100 3375 (response)\001
4 2 0 50 0 0 10 0.0000 4 135 1650 5925 3450 Relay c2{Data, (response)}\001
4 2 0 50 0 0 10 0.0000 4 135 1545 5925 1425 Created c2, g^y2, H(K2)\001
4 0 0 50 0 0 10 0.0000 4 135 1170 3675 1125 Create c2, E(g^x2)\001
4 0 0 50 0 0 10 0.0000 4 135 1170 1275 450 Create c1, E(g^x1)\001
4 2 0 50 0 0 10 0.0000 4 135 1545 3525 750 Created c1, g^y1, H(K1)\001
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large Load Diff
+170
View File
@@ -0,0 +1,170 @@
% ---------------------------------------------------------------
%
% $Id$
%
% by Paolo.Ienne@di.epfl.ch
%
% ---------------------------------------------------------------
%
% no guarantee is given that the format corresponds perfectly to
% IEEE 8.5" x 11" Proceedings, but most features should be ok.
%
% ---------------------------------------------------------------
% with LaTeX2e:
% =============
%
% use as
% \documentclass[times,10pt,twocolumn]{article}
% \usepackage{latex8}
% \usepackage{times}
%
% ---------------------------------------------------------------
% with LaTeX 2.09:
% ================
%
% use as
% \documentstyle[times,art10,twocolumn,latex8]{article}
%
% ---------------------------------------------------------------
% with both versions:
% ===================
%
% specify \pagestyle{empty} to omit page numbers in the final
% version
%
% specify references as
% \bibliographystyle{latex8}
% \bibliography{...your files...}
%
% use Section{} and SubSection{} instead of standard section{}
% and subsection{} to obtain headings in the form
% "1.3. My heading"
%
% ---------------------------------------------------------------
\typeout{IEEE 8.5 x 11-Inch Proceedings Style `latex8.sty'.}
% ten point helvetica bold required for captions
% in some sites the name of the helvetica bold font may differ,
% change the name here:
\font\tenhv = phvb at 10pt
%\font\tenhv = phvb7t at 10pt
% eleven point times bold required for second-order headings
% \font\elvbf = cmbx10 scaled 1100
\font\elvbf = ptmb scaled 1100
% set dimensions of columns, gap between columns, and paragraph indent
\setlength{\textheight}{8.875in}
\setlength{\textwidth}{6.875in}
\setlength{\columnsep}{0.3125in}
%\setlength{\columnsep}{0.26in}
\setlength{\topmargin}{0in}
\setlength{\headheight}{0in}
\setlength{\headsep}{.5in}
\setlength{\parindent}{1pc}
\setlength{\oddsidemargin}{-.304in}
\setlength{\evensidemargin}{-.304in}
% memento from size10.clo
% \normalsize{\@setfontsize\normalsize\@xpt\@xiipt}
% \small{\@setfontsize\small\@ixpt{11}}
% \footnotesize{\@setfontsize\footnotesize\@viiipt{9.5}}
% \scriptsize{\@setfontsize\scriptsize\@viipt\@viiipt}
% \tiny{\@setfontsize\tiny\@vpt\@vipt}
% \large{\@setfontsize\large\@xiipt{14}}
% \Large{\@setfontsize\Large\@xivpt{18}}
% \LARGE{\@setfontsize\LARGE\@xviipt{22}}
% \huge{\@setfontsize\huge\@xxpt{25}}
% \Huge{\@setfontsize\Huge\@xxvpt{30}}
\def\@maketitle
{
\newpage
\null
\vskip .375in
\begin{center}
{\Large \bf \@title \par}
% additional two empty lines at the end of the title
\vspace*{24pt}
{
\large
\lineskip .5em
\begin{tabular}[t]{c}
\@author
\end{tabular}
\par
}
% additional small space at the end of the author name
\vskip .5em
{
\large
\begin{tabular}[t]{c}
\@affiliation
\end{tabular}
\par
\ifx \@empty \@email
\else
\begin{tabular}{r@{~}l}
E-mail: & {\tt \@email}
\end{tabular}
\par
\fi
}
% additional empty line at the end of the title block
\vspace*{12pt}
\end{center}
}
\def\abstract
{%
\centerline{\large\bf Abstract}%
\vspace*{12pt}%
\it%
}
\def\endabstract
{
% additional empty line at the end of the abstract
\vspace*{12pt}
}
\def\affiliation#1{\gdef\@affiliation{#1}} \gdef\@affiliation{}
\def\email#1{\gdef\@email{#1}}
\gdef\@email{}
\newlength{\@ctmp}
\newlength{\@figindent}
\setlength{\@figindent}{1pc}
\long\def\@makecaption#1#2{
\vskip 10pt
\setbox\@tempboxa\hbox{\tenhv\noindent #1.~#2}
\setlength{\@ctmp}{\hsize}
\addtolength{\@ctmp}{-\@figindent}\addtolength{\@ctmp}{-\@figindent}
% IF longer than one indented paragraph line
\ifdim \wd\@tempboxa >\@ctmp
% THEN set as an indented paragraph
\begin{list}{}{\leftmargin\@figindent \rightmargin\leftmargin}
\item[]\tenhv #1.~#2\par
\end{list}
\else
% ELSE center
\hbox to\hsize{\hfil\box\@tempboxa\hfil}
\fi}
% correct heading spacing and type
\def\section{\@startsection {section}{1}{\z@}
{14pt plus 2pt minus 2pt}{14pt plus 2pt minus 2pt} {\large\bf}}
\def\subsection{\@startsection {subsection}{2}{\z@}
{13pt plus 2pt minus 2pt}{13pt plus 2pt minus 2pt} {\elvbf}}
% add the period after section numbers
\newcommand{\Section}[1]{\section{\hskip -1em.~#1}}
\newcommand{\SubSection}[1]{\subsection{\hskip -1em.~#1}}
% end of file latex8.sty
% ---------------------------------------------------------------
+333
View File
@@ -0,0 +1,333 @@
$Id$
[XXX We need to make nicknames in intro* cells padded to 20
bytes, and maybe have a fixed length for nicknames in the
descriptor too -RD]
Tor Rendezvous Spec
0. Overview and preliminaries
Rendezvous points provide location-hidden services (server
anonymity) for the onion routing network. With rendezvous points,
Bob can offer a TCP service (say, a webserver) via the onion
routing network, without revealing the IP of that service.
Bob does this by anonymously advertising a public key for his
service, along with a list of onion routers to act as "Introduction
Points" for his service. He creates forward OR circuits to those
introduction points, and tells them about his public key. To
connect to Bob, Alice first builds an OR circuit to an OR to act as
her "Rendezvous Point", then connects to one of Bob's chosen
introduction points, and asks it to tell him about her Rendezvous
Point (RP). If Bob chooses to answer, he builds an OR circuit to her
RP, and tells it to connect him to Alice. The RP joints their
circuits together, and begins relaying cells. Alice's 'BEGIN'
cells are received directly by Bob's OP, which responds by
communication with the local server implementing Bob's service.
Below, we describe a network-level specification of this service,
along with interfaces to make this process transparent to Alice
(so long as she is using an OP).
0.1. Notation, conventions and prerequisites
In the specifications below, we use the same notation as in
"tor-spec.txt". The service specified here also requires the existence of
an onion routing network as specified in "tor-spec.txt".
H(x) is a SHA1 digest of x.
PKSign(SK,x) is a PKCS.1-padded RSA signature of x with SK.
PKEncrypt(SK,x) is a PKCS.1-padded RSA encryption of x with SK.
Public keys are all RSA, and encoded in ASN.1.
All integers are stored in network (big-endian) order.
All symmetric encryption uses AES in counter mode, except where
otherwise noted.
In all discussions, "Alice" will refer to a user connecting to a
location-hidden service, and "Bob" will refer to a user running a
location-hidden service.
0.2. Protocol outline
1. Bob->Bob's OP: "Offer IP:Port as public-key-name:Port". [configuration]
(We do not specify this step; it is left to the implementor of
Bob's OP.)
2. Bob's OP generates keypair and rendezvous service descriptor:
"Meet public-key X at introduction point A, B, or C." (signed)
3. Bob's OP->Introduction point via Tor: [introduction setup]
"This pk is me."
4. Bob's OP->directory service via Tor: publishes Bob's service descriptor
[advertisement]
5. Out of band, Alice receives a y.onion:port address. She opens a
SOCKS connection to her OP, and requests y.onion:port.
6. Alice's OP retrieves Bob's descriptor via Tor: [descriptor lookup.]
7. Alice's OP chooses a rendezvous point, opens a circuit to that
rendezvous point, and establishes a rendezvous circuit. [rendezvous
setup.]
8. Alice connects to the Introduction point via Tor, and tells it about
her rendezvous point. (Encrypted to Bob.) [Introduction 1]
9. The Introduction point passes this on to Bob's OP via Tor, along the
introduction circuit. [Introduction 2]
10. Bob's OP decides whether to connect to Alice, and if so, creates a
circuit to Alice's RP via Tor. Establishes a shared circuit.
[Rendezvous.]
11. Alice's OP sends begin cells to Bob's OP. [Connection]
0.3. Constants and new cell types
Relay cell types
32 -- RELAY_ESTABLISH_INTRO
33 -- RELAY_ESTABLISH_RENDEZVOUS
34 -- RELAY_INTRODUCE1
35 -- RELAY_INTRODUCE2
36 -- RELAY_RENDEZVOUS1
37 -- RELAY_RENDEZVOUS2
38 -- RELAY_INTRO_ESTABLISHED
39 -- RELAY_RENDEZVOUS_ESTABLISHED
40 -- RELAY_COMMAND_INTRODUCE_ACK
1. The Protocol
1.1. Bob configures his local OP.
We do not specify a format for the OP configuration file. However,
OPs SHOULD allow Bob to provide more than one advertised service
per OP, and MUST allow Bob to specify one or more virtual ports per
service. Bob provides a mapping from each of these virtual ports
to a local IP:Port pair.
1.2. Bob's OP generates service descriptors.
The first time the OP provides an advertised service, it generates
a public/private keypair (stored locally). Periodically, the OP
generates service descriptor, containing:
KL Key length [2 octets]
PK Bob's public key [KL octets]
TS A timestamp [4 octets]
NI Number of introduction points [2 octets]
Ipt A list of NUL-terminated OR nicknames [variable]
SIG Signature of above fields [variable]
KL is the length of PK, in octets. (Currently, KL must be 128.)
TS is the number of seconds elapsed since Jan 1, 1970.
[It's ok for Bob to advertise 0 introduction points. He might want
to do that if he previously advertised some introduction points,
and now he doesn't have any. -RD]
[Shouldn't the nicknames be hostname:port's instead? That way, Alice's
directory servers don't need to know Bob's chosen introduction points.
Not important now, but essential if we ever have a non-total-knowledge
design. -NM]
1.3. Bob's OP establishes his introduction points.
The OP establishes a new introduction circuit to each introduction
point. These circuits MUST NOT be used for anything but rendezvous
introduction. To establish the introduction, Bob sends a
RELAY_ESTABLISH_INTRO cell, containing:
KL Key length [2 octets]
PK Bob's public key [KL octets]
HS Hash of session info [20 octets]
SIG Signature of above information [variable]
To prevent replay attacks, the HS field contains a SHA-1 hash based on the
shared secret KH between Bob's OP and the introduction point, as
follows:
HS = H(KH | "INTRODUCE")
That is:
HS = H(KH | [49 4E 54 52 4F 44 55 43 45])
(KH, as specified in tor-spec.txt, is H(g^xy | [00]) .)
Upon receiving such a cell, the OR first checks that the signature is
correct with the included public key. If so, it checks whether HS is
correct given the shared state between Bob's OP and the OR. If either
check fails, the OP discards the cell; otherwise, it associates the
circuit with Bob's public key, and dissociates any other circuits
currently associated with PK. On success, the OR sends Bob a
RELAY_INTRO_ESTABLISHED cell with an empty payload.
1.4. Bob's OP advertises his server descriptor
Bob's OP opens a stream to each directory server's directory port via Tor.
(He may re-use old circuits for this.)
Over this stream, Bob's OP makes an HTTP 'POST' request, to the URL
'/rendezvous/publish' (relative to the directory server's root),
containing as its body Bob's service descriptor. Upon receiving a
descriptor, the directory server checks the signature, and discards the
descriptor if the signature does not match the enclosed public key. Next,
the directory server checks the timestamp. If the timestamp is more than
24 hours in the past or more than 1 hour in the future, or the directory
server already has a newer descriptor with the same public key, the server
discards the descriptor. Otherwise, the server discards any older
descriptors with the same public key, and associates the new descriptor
with the public key. The directory server remembers this descriptor for
at least 24 hours after its timestamp. At least every 24 hours, Bob's OP
uploads a fresh descriptor.
1.5. Alice receives a y.onion address
When Alice receives a pointer to a location-hidden service, it is as a
hostname of the form "y.onion", where y is a base-32 encoding of a
10-octet hash of Bob's service's public key, computed as follows:
1. Let H = H(PK).
2. Let H' = the first 80 bits of H, considering each octet from
most significant bit to least significant bit.
2. Generate a 16-character encoding of H', using base32 as defined
in RFC 3548.
(We only use 80 bits instead of the 160 bits from SHA1 because we don't
need to worry about man-in-the-middle attacks, and because it will make
handling the url's more convenient.)
[Yes, numbers are allowed at the beginning. See RFC1123. -NM]
1.6. Alice's OP retrieves a service descriptor
Alice opens a stream to a directory server via Tor, and makes an HTTP GET
request for the document '/rendezvous/<y>', where '<y> is replaced with the
encoding of Bob's public key as described above. (She may re-use old
circuits for this.) The directory replies with a 404 HTTP response if
it does not recognize <y>, and otherwise returns Bob's most recently
uploaded service descriptor.
If Alice's OP receives a 404 response, it tries the other directory
servers, and only fails the lookup if none recognizes the public key hash.
Upon receiving a service descriptor, Alice verifies with the same process
as the directory server uses, described above in section 1.4.
The directory server gives a 400 response if it cannot understand Alice's
request.
Alice should cache the descriptor locally, but should not use
descriptors that are more than 24 hours older than their timestamp.
[Caching may make her partitionable, but she fetched it anonymously,
and we can't very well *not* cache it. -RD]
1.7. Alice's OP establishes a rendezvous point.
When Alice requests a connection to a given location-hidden service,
and Alice's OP does not have an established circuit to that service,
the OP builds a rendezvous circuit. It does this by establishing
a circuit to a randomly chosen OR, and sending a
RELAY_ESTABLISH_RENDEZVOUS cell to that OR. The body of that cell
contains:
RC Rendezvous cookie [20 octets]
The rendezvous cookie is an arbitrary 20-byte value, chosen randomly by
Alice's OP.
Upon receiving a RELAY_ESTABLISH_RENDEZVOUS cell, the OR associates the
RC with the circuit that sent it. It replies to Alice with an empty
RELAY_RENDEZVOUS_ESTABLISHED cell to indicate success.
Alice's OP MUST NOT use the circuit which sent the cell for any purpose
other than rendezvous with the given location-hidden service.
1.8. Introduction: from Alice's OP to Introduction Point
Alice builds a separate circuit to one of Bob's chosen introduction
points, and sends it a RELAY_INTRODUCE1 cell containing:
Cleartext
PK_ID Identifier for Bob's PK [20 octets]
Encrypted to Bob's PK:
RP Rendezvous point's nickname [20 octets]
RC Rendezvous cookie [20 octets]
g^x Diffie-Hellman data, part 1 [128 octetes]
PK_ID is the hash of Bob's public key. RP is NUL-padded.
The hybrid encryption to Bob's PK works just like the hybrid
encryption in CREATE cells (see main spec). Thus the payload of the
RELAY_INTRODUCE1 cell on the wire will contain 20+42+16+20+20+128=246
bytes.
1.9. Introduction: From the Introduction Point to Bob's OP
If the Introduction Point recognizes PK_ID as a public key which has
established a circuit for introductions as in 1.3 above, it sends the body
of the cell in a new RELAY_INTRODUCE2 cell down the corresponding circuit.
(If the PK_ID is unrecognized, the RELAY_INTRODUCE1 cell is discarded.)
After sending the RELAY_INTRODUCE2 cell, the OR replies to Alice with an
empty RELAY_COMMAND_INTRODUCE_ACK cell. If no RELAY_INTRODUCE2 cell can
be sent, the OR replies to Alice with a non-empty cell to indicate an
error. (The semantics of the cell body may be determined later; the
current implementation sends a single '1' byte on failure.)
When Bob's OP receives the RELAY_INTRODUCE2 cell, it decrypts it with
the private key for the corresponding hidden service, and extracts the
rendezvous point's nickname, the rendezvous cookie, and the value of g^x
chosen by Alice.
1.10. Rendezvous
Bob's OP build a new Tor circuit ending at Alice's chosen rendezvous
point, and sends a RELAY_RENDEZVOUS1 cell along this circuit, containing:
RC Rendezvous cookie [20 octets]
g^y Diffie-Hellman [128 octets]
KH Handshake digest [20 octets]
(Bob's OP MUST NOT use this circuit for any other purpose.)
If the RP recognizes RC, it relays the rest of the cell down the
corresponding circuit in a RELAY_RENDEZVOUS2 cell, containing:
g^y Diffie-Hellman [128 octets]
KH Handshake digest [20 octets]
(If the RP does not recognize the RC, it discards the cell and
tears down the circuit.)
When Alice's OP receives a RELAY_RENDEZVOUS2 cell on a circuit which
has sent a RELAY_ESTABLISH_RENDEZVOUS cell but which has not yet received
a reply, it uses g^y and H(g^xy) to complete the handshake as in the Tor
circuit extend process: they establish a 60-octet string as
K = SHA1(g^xy | [00]) | SHA1(g^xy | [01]) | SHA1(g^xy | [02])
and generate
KH = K[0..15]
Kf = K[16..31]
Kb = K[32..47]
Subsequently, the rendezvous point passes relay cells, unchanged, from
each of the two circuits to the other. When Alice's OP sends
RELAY cells along the circuit, it first encrypts them with the
Kf, then with all of the keys for the ORs in Alice's side of the circuit;
and when Alice's OP receives RELAY cells from the circuit, it decrypts
them with the keys for the ORs in Alice's side of the circuit, then
decrypts them with Kb. Bob's OP does the same, with Kf and Kb
interchanged.
1.11. Creating streams
To open TCP connections to Bob's location-hidden service, Alice's OP sends
a RELAY_BEGIN cell along the established circuit, using the special
address "", and a chosen port. Bob's OP chooses a destination IP and
port, based on the configuration of the service connected to the circuit,
and opens a TCP stream. From then on, Bob's OP treats the stream as an
ordinary exit connection.
[ Except he doesn't include addr in the connected cell or the end
cell. -RD]
Alice MAY send multiple RELAY_BEGIN cells along the circuit, to open
multiple streams to Bob. Alice SHOULD NOT send RELAY_BEGIN cells for any
other address along her circuit to Bob; if she does, Bob MUST reject them.
+175
View File
@@ -0,0 +1,175 @@
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%deffont "standard" xfont "comic sans ms-medium-r"
%%deffont "thick" xfont "arial black-medium-r"
%%deffont "typewriter" xfont "courier new-bold-r"
%%deffont "type2writer" xfont "arial narrow-bold-r"
%%deffont "standard" tfont "standard.ttf", tmfont "kochi-mincho.ttf"
%%deffont "thick" tfont "thick.ttf", tmfont "goth.ttf"
%%deffont "typewriter" tfont "typewriter.ttf", tmfont "goth.ttf"
%deffont "standard" xfont "helvetica-medium-r", tfont "arial.ttf", tmfont "times.ttf"
%deffont "thick" xfont "helvetica-bold-r", tfont "arialbd.ttf", tmfont "hoso6.ttf"
%deffont "italic" xfont "helvetica-italic-r", tfont "ariali.ttf", tmfont "hoso6.ttf"
%deffont "typewriter" xfont "courier-medium-r", tfont "typewriter.ttf", tmfont "hoso6.ttf"
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
%% Default settings per each line numbers.
%%
%default 1 leftfill, size 8, fore "black", back "white", font "thick", hgap 1
%default 2 size 8, vgap 10, prefix " ", ccolor "black"
%default 3 size 6, bar "gray70", vgap 0
%default 4 size 6, fore "black", vgap 0, prefix " ", font "standard"
%%
%%default 1 area 90 90, leftfill, size 9, fore "yellow", back "blue", font "thick"
%%default 2 size 9, vgap 10, prefix " "
%%default 3 size 7, bar "gray70", vgap 10
%%default 4 size 7, vgap 30, prefix " ", font "standard"
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
%% Default settings that are applied to TAB-indented lines.
%%
%tab 1 size 5, vgap 40, prefix " ", icon arc "red" 50
%tab 2 size 4, vgap 35, prefix " ", icon delta3 "blue" 40
%tab 3 size 3, vgap 35, prefix " ", icon dia "DarkViolet" 40
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%page
%nodefault
%center, size 9, font "thick", back "white", fore "black"
Tor:
%size 8
Next-generation Onion Routing
%size 7
Roger Dingledine
Nick Mathewson
Paul Syverson
%%The Free Haven Project
%%%font "typewriter", fore "blue"
%%http://freehaven.net/
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%page
Low-latency anonymity system
%leftfill
Deployed: 19 nodes, hundreds of users (?)
Many improvements on earlier design
Free software -- available source code
Design is not covered by earlier onion routing
patent
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%page
Perfect forward secrecy
Telescoping circuit
negotiates keys at each hop
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%page
%%
%%Separation from "protocol cleaning"
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%page
No mixing, padding, traffic shaping (yet)
Please show us they're worth the usability tradeoff
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%page
%%
%%Many TCP streams can share one circuit
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%page
Congestion control
Simple rate limiting
Plus have to keep internal nodes from overflowing
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%page
Directory servers
Approve new servers
Tell clients who's up right now
plus their keys, location, etc
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%page
Variable exit policies
Each server allows different outgoing connections
E.g. no servers allow outgoing mail currently
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%page
End-to-end integrity checking
In previous onion routing, an insider could change
the text being transmitted:
"dir" => "rm *"
Even an external adversary could do this!
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%page
Rendezvous points
allow hidden services
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%page
Differences / limitations
We're TCP-only, not all IP (but we're user-space and very portable)
Not peer-to-peer
No protocol normalization
%%Not unobservable
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%page
We have working code
Plus a design document,
and a byte-level specification
%size 9
http://freehaven.net/tor/
@@ -0,0 +1,60 @@
$Id$
Tor's extensions to the SOCKS protocol
1. Overview
The SOCKS protocol provides a generic interface for TCP proxies. Client
software connects to a SOCKS server via TCP, and requests a TCP connection
to another address and port. The SOCKS server establishes the connection,
and reports success or failure to the client. After the connection has
been established, the client application uses the TCP stream as usual.
Tor supports SOCKS4 as defined in [1], SOCKS4A as defined in [2], and
SOCKS5 as defined in [3].
The stickiest issue for Tor in supporting clients, in practice, is forcing
DNS lookups to occur at the OR side: if clients do their own DNS lookup,
the DNS server can learn which addresses the client wants to reach.
SOCKS4 supports addressing by IPv4 address; SOCKS4A is a kludge on top of
SOCKS4 to allow addressing by hostname; SOCKS5 supports IPv4, IPv6, and
hostnames.
1.1. Extent of support
Tor supports the SOCKS4, SOCKS4A, and SOCKS5 standards, except as follows:
BOTH:
- The BIND command is not supported.
SOCKS4,4A:
- SOCKS4 usernames are ignored.
SOCKS5:
- The (SOCKS5) "UDP ASSOCIATE" command is not supported.
- IPv6 is not supported in CONNECT commands.
- Only the "NO AUTHENTICATION" (SOCKS5) authentication method [00] is
supported.
2. Name lookup
As an extension to SOCKS4A and SOCKS5, Tor implements a new command value,
"RESOLVE" [F0]. When Tor receives a "RESOLVE" SOCKS command, it initiates
a remote lookup of the hostname provided as the target address in the SOCKS
request. The reply is either an error (if the address couldn't be
resolved) or a success response. In the case of success, the address is
stored in the portion of the SOCKS response reserved for remote IP address.
(We support RESOLVE in SOCKS4 too, even though it is unnecessary.)
3. HTTP-resistance
Tor checks the first byte of each socks request to see whether it looks
more like an HTTP request (that is, it starts with a "G", "H", or "P"). If
so, Tor returns a small webpage, telling the user that his/her browser is
misconfigured. This is helpful for the many users who mistakenly try to
use Tor as an HTTP proxy instead of a SOCKS proxy.
References:
[1] http://archive.socks.permeo.com/protocol/socks4.protocol
[2] http://archive.socks.permeo.com/protocol/socks4a.protocol
[3] SOCKS5: RFC1928
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
Binary file not shown.
File diff suppressed because it is too large Load Diff
+89
View File
@@ -0,0 +1,89 @@
/* *******************************************************
$Id$
This file is maintained in CVS; edit the version in the
repository.
*******************************************************
*/
BODY {
background-color: #FFF;
color: #000;
}
P, TD, TH, DD, DT, LI {
font-family: lucida, "Lucida Sans", "Geneva", sans-serif;
}
TH, DT {
font-weight: bold;
}
H1, H2, H3, H4, H5, H6 {
font-family: lucida, "Lucida Sans", "Geneva", sans-serif;
}
H1 {
text-align: center;
}
H2, H3, H4, H5, H6 {
text-align: left;
}
H2 {
background-color: #AFA;
color: #000;
padding: 2px 2px 2px 2px;
border-width: 2px 2px 2px 2px;
border-color: #000;
border-style: solid;
}
H3 {
background-color: #CCF;
color: #000;
padding: 2px 2px 2px 2px;
margin: 0 0 0 1em;
border-width: 2px 2px 2px 2px;
border-color: #000;
border-style: solid;
}
DIV.answer {
margin: 0 0 0 2em;
}
SPAN.heading {
background-color: #ABF;
color: #000;
border-width: 1px;
padding: 0 0.2em 0 0.2em;
border-color: #000;
border-style: solid;
}
SPAN.date {
background-color: #FFF;
color: #0A0;
font-weight: bold;
}
P.date {
background-color: #FFF;
color: #0A0;
font-weight: bold;
margin-bottom: 0;
}
P.news {
margin-top: 0;
margin-left: 3em;
}
P.credit {
font-size: smaller;
font-style: italic;
padding-left: 3px;
border-left: 3px solid;
}
+341
View File
@@ -0,0 +1,341 @@
<html>
<head>
<title>Tor: an anonymizing overlay network for TCP</title>
<meta name="Author" content="Roger Dingledine">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="Content-Style-Type" content="text/css">
<link rel="stylesheet" type="text/css" href="tor-doc.css">
</head>
<body>
<h1><a href="http://freehaven.net/tor/">Tor</a> documentation</h1>
<p>The simple version: Tor provides a distributed network of servers
("onion routers"). Users bounce their TCP streams (web traffic, FTP, SSH,
etc.) around the routers. This makes it hard for recipients, observers, and
even the onion routers themselves to track the source of the stream.</p>
<p>The complex version: Onion Routing is a connection-oriented anonymizing
communication service. Users choose a source-routed path through a set of
nodes, and negotiate a "virtual circuit" through the network, in which
each node knows its predecessor and successor, but no others. Traffic
flowing down the circuit is unwrapped by a symmetric key at each node,
which reveals the downstream node.</p>
<a name="why"></a>
<h2>Why should I use Tor?</h2>
<p>Individuals need Tor for privacy:
<ul>
<li>Privacy in web browsing -- both from the remote website (so it can't
track and sell your behavior), and similarly from your local ISP.
<li>Safety in web browsing: if your local government doesn't approve
of its citizens visiting certain websites, they may monitor the sites
and put readers on a list of suspicious persons.
<li>Circumvention of local censorship: connect to resources (news
sites, instant messaging, etc) that are restricted from your
ISP/school/company/government.
<li>Socially sensitive communication: chat rooms and web forums for
rape and abuse survivors, or people with illnesses.
</ul>
<p>Journalists and NGOs need Tor for safety:
<ul>
<li>Allowing dissidents and whistleblowers to communicate more safely.
<li>Censorship-resistant publication, such as making available your
home-made movie anonymously via a Tor <a href="#hidden-service">hidden
service</a>; and reading, e.g. of news sites not permitted in some
countries.
<li>Allowing their agents to check back with their home website while
they're in a foreign country, without notifying everybody nearby that
they're working with that organization.
</ul>
<p>Companies need Tor for business security:
<ul>
<li>Competitive analysis: browse the competition's website safely.
<li>Protecting collaborations of sensitive business units or partners.
<li>Protecting procurement suppliers or patterns.
<li>Putting the "P" back in "VPN": traditional VPNs reveal the exact
amount and frequency of communication. Which locations have employees
working late? Which locations have employees consulting job-hunting
websites? Which research groups are communicating with your company's
patent lawyers?
</ul>
<p>Governments need Tor for traffic-analysis-resistant communication:
<ul>
<li>Open source intelligence gathering (hiding individual analysts is
not enough -- the organization itself may be sensitive).
<li>Defense in depth on open <em>and classified</em> networks -- networks
with a million users (even if they're all cleared) can't be made safe just
by hardening them to external threat.
<li>Dynamic and semi-trusted international coalitions: the network can
be shared without revealing the existence or amount of communication
between all parties.
<li>Networks partially under known hostile control: to block
communications, the enemy must take down the whole network.
<li>Politically sensitive negotations.
<li>Road warriors.
<li>Protecting procurement patterns.
<li>Anonymous tips.
</ul>
<p>Law enforcement needs Tor for safety:
<ul>
<li>Allowing anonymous tips or crime reporting
<li>Allowing agents to observe websites without notifying them that
they're being observed (or, more broadly, without having it be an
official visit from law enforcement).
<li>Surveillance and honeypots (sting operations)
</ul>
<p>Does the idea of sharing the Tor network with
all of these groups bother you? It shouldn't -- <a
href="http://freehaven.net/doc/fc03/econymics.pdf">you need them for
your security</a>.</p>
<a name="client-or-server"></a>
<h2>Should I run a client or a server?</h2>
<p>You can run Tor in either client mode or server mode. By default,
everybody is a <i>client</i>. This means you don't relay traffic for
anybody but yourself.</p>
<p>If you have less than 768kbit in both directions, you should stay
a client. Otherwise, please consider being a server, to help out the
network. (Currently each server uses 20-30 gigabytes of traffic
per month; but that may go up.)</p>
<p>Note that you can be a server without allowing users to make
connections from your computer to the outside world. This is called being
a middleman server.</p>
<p> Benefits of running a server include:
<ul>
<li>Clients are generally limited to 100KB/s, whereas servers can inject
or receive as much traffic as they want.
<li>You may get stronger anonymity, since your destination can't know
whether connections relayed through your computer originated at your
computer or not.
<li>You can also get stronger anonymity by configuring your Tor clients
to use your Tor server for entry or for exit.
<li>You're helping me with development and scalability testing.
<li>You're helping your fellow Internet users by providing a larger
network. Also, having servers in many different pieces of the Internet
gives users more robustness against curious telcos and brute force
attacks.
</ul>
<p>You can read more about setting up Tor as a
server <a href="#server">below</a>.</p>
<a name="installing"></a>
<h2>Installing Tor</h2>
<p>You can get the latest releases <a
href="http://freehaven.net/tor/dist/">here</a>.</p>
<p>If you got Tor from a tarball, unpack it: <tt>tar xzf
tor-0.0.7.tar.gz; cd tor-0.0.7</tt>. Run <tt>./configure</tt>, then
<tt>make</tt>, and then <tt>make install</tt> (as root if necessary). Then
you can launch tor from the command-line by running <tt>tor</tt>.</p>
<p>If you got Tor from the Win32 .exe file, you
can just click-click it (you may need to install <a
href="http://www.slproweb.com/products/Win32OpenSSL.html">OpenSSL
0.9.7</a> first, if you get an error about missing
libeay32.dll.) You might also want to run Tor in a dos window,
so you can see its logs, and see its error messages if it
crashes. If you don't want the default configuration, fetch the <a
href="http://freehaven.net/tor/doc/torrc.sample">torrc</a>, edit it,
and use <tt>tor.exe -f torrc</tt>.</p>
<p>Otherwise, if you got it prepackaged (e.g. in the <a
href="http://packages.debian.org/tor">Debian package</a> or <a
href="http://packages.gentoo.org/packages/?category=net-misc;name=tor">Gentoo
package</a>), these steps are already done for you, and you may
even already have Tor started in the background (logging to
/var/log/something).</p>
<p>In any case, see the next section for what to <i>do</i> with it now that
you've got it running.</p>
<a name="client"></a>
<h2>Configuring a client</h2>
<p>Tor comes configured as a client by default. It uses a built-in
default configuration file, and most people won't need to change any of
the settings.</p>
<p>The only setting you might need to change is "SocksAddress".
By default, your Tor client only listens for applications that connect
from localhost. Connections from other computers are refused. If you
want to torify applications on different computers than the Tor client,
you should copy torrc.sample to torrc (it's installed by default
to /usr/local/etc/tor/), change the SocksAddress line to
0.0.0.0, and then restart Tor.</p>
<p>To test if it's working, point your browser
to socks4 or socks5 proxy at localhost port 9050. In
Mozilla, this is in edit|preferences|advanced|proxies. Go to <a
href="http://www.junkbusters.com/cgi-bin/privacy">http://www.junkbusters.com/cgi-bin/privacy</a>
and see what IP it says you're coming from. (If you have a personal
firewall, be sure to allow local connections to port 9050. If your
firewall blocks outgoing connections, punch a hole so it can connect to
TCP *:9001-9004 and *:9030-9033. If you're using Safari as your browser,
keep in mind that OS X before 10.3 claims to support socks but does
not.)</p>
<p>Once you've tested that it works, you should install <a
href="http://www.privoxy.org/">privoxy</a>, which is a filtering web
proxy that integrates well with Tor. Add the line <br>
<tt>forward-socks4a / localhost:9050 .</tt><br>
(don't forget the dot) to its
config file. Then change your mozilla to http proxy at localhost port 8118
(and no socks proxy). You should also set your SSL proxy to the same
thing, to hide your https traffic. Using privoxy will give you good html
scrubbing as well.
(See <a href="http://freehaven.net/tor/cvs/doc/CLIENTS">this explanation</a>
for why direct socks gives you less anonymity.)</p>
<p>You might want to use Tor with an application that doesn't
support socks directly. In this case, you should look at
using <a href="http://tsocks.sourceforge.net/">tsocks</a>
to dynamically replace the system calls in your program to
route through Tor. If you want to use socks4a, consider using <a
href="http://www.dest-unreach.org/socat/">socat</a> (specific instructions
are on <a href="http://6sxoyfb3h2nvok2d.onion/tor/SocatHelp">this hidden
service url</a>).</p>
<a name="server"></a>
<h2>Configuring a server</h2>
<p>We're looking for people with reasonably reliable Internet connections,
that have at least 768kbit each way. Currently we don't use all of that,
but we want it available for burst traffic.</p>
<p>The Tor server doesn't need to be run as root, and doesn't
need any special system permissions or kernel mods. If you're
the paranoid sort, feel free to put it into a chroot jail (<a
href="http://archives.seul.org/or/dev/Jun-2004/msg00001.html">some
hints</a>), etc.</p>
<p>First, copy torrc.sample to torrc (by default it's in
/usr/local/etc/tor/), and edit the middle part. Create the DataDirectory,
and make sure it's owned by whoever will be running tor. Fix your system
clock so it's not too far off. Make sure name resolution works. Open a
hole in your firewall so outsiders can connect to your ORPort.</p>
<p>Then run tor to generate keys: <tt>tor</tt>. One of the files generated
in your DataDirectory is your 'fingerprint' file. Mail it to
tor-ops@freehaven.net.</p>
<p>In that mail, be sure to tell us who you are, so we know whom to contact
if there's any problem. Also describe what kind of connectivity the new
server will have. If possible, PGP sign your mail.</p>
<p>NOTE: You won't be able to use tor as a client or server
in this configuration until you've been added to the directory
and can authenticate to the other nodes.</p>
<p>Once your fingerprint has been approved, you can click <a
href="http://moria.seul.org:9031/">here</a> or <a
href="http://62.116.124.106:9030/">here</a> and look at the
running-routers line to see if your server is part of the network.</p>
<a name="hidden-service"></a>
<h2>Configuring a hidden service</h2>
<p>Tor allows clients and servers to offer <em>hidden services</em>. That
is, you can offer an apache, sshd, etc, without revealing your IP to its
users. This works via Tor's rendezvous point design: both sides build
a Tor circuit out, and they meet in the middle.</p>
<p>If you're using Tor and <a href="http://www.privoxy.org/">Privoxy</a>,
you can <a href="http://6sxoyfb3h2nvok2d.onion/">go to the hidden wiki</a>
to see hidden services in action.</p>
<p>To set up a hidden service, copy torrc.sample to torrc (by default it's
in /usr/local/etc/tor/), and edit the bottom part. Then run Tor. It will
create each HiddenServiceDir you have configured, and it will create a
'hostname' file which specifies the url (xyz.onion) for that service. You
can tell people the url, and they can connect to it via their Tor client,
assuming they're using a proxy (such as Privoxy) that speaks socks4a.</p>
<a name="own-network"></a>
<h2>Setting up your own network</h2>
<p>
If you want to experiment locally with your own network, or you're cut
off from the Internet and want to be able to mess with Tor still, then
you may want to set up your own separate Tor network.
<p>
To set up your own Tor network, you need to run your own directory
servers, and you need to change the tarball so it points to your directory
servers rather than the default ones.
<ul>
<li>1: Grab the latest release.
<li>2: For each directory server you want,
<ul>
<li>2a: Set it up as a server (see <a href="#server">"setting up a
server"</a> above), with a least ORPort, DataDirectory, and Nickname
defined.
<li>2b: Set "DirPort" to the intended port for serving directories.
<li>2c: Set "RecommendedVersions" to a comma-separated list of acceptable
versions of the code for clients and servers to be running (see step
4c below).
<!-- <li>2d: Create a file called approved-routers in your DataDirectory:
<tt>touch approved-routers</tt>. It will be empty for now. We'll fill it in
step 5. -->
<li>2d: Create an empty dirservers file (<tt>touch dirservers</tt>). Point
RouterFile at it in your torrc.
<li>2e: Run it: <tt>tor -f torrc</tt>. This will generate your keys and a
router.desc (router descriptor) file. It will then exit with a complaint
that it can't open the fingerprint file; that's fine.
</ul>
<li>3: Create the new dirservers file. You do this by concatenating the
"router.desc" files from each dirserver's DataDirectory: <tt>cat router1.desc
router2.desc ... &gt; dirservers</tt>
<li>4: Now you need to teach clients and servers to use the new
dirservers file. First, check out the tor cvs repository (instructions <a
href="http://freehaven.net/tor/">here</a> -- be sure to check out the
tag that matches the version of the code you intend to use; and note that
the latest cvs version may not compile or work right). Then:
<ul>
<li>4a: Edit src/or/config.c and change the default_dirservers_string array
so that it reflects the contents of the new dirservers file instead
of the old one. Be sure to get the quotes and newlines and semicolons
right. (This step sucks. Please suggest a better way to handle this
step. ;)
<li>4b: Replace the dirservers file in your sandbox (in src/config/)
with the one from step 3.
<li>4c: edit configure.in, change the AM_INIT_AUTOMAKE(tor, 0.0.6)
line so that it specifies a version that is specific to you, such as
0.0.6-arma. This will help you keep from being confused later. Be sure
to update the RecommendedVersions lines to include this version.
<li>4d: run <tt>./autogen.sh</tt> (you'll need a new enough set of auto* tools),
then <tt>make dist</tt>.
</ul>
<li>5: Create a file called approved-routers in the DataDirectory
of each directory server. Collect the 'fingerprint' lines from the
DataDirectory of each server (including directory servers), and include
them (one per line) in each approved-routers file. You can hup the tor
process for each directory server to reload the approved-routers file
(so you don't have to restart the process).
</ul>
<h2>Other doc resources</h2>
<ul>
<li>Design paper
<li>Spec and rend-spec
<li>others
</ul>
</body>
</html>
+657
View File
@@ -0,0 +1,657 @@
$Id$
Tor Spec
Note: This is an attempt to specify Tor as it exists as implemented in
early March, 2004. It is not recommended that others implement this
design as it stands; future versions of Tor will implement improved
protocols.
This is not a design document; most design criteria are not examined. For
more information on why Tor acts as it does, see tor-design.pdf.
TODO: (very soon)
- REASON_CONNECTFAILED should include an IP.
- Copy prose from tor-design to make everything more readable.
0. Notation:
PK -- a public key.
SK -- a private key
K -- a key for a symmetric cypher
a|b -- concatenation of 'a' and 'b'.
[A0 B1 C2] -- a three-byte sequence, containing the bytes with
hexadecimal values A0, B1, and C2, in that order.
All numeric values are encoded in network (big-endian) order.
Unless otherwise specified, all symmetric ciphers are AES in counter
mode, with an IV of all 0 bytes. Asymmetric ciphers are either RSA
with 1024-bit keys and exponents of 65537, or DH with the safe prime
from rfc2409, section 6.2, whose hex representation is:
"FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E08"
"8A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B"
"302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9"
"A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE6"
"49286651ECE65381FFFFFFFFFFFFFFFF"
1. System overview
Onion Routing is a distributed overlay network designed to anonymize
low-latency TCP-based applications such as web browsing, secure shell,
and instant messaging. Clients choose a path through the network and
build a ``circuit'', in which each node (or ``onion router'' or ``OR'')
in the path knows its predecessor and successor, but no other nodes in
the circuit. Traffic flowing down the circuit is sent in fixed-size
``cells'', which are unwrapped by a symmetric key at each node (like
the layers of an onion) and relayed downstream.
2. Connections
There are two ways to connect to an onion router (OR). The first is
as an onion proxy (OP), which allows the OP to authenticate the OR
without authenticating itself. The second is as another OR, which
allows mutual authentication.
Tor uses TLS for link encryption. All implementations MUST support
the TLS ciphersuite "TLS_EDH_RSA_WITH_DES_192_CBC3_SHA", and SHOULD
support "TLS_DHE_RSA_WITH_AES_128_CBC_SHA" if it is available.
Implementations MAY support other ciphersuites, but MUST NOT
support any suite without ephemeral keys, symmetric keys of at
least 128 bits, and digests of at least 160 bits.
An OR always sends a two-certificate chain, consisting of a self-signed
certificate containing the OR's identity key, and a second certificate
using a short-term connection key. The commonName of the second
certificate is the OR's nickname, and the commonName of the first
certificate is the OR's nickname, followed by a space and the string
"<identity>".
All parties receiving certificates must confirm that the identity key is
as expected. (When initiating a connection, the expected identity key is
the one given in the directory; when creating a connection because of an
EXTEND cell, the expected identity key is the one given in the cell.) If
the key is not as expected, the party must close the connection.
Once a TLS connection is established, the two sides send cells
(specified below) to one another. Cells are sent serially. All
cells are 512 bytes long. Cells may be sent embedded in TLS
records of any size or divided across TLS records, but the framing
of TLS records MUST NOT leak information about the type or contents
of the cells.
OR-to-OR connections are never deliberately closed. When an OR
starts or receives a new directory, it tries to open new
connections to any OR it is not already connected to.
OR-to-OP connections are not permanent. An OP should close a
connection to an OR if there are no circuits running over the
connection, and an amount of time (KeepalivePeriod, defaults to 5
minutes) has passed.
3. Cell Packet format
The basic unit of communication for onion routers and onion
proxies is a fixed-width "cell". Each cell contains the following
fields:
CircID [2 bytes]
Command [1 byte]
Payload (padded with 0 bytes) [509 bytes]
[Total size: 512 bytes]
The CircID field determines which circuit, if any, the cell is
associated with.
The 'Command' field holds one of the following values:
0 -- PADDING (Padding) (See Sec 6.2)
1 -- CREATE (Create a circuit) (See Sec 4)
2 -- CREATED (Acknowledge create) (See Sec 4)
3 -- RELAY (End-to-end data) (See Sec 5)
4 -- DESTROY (Stop using a circuit) (See Sec 4)
The interpretation of 'Payload' depends on the type of the cell.
PADDING: Payload is unused.
CREATE: Payload contains the handshake challenge.
CREATED: Payload contains the handshake response.
RELAY: Payload contains the relay header and relay body.
DESTROY: Payload is unused.
Upon receiving any other value for the command field, an OR must
drop the cell.
The payload is padded with 0 bytes.
PADDING cells are currently used to implement connection keepalive.
If there is no other traffic, ORs and OPs send one another a PADDING
cell every few minutes.
CREATE, CREATED, and DESTROY cells are used to manage circuits;
see section 4 below.
RELAY cells are used to send commands and data along a circuit; see
section 5 below.
4. Circuit management
4.1. CREATE and CREATED cells
Users set up circuits incrementally, one hop at a time. To create a
new circuit, OPs send a CREATE cell to the first node, with the
first half of the DH handshake; that node responds with a CREATED
cell with the second half of the DH handshake plus the first 20 bytes
of derivative key data (see section 4.2). To extend a circuit past
the first hop, the OP sends an EXTEND relay cell (see section 5)
which instructs the last node in the circuit to send a CREATE cell
to extend the circuit.
The payload for a CREATE cell is an 'onion skin', which consists
of the first step of the DH handshake data (also known as g^x).
The data is encrypted to Bob's PK as follows: Suppose Bob's PK is
L octets long. If the data to be encrypted is shorter than L-42,
then it is encrypted directly (with OAEP padding). If the data is at
least as long as L-42, then a randomly generated 16-byte symmetric
key is prepended to the data, after which the first L-16-42 bytes
of the data are encrypted with Bob's PK; and the rest of the data is
encrypted with the symmetric key.
So in this case, the onion skin on the wire looks like:
RSA-encrypted:
OAEP padding [42 bytes]
Symmetric key [16 bytes]
First part of g^x [70 bytes]
Symmetrically encrypted:
Second part of g^x [58 bytes]
The relay payload for an EXTEND relay cell consists of:
Address [4 bytes]
Port [2 bytes]
Onion skin [186 bytes]
Public key hash [20 bytes]
The port and address field denote the IPV4 address and port of the
next onion router in the circuit; the public key hash is the SHA1 hash of
the ASN1 encoding of the next onion router's identity key.
[XXXX Before 0.0.8, EXTEND cells did not include the public key hash.
Servers running 0.0.8 distinguish the old-style cells based on the
length of payloads. (Servers running 0.0.7 blindly pass on the extend
cell regardless of length.) In a future release, old-style EXTEND
cells will not be supported.]
The payload for a CREATED cell, or the relay payload for an
EXTENDED cell, contains:
DH data (g^y) [128 bytes]
Derivative key data (KH) [20 bytes] <see 4.2 below>
The CircID for a CREATE cell is an arbitrarily chosen 2-byte
integer, selected by the node (OP or OR) that sends the CREATE
cell. To prevent CircID collisions, when one OR sends a CREATE
cell to another, it chooses from only one half of the possible
values based on the ORs' nicknames: if the sending OR has a
lexicographically earlier nickname, it chooses a CircID with a high
bit of 0; otherwise, it chooses a CircID with a high bit of 1.
4.2. Setting circuit keys
Once the handshake between the OP and an OR is completed, both
servers can now calculate g^xy with ordinary DH. From the base key
material g^xy, they compute derivative key material as follows.
First, the server represents g^xy as a big-endian unsigned integer.
Next, the server computes 100 bytes of key data as K = SHA1(g^xy |
[00]) | SHA1(g^xy | [01]) | ... SHA1(g^xy | [04]) where "00" is
a single octet whose value is zero, [01] is a single octet whose
value is one, etc. The first 20 bytes of K form KH, bytes 21-40 form
the forward digest Df, 41-60 form the backward digest Db, 61-76 form
Kf, and 77-92 form Kb.
KH is used in the handshake response to demonstrate knowledge of the
computed shared key. Df is used to seed the integrity-checking hash
for the stream of data going from the OP to the OR, and Db seeds the
integrity-checking hash for the data stream from the OR to the OP. Kf
is used to encrypt the stream of data going from the OP to the OR, and
Kb is used to encrypt the stream of data going from the OR to the OP.
4.3. Creating circuits
When creating a circuit through the network, the circuit creator
(OP) performs the following steps:
1. Choose an onion router as an exit node (R_N), such that the onion
router's exit policy does not exclude all pending streams
that need a circuit.
2. Choose a chain of (N-1) chain of N onion routers
(R_1...R_N-1) to constitute the path, such that no router
appears in the path twice.
3. If not already connected to the first router in the chain,
open a new connection to that router.
4. Choose a circID not already in use on the connection with the
first router in the chain; send a CREATE cell along the
connection, to be received by the first onion router.
5. Wait until a CREATED cell is received; finish the handshake
and extract the forward key Kf_1 and the backward key Kb_1.
6. For each subsequent onion router R (R_2 through R_N), extend
the circuit to R.
To extend the circuit by a single onion router R_M, the OP performs
these steps:
1. Create an onion skin, encrypted to R_M's public key.
2. Send the onion skin in a relay EXTEND cell along
the circuit (see section 5).
3. When a relay EXTENDED cell is received, verify KH, and
calculate the shared keys. The circuit is now extended.
When an onion router receives an EXTEND relay cell, it sends a CREATE
cell to the next onion router, with the enclosed onion skin as its
payload. The initiating onion router chooses some circID not yet
used on the connection between the two onion routers. (But see
section 4.1. above, concerning choosing circIDs based on
lexicographic order of nicknames.)
As an extension (called router twins), if the desired next onion
router R in the circuit is down, and some other onion router R'
has the same public keys as R, then it's ok to extend to R' rather than R.
When an onion router receives a CREATE cell, if it already has a
circuit on the given connection with the given circID, it drops the
cell. Otherwise, after receiving the CREATE cell, it completes the
DH handshake, and replies with a CREATED cell. Upon receiving a
CREATED cell, an onion router packs it payload into an EXTENDED relay
cell (see section 5), and sends that cell up the circuit. Upon
receiving the EXTENDED relay cell, the OP can retrieve g^y.
(As an optimization, OR implementations may delay processing onions
until a break in traffic allows time to do so without harming
network latency too greatly.)
4.4. Tearing down circuits
Circuits are torn down when an unrecoverable error occurs along
the circuit, or when all streams on a circuit are closed and the
circuit's intended lifetime is over. Circuits may be torn down
either completely or hop-by-hop.
To tear down a circuit completely, an OR or OP sends a DESTROY
cell to the adjacent nodes on that circuit, using the appropriate
direction's circID.
Upon receiving an outgoing DESTROY cell, an OR frees resources
associated with the corresponding circuit. If it's not the end of
the circuit, it sends a DESTROY cell for that circuit to the next OR
in the circuit. If the node is the end of the circuit, then it tears
down any associated edge connections (see section 5.1).
After a DESTROY cell has been processed, an OR ignores all data or
destroy cells for the corresponding circuit.
(The rest of this section is not currently used; on errors, circuits
are destroyed, not truncated.)
To tear down part of a circuit, the OP may send a RELAY_TRUNCATE cell
signaling a given OR (Stream ID zero). That OR sends a DESTROY
cell to the next node in the circuit, and replies to the OP with a
RELAY_TRUNCATED cell.
When an unrecoverable error occurs along one connection in a
circuit, the nodes on either side of the connection should, if they
are able, act as follows: the node closer to the OP should send a
RELAY_TRUNCATED cell towards the OP; the node farther from the OP
should send a DESTROY cell down the circuit.
4.5. Routing relay cells
When an OR receives a RELAY cell, it checks the cell's circID and
determines whether it has a corresponding circuit along that
connection. If not, the OR drops the RELAY cell.
Otherwise, if the OR is not at the OP edge of the circuit (that is,
either an 'exit node' or a non-edge node), it de/encrypts the payload
with AES/CTR, as follows:
'Forward' relay cell (same direction as CREATE):
Use Kf as key; decrypt.
'Back' relay cell (opposite direction from CREATE):
Use Kb as key; encrypt.
The OR then decides whether it recognizes the relay cell, by
inspecting the payload as described in section 5.1 below. If the OR
recognizes the cell, it processes the contents of the relay cell.
Otherwise, it passes the decrypted relay cell along the circuit if
the circuit continues. If the OR at the end of the circuit
encounters an unrecognized relay cell, an error has occurred: the OR
sends a DESTROY cell to tear down the circuit.
When a relay cell arrives at an OP, the OP decrypts the payload
with AES/CTR as follows:
OP receives data cell:
For I=N...1,
Decrypt with Kb_I. If the payload is recognized (see
section 5.1), then stop and process the payload.
For more information, see section 5 below.
5. Application connections and stream management
5.1. Relay cells
Within a circuit, the OP and the exit node use the contents of
RELAY packets to tunnel end-to-end commands and TCP connections
("Streams") across circuits. End-to-end commands can be initiated
by either edge; streams are initiated by the OP.
The payload of each unencrypted RELAY cell consists of:
Relay command [1 byte]
'Recognized' [2 bytes]
StreamID [2 bytes]
Digest [4 bytes]
Length [2 bytes]
Data [498 bytes]
The relay commands are:
1 -- RELAY_BEGIN
2 -- RELAY_DATA
3 -- RELAY_END
4 -- RELAY_CONNECTED
5 -- RELAY_SENDME
6 -- RELAY_EXTEND
7 -- RELAY_EXTENDED
8 -- RELAY_TRUNCATE
9 -- RELAY_TRUNCATED
10 -- RELAY_DROP
11 -- RELAY_RESOLVE
12 -- RELAY_RESOLVED
The 'Recognized' field in any unencrypted relay payload is always
set to zero; the 'digest' field is computed as the first four bytes
of the running SHA-1 digest of all the bytes that have travelled
over this circuit, seeded from Df or Db respectively (obtained in
section 4.2 above), and including this RELAY cell's entire payload
(taken with the digest field set to zero).
When the 'recognized' field of a RELAY cell is zero, and the digest
is correct, the cell is considered "recognized" for the purposes of
decryption (see section 4.5 above).
All RELAY cells pertaining to the same tunneled stream have the
same stream ID. StreamIDs are chosen randomly by the OP. RELAY
cells that affect the entire circuit rather than a particular
stream use a StreamID of zero.
The 'Length' field of a relay cell contains the number of bytes in
the relay payload which contain real payload data. The remainder of
the payload is padded with NUL bytes.
5.2. Opening streams and transferring data
To open a new anonymized TCP connection, the OP chooses an open
circuit to an exit that may be able to connect to the destination
address, selects an arbitrary StreamID not yet used on that circuit,
and constructs a RELAY_BEGIN cell with a payload encoding the address
and port of the destination host. The payload format is:
ADDRESS | ':' | PORT | [00]
where ADDRESS is be a DNS hostname, or an IPv4 address in
dotted-quad format; and where PORT is encoded in decimal.
[What is the [00] for? -NM]
[It's so the payload is easy to parse out with string funcs -RD]
Upon receiving this cell, the exit node resolves the address as
necessary, and opens a new TCP connection to the target port. If the
address cannot be resolved, or a connection can't be established, the
exit node replies with a RELAY_END cell. (See 5.4 below.)
Otherwise, the exit node replies with a RELAY_CONNECTED cell, whose
payload is the 4-byte IP address to which the connection was made.
The OP waits for a RELAY_CONNECTED cell before sending any data.
Once a connection has been established, the OP and exit node
package stream data in RELAY_DATA cells, and upon receiving such
cells, echo their contents to the corresponding TCP stream.
RELAY_DATA cells sent to unrecognized streams are dropped.
Relay RELAY_DROP cells are long-range dummies; upon receiving such
a cell, the OR or OP must drop it.
5.3. Closing streams
When an anonymized TCP connection is closed, or an edge node
encounters error on any stream, it sends a 'RELAY_END' cell along the
circuit (if possible) and closes the TCP connection immediately. If
an edge node receives a 'RELAY_END' cell for any stream, it closes
the TCP connection completely, and sends nothing more along the
circuit for that stream.
The payload of a RELAY_END cell begins with a single 'reason' byte to
describe why the stream is closing, plus optional data (depending on
the reason.) The values are:
1 -- REASON_MISC (catch-all for unlisted reasons)
2 -- REASON_RESOLVEFAILED (couldn't look up hostname)
3 -- REASON_CONNECTFAILED (couldn't connect to host/port)
4 -- REASON_EXITPOLICY (OR refuses to connect to host or port)
5 -- REASON_DESTROY (circuit is being destroyed [???-NM])
6 -- REASON_DONE (anonymized TCP connection was closed)
7 -- REASON_TIMEOUT (OR timed out while connecting [???-NM])
(With REASON_EXITPOLICY, the 4-byte IP address forms the optional
data; no other reason currently has extra data.)
*** [The rest of this section describes unimplemented functionality.]
Because TCP connections can be half-open, we follow an equivalent
to TCP's FIN/FIN-ACK/ACK protocol to close streams.
An exit connection can have a TCP stream in one of three states:
'OPEN', 'DONE_PACKAGING', and 'DONE_DELIVERING'. For the purposes
of modeling transitions, we treat 'CLOSED' as a fourth state,
although connections in this state are not, in fact, tracked by the
onion router.
A stream begins in the 'OPEN' state. Upon receiving a 'FIN' from
the corresponding TCP connection, the edge node sends a 'RELAY_FIN'
cell along the circuit and changes its state to 'DONE_PACKAGING'.
Upon receiving a 'RELAY_FIN' cell, an edge node sends a 'FIN' to
the corresponding TCP connection (e.g., by calling
shutdown(SHUT_WR)) and changing its state to 'DONE_DELIVERING'.
When a stream in already in 'DONE_DELIVERING' receives a 'FIN', it
also sends a 'RELAY_FIN' along the circuit, and changes its state
to 'CLOSED'. When a stream already in 'DONE_PACKAGING' receives a
'RELAY_FIN' cell, it sends a 'FIN' and changes its state to
'CLOSED'.
If an edge node encounters an error on any stream, it sends a
'RELAY_END' cell (if possible) and closes the stream immediately.
5.4. Remote hostname lookup
To find the address associated with a hostname, the OP sends a
RELAY_RESOLVE cell containing the hostname to be resolved. The OR
replies with an RELAY_RESOLVED cell containing a status byte, and any
number of answers. Each answer is of the form:
Type (1 octet)
Length (1 octet)
Value (variable-width)
"Length" is the length of the Value field. "Type" is one of:
0x04 -- IPv4 address
0x06 -- IPv6 address
0xF0 -- Error, transient
0xF1 -- Error, nontransient
If any answer has a type of 'Error', then no other answer may be given.
The RELAY_RESOLVE cell must use a nonzero, distinct streamID; the
corresponding RELAY_RESOLVED cell must use the same streamID. No stream
is actually created by the OR when resolving the name.
6. Flow control
6.1. Link throttling
Each node should do appropriate bandwidth throttling to keep its
user happy.
Communicants rely on TCP's default flow control to push back when they
stop reading.
6.2. Link padding
Currently nodes are not required to do any sort of link padding or
dummy traffic. Because strong attacks exist even with link padding,
and because link padding greatly increases the bandwidth requirements
for running a node, we plan to leave out link padding until this
tradeoff is better understood.
6.3. Circuit-level flow control
To control a circuit's bandwidth usage, each OR keeps track of
two 'windows', consisting of how many RELAY_DATA cells it is
allowed to package for transmission, and how many RELAY_DATA cells
it is willing to deliver to streams outside the network.
Each 'window' value is initially set to 1000 data cells
in each direction (cells that are not data cells do not affect
the window). When an OR is willing to deliver more cells, it sends a
RELAY_SENDME cell towards the OP, with Stream ID zero. When an OR
receives a RELAY_SENDME cell with stream ID zero, it increments its
packaging window.
Each of these cells increments the corresponding window by 100.
The OP behaves identically, except that it must track a packaging
window and a delivery window for every OR in the circuit.
An OR or OP sends cells to increment its delivery window when the
corresponding window value falls under some threshold (900).
If a packaging window reaches 0, the OR or OP stops reading from
TCP connections for all streams on the corresponding circuit, and
sends no more RELAY_DATA cells until receiving a RELAY_SENDME cell.
[this stuff is badly worded; copy in the tor-design section -RD]
6.4. Stream-level flow control
Edge nodes use RELAY_SENDME cells to implement end-to-end flow
control for individual connections across circuits. Similarly to
circuit-level flow control, edge nodes begin with a window of cells
(500) per stream, and increment the window by a fixed value (50)
upon receiving a RELAY_SENDME cell. Edge nodes initiate RELAY_SENDME
cells when both a) the window is <= 450, and b) there are less than
ten cell payloads remaining to be flushed at that edge.
7. Directories and routers
7.1. Extensible information format
Router descriptors and directories both obey the following lightweight
extensible information format.
The highest level object is a Document, which consists of one or more Items.
Every Item begins with a KeywordLine, followed by one or more Objects. A
KeywordLine begins with a Keyword, optionally followed by a space and more
non-newline characters, and ends with a newline. A Keyword is a sequence of
one or more characters in the set [A-Za-z0-9-]. An Object is a block of
encoded data in pseudo-Open-PGP-style armor. (cf. RFC 2440)
More formally:
Document ::= (Item | NL)+
Item ::= KeywordLine Object*
KeywordLine ::= Keyword NL | Keyword SP ArgumentsChar+ NL
Keyword = KeywordChar+
KeywordChar ::= 'A' ... 'Z' | 'a' ... 'z' | '0' ... '9' | '-'
ArgumentChar ::= any printing ASCII character except NL.
Object ::= BeginLine Base-64-encoded-data EndLine
BeginLine ::= "-----BEGIN " Keyword "-----" NL
EndLine ::= "-----END " Keyword "-----" NL
The BeginLine and EndLine of an Object must use the same keyword.
When interpreting a Document, software MUST reject any document containing a
KeywordLine that starts with a keyword it doesn't recognize.
7.1. Router descriptor format.
Every router descriptor MUST start with a "router" Item; MUST end with a
"router-signature" Item and an extra NL; and MUST contain exactly one
instance of each of the following Items: "published" "onion-key" "link-key"
"signing-key". Additionally, a router descriptor MAY contain any number of
"accept", "reject", and "opt" Items. Other than "router" and
"router-signature", the items may appear in any order.
The items' formats are as follows:
"router" nickname address (ORPort SocksPort DirPort)?
"ports" ORPort SocksPort DirPort
"bandwidth" bandwidth-avg bandwidth-burst
"platform" string
"published" YYYY-MM-DD HH:MM:SS
"onion-key" NL a public key in PEM format
"signing-key" NL a public key in PEM format
"accept" string
"reject" string
"router-signature" NL "-----BEGIN SIGNATURE-----" NL Signature NL
"-----END SIGNATURE-----"
"opt" SP keyword string? NL,Object?
ORport ::= port where the router listens for routers/proxies (speaking cells)
SocksPort ::= where the router listens for applications (speaking socks)
DirPort ::= where the router listens for directory download requests
bandwidth-avg ::= maximum average bandwidth, in bytes/s
bandwidth-burst ::= maximum bandwidth spike, in bytes/s
nickname ::= between 1 and 19 alphanumeric characters, case-insensitive.
Bandwidth and ports are required; if they are not included in the router
line, they must appear in "bandwidth" and "ports" lines.
"opt" is reserved for non-critical future extensions.
7.2. Directory format
A Directory begins with a "signed-directory" item, followed by one each of
the following, in any order: "recommended-software", "published",
"running-routers". It may include any number of "opt" items. After these
items, a directory includes any number of router descriptors, and a single
"directory-signature" item.
"signed-directory"
"published" YYYY-MM-DD HH:MM:SS
"recommended-software" comma-separated-version-list
"running-routers" comma-separated-nickname-list
"directory-signature" nickname-of-dirserver NL Signature
Note: The router descriptor for the directory server must appear first.
The signature is computed by computing the SHA-1 hash of the
directory, from the characters "signed-directory", through the newline
after "directory-signature". This digest is then padded with PKCS.1,
and signed with the directory server's signing key.
If software encounters an unrecognized keyword in a single router descriptor,
it should reject only that router descriptor, and continue using the
others. If it encounters an unrecognized keyword in the directory header,
it should reject the entire directory.
7.3. Behavior of a directory server
lists nodes that are connected currently
speaks http on a socket, spits out directory on request
-----------
(for emacs)
Local Variables:
mode:text
indent-tabs-mode:nil
fill-column:77
End:
+212
View File
@@ -0,0 +1,212 @@
.TH TOR 1 "November 2003" "TOR"
.SH NAME
tor \- The second-generation onion router
.SH SYNOPSIS
.B tor
[\fIOPTION value\fR]...
.SH DESCRIPTION
.I tor
is a connection-oriented anonymizing communication
service. Users choose a source-routed path through a set of nodes, and
negotiate a "virtual circuit" through the network, in which each node
knows its predecessor and successor, but no others. Traffic flowing down
the circuit is unwrapped by a symmetric key at each node, which reveals
the downstream node.
.PP
Basically \fItor\fR provides a distributed network of servers ("onion
routers"). Users bounce their tcp streams -- web traffic, ftp, ssh, etc --
around the routers, and recipients, observers, and even the routers
themselves have difficulty tracking the source of the stream.
.SH OPTIONS
\fB-h, -help\fP
Display a short help message and exit.
.TP
\fB-f \fR\fIFILE\fP
FILE contains further "option value" pairs. (Default: @CONFDIR@/torrc)
.TP
Other options can be specified either on the commandline (\fI--option value\fR), or in the configuration file (\fIoption value\fR).
.TP
\fBloglevel debug|info|warn|err\fP
Set the verboseness level of the primary log. (Default: warn)
.TP
\fBlogfile \fR\fIFILE\fP
Rather than logging to stdout, log to FILE.
.TP
\fBbandwidthrate \fR\fINUM\fP
A token bucket limits the average incoming bandwidth on this node to NUM bytes per second. (Default: 800000)
.TP
\fBbandwidthburst \fR\fINUM\fP
Limit the maximum token bucket size (also known as the burst) to NUM bytes. (Default: 10000000)
.TP
\fBdebuglogfile \fR\fIFILE\fP
In addition to other logging, we will log to FILE at log-level debug.
.TP
\fBgroup \fR\fIGID\fP
On startup, setgid to this user.
.TP
\fBkeepaliveperiod \fR\fINUM\fP
To keep firewalls from expiring connections, send a padding keepalive cell on open connections every NUM seconds. (Default: 300)
.TP
\fBpidfile \fR\fIFILE\fP
On startup, write our PID to FILE. On clean shutdown, remove FILE.
.TP
\fBrouterfile \fR\fIFILE\fP
FILE contains a list of directory servers, to bootstrap into the network. (Default: @CONFDIR@/dirservers)
.TP
\fBrunasdaemon \fR\fI0|1\fP
If 1, Tor forks and daemonizes to the background. (Default: 0)
.TP
\fBuser \fR\fIUID\fP
On startup, setuid to this user.
.SH CLIENT OPTIONS
.PP
The following options are useful only for clients (that is, if \fBsocksport\fP is non-zero):
.TP
\fBentrynodes \fR\fInickname,nickname,...\fP
A list of preferred nodes to use for the first hop in the circuit, if possible.
.TP
\fBexitnodes \fR\fInickname,nickname,...\fP
A list of preferred nodes to use for the last hop in the circuit, if possible.
.TP
\fBexcludenodes \fR\iInickname,nickname,...\fP
A list of nodes to never use when building a circuit.
.TP
\fBnewcircuitperiod \fR\fINUM\fP
Every NUM seconds consider whether to build a new circuit. (Default: 60)
.TP
\fBpathlencoinweight \fR\fI0.0-1.0\fP
Paths are 3 hops plus a geometric distribution centered around this coinweight. Must be >=0.0 and <1.0. (Default: 0.3)
.TP
\fBsocksport \fR\fIPORT\fP
Bind to this port to listen for connections from socks-speaking applications.
.TP
\fBsocksbindaddress \fR\fIIP\fP
Bind to this address to listen for connections from socks-speaking applications. (Default: 127.0.0.1) You can also specify a port (e.g. 192.168.0.1:9100). This directive can be specified multiple times to bind to multiple addresses/ports.
.TP
\fBsockspolicy \fR\fIpolicy,policy,...\fP
Set an entrance policy for this server, so limit who can connect to the socks ports. The policies have the same form as exit policies below.
.SH SERVER OPTIONS
.PP
The following options are useful only for servers (that is, if \fBorport\fP is non-zero):
.TP
\fBaddress address\fP
The fqdn of this server (e.g. moria.mit.edu).
.TP
\fBdatadirectory \fR\fIDIR\fP
Store working data in DIR (Default: @LOCALSTATEDIR@/lib/tor)
.TP
\fBexitpolicy \fR\fIpolicy,policy,...\fP
Set an exit policy for this server. Each policy is of the form
"\fBreject\fP \fIADDR\fP\fB/\fP\fIMASK\fP\fB:\fP\fIPORT\fP".
If \fB/\fP\fIMASK\fP is omitted then this policy just applies to the host
given. Instead of giving a host or network you can also use "\fB*\fP" to
denote the universe (0.0.0.0/0). \fIPORT\fP can either be a single port number
or an interval of ports: "\fIFROM_PORT\fP\fB-\fP\fITO_PORT\fP".
For example, "reject 127.0.0.1:*,reject 192.168.1.0/24:*,accept *:*" would
reject any traffic destined for localhost and any 192.168.1.* address, but
accept anything else.
This directive can be specified multiple times so you don't have to put
it all on one line.
See RFC 3330 for more details about internal and reserved IP address
space. The default exit policy is:
.PD 0
.RS 12
.IP "reject 0.0.0.0/8" 0
.IP "reject 169.254.0.0/16" 4
.IP "reject 127.0.0.0/8"
.IP "reject 192.168.0.0/16"
.IP "reject 10.0.0.0/8"
.IP "reject 172.16.0.0/12"
.IP "accept *:20-22"
.IP "accept *:53"
.IP "accept *:79-81"
.IP "accept *:110"
.IP "accept *:143"
.IP "accept *:443"
.IP "accept *:873"
.IP "accept *:993"
.IP "accept *:995" 4
.IP "accept *:1024-65535"
.IP "reject *:*"
.RE
.PD
.TP
\fBmaxonionspending \fR\fINUM\fP
If you have more than this number of onionskins queued for decrypt, reject new ones. (Default: 100)
.TP
\fBnickname \fR\fIname\fP
Set the server's nickname to 'name'.
.TP
\fBnumcpus \fR\fInum\fP
How many processes to use at once for decrypting onionskins. (Default: 1)
.TP
\fBorport \fR\fIPORT\fP
Bind to this port to listen for connections from Tor clients and servers.
.TP
\fBorbindaddress \fR\fIIP\fP
Bind to this address to listen for connections from Tor clients and servers. (Default: 0.0.0.0)
.SH DIRECTORY SERVER OPTIONS
.PP
The following options are useful only for directory servers (that is, if \fBdirport\fP is non-zero):
.TP
\fBdirport \fR\fIPORT\fP
Bind the directory service to this port.
.TP
\fBdirbindaddress \fR\fIIP\fP
Bind the directory service to this address. (Default: 0.0.0.0)
.TP
\fBrecommendedversions \fR\fISTRING\fP
STRING is a command-separated list of Tor versions currently believed to be safe. The list is included in each directory, and nodes which pull down the directory learn whether they need to upgrade.
.SH HIDDEN SERVER OPTIONS
.PP
The following options are used to configure a hidden service.
.TP
\fBhiddenservicedir \fR\fIDIRECTORY\fP
Store data files for a hidden service in DIRECTORY. Every hidden
service must have a separate directory. You may use this option multiple
times to specify multiple services.
.TP
\fBhiddenserviceport \fR\fIVIRTPORT \fR[\fITARGET\fR]\fP
Configure a virtual port VIRTPORT for a hidden service. You may use this
option multiple times; each time applies to the service using the most recent
hiddenservicedir. By default, this option maps the virtual port to the
same port on 127.0.0.1. You may override the target port, address, or both
by specifying a target of addr, port, or addr:port.
.TP
\fBhiddenservicenodes \fR\fInickname,nicknamme,...\fP
If possible, use the specified nodes as introduction points for the hidden
service.
.TP
\fBhiddenserviceexcludenodes \fR\fInickname,nicknamme,...\fP
Do not use the specified nodes as introduction points for the hidden
service.
.SH FILES
.TP
.I @CONFDIR@/torrc
The configuration file, which contains "option value" pairs.
.TP
.I @CONFDIR@/dirservers
A list of directory servers, to bootstrap into the network.
.TP
.I @LOCALSTATEDIR@/lib/tor/
The tor server stores keys/etc here.
.SH SEE ALSO
.BR privoxy (1),
.BR tsocks (1)
.BR http://freehaven.net/tor/
.SH BUGS
Plenty, probably. It's still in alpha. Please report them.
.SH AUTHORS
Roger Dingledine <arma@mit.edu>.
+98
View File
@@ -0,0 +1,98 @@
% usenix-2e.sty - to be used with latex2e (the new one) for USENIX.
% To use this style file, do this:
%
% \documentclass[twocolumn]{article}
% \usepackage{usenix-2e}
% and put {\rm ....} around the author names.
%
% $Id$
%
% The following definitions are modifications of standard article.sty
% definitions, arranged to do a better job of matching the USENIX
% guidelines.
% It will automatically select two-column mode and the Times-Roman
% font.
%
% USENIX papers are two-column.
% Times-Roman font is nice if you can get it (requires NFSS,
% which is in latex2e.
\if@twocolumn\else\input twocolumn.sty\fi
\usepackage{times}
%
% USENIX wants margins of: 7/8" side, 1" bottom, and 3/4" top.
% 0.25" gutter between columns.
% Gives active areas of 6.75" x 9.25"
%
\setlength{\textheight}{9.0in}
\setlength{\columnsep}{0.25in}
%%\setlength{\textwidth}{6.75in}
\setlength{\textwidth}{7.00in}
%\setlength{\footheight}{0.0in}
\setlength{\topmargin}{-0.25in}
\setlength{\headheight}{0.0in}
\setlength{\headsep}{0.0in}
\setlength{\evensidemargin}{-0.125in}
\setlength{\oddsidemargin}{-0.125in}
%
% Usenix wants no page numbers for submitted papers, so that they can
% number them themselves.
%
\pagestyle{empty}
%
% Usenix titles are in 14-point bold type, with no date, and with no
% change in the empty page headers. The whol author section is 12 point
% italic--- you must use {\rm } around the actual author names to get
% them in roman.
%
\def\maketitle{\par
\begingroup
\renewcommand\thefootnote{\fnsymbol{footnote}}%
\def\@makefnmark{\hbox to\z@{$\m@th^{\@thefnmark}$\hss}}%
\long\def\@makefntext##1{\parindent 1em\noindent
\hbox to1.8em{\hss$\m@th^{\@thefnmark}$}##1}%
\if@twocolumn
\twocolumn[\@maketitle]%
\else \newpage
\global\@topnum\z@
\@maketitle \fi\@thanks
\endgroup
\setcounter{footnote}{0}%
\let\maketitle\relax
\let\@maketitle\relax
\gdef\@thanks{}\gdef\@author{}\gdef\@title{}\let\thanks\relax}
\def\@maketitle{\newpage
\vbox to 2.5in{
\vspace*{\fill}
\vskip 2em
\begin{center}%
{\Large\bf \@title \par}%
\vskip 0.375in minus 0.300in
{\large\it
\lineskip .5em
\begin{tabular}[t]{c}\@author
\end{tabular}\par}%
\end{center}%
\par
\vspace*{\fill}
% \vskip 1.5em
}
}
%
% The abstract is preceded by a 12-pt bold centered heading
\def\abstract{\begin{center}%
{\large\bf \abstractname\vspace{-.5em}\vspace{\z@}}%
\end{center}}
\def\endabstract{}
%
% Main section titles are 12-pt bold. Others can be same or smaller.
%
\def\section{\@startsection {section}{1}{\z@}{-3.5ex plus-1ex minus
-.2ex}{2.3ex plus.2ex}{\reset@font\large\bf}}
+2
View File
@@ -0,0 +1,2 @@
Makefile
Makefile.in
+6
View File
@@ -0,0 +1,6 @@
# leave in dependency order, since common must be built first
SUBDIRS = common or config
DIST_SUBDIRS = common or config
+3
View File
@@ -0,0 +1,3 @@
Makefile
Makefile.in
.deps
@@ -0,0 +1,8 @@
noinst_LIBRARIES = libor.a
#CFLAGS = -Wall -Wpointer-arith -O2
libor_a_SOURCES = log.c crypto.c fakepoll.c util.c aes.c tortls.c
noinst_HEADERS = log.h crypto.h fakepoll.h test.h util.h aes.h torint.h tortls.h strlcpy.c strlcat.c
+819
View File
@@ -0,0 +1,819 @@
/* Copyright 2001,2002,2003 Roger Dingledine, Matej Pfajfar. */
/* See LICENSE for licensing information */
/* $Id$ */
/**
* \file aes.c
*
* \brief Implementation of a simple AES counter mode.
**/
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include "orconfig.h"
#include "aes.h"
#include "util.h"
/*======================================================================*/
/* From rijndael-alg-fst.h */
typedef uint64_t u64;
typedef uint32_t u32;
typedef uint8_t u8;
#define MAXKC (256/32)
#define MAXKB (256/8)
#define MAXNR 14
static int rijndaelKeySetupEnc(u32 rk[/*4*(Nr + 1)*/], const u8 cipherKey[], int keyBits);
static void rijndaelEncrypt(const u32 rk[/*4*(Nr + 1)*/], int Nr, const u8 pt[16], u8 ct[16]);
/*======================================================================*/
/* Interface to AES code, and counter implementation */
struct aes_cnt_cipher {
u32 rk[4*(MAXNR+1)];
int nr;
u32 counter1;
u32 counter0;
u8 buf[16];
u8 pos;
};
/**
* Helper function: set <b>cipher</b>'s internal buffer to the encrypted
* value of the current counter.
*/
static void
_aes_fill_buf(aes_cnt_cipher_t *cipher)
{
u32 counter0 = cipher->counter0;
u32 counter1 = cipher->counter1;
u8 buf[16];
memset(buf, 0, 8);
buf[15] = (counter0 >> 0) & 0xff;
buf[14] = (counter0 >> 8) & 0xff;
buf[13] = (counter0 >> 16) & 0xff;
buf[12] = (counter0 >> 24) & 0xff;
buf[11] = (counter1 >> 0) & 0xff;
buf[10] = (counter1 >> 8) & 0xff;
buf[ 9] = (counter1 >> 16) & 0xff;
buf[ 8] = (counter1 >> 24) & 0xff;
rijndaelEncrypt(cipher->rk, cipher->nr, buf, cipher->buf);
}
/**
* Return a newly allocated counter-mode AES128 cipher implementation.
*/
aes_cnt_cipher_t*
aes_new_cipher()
{
aes_cnt_cipher_t* result = tor_malloc(sizeof(aes_cnt_cipher_t));
memset(result->rk, 0, 4*(MAXNR+1));
memset(result->buf, 0, 16);
return result;
}
/** Set the key of <b>cipher</b> to <b>key</b>, which is
* <b>key_bits</b> bits long (must be 128, 192, or 256). Also resets
* the counter to 0.
*/
void
aes_set_key(aes_cnt_cipher_t *cipher, const unsigned char *key, int key_bits)
{
cipher->nr = rijndaelKeySetupEnc(cipher->rk, key, key_bits);
cipher->counter0 = 0;
cipher->counter1 = 0;
cipher->pos = 0;
_aes_fill_buf(cipher);
}
/** Release storage held by <b>cipher</b>
*/
void
aes_free_cipher(aes_cnt_cipher_t *cipher)
{
assert(cipher);
memset(cipher, 0, sizeof(cipher));
free(cipher);
}
/** Encrypt <b>len</b> bytes from <b>input</b>, storing the result in
* <b>output</b>. Uses the key in <b>cipher</b>, and advances the counter
* by <b>len</b> bytes as it encrypts.
*/
void
aes_crypt(aes_cnt_cipher_t *cipher, const char *input, int len, char *output)
{
int c = cipher->pos;
if (!len) return;
while (1) {
do {
if (len-- == 0) { cipher->pos = c; return; }
*(output++) = *(input++) ^ cipher->buf[c];
} while (++c != 16);
cipher->pos = c = 0;
if (! ++cipher->counter0)
++cipher->counter1;
_aes_fill_buf(cipher);
}
}
/** Return the current value of <b>cipher</b>'s counter. */
u64
aes_get_counter(aes_cnt_cipher_t *cipher)
{
u64 counter = cipher->pos;
counter |= ((u64)cipher->counter0) << 4;
counter |= ((u64)cipher->counter1) << 36;
return counter;
}
/** Set <b>cipher</b>'s counter to <b>counter</b>. */
void
aes_set_counter(aes_cnt_cipher_t *cipher, u64 counter)
{
cipher->pos = (u8)(counter & 0x0f);
cipher->counter0 = (u32) ((counter >> 4) & 0xffffffff);
cipher->counter1 = (u32) (counter >> 36);
_aes_fill_buf(cipher);
}
/** Increment <b>cipher</b>'s counter by <b>delta</b>. */
void
aes_adjust_counter(aes_cnt_cipher_t *cipher, long delta)
{
u64 counter = aes_get_counter(cipher);
counter += delta;
aes_set_counter(cipher, counter);
}
/*======================================================================*/
/* From rijndael-alg-fst.c */
/**
* rijndael-alg-fst.c
*
* @version 3.0 (December 2000)
*
* Optimised ANSI C code for the Rijndael cipher (now AES)
*
* @author Vincent Rijmen <vincent.rijmen@esat.kuleuven.ac.be>
* @author Antoon Bosselaers <antoon.bosselaers@esat.kuleuven.ac.be>
* @author Paulo Barreto <paulo.barreto@terra.com.br>
*
* This code is hereby placed in the public domain.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
Te0[x] = S [x].[02, 01, 01, 03];
Te1[x] = S [x].[03, 02, 01, 01];
Te2[x] = S [x].[01, 03, 02, 01];
Te3[x] = S [x].[01, 01, 03, 02];
Te4[x] = S [x].[01, 01, 01, 01];
Td0[x] = Si[x].[0e, 09, 0d, 0b];
Td1[x] = Si[x].[0b, 0e, 09, 0d];
Td2[x] = Si[x].[0d, 0b, 0e, 09];
Td3[x] = Si[x].[09, 0d, 0b, 0e];
Td4[x] = Si[x].[01, 01, 01, 01];
*/
static const u32 Te0[256] = {
0xc66363a5U, 0xf87c7c84U, 0xee777799U, 0xf67b7b8dU,
0xfff2f20dU, 0xd66b6bbdU, 0xde6f6fb1U, 0x91c5c554U,
0x60303050U, 0x02010103U, 0xce6767a9U, 0x562b2b7dU,
0xe7fefe19U, 0xb5d7d762U, 0x4dababe6U, 0xec76769aU,
0x8fcaca45U, 0x1f82829dU, 0x89c9c940U, 0xfa7d7d87U,
0xeffafa15U, 0xb25959ebU, 0x8e4747c9U, 0xfbf0f00bU,
0x41adadecU, 0xb3d4d467U, 0x5fa2a2fdU, 0x45afafeaU,
0x239c9cbfU, 0x53a4a4f7U, 0xe4727296U, 0x9bc0c05bU,
0x75b7b7c2U, 0xe1fdfd1cU, 0x3d9393aeU, 0x4c26266aU,
0x6c36365aU, 0x7e3f3f41U, 0xf5f7f702U, 0x83cccc4fU,
0x6834345cU, 0x51a5a5f4U, 0xd1e5e534U, 0xf9f1f108U,
0xe2717193U, 0xabd8d873U, 0x62313153U, 0x2a15153fU,
0x0804040cU, 0x95c7c752U, 0x46232365U, 0x9dc3c35eU,
0x30181828U, 0x379696a1U, 0x0a05050fU, 0x2f9a9ab5U,
0x0e070709U, 0x24121236U, 0x1b80809bU, 0xdfe2e23dU,
0xcdebeb26U, 0x4e272769U, 0x7fb2b2cdU, 0xea75759fU,
0x1209091bU, 0x1d83839eU, 0x582c2c74U, 0x341a1a2eU,
0x361b1b2dU, 0xdc6e6eb2U, 0xb45a5aeeU, 0x5ba0a0fbU,
0xa45252f6U, 0x763b3b4dU, 0xb7d6d661U, 0x7db3b3ceU,
0x5229297bU, 0xdde3e33eU, 0x5e2f2f71U, 0x13848497U,
0xa65353f5U, 0xb9d1d168U, 0x00000000U, 0xc1eded2cU,
0x40202060U, 0xe3fcfc1fU, 0x79b1b1c8U, 0xb65b5bedU,
0xd46a6abeU, 0x8dcbcb46U, 0x67bebed9U, 0x7239394bU,
0x944a4adeU, 0x984c4cd4U, 0xb05858e8U, 0x85cfcf4aU,
0xbbd0d06bU, 0xc5efef2aU, 0x4faaaae5U, 0xedfbfb16U,
0x864343c5U, 0x9a4d4dd7U, 0x66333355U, 0x11858594U,
0x8a4545cfU, 0xe9f9f910U, 0x04020206U, 0xfe7f7f81U,
0xa05050f0U, 0x783c3c44U, 0x259f9fbaU, 0x4ba8a8e3U,
0xa25151f3U, 0x5da3a3feU, 0x804040c0U, 0x058f8f8aU,
0x3f9292adU, 0x219d9dbcU, 0x70383848U, 0xf1f5f504U,
0x63bcbcdfU, 0x77b6b6c1U, 0xafdada75U, 0x42212163U,
0x20101030U, 0xe5ffff1aU, 0xfdf3f30eU, 0xbfd2d26dU,
0x81cdcd4cU, 0x180c0c14U, 0x26131335U, 0xc3ecec2fU,
0xbe5f5fe1U, 0x359797a2U, 0x884444ccU, 0x2e171739U,
0x93c4c457U, 0x55a7a7f2U, 0xfc7e7e82U, 0x7a3d3d47U,
0xc86464acU, 0xba5d5de7U, 0x3219192bU, 0xe6737395U,
0xc06060a0U, 0x19818198U, 0x9e4f4fd1U, 0xa3dcdc7fU,
0x44222266U, 0x542a2a7eU, 0x3b9090abU, 0x0b888883U,
0x8c4646caU, 0xc7eeee29U, 0x6bb8b8d3U, 0x2814143cU,
0xa7dede79U, 0xbc5e5ee2U, 0x160b0b1dU, 0xaddbdb76U,
0xdbe0e03bU, 0x64323256U, 0x743a3a4eU, 0x140a0a1eU,
0x924949dbU, 0x0c06060aU, 0x4824246cU, 0xb85c5ce4U,
0x9fc2c25dU, 0xbdd3d36eU, 0x43acacefU, 0xc46262a6U,
0x399191a8U, 0x319595a4U, 0xd3e4e437U, 0xf279798bU,
0xd5e7e732U, 0x8bc8c843U, 0x6e373759U, 0xda6d6db7U,
0x018d8d8cU, 0xb1d5d564U, 0x9c4e4ed2U, 0x49a9a9e0U,
0xd86c6cb4U, 0xac5656faU, 0xf3f4f407U, 0xcfeaea25U,
0xca6565afU, 0xf47a7a8eU, 0x47aeaee9U, 0x10080818U,
0x6fbabad5U, 0xf0787888U, 0x4a25256fU, 0x5c2e2e72U,
0x381c1c24U, 0x57a6a6f1U, 0x73b4b4c7U, 0x97c6c651U,
0xcbe8e823U, 0xa1dddd7cU, 0xe874749cU, 0x3e1f1f21U,
0x964b4bddU, 0x61bdbddcU, 0x0d8b8b86U, 0x0f8a8a85U,
0xe0707090U, 0x7c3e3e42U, 0x71b5b5c4U, 0xcc6666aaU,
0x904848d8U, 0x06030305U, 0xf7f6f601U, 0x1c0e0e12U,
0xc26161a3U, 0x6a35355fU, 0xae5757f9U, 0x69b9b9d0U,
0x17868691U, 0x99c1c158U, 0x3a1d1d27U, 0x279e9eb9U,
0xd9e1e138U, 0xebf8f813U, 0x2b9898b3U, 0x22111133U,
0xd26969bbU, 0xa9d9d970U, 0x078e8e89U, 0x339494a7U,
0x2d9b9bb6U, 0x3c1e1e22U, 0x15878792U, 0xc9e9e920U,
0x87cece49U, 0xaa5555ffU, 0x50282878U, 0xa5dfdf7aU,
0x038c8c8fU, 0x59a1a1f8U, 0x09898980U, 0x1a0d0d17U,
0x65bfbfdaU, 0xd7e6e631U, 0x844242c6U, 0xd06868b8U,
0x824141c3U, 0x299999b0U, 0x5a2d2d77U, 0x1e0f0f11U,
0x7bb0b0cbU, 0xa85454fcU, 0x6dbbbbd6U, 0x2c16163aU,
};
static const u32 Te1[256] = {
0xa5c66363U, 0x84f87c7cU, 0x99ee7777U, 0x8df67b7bU,
0x0dfff2f2U, 0xbdd66b6bU, 0xb1de6f6fU, 0x5491c5c5U,
0x50603030U, 0x03020101U, 0xa9ce6767U, 0x7d562b2bU,
0x19e7fefeU, 0x62b5d7d7U, 0xe64dababU, 0x9aec7676U,
0x458fcacaU, 0x9d1f8282U, 0x4089c9c9U, 0x87fa7d7dU,
0x15effafaU, 0xebb25959U, 0xc98e4747U, 0x0bfbf0f0U,
0xec41adadU, 0x67b3d4d4U, 0xfd5fa2a2U, 0xea45afafU,
0xbf239c9cU, 0xf753a4a4U, 0x96e47272U, 0x5b9bc0c0U,
0xc275b7b7U, 0x1ce1fdfdU, 0xae3d9393U, 0x6a4c2626U,
0x5a6c3636U, 0x417e3f3fU, 0x02f5f7f7U, 0x4f83ccccU,
0x5c683434U, 0xf451a5a5U, 0x34d1e5e5U, 0x08f9f1f1U,
0x93e27171U, 0x73abd8d8U, 0x53623131U, 0x3f2a1515U,
0x0c080404U, 0x5295c7c7U, 0x65462323U, 0x5e9dc3c3U,
0x28301818U, 0xa1379696U, 0x0f0a0505U, 0xb52f9a9aU,
0x090e0707U, 0x36241212U, 0x9b1b8080U, 0x3ddfe2e2U,
0x26cdebebU, 0x694e2727U, 0xcd7fb2b2U, 0x9fea7575U,
0x1b120909U, 0x9e1d8383U, 0x74582c2cU, 0x2e341a1aU,
0x2d361b1bU, 0xb2dc6e6eU, 0xeeb45a5aU, 0xfb5ba0a0U,
0xf6a45252U, 0x4d763b3bU, 0x61b7d6d6U, 0xce7db3b3U,
0x7b522929U, 0x3edde3e3U, 0x715e2f2fU, 0x97138484U,
0xf5a65353U, 0x68b9d1d1U, 0x00000000U, 0x2cc1ededU,
0x60402020U, 0x1fe3fcfcU, 0xc879b1b1U, 0xedb65b5bU,
0xbed46a6aU, 0x468dcbcbU, 0xd967bebeU, 0x4b723939U,
0xde944a4aU, 0xd4984c4cU, 0xe8b05858U, 0x4a85cfcfU,
0x6bbbd0d0U, 0x2ac5efefU, 0xe54faaaaU, 0x16edfbfbU,
0xc5864343U, 0xd79a4d4dU, 0x55663333U, 0x94118585U,
0xcf8a4545U, 0x10e9f9f9U, 0x06040202U, 0x81fe7f7fU,
0xf0a05050U, 0x44783c3cU, 0xba259f9fU, 0xe34ba8a8U,
0xf3a25151U, 0xfe5da3a3U, 0xc0804040U, 0x8a058f8fU,
0xad3f9292U, 0xbc219d9dU, 0x48703838U, 0x04f1f5f5U,
0xdf63bcbcU, 0xc177b6b6U, 0x75afdadaU, 0x63422121U,
0x30201010U, 0x1ae5ffffU, 0x0efdf3f3U, 0x6dbfd2d2U,
0x4c81cdcdU, 0x14180c0cU, 0x35261313U, 0x2fc3ececU,
0xe1be5f5fU, 0xa2359797U, 0xcc884444U, 0x392e1717U,
0x5793c4c4U, 0xf255a7a7U, 0x82fc7e7eU, 0x477a3d3dU,
0xacc86464U, 0xe7ba5d5dU, 0x2b321919U, 0x95e67373U,
0xa0c06060U, 0x98198181U, 0xd19e4f4fU, 0x7fa3dcdcU,
0x66442222U, 0x7e542a2aU, 0xab3b9090U, 0x830b8888U,
0xca8c4646U, 0x29c7eeeeU, 0xd36bb8b8U, 0x3c281414U,
0x79a7dedeU, 0xe2bc5e5eU, 0x1d160b0bU, 0x76addbdbU,
0x3bdbe0e0U, 0x56643232U, 0x4e743a3aU, 0x1e140a0aU,
0xdb924949U, 0x0a0c0606U, 0x6c482424U, 0xe4b85c5cU,
0x5d9fc2c2U, 0x6ebdd3d3U, 0xef43acacU, 0xa6c46262U,
0xa8399191U, 0xa4319595U, 0x37d3e4e4U, 0x8bf27979U,
0x32d5e7e7U, 0x438bc8c8U, 0x596e3737U, 0xb7da6d6dU,
0x8c018d8dU, 0x64b1d5d5U, 0xd29c4e4eU, 0xe049a9a9U,
0xb4d86c6cU, 0xfaac5656U, 0x07f3f4f4U, 0x25cfeaeaU,
0xafca6565U, 0x8ef47a7aU, 0xe947aeaeU, 0x18100808U,
0xd56fbabaU, 0x88f07878U, 0x6f4a2525U, 0x725c2e2eU,
0x24381c1cU, 0xf157a6a6U, 0xc773b4b4U, 0x5197c6c6U,
0x23cbe8e8U, 0x7ca1ddddU, 0x9ce87474U, 0x213e1f1fU,
0xdd964b4bU, 0xdc61bdbdU, 0x860d8b8bU, 0x850f8a8aU,
0x90e07070U, 0x427c3e3eU, 0xc471b5b5U, 0xaacc6666U,
0xd8904848U, 0x05060303U, 0x01f7f6f6U, 0x121c0e0eU,
0xa3c26161U, 0x5f6a3535U, 0xf9ae5757U, 0xd069b9b9U,
0x91178686U, 0x5899c1c1U, 0x273a1d1dU, 0xb9279e9eU,
0x38d9e1e1U, 0x13ebf8f8U, 0xb32b9898U, 0x33221111U,
0xbbd26969U, 0x70a9d9d9U, 0x89078e8eU, 0xa7339494U,
0xb62d9b9bU, 0x223c1e1eU, 0x92158787U, 0x20c9e9e9U,
0x4987ceceU, 0xffaa5555U, 0x78502828U, 0x7aa5dfdfU,
0x8f038c8cU, 0xf859a1a1U, 0x80098989U, 0x171a0d0dU,
0xda65bfbfU, 0x31d7e6e6U, 0xc6844242U, 0xb8d06868U,
0xc3824141U, 0xb0299999U, 0x775a2d2dU, 0x111e0f0fU,
0xcb7bb0b0U, 0xfca85454U, 0xd66dbbbbU, 0x3a2c1616U,
};
static const u32 Te2[256] = {
0x63a5c663U, 0x7c84f87cU, 0x7799ee77U, 0x7b8df67bU,
0xf20dfff2U, 0x6bbdd66bU, 0x6fb1de6fU, 0xc55491c5U,
0x30506030U, 0x01030201U, 0x67a9ce67U, 0x2b7d562bU,
0xfe19e7feU, 0xd762b5d7U, 0xabe64dabU, 0x769aec76U,
0xca458fcaU, 0x829d1f82U, 0xc94089c9U, 0x7d87fa7dU,
0xfa15effaU, 0x59ebb259U, 0x47c98e47U, 0xf00bfbf0U,
0xadec41adU, 0xd467b3d4U, 0xa2fd5fa2U, 0xafea45afU,
0x9cbf239cU, 0xa4f753a4U, 0x7296e472U, 0xc05b9bc0U,
0xb7c275b7U, 0xfd1ce1fdU, 0x93ae3d93U, 0x266a4c26U,
0x365a6c36U, 0x3f417e3fU, 0xf702f5f7U, 0xcc4f83ccU,
0x345c6834U, 0xa5f451a5U, 0xe534d1e5U, 0xf108f9f1U,
0x7193e271U, 0xd873abd8U, 0x31536231U, 0x153f2a15U,
0x040c0804U, 0xc75295c7U, 0x23654623U, 0xc35e9dc3U,
0x18283018U, 0x96a13796U, 0x050f0a05U, 0x9ab52f9aU,
0x07090e07U, 0x12362412U, 0x809b1b80U, 0xe23ddfe2U,
0xeb26cdebU, 0x27694e27U, 0xb2cd7fb2U, 0x759fea75U,
0x091b1209U, 0x839e1d83U, 0x2c74582cU, 0x1a2e341aU,
0x1b2d361bU, 0x6eb2dc6eU, 0x5aeeb45aU, 0xa0fb5ba0U,
0x52f6a452U, 0x3b4d763bU, 0xd661b7d6U, 0xb3ce7db3U,
0x297b5229U, 0xe33edde3U, 0x2f715e2fU, 0x84971384U,
0x53f5a653U, 0xd168b9d1U, 0x00000000U, 0xed2cc1edU,
0x20604020U, 0xfc1fe3fcU, 0xb1c879b1U, 0x5bedb65bU,
0x6abed46aU, 0xcb468dcbU, 0xbed967beU, 0x394b7239U,
0x4ade944aU, 0x4cd4984cU, 0x58e8b058U, 0xcf4a85cfU,
0xd06bbbd0U, 0xef2ac5efU, 0xaae54faaU, 0xfb16edfbU,
0x43c58643U, 0x4dd79a4dU, 0x33556633U, 0x85941185U,
0x45cf8a45U, 0xf910e9f9U, 0x02060402U, 0x7f81fe7fU,
0x50f0a050U, 0x3c44783cU, 0x9fba259fU, 0xa8e34ba8U,
0x51f3a251U, 0xa3fe5da3U, 0x40c08040U, 0x8f8a058fU,
0x92ad3f92U, 0x9dbc219dU, 0x38487038U, 0xf504f1f5U,
0xbcdf63bcU, 0xb6c177b6U, 0xda75afdaU, 0x21634221U,
0x10302010U, 0xff1ae5ffU, 0xf30efdf3U, 0xd26dbfd2U,
0xcd4c81cdU, 0x0c14180cU, 0x13352613U, 0xec2fc3ecU,
0x5fe1be5fU, 0x97a23597U, 0x44cc8844U, 0x17392e17U,
0xc45793c4U, 0xa7f255a7U, 0x7e82fc7eU, 0x3d477a3dU,
0x64acc864U, 0x5de7ba5dU, 0x192b3219U, 0x7395e673U,
0x60a0c060U, 0x81981981U, 0x4fd19e4fU, 0xdc7fa3dcU,
0x22664422U, 0x2a7e542aU, 0x90ab3b90U, 0x88830b88U,
0x46ca8c46U, 0xee29c7eeU, 0xb8d36bb8U, 0x143c2814U,
0xde79a7deU, 0x5ee2bc5eU, 0x0b1d160bU, 0xdb76addbU,
0xe03bdbe0U, 0x32566432U, 0x3a4e743aU, 0x0a1e140aU,
0x49db9249U, 0x060a0c06U, 0x246c4824U, 0x5ce4b85cU,
0xc25d9fc2U, 0xd36ebdd3U, 0xacef43acU, 0x62a6c462U,
0x91a83991U, 0x95a43195U, 0xe437d3e4U, 0x798bf279U,
0xe732d5e7U, 0xc8438bc8U, 0x37596e37U, 0x6db7da6dU,
0x8d8c018dU, 0xd564b1d5U, 0x4ed29c4eU, 0xa9e049a9U,
0x6cb4d86cU, 0x56faac56U, 0xf407f3f4U, 0xea25cfeaU,
0x65afca65U, 0x7a8ef47aU, 0xaee947aeU, 0x08181008U,
0xbad56fbaU, 0x7888f078U, 0x256f4a25U, 0x2e725c2eU,
0x1c24381cU, 0xa6f157a6U, 0xb4c773b4U, 0xc65197c6U,
0xe823cbe8U, 0xdd7ca1ddU, 0x749ce874U, 0x1f213e1fU,
0x4bdd964bU, 0xbddc61bdU, 0x8b860d8bU, 0x8a850f8aU,
0x7090e070U, 0x3e427c3eU, 0xb5c471b5U, 0x66aacc66U,
0x48d89048U, 0x03050603U, 0xf601f7f6U, 0x0e121c0eU,
0x61a3c261U, 0x355f6a35U, 0x57f9ae57U, 0xb9d069b9U,
0x86911786U, 0xc15899c1U, 0x1d273a1dU, 0x9eb9279eU,
0xe138d9e1U, 0xf813ebf8U, 0x98b32b98U, 0x11332211U,
0x69bbd269U, 0xd970a9d9U, 0x8e89078eU, 0x94a73394U,
0x9bb62d9bU, 0x1e223c1eU, 0x87921587U, 0xe920c9e9U,
0xce4987ceU, 0x55ffaa55U, 0x28785028U, 0xdf7aa5dfU,
0x8c8f038cU, 0xa1f859a1U, 0x89800989U, 0x0d171a0dU,
0xbfda65bfU, 0xe631d7e6U, 0x42c68442U, 0x68b8d068U,
0x41c38241U, 0x99b02999U, 0x2d775a2dU, 0x0f111e0fU,
0xb0cb7bb0U, 0x54fca854U, 0xbbd66dbbU, 0x163a2c16U,
};
static const u32 Te3[256] = {
0x6363a5c6U, 0x7c7c84f8U, 0x777799eeU, 0x7b7b8df6U,
0xf2f20dffU, 0x6b6bbdd6U, 0x6f6fb1deU, 0xc5c55491U,
0x30305060U, 0x01010302U, 0x6767a9ceU, 0x2b2b7d56U,
0xfefe19e7U, 0xd7d762b5U, 0xababe64dU, 0x76769aecU,
0xcaca458fU, 0x82829d1fU, 0xc9c94089U, 0x7d7d87faU,
0xfafa15efU, 0x5959ebb2U, 0x4747c98eU, 0xf0f00bfbU,
0xadadec41U, 0xd4d467b3U, 0xa2a2fd5fU, 0xafafea45U,
0x9c9cbf23U, 0xa4a4f753U, 0x727296e4U, 0xc0c05b9bU,
0xb7b7c275U, 0xfdfd1ce1U, 0x9393ae3dU, 0x26266a4cU,
0x36365a6cU, 0x3f3f417eU, 0xf7f702f5U, 0xcccc4f83U,
0x34345c68U, 0xa5a5f451U, 0xe5e534d1U, 0xf1f108f9U,
0x717193e2U, 0xd8d873abU, 0x31315362U, 0x15153f2aU,
0x04040c08U, 0xc7c75295U, 0x23236546U, 0xc3c35e9dU,
0x18182830U, 0x9696a137U, 0x05050f0aU, 0x9a9ab52fU,
0x0707090eU, 0x12123624U, 0x80809b1bU, 0xe2e23ddfU,
0xebeb26cdU, 0x2727694eU, 0xb2b2cd7fU, 0x75759feaU,
0x09091b12U, 0x83839e1dU, 0x2c2c7458U, 0x1a1a2e34U,
0x1b1b2d36U, 0x6e6eb2dcU, 0x5a5aeeb4U, 0xa0a0fb5bU,
0x5252f6a4U, 0x3b3b4d76U, 0xd6d661b7U, 0xb3b3ce7dU,
0x29297b52U, 0xe3e33eddU, 0x2f2f715eU, 0x84849713U,
0x5353f5a6U, 0xd1d168b9U, 0x00000000U, 0xeded2cc1U,
0x20206040U, 0xfcfc1fe3U, 0xb1b1c879U, 0x5b5bedb6U,
0x6a6abed4U, 0xcbcb468dU, 0xbebed967U, 0x39394b72U,
0x4a4ade94U, 0x4c4cd498U, 0x5858e8b0U, 0xcfcf4a85U,
0xd0d06bbbU, 0xefef2ac5U, 0xaaaae54fU, 0xfbfb16edU,
0x4343c586U, 0x4d4dd79aU, 0x33335566U, 0x85859411U,
0x4545cf8aU, 0xf9f910e9U, 0x02020604U, 0x7f7f81feU,
0x5050f0a0U, 0x3c3c4478U, 0x9f9fba25U, 0xa8a8e34bU,
0x5151f3a2U, 0xa3a3fe5dU, 0x4040c080U, 0x8f8f8a05U,
0x9292ad3fU, 0x9d9dbc21U, 0x38384870U, 0xf5f504f1U,
0xbcbcdf63U, 0xb6b6c177U, 0xdada75afU, 0x21216342U,
0x10103020U, 0xffff1ae5U, 0xf3f30efdU, 0xd2d26dbfU,
0xcdcd4c81U, 0x0c0c1418U, 0x13133526U, 0xecec2fc3U,
0x5f5fe1beU, 0x9797a235U, 0x4444cc88U, 0x1717392eU,
0xc4c45793U, 0xa7a7f255U, 0x7e7e82fcU, 0x3d3d477aU,
0x6464acc8U, 0x5d5de7baU, 0x19192b32U, 0x737395e6U,
0x6060a0c0U, 0x81819819U, 0x4f4fd19eU, 0xdcdc7fa3U,
0x22226644U, 0x2a2a7e54U, 0x9090ab3bU, 0x8888830bU,
0x4646ca8cU, 0xeeee29c7U, 0xb8b8d36bU, 0x14143c28U,
0xdede79a7U, 0x5e5ee2bcU, 0x0b0b1d16U, 0xdbdb76adU,
0xe0e03bdbU, 0x32325664U, 0x3a3a4e74U, 0x0a0a1e14U,
0x4949db92U, 0x06060a0cU, 0x24246c48U, 0x5c5ce4b8U,
0xc2c25d9fU, 0xd3d36ebdU, 0xacacef43U, 0x6262a6c4U,
0x9191a839U, 0x9595a431U, 0xe4e437d3U, 0x79798bf2U,
0xe7e732d5U, 0xc8c8438bU, 0x3737596eU, 0x6d6db7daU,
0x8d8d8c01U, 0xd5d564b1U, 0x4e4ed29cU, 0xa9a9e049U,
0x6c6cb4d8U, 0x5656faacU, 0xf4f407f3U, 0xeaea25cfU,
0x6565afcaU, 0x7a7a8ef4U, 0xaeaee947U, 0x08081810U,
0xbabad56fU, 0x787888f0U, 0x25256f4aU, 0x2e2e725cU,
0x1c1c2438U, 0xa6a6f157U, 0xb4b4c773U, 0xc6c65197U,
0xe8e823cbU, 0xdddd7ca1U, 0x74749ce8U, 0x1f1f213eU,
0x4b4bdd96U, 0xbdbddc61U, 0x8b8b860dU, 0x8a8a850fU,
0x707090e0U, 0x3e3e427cU, 0xb5b5c471U, 0x6666aaccU,
0x4848d890U, 0x03030506U, 0xf6f601f7U, 0x0e0e121cU,
0x6161a3c2U, 0x35355f6aU, 0x5757f9aeU, 0xb9b9d069U,
0x86869117U, 0xc1c15899U, 0x1d1d273aU, 0x9e9eb927U,
0xe1e138d9U, 0xf8f813ebU, 0x9898b32bU, 0x11113322U,
0x6969bbd2U, 0xd9d970a9U, 0x8e8e8907U, 0x9494a733U,
0x9b9bb62dU, 0x1e1e223cU, 0x87879215U, 0xe9e920c9U,
0xcece4987U, 0x5555ffaaU, 0x28287850U, 0xdfdf7aa5U,
0x8c8c8f03U, 0xa1a1f859U, 0x89898009U, 0x0d0d171aU,
0xbfbfda65U, 0xe6e631d7U, 0x4242c684U, 0x6868b8d0U,
0x4141c382U, 0x9999b029U, 0x2d2d775aU, 0x0f0f111eU,
0xb0b0cb7bU, 0x5454fca8U, 0xbbbbd66dU, 0x16163a2cU,
};
static const u32 Te4[256] = {
0x63636363U, 0x7c7c7c7cU, 0x77777777U, 0x7b7b7b7bU,
0xf2f2f2f2U, 0x6b6b6b6bU, 0x6f6f6f6fU, 0xc5c5c5c5U,
0x30303030U, 0x01010101U, 0x67676767U, 0x2b2b2b2bU,
0xfefefefeU, 0xd7d7d7d7U, 0xababababU, 0x76767676U,
0xcacacacaU, 0x82828282U, 0xc9c9c9c9U, 0x7d7d7d7dU,
0xfafafafaU, 0x59595959U, 0x47474747U, 0xf0f0f0f0U,
0xadadadadU, 0xd4d4d4d4U, 0xa2a2a2a2U, 0xafafafafU,
0x9c9c9c9cU, 0xa4a4a4a4U, 0x72727272U, 0xc0c0c0c0U,
0xb7b7b7b7U, 0xfdfdfdfdU, 0x93939393U, 0x26262626U,
0x36363636U, 0x3f3f3f3fU, 0xf7f7f7f7U, 0xccccccccU,
0x34343434U, 0xa5a5a5a5U, 0xe5e5e5e5U, 0xf1f1f1f1U,
0x71717171U, 0xd8d8d8d8U, 0x31313131U, 0x15151515U,
0x04040404U, 0xc7c7c7c7U, 0x23232323U, 0xc3c3c3c3U,
0x18181818U, 0x96969696U, 0x05050505U, 0x9a9a9a9aU,
0x07070707U, 0x12121212U, 0x80808080U, 0xe2e2e2e2U,
0xebebebebU, 0x27272727U, 0xb2b2b2b2U, 0x75757575U,
0x09090909U, 0x83838383U, 0x2c2c2c2cU, 0x1a1a1a1aU,
0x1b1b1b1bU, 0x6e6e6e6eU, 0x5a5a5a5aU, 0xa0a0a0a0U,
0x52525252U, 0x3b3b3b3bU, 0xd6d6d6d6U, 0xb3b3b3b3U,
0x29292929U, 0xe3e3e3e3U, 0x2f2f2f2fU, 0x84848484U,
0x53535353U, 0xd1d1d1d1U, 0x00000000U, 0xededededU,
0x20202020U, 0xfcfcfcfcU, 0xb1b1b1b1U, 0x5b5b5b5bU,
0x6a6a6a6aU, 0xcbcbcbcbU, 0xbebebebeU, 0x39393939U,
0x4a4a4a4aU, 0x4c4c4c4cU, 0x58585858U, 0xcfcfcfcfU,
0xd0d0d0d0U, 0xefefefefU, 0xaaaaaaaaU, 0xfbfbfbfbU,
0x43434343U, 0x4d4d4d4dU, 0x33333333U, 0x85858585U,
0x45454545U, 0xf9f9f9f9U, 0x02020202U, 0x7f7f7f7fU,
0x50505050U, 0x3c3c3c3cU, 0x9f9f9f9fU, 0xa8a8a8a8U,
0x51515151U, 0xa3a3a3a3U, 0x40404040U, 0x8f8f8f8fU,
0x92929292U, 0x9d9d9d9dU, 0x38383838U, 0xf5f5f5f5U,
0xbcbcbcbcU, 0xb6b6b6b6U, 0xdadadadaU, 0x21212121U,
0x10101010U, 0xffffffffU, 0xf3f3f3f3U, 0xd2d2d2d2U,
0xcdcdcdcdU, 0x0c0c0c0cU, 0x13131313U, 0xececececU,
0x5f5f5f5fU, 0x97979797U, 0x44444444U, 0x17171717U,
0xc4c4c4c4U, 0xa7a7a7a7U, 0x7e7e7e7eU, 0x3d3d3d3dU,
0x64646464U, 0x5d5d5d5dU, 0x19191919U, 0x73737373U,
0x60606060U, 0x81818181U, 0x4f4f4f4fU, 0xdcdcdcdcU,
0x22222222U, 0x2a2a2a2aU, 0x90909090U, 0x88888888U,
0x46464646U, 0xeeeeeeeeU, 0xb8b8b8b8U, 0x14141414U,
0xdedededeU, 0x5e5e5e5eU, 0x0b0b0b0bU, 0xdbdbdbdbU,
0xe0e0e0e0U, 0x32323232U, 0x3a3a3a3aU, 0x0a0a0a0aU,
0x49494949U, 0x06060606U, 0x24242424U, 0x5c5c5c5cU,
0xc2c2c2c2U, 0xd3d3d3d3U, 0xacacacacU, 0x62626262U,
0x91919191U, 0x95959595U, 0xe4e4e4e4U, 0x79797979U,
0xe7e7e7e7U, 0xc8c8c8c8U, 0x37373737U, 0x6d6d6d6dU,
0x8d8d8d8dU, 0xd5d5d5d5U, 0x4e4e4e4eU, 0xa9a9a9a9U,
0x6c6c6c6cU, 0x56565656U, 0xf4f4f4f4U, 0xeaeaeaeaU,
0x65656565U, 0x7a7a7a7aU, 0xaeaeaeaeU, 0x08080808U,
0xbabababaU, 0x78787878U, 0x25252525U, 0x2e2e2e2eU,
0x1c1c1c1cU, 0xa6a6a6a6U, 0xb4b4b4b4U, 0xc6c6c6c6U,
0xe8e8e8e8U, 0xddddddddU, 0x74747474U, 0x1f1f1f1fU,
0x4b4b4b4bU, 0xbdbdbdbdU, 0x8b8b8b8bU, 0x8a8a8a8aU,
0x70707070U, 0x3e3e3e3eU, 0xb5b5b5b5U, 0x66666666U,
0x48484848U, 0x03030303U, 0xf6f6f6f6U, 0x0e0e0e0eU,
0x61616161U, 0x35353535U, 0x57575757U, 0xb9b9b9b9U,
0x86868686U, 0xc1c1c1c1U, 0x1d1d1d1dU, 0x9e9e9e9eU,
0xe1e1e1e1U, 0xf8f8f8f8U, 0x98989898U, 0x11111111U,
0x69696969U, 0xd9d9d9d9U, 0x8e8e8e8eU, 0x94949494U,
0x9b9b9b9bU, 0x1e1e1e1eU, 0x87878787U, 0xe9e9e9e9U,
0xcecececeU, 0x55555555U, 0x28282828U, 0xdfdfdfdfU,
0x8c8c8c8cU, 0xa1a1a1a1U, 0x89898989U, 0x0d0d0d0dU,
0xbfbfbfbfU, 0xe6e6e6e6U, 0x42424242U, 0x68686868U,
0x41414141U, 0x99999999U, 0x2d2d2d2dU, 0x0f0f0f0fU,
0xb0b0b0b0U, 0x54545454U, 0xbbbbbbbbU, 0x16161616U,
};
static const u32 rcon[] = {
0x01000000, 0x02000000, 0x04000000, 0x08000000,
0x10000000, 0x20000000, 0x40000000, 0x80000000,
0x1B000000, 0x36000000, /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */
};
#define SWAP(x) (_lrotl(x, 8) & 0x00ff00ff | _lrotr(x, 8) & 0xff00ff00)
#ifdef _MSC_VER
#define GETU32(p) SWAP(*((u32 *)(p)))
#define PUTU32(ct, st) { *((u32 *)(ct)) = SWAP((st)); }
#else
#define GETU32(pt) (((u32)(pt)[0] << 24) ^ ((u32)(pt)[1] << 16) ^ ((u32)(pt)[2] << 8) ^ ((u32)(pt)[3]))
#define PUTU32(ct, st) { (ct)[0] = (u8)((st) >> 24); (ct)[1] = (u8)((st) >> 16); (ct)[2] = (u8)((st) >> 8); (ct)[3] = (u8)(st); }
#endif
/**
* Expand the cipher key into the encryption key schedule.
*
* @return the number of rounds for the given cipher key size.
*/
int rijndaelKeySetupEnc(u32 rk[/*4*(Nr + 1)*/], const u8 cipherKey[], int keyBits) {
int i = 0;
u32 temp;
rk[0] = GETU32(cipherKey );
rk[1] = GETU32(cipherKey + 4);
rk[2] = GETU32(cipherKey + 8);
rk[3] = GETU32(cipherKey + 12);
if (keyBits == 128) {
for (;;) {
temp = rk[3];
rk[4] = rk[0] ^
(Te4[(temp >> 16) & 0xff] & 0xff000000) ^
(Te4[(temp >> 8) & 0xff] & 0x00ff0000) ^
(Te4[(temp ) & 0xff] & 0x0000ff00) ^
(Te4[(temp >> 24) ] & 0x000000ff) ^
rcon[i];
rk[5] = rk[1] ^ rk[4];
rk[6] = rk[2] ^ rk[5];
rk[7] = rk[3] ^ rk[6];
if (++i == 10) {
return 10;
}
rk += 4;
}
}
rk[4] = GETU32(cipherKey + 16);
rk[5] = GETU32(cipherKey + 20);
if (keyBits == 192) {
for (;;) {
temp = rk[ 5];
rk[ 6] = rk[ 0] ^
(Te4[(temp >> 16) & 0xff] & 0xff000000) ^
(Te4[(temp >> 8) & 0xff] & 0x00ff0000) ^
(Te4[(temp ) & 0xff] & 0x0000ff00) ^
(Te4[(temp >> 24) ] & 0x000000ff) ^
rcon[i];
rk[ 7] = rk[ 1] ^ rk[ 6];
rk[ 8] = rk[ 2] ^ rk[ 7];
rk[ 9] = rk[ 3] ^ rk[ 8];
if (++i == 8) {
return 12;
}
rk[10] = rk[ 4] ^ rk[ 9];
rk[11] = rk[ 5] ^ rk[10];
rk += 6;
}
}
rk[6] = GETU32(cipherKey + 24);
rk[7] = GETU32(cipherKey + 28);
if (keyBits == 256) {
for (;;) {
temp = rk[ 7];
rk[ 8] = rk[ 0] ^
(Te4[(temp >> 16) & 0xff] & 0xff000000) ^
(Te4[(temp >> 8) & 0xff] & 0x00ff0000) ^
(Te4[(temp ) & 0xff] & 0x0000ff00) ^
(Te4[(temp >> 24) ] & 0x000000ff) ^
rcon[i];
rk[ 9] = rk[ 1] ^ rk[ 8];
rk[10] = rk[ 2] ^ rk[ 9];
rk[11] = rk[ 3] ^ rk[10];
if (++i == 7) {
return 14;
}
temp = rk[11];
rk[12] = rk[ 4] ^
(Te4[(temp >> 24) ] & 0xff000000) ^
(Te4[(temp >> 16) & 0xff] & 0x00ff0000) ^
(Te4[(temp >> 8) & 0xff] & 0x0000ff00) ^
(Te4[(temp ) & 0xff] & 0x000000ff);
rk[13] = rk[ 5] ^ rk[12];
rk[14] = rk[ 6] ^ rk[13];
rk[15] = rk[ 7] ^ rk[14];
rk += 8;
}
}
return 0;
}
void rijndaelEncrypt(const u32 rk[/*4*(Nr + 1)*/], int Nr, const u8 pt[16], u8 ct[16]) {
u32 s0, s1, s2, s3, t0, t1, t2, t3;
#ifndef FULL_UNROLL
int r;
#endif /* ?FULL_UNROLL */
/*
* map byte array block to cipher state
* and add initial round key:
*/
s0 = GETU32(pt ) ^ rk[0];
s1 = GETU32(pt + 4) ^ rk[1];
s2 = GETU32(pt + 8) ^ rk[2];
s3 = GETU32(pt + 12) ^ rk[3];
#ifdef FULL_UNROLL
/* round 1: */
t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[ 4];
t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[ 5];
t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[ 6];
t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[ 7];
/* round 2: */
s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[ 8];
s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[ 9];
s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[10];
s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[11];
/* round 3: */
t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[12];
t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[13];
t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[14];
t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[15];
/* round 4: */
s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[16];
s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[17];
s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[18];
s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[19];
/* round 5: */
t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[20];
t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[21];
t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[22];
t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[23];
/* round 6: */
s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[24];
s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[25];
s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[26];
s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[27];
/* round 7: */
t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[28];
t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[29];
t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[30];
t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[31];
/* round 8: */
s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[32];
s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[33];
s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[34];
s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[35];
/* round 9: */
t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[36];
t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[37];
t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[38];
t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[39];
if (Nr > 10) {
/* round 10: */
s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[40];
s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[41];
s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[42];
s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[43];
/* round 11: */
t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[44];
t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[45];
t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[46];
t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[47];
if (Nr > 12) {
/* round 12: */
s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[48];
s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[49];
s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[50];
s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[51];
/* round 13: */
t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[52];
t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[53];
t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[54];
t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[55];
}
}
rk += Nr << 2;
#else /* !FULL_UNROLL */
/*
* Nr - 1 full rounds:
*/
r = Nr >> 1;
for (;;) {
t0 =
Te0[(s0 >> 24) ] ^
Te1[(s1 >> 16) & 0xff] ^
Te2[(s2 >> 8) & 0xff] ^
Te3[(s3 ) & 0xff] ^
rk[4];
t1 =
Te0[(s1 >> 24) ] ^
Te1[(s2 >> 16) & 0xff] ^
Te2[(s3 >> 8) & 0xff] ^
Te3[(s0 ) & 0xff] ^
rk[5];
t2 =
Te0[(s2 >> 24) ] ^
Te1[(s3 >> 16) & 0xff] ^
Te2[(s0 >> 8) & 0xff] ^
Te3[(s1 ) & 0xff] ^
rk[6];
t3 =
Te0[(s3 >> 24) ] ^
Te1[(s0 >> 16) & 0xff] ^
Te2[(s1 >> 8) & 0xff] ^
Te3[(s2 ) & 0xff] ^
rk[7];
rk += 8;
if (--r == 0) {
break;
}
s0 =
Te0[(t0 >> 24) ] ^
Te1[(t1 >> 16) & 0xff] ^
Te2[(t2 >> 8) & 0xff] ^
Te3[(t3 ) & 0xff] ^
rk[0];
s1 =
Te0[(t1 >> 24) ] ^
Te1[(t2 >> 16) & 0xff] ^
Te2[(t3 >> 8) & 0xff] ^
Te3[(t0 ) & 0xff] ^
rk[1];
s2 =
Te0[(t2 >> 24) ] ^
Te1[(t3 >> 16) & 0xff] ^
Te2[(t0 >> 8) & 0xff] ^
Te3[(t1 ) & 0xff] ^
rk[2];
s3 =
Te0[(t3 >> 24) ] ^
Te1[(t0 >> 16) & 0xff] ^
Te2[(t1 >> 8) & 0xff] ^
Te3[(t2 ) & 0xff] ^
rk[3];
}
#endif /* ?FULL_UNROLL */
/*
* apply last round and
* map cipher state to byte array block:
*/
s0 =
(Te4[(t0 >> 24) ] & 0xff000000) ^
(Te4[(t1 >> 16) & 0xff] & 0x00ff0000) ^
(Te4[(t2 >> 8) & 0xff] & 0x0000ff00) ^
(Te4[(t3 ) & 0xff] & 0x000000ff) ^
rk[0];
PUTU32(ct , s0);
s1 =
(Te4[(t1 >> 24) ] & 0xff000000) ^
(Te4[(t2 >> 16) & 0xff] & 0x00ff0000) ^
(Te4[(t3 >> 8) & 0xff] & 0x0000ff00) ^
(Te4[(t0 ) & 0xff] & 0x000000ff) ^
rk[1];
PUTU32(ct + 4, s1);
s2 =
(Te4[(t2 >> 24) ] & 0xff000000) ^
(Te4[(t3 >> 16) & 0xff] & 0x00ff0000) ^
(Te4[(t0 >> 8) & 0xff] & 0x0000ff00) ^
(Te4[(t1 ) & 0xff] & 0x000000ff) ^
rk[2];
PUTU32(ct + 8, s2);
s3 =
(Te4[(t3 >> 24) ] & 0xff000000) ^
(Te4[(t0 >> 16) & 0xff] & 0x00ff0000) ^
(Te4[(t1 >> 8) & 0xff] & 0x0000ff00) ^
(Te4[(t2 ) & 0xff] & 0x000000ff) ^
rk[3];
PUTU32(ct + 12, s3);
}
/*
Local Variables:
mode:c
indent-tabs-mode:nil
c-basic-offset:2
End:
*/
+36
View File
@@ -0,0 +1,36 @@
/* Copyright 2003 Roger Dingledine */
/* See LICENSE for licensing information */
/* $Id$ */
/* Implements a minimal interface to counter-mode AES. */
#ifndef __AES_H
#define __AES_H
/**
* \file aes.h
* \brief Headers for aes.c
*/
#include "../common/torint.h"
struct aes_cnt_cipher;
typedef struct aes_cnt_cipher aes_cnt_cipher_t;
aes_cnt_cipher_t* aes_new_cipher();
void aes_free_cipher(aes_cnt_cipher_t *cipher);
void aes_set_key(aes_cnt_cipher_t *cipher, const unsigned char *key, int key_bits);
void aes_crypt(aes_cnt_cipher_t *cipher, const char *input, int len, char *output);
uint64_t aes_get_counter(aes_cnt_cipher_t *cipher);
void aes_set_counter(aes_cnt_cipher_t *cipher, uint64_t counter);
void aes_adjust_counter(aes_cnt_cipher_t *cipher, long delta);
#endif
/*
Local Variables:
mode:c
indent-tabs-mode:nil
c-basic-offset:2
End:
*/
File diff suppressed because it is too large Load Diff
+153
View File
@@ -0,0 +1,153 @@
/* Copyright 2001,2002,2003 Roger Dingledine, Matej Pfajfar. */
/* See LICENSE for licensing information */
/* $Id$ */
/**
* \file crypto.h
*
* \brief Headers for low-level cryptographic functions.
**/
#ifndef __CRYPTO_H
#define __CRYPTO_H
#include <stdio.h>
/** Length of the output of our message digest. */
#define DIGEST_LEN 20
/** Length of our symmetric cipher's keys. */
#define CIPHER_KEY_LEN 16
/** Length of our public keys. */
#define PK_BYTES (1024/8)
/** Length of our DH keys. */
#define DH_BYTES (1024/8)
/** Constants used to indicate no padding for public-key encryption */
#define PK_NO_PADDING 60000
/** Constants used to indicate PKCS1 padding for public-key encryption */
#define PK_PKCS1_PADDING 60001
/** Constants used to indicate OAEP padding for public-key encryption */
#define PK_PKCS1_OAEP_PADDING 60002
/** Number of bytes added for PKCS1 padding. */
#define PKCS1_PADDING_OVERHEAD 11
/** Number of bytes added for PKCS1-OAEP padding. */
#define PKCS1_OAEP_PADDING_OVERHEAD 42
/** Length of encoded public key fingerprints, including space; but not
* including terminating NUL. */
#define FINGERPRINT_LEN 49
/** Length of hex encoding of SHA1 digest, not including final NUL. */
#define HEX_DIGEST_LEN 40
typedef struct crypto_pk_env_t crypto_pk_env_t;
typedef struct crypto_cipher_env_t crypto_cipher_env_t;
typedef struct crypto_digest_env_t crypto_digest_env_t;
typedef struct crypto_dh_env_t crypto_dh_env_t;
/* global state */
int crypto_global_init();
int crypto_global_cleanup();
/* environment setup */
crypto_pk_env_t *crypto_new_pk_env(void);
void crypto_free_pk_env(crypto_pk_env_t *env);
crypto_cipher_env_t *crypto_new_cipher_env(void);
void crypto_free_cipher_env(crypto_cipher_env_t *env);
/* public key crypto */
int crypto_pk_generate_key(crypto_pk_env_t *env);
int crypto_pk_write_public_key_to_string(crypto_pk_env_t *env, char **dest, int *len);
int crypto_pk_read_public_key_from_string(crypto_pk_env_t *env, const char *src, int len);
int crypto_pk_write_private_key_to_filename(crypto_pk_env_t *env, const char *fname);
int crypto_pk_check_key(crypto_pk_env_t *env);
int crypto_pk_read_private_key_from_filename(crypto_pk_env_t *env, const char *keyfile);
int crypto_pk_cmp_keys(crypto_pk_env_t *a, crypto_pk_env_t *b);
crypto_pk_env_t *crypto_pk_dup_key(crypto_pk_env_t *orig);
int crypto_pk_keysize(crypto_pk_env_t *env);
int crypto_pk_public_encrypt(crypto_pk_env_t *env, const unsigned char *from, int fromlen, unsigned char *to, int padding);
int crypto_pk_private_decrypt(crypto_pk_env_t *env, const unsigned char *from, int fromlen, unsigned char *to, int padding, int warnOnFailure);
int crypto_pk_private_sign(crypto_pk_env_t *env, const unsigned char *from, int fromlen, unsigned char *to);
int crypto_pk_private_sign_digest(crypto_pk_env_t *env, const unsigned char *from, int fromlen, unsigned char *to);
int crypto_pk_public_checksig(crypto_pk_env_t *env, const unsigned char *from, int fromlen, unsigned char *to);
int crypto_pk_public_checksig_digest(crypto_pk_env_t *env, const unsigned char *data, int datalen, const unsigned char *sig, int siglen);
int crypto_pk_public_hybrid_encrypt(crypto_pk_env_t *env,
const unsigned char *from, int fromlen,
unsigned char *to, int padding, int force);
int crypto_pk_private_hybrid_decrypt(crypto_pk_env_t *env,
const unsigned char *from, int fromlen,
unsigned char *to,int padding,
int warnOnFailure);
int crypto_pk_asn1_encode(crypto_pk_env_t *pk, char *dest, int dest_len);
crypto_pk_env_t *crypto_pk_asn1_decode(const char *str, int len);
int crypto_pk_get_digest(crypto_pk_env_t *pk, char *digest_out);
int crypto_pk_get_fingerprint(crypto_pk_env_t *pk, char *fp_out);
int crypto_pk_check_fingerprint_syntax(const char *s);
int base64_encode(char *dest, int destlen, const char *src, int srclen);
int base64_decode(char *dest, int destlen, const char *src, int srclen);
#define BASE32_CHARS "abcdefghijklmnopqrstuvwxyz234567"
void base32_encode(char *dest, int destlen, const char *src, int srclen);
void base16_encode(char *dest, int destlen, const char *src, int srclen);
int base16_decode(char *dest, int destlen, const char *src, int srclen);
/* Key negotiation */
crypto_dh_env_t *crypto_dh_new();
int crypto_dh_get_bytes(crypto_dh_env_t *dh);
int crypto_dh_generate_public(crypto_dh_env_t *dh);
int crypto_dh_get_public(crypto_dh_env_t *dh, char *pubkey_out,
int pubkey_out_len);
int crypto_dh_compute_secret(crypto_dh_env_t *dh,
const char *pubkey, int pubkey_len,
char *secret_out, int secret_out_len);
void crypto_dh_free(crypto_dh_env_t *dh);
/* symmetric crypto */
int crypto_cipher_generate_key(crypto_cipher_env_t *env);
int crypto_cipher_set_key(crypto_cipher_env_t *env, const unsigned char *key);
int crypto_cipher_encrypt_init_cipher(crypto_cipher_env_t *env);
int crypto_cipher_decrypt_init_cipher(crypto_cipher_env_t *env);
const unsigned char *crypto_cipher_get_key(crypto_cipher_env_t *env);
int crypto_cipher_encrypt(crypto_cipher_env_t *env, const unsigned char *from, unsigned int fromlen, unsigned char *to);
int crypto_cipher_decrypt(crypto_cipher_env_t *env, const unsigned char *from, unsigned int fromlen, unsigned char *to);
/* only implemented for CRYPTO_CIPHER_AES_CTR */
int crypto_cipher_rewind(crypto_cipher_env_t *env, long delta);
int crypto_cipher_advance(crypto_cipher_env_t *env, long delta);
/* convenience function: wraps crypto_create_crypto_env, set_key, and init. */
crypto_cipher_env_t *crypto_create_init_cipher(const char *key, int encrypt_mode);
/* SHA-1 */
int crypto_digest(const unsigned char *m, int len, unsigned char *digest);
crypto_digest_env_t *crypto_new_digest_env();
void crypto_free_digest_env(crypto_digest_env_t *digest);
void crypto_digest_add_bytes(crypto_digest_env_t *digest, const char *data,
size_t len);
void crypto_digest_get_digest(crypto_digest_env_t *digest,
char *out, size_t out_len);
crypto_digest_env_t *crypto_digest_dup(const crypto_digest_env_t *digest);
void crypto_digest_assign(crypto_digest_env_t *into,
const crypto_digest_env_t *from);
/* random numbers */
int crypto_seed_rng();
int crypto_rand(unsigned int n, unsigned char *to);
void crypto_pseudo_rand(unsigned int n, unsigned char *to);
int crypto_pseudo_rand_int(unsigned int max);
#endif
/*
Local Variables:
mode:c
indent-tabs-mode:nil
c-basic-offset:2
End:
*/
+124
View File
@@ -0,0 +1,124 @@
/* Copyright 2002,2003 Nick Mathewson, Roger Dingledine */
/* See LICENSE for licensing information */
/* $Id$ */
/**
* \file fakepoll.c
*
* \brief On systems where poll() doesn't exist, fake it with select().
**/
#include "orconfig.h"
#include "fakepoll.h"
#define MAXCONNECTIONS 10000 /* XXXX copied from or.h */
#define FD_SETSIZE MAXCONNECTIONS
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef HAVE_STRING_H
#include <string.h>
#endif
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
#endif
#if _MSC_VER > 1300
#include <winsock2.h>
#include <ws2tcpip.h>
#elif defined(_MSC_VER)
#include <winsock.h>
#endif
#include <assert.h>
#include <stdlib.h>
#include "util.h"
#include "log.h"
#ifndef USE_FAKE_POLL
int
tor_poll(struct pollfd *ufds, unsigned int nfds, int timeout)
{
int i;
for (i=0;i<nfds;++i) {
tor_assert(ufds[i].fd >= 0);
}
return poll(ufds,nfds,timeout);
}
#else
int
tor_poll(struct pollfd *ufds, unsigned int nfds, int timeout)
{
unsigned int idx;
int maxfd, fd;
int r;
#ifdef MS_WINDOWS
int any_fds_set = 0;
#endif
fd_set readfds, writefds, exceptfds;
#ifdef USING_FAKE_TIMEVAL
#undef timeval
#undef tv_sec
#undef tv_usec
#endif
struct timeval _timeout;
_timeout.tv_sec = timeout/1000;
_timeout.tv_usec = (timeout%1000)*1000;
FD_ZERO(&readfds);
FD_ZERO(&writefds);
FD_ZERO(&exceptfds);
maxfd = -1;
for (idx = 0; idx < nfds; ++idx) {
ufds[idx].revents = 0;
fd = ufds[idx].fd;
tor_assert(fd >= 0);
if (fd > maxfd) {
maxfd = fd;
#ifdef MS_WINDOWS
any_fds_set = 1;
#endif
}
if (ufds[idx].events & POLLIN)
FD_SET(fd, &readfds);
if (ufds[idx].events & POLLOUT)
FD_SET(fd, &writefds);
FD_SET(fd, &exceptfds);
}
#ifdef MS_WINDOWS
if (!any_fds_set) {
Sleep(timeout);
return 0;
}
#endif
r = select(maxfd+1, &readfds, &writefds, &exceptfds,
timeout == -1 ? NULL : &_timeout);
if (r <= 0)
return r;
r = 0;
for (idx = 0; idx < nfds; ++idx) {
fd = ufds[idx].fd;
if (FD_ISSET(fd, &readfds))
ufds[idx].revents |= POLLIN;
if (FD_ISSET(fd, &writefds))
ufds[idx].revents |= POLLOUT;
if (FD_ISSET(fd, &exceptfds))
ufds[idx].revents |= POLLERR;
if (ufds[idx].revents)
++r;
}
return r;
}
#endif
/*
Local Variables:
mode:c
indent-tabs-mode:nil
c-basic-offset:2
End:
*/
+56
View File
@@ -0,0 +1,56 @@
/* Copyright 2002,2003 Nick Mathewson, Roger Dingledine. */
/* See LICENSE for licensing information */
/* $Id$ */
#ifndef __FAKEPOLL_H
#define __FAKEPOLL_H
/**
* \file fakepoll.h
* \brief Headers for fakepoll.c
*/
#include "orconfig.h"
#define POLL_NO_WARN
#if defined(HAVE_POLL_H)
#include <poll.h>
#elif defined(HAVE_SYS_POLL_H)
#include <sys/poll.h>
#endif
/* If _POLL_EMUL_H_ is defined, then poll is just a just a thin wrapper around
* select. On Mac OS 10.3, this wrapper is kinda flaky, and we should
* use our own.
*/
#if !(defined(HAVE_POLL_H)||defined(HAVE_SYS_POLL_H))&&!defined(_POLL_EMUL_H_)
#define USE_FAKE_POLL
#endif
#if defined USE_FAKE_POLL && !defined(_POLL_EMUL_H_)
struct pollfd {
int fd;
short events;
short revents;
};
#define POLLIN 0x0001
#define POLLPRI 0x0002
#define POLLOUT 0x0004
#define POLLERR 0x0008
#define POLLHUP 0x0010
#define POLLNVAL 0x0020
#endif
int tor_poll(struct pollfd *ufds, unsigned int nfds, int timeout);
#endif
/*
Local Variables:
mode:c
indent-tabs-mode:nil
c-basic-offset:2
End:
*/
+301
View File
@@ -0,0 +1,301 @@
/* Copyright 2001,2002,2003 Roger Dingledine, Matej Pfajfar. */
/* See LICENSE for licensing information */
/* $Id$ */
/**
* \file log.c
*
* \brief Functions to send messages to log files or the console.
*/
#include <stdarg.h>
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include "orconfig.h"
#include "./util.h"
#include "./log.h"
#ifdef MS_WINDOWS
#define vsnprintf _vsnprintf
#define snprintf _snprintf
#endif
/** Information for a single logfile; only used in log.c */
typedef struct logfile_t {
struct logfile_t *next; /**< Next logfile_t in the linked list. */
char *filename; /**< Filename to open. */
FILE *file; /**< Stream to receive log messages. */
int needs_close; /**< Boolean: true if the stream gets closed on shutdown. */
int loglevel; /**< Lowest severity level to send to this stream. */
int max_loglevel; /**< Highest severity level to send to this stream. */
int is_temporary; /**< Boolean: close after initializing logging subsystem.*/
} logfile_t;
/** Helper: map a log severity to descriptive string. */
static INLINE const char *sev_to_string(int severity) {
switch(severity) {
case LOG_DEBUG: return "debug";
case LOG_INFO: return "info";
case LOG_NOTICE: return "notice";
case LOG_WARN: return "warn";
case LOG_ERR: return "err";
default: assert(0); return "UNKNOWN";
}
}
/** Linked list of logfile_t. */
static logfile_t *logfiles = NULL;
static INLINE size_t _log_prefix(char *buf, size_t buf_len, int severity)
{
time_t t;
struct timeval now;
size_t n;
tor_gettimeofday(&now);
t = (time_t)now.tv_sec;
n = strftime(buf, buf_len, "%b %d %H:%M:%S", localtime(&t));
n += snprintf(buf+n, buf_len-n,
".%.3ld [%s] ",
(long)now.tv_usec / 1000, sev_to_string(severity));
if(n > buf_len)
n = buf_len-1; /* the *nprintf funcs return how many bytes they
* _would_ print, if the output is truncated.
* Subtract one because the count doesn't include the \0 */
return n;
}
/** If lf refers to an actual file that we have just opened, and the file
* contains no data, log an "opening new logfile" message at the top. **/
static void log_tor_version(logfile_t *lf, int reset)
{
char buf[256];
size_t n;
int is_new;
if (!lf->needs_close)
/* If it doesn't get closed, it isn't really a file. */
return;
if (lf->is_temporary)
/* If it's temporary, it isn't really a file. */
return;
is_new = (ftell(lf->file) == 0);
if (reset && !is_new)
/* We are resetting, but we aren't at the start of the file; no
* need to log again. */
return;
n = _log_prefix(buf, 250, LOG_NOTICE);
n += snprintf(buf+n, 250-n, "Tor %s opening %slog file.\n", VERSION,
is_new?"new ":"");
if (n>250)
n = 250;
buf[n+1]='\0';
fputs(buf, lf->file);
}
/** Helper: Format a log message into a fixed-sized buffer. (This is
* factored out of <b>logv</b> so that we never format a message more
* than once.)
*/
static INLINE void format_msg(char *buf, size_t buf_len,
int severity, const char *funcname,
const char *format, va_list ap)
{
size_t n;
buf_len -= 2; /* subtract 2 characters so we have room for \n\0 */
n = _log_prefix(buf, buf_len, severity);
if (funcname) {
n += snprintf(buf+n, buf_len-n, "%s(): ", funcname);
if(n > buf_len)
n = buf_len-1;
}
n += vsnprintf(buf+n,buf_len-n,format,ap);
if(n > buf_len)
n = buf_len-1;
buf[n]='\n';
buf[n+1]='\0';
}
/** Helper: sends a message to the appropriate logfiles, at loglevel
* <b>severity</b>. If provided, <b>funcname</b> is prepended to the
* message. The actual message is derived as from vsprintf(format,ap).
*/
static void
logv(int severity, const char *funcname, const char *format, va_list ap)
{
char buf[10024];
int formatted = 0;
logfile_t *lf;
assert(format);
for (lf = logfiles; lf; lf = lf->next) {
if (severity < lf->loglevel || severity > lf->max_loglevel)
continue;
if (!lf->file)
continue;
if (!formatted) {
format_msg(buf, 10024, severity, funcname, format, ap);
formatted = 1;
}
if(fputs(buf, lf->file) == EOF) { /* error */
assert(0); /* XXX */
}
if(fflush(lf->file) == EOF) { /* error */
/* don't log the error! */
assert(0); /* XXX fail for now. what's better to do? */
}
}
}
/** Output a message to the log. */
void _log(int severity, const char *format, ...)
{
va_list ap;
va_start(ap,format);
logv(severity, NULL, format, ap);
va_end(ap);
}
/** Output a message to the log, prefixed with a function name <b>fn</b>. */
void _log_fn(int severity, const char *fn, const char *format, ...)
{
va_list ap;
va_start(ap,format);
logv(severity, fn, format, ap);
va_end(ap);
}
/** Close all open log files. */
void close_logs()
{
logfile_t *victim;
while(logfiles) {
victim = logfiles;
logfiles = logfiles->next;
if (victim->needs_close)
fclose(victim->file);
tor_free(victim->filename);
tor_free(victim);
}
}
/** Close and re-open all log files; used to rotate logs on SIGHUP. */
void reset_logs()
{
logfile_t *lf;
for (lf = logfiles; lf; lf = lf->next) {
if (lf->needs_close) {
fclose(lf->file);
lf->file = fopen(lf->filename, "a");
log_tor_version(lf, 1);
}
}
}
/** Add a log handler to send all messages of severity <b>loglevel</b>
* or higher to <b>stream</b>. */
void add_stream_log(int loglevelMin, int loglevelMax, const char *name, FILE *stream)
{
logfile_t *lf;
lf = tor_malloc(sizeof(logfile_t));
lf->filename = tor_strdup(name);
lf->needs_close = 0;
lf->loglevel = loglevelMin;
lf->max_loglevel = loglevelMax;
lf->file = stream;
lf->next = logfiles;
lf->is_temporary = 0;
logfiles = lf;
}
/** Add a log handler to receive messages during startup (before the real
* logs are initialized).
*/
void add_temp_log(void)
{
add_stream_log(LOG_INFO, LOG_ERR, "<temp>", stdout);
logfiles->is_temporary = 1;
}
void close_temp_logs(void)
{
logfile_t *lf, **p;
for (p = &logfiles; *p; ) {
if ((*p)->is_temporary) {
lf = *p;
*p = (*p)->next;
if (lf->needs_close)
fclose(lf->file);
tor_free(lf->filename);
tor_free(lf);
} else {
p = &((*p)->next);
}
}
}
void mark_logs_temp(void)
{
logfile_t *lf;
for (lf = logfiles; lf; lf = lf->next)
lf->is_temporary = 1;
}
/**
* Add a log handler to send messages to <b>filename</b>. If opening
* the logfile fails, -1 is returned and errno is set appropriately
* (by fopen).
*/
int add_file_log(int loglevelMin, int loglevelMax, const char *filename)
{
FILE *f;
f = fopen(filename, "a");
if (!f) return -1;
add_stream_log(loglevelMin, loglevelMax, filename, f);
logfiles->needs_close = 1;
log_tor_version(logfiles, 0);
return 0;
}
/** If <b>level</b> is a valid log severity, return the corresponding
* numeric value. Otherwise, return -1. */
int parse_log_level(const char *level) {
if (!strcasecmp(level, "err"))
return LOG_ERR;
if (!strcasecmp(level, "warn"))
return LOG_WARN;
if (!strcasecmp(level, "notice"))
return LOG_NOTICE;
if (!strcasecmp(level, "info"))
return LOG_INFO;
if (!strcasecmp(level, "debug"))
return LOG_DEBUG;
return -1;
}
int get_min_log_level(void)
{
logfile_t *lf;
int min = LOG_ERR;
for (lf = logfiles; lf; lf = lf->next) {
if (lf->loglevel < min)
min = lf->loglevel;
}
return min;
}
/*
Local Variables:
mode:c
indent-tabs-mode:nil
c-basic-offset:2
End:
*/
+83
View File
@@ -0,0 +1,83 @@
/* Copyright 2001,2002,2003 Roger Dingledine, Matej Pfajfar. */
/* See LICENSE for licensing information */
/* $Id$ */
/**
* /file log.h
*
* /brief Headers for logging functions.
**/
#ifndef __LOG_H
/**
* \file log.h
* \brief Headers for log.c
*/
#ifdef HAVE_SYSLOG_H
#include <syslog.h>
#define LOG_WARN LOG_WARNING
#else
/** Debug-level severity: for hyper-verbose messages of no interest to
* anybody but developers. */
#define LOG_DEBUG 0
/** Info-level severity: for messages that appear frequently during normal
* operation. */
#define LOG_INFO 1
/** Notice-level severity: for messages that appear infrequently
* during normal operation; that the user will probably care about;
* and that are not errors.
*/
#define LOG_NOTICE 2
/** Warn-level severity: for messages that only appear when something has gone
* wrong. */
#define LOG_WARN 3
/** Error-level severity: for messages that only appear when something has gone
* very wrong, and the Tor process can no longer proceed. */
#define LOG_ERR 4
#endif
/* magic to make GCC check for proper format strings. */
#ifdef __GNUC__
#define CHECK_PRINTF(formatIdx, firstArg) \
__attribute__ ((format (printf, formatIdx, firstArg)))
#else
#define CHECK_PRINTF(formatIdx, firstArg)
#endif
int parse_log_level(const char *level);
void add_stream_log(int severityMin, int severityMax, const char *name, FILE *stream);
int add_file_log(int severityMin, int severityMax, const char *filename);
int get_min_log_level(void);
void close_logs();
void reset_logs();
void add_temp_log(void);
void close_temp_logs(void);
void mark_logs_temp(void);
/* Outputs a message to stdout */
void _log(int severity, const char *format, ...) CHECK_PRINTF(2,3);
#ifdef __GNUC__
void _log_fn(int severity, const char *funcname, const char *format, ...)
CHECK_PRINTF(3,4);
/** Log a message at level <b>severity</b>, using a pretty-printed version
* of the current function name. */
#define log_fn(severity, args...) \
_log_fn(severity, __PRETTY_FUNCTION__, args)
#else
#define log_fn _log
#endif
#define log _log /* hack it so we don't conflict with log() as much */
# define __LOG_H
#endif
/*
Local Variables:
mode:c
indent-tabs-mode:nil
c-basic-offset:2
End:
*/
+73
View File
@@ -0,0 +1,73 @@
/* $OpenBSD: strlcat.c,v 1.8 2001/05/13 15:40:15 deraadt Exp $ */
/*
* Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#if defined(LIBC_SCCS) && !defined(lint)
static char *rcsid = "$OpenBSD: strlcat.c,v 1.8 2001/05/13 15:40:15 deraadt Exp $";
#endif /* LIBC_SCCS and not lint */
#include <sys/types.h>
#include <string.h>
/*
* Appends src to string dst of size siz (unlike strncat, siz is the
* full size of dst, not space left). At most siz-1 characters
* will be copied. Always NUL terminates (unless siz <= strlen(dst)).
* Returns strlen(src) + MIN(siz, strlen(initial dst)).
* If retval >= siz, truncation occurred.
*/
size_t
strlcat(dst, src, siz)
char *dst;
const char *src;
size_t siz;
{
register char *d = dst;
register const char *s = src;
register size_t n = siz;
size_t dlen;
/* Find the end of dst and adjust bytes left but don't go past end */
while (n-- != 0 && *d != '\0')
d++;
dlen = d - dst;
n = siz - dlen;
if (n == 0)
return(dlen + strlen(s));
while (*s != '\0') {
if (n != 1) {
*d++ = *s;
n--;
}
s++;
}
*d = '\0';
return(dlen + (s - src)); /* count does not include NUL */
}
+64
View File
@@ -0,0 +1,64 @@
/* $Id$ */
/* $OpenBSD: strlcpy.c,v 1.2 1998/11/06 04:33:16 wvdputte Exp $ */
/*
* Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#if defined(LIBC_SCCS) && !defined(lint)
static char *rcsid = "$OpenBSD: strlcpy.c,v 1.2 1998/11/06 04:33:16 wvdputte Exp $";
#endif /* LIBC_SCCS and not lint */
#include <sys/types.h>
#include <string.h>
/*
* Copy src to string dst of size siz. At most siz-1 characters
* will be copied. Always NUL terminates (unless siz == 0).
* Returns strlen(src); if retval >= siz, truncation occurred.
*/
size_t strlcpy(dst, src, siz)
char *dst;
const char *src;
size_t siz;
{
register char *d = dst;
register const char *s = src;
register size_t n = siz;
if (n == 0)
return(strlen(s));
while (*s != '\0') {
if (n != 1) {
*d++ = *s;
n--;
}
s++;
}
*d = '\0';
return(s - src); /* count does not include NUL */
}
+143
View File
@@ -0,0 +1,143 @@
/* Copyright 2001,2002,2003 Roger Dingledine. */
/* See LICENSE for licensing information */
/* $Id$ */
#ifndef __TEST_H
#define __TEST_H
/**
* \file test.h
* \brief Headers for test.c
*/
#include <string.h>
#include <stdio.h>
#define STMT_BEGIN do {
#define STMT_END } while (0)
#ifdef __GNUC__
#define PRETTY_FUNCTION __PRETTY_FUNCTION__
#else
#define PRETTY_FUNCTION ""
#endif
extern int have_failed;
#define test_fail() \
STMT_BEGIN \
have_failed = 1; \
printf("\nFile %s: line %d (%s): assertion failed.", \
__FILE__, \
__LINE__, \
PRETTY_FUNCTION); \
return; \
STMT_END
#define test_assert(expr) \
STMT_BEGIN \
if(expr) { printf("."); fflush(stdout); } else { \
have_failed = 1; \
printf("\nFile %s: line %d (%s): assertion failed: (%s)\n", \
__FILE__, \
__LINE__, \
PRETTY_FUNCTION, \
#expr); \
return; \
} STMT_END
#define test_eq(expr1, expr2) \
STMT_BEGIN \
long v1=(long)(expr1), v2=(long)(expr2); \
if(v1==v2) { printf("."); fflush(stdout); } else { \
have_failed = 1; \
printf("\nFile %s: line %d (%s): Assertion failed: (%s==%s)\n"\
" (%ld != %ld)\n", \
__FILE__, \
__LINE__, \
PRETTY_FUNCTION, \
#expr1, #expr2, \
v1, v2); \
return; \
} STMT_END
#define test_neq(expr1, expr2) \
STMT_BEGIN \
long v1=(long)(expr1), v2=(long)(expr2); \
if(v1!=v2) { printf("."); fflush(stdout); } else { \
have_failed = 1; \
printf("\nFile %s: line %d (%s): Assertion failed: (%s!=%s)\n"\
" (%ld == %ld)\n", \
__FILE__, \
__LINE__, \
PRETTY_FUNCTION, \
#expr1, #expr2, \
v1, v2); \
return; \
} STMT_END
#define test_streq(expr1, expr2) \
STMT_BEGIN \
const char *v1=(expr1), *v2=(expr2); \
if(!strcmp(v1,v2)) { printf("."); fflush(stdout); } else { \
have_failed = 1; \
printf("\nFile %s: line %d (%s): Assertion failed: (%s==%s)\n"\
" (\"%s\" != \"%s\")\n", \
__FILE__, \
__LINE__, \
PRETTY_FUNCTION, \
#expr1, #expr2, \
v1, v2); \
return; \
} STMT_END
#define test_strneq(expr1, expr2) \
STMT_BEGIN \
const char *v1=(expr1), *v2=(expr2); \
if(strcmp(v1,v2)) { printf("."); fflush(stdout); } else { \
have_failed = 1; \
printf("\nFile %s: line %d (%s): Assertion failed: (%s!=%s)\n"\
" (\"%s\" == \"%s\")\n", \
__FILE__, \
__LINE__, \
PRETTY_FUNCTION, \
#expr1, #expr2, \
v1, v2); \
return; \
} STMT_END
#define test_memeq(expr1, expr2, len) \
STMT_BEGIN \
void *v1=(expr1), *v2=(expr2); \
if(!memcmp(v1,v2,(len))) { printf("."); fflush(stdout); } else { \
have_failed = 1; \
printf("\nFile %s: line %d (%s): Assertion failed: (%s==%s)\n", \
__FILE__, \
__LINE__, \
PRETTY_FUNCTION, \
#expr1, #expr2); \
return; \
} STMT_END
#define test_memneq(expr1, expr2, len) \
STMT_BEGIN \
void *v1=(expr1), *v2=(expr2); \
if(memcmp(v1,v2,(len))) { printf("."); fflush(stdout); } else { \
have_failed = 1; \
printf("\nFile %s: line %d (%s): Assertion failed: (%s!=%s)\n", \
__FILE__, \
__LINE__, \
PRETTY_FUNCTION, \
#expr1, #expr2); \
return; \
} STMT_END
#endif
/*
Local Variables:
mode:c
indent-tabs-mode:nil
c-basic-offset:2
End:
*/
+191
View File
@@ -0,0 +1,191 @@
/* Copyright 2003 Roger Dingledine */
/* See LICENSE for licensing information */
/* $Id$ */
/**
* \file torint.h
* \brief Header file to define uint32_t and friends
**/
#ifndef __TORINT_H
#define __TORINT_H
#include "orconfig.h"
#ifdef HAVE_STDINT_H
#include <stdint.h>
#endif
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#if (SIZEOF_INT8_T != 0)
#define HAVE_INT8_T
#endif
#if (SIZEOF_INT16_T != 0)
#define HAVE_INT16_T
#endif
#if (SIZEOF_INT32_T != 0)
#define HAVE_INT32_T
#endif
#if (SIZEOF_INT64_T != 0)
#define HAVE_INT64_T
#endif
#if (SIZEOF_UINT8_T != 0)
#define HAVE_UINT8_T
#endif
#if (SIZEOF_UINT16_T != 0)
#define HAVE_UINT16_T
#endif
#if (SIZEOF_UINT32_T != 0)
#define HAVE_UINT32_T
#endif
#if (SIZEOF_UINT64_T != 0)
#define HAVE_UINT64_T
#endif
#if (SIZEOF_INTPTR_T != 0)
#define HAVE_INTPTR_T
#endif
#if (SIZEOF_UINTPTR_T != 0)
#define HAVE_UINTPTR_T
#endif
#if (SIZEOF_CHAR == 1)
#ifndef HAVE_INT8_T
typedef signed char int8_t;
#define HAVE_INT8_T
#endif
#ifndef HAVE_UINT8_T
typedef unsigned char uint8_t;
#define HAVE_UINT8_T
#endif
#endif
#if (SIZEOF_SHORT == 2)
#ifndef HAVE_INT16_T
typedef signed short int16_t;
#define HAVE_INT16_T
#endif
#ifndef HAVE_UINT16_T
typedef unsigned short uint16_t;
#define HAVE_UINT16_T
#endif
#endif
#if (SIZEOF_INT == 2)
#ifndef HAVE_INT16_T
typedef signed int int16_t;
#define HAVE_INT16_T
#endif
#ifndef HAVE_UINT16_T
typedef unsigned int uint16_t;
#define HAVE_UINT16_T
#endif
#elif (SIZEOF_INT == 4)
#ifndef HAVE_INT32_T
typedef signed int int32_t;
#define HAVE_INT32_T
#endif
#ifndef HAVE_UINT32_T
typedef unsigned int uint32_t;
#define HAVE_UINT32_T
#endif
#endif
#if (SIZEOF_LONG == 4)
#ifndef HAVE_INT32_T
typedef signed long int32_t;
#define HAVE_INT32_T
#endif
#ifndef HAVE_UINT32_T
typedef unsigned long uint32_t;
#define HAVE_UINT32_T
#endif
#elif (SIZEOF_LONG == 8)
#ifndef HAVE_INT64_T
typedef signed long int64_t;
#define HAVE_INT64_T
#endif
#ifndef HAVE_UINT32_T
typedef unsigned long uint64_t;
#define HAVE_UINT32_T
#endif
#endif
#if (SIZEOF_LONG_LONG == 8)
#ifndef HAVE_INT64_T
typedef signed long long int64_t;
#define HAVE_INT64_T
#endif
#ifndef HAVE_UINT64_T
typedef unsigned long long uint64_t;
#define HAVE_UINT64_T
#endif
#endif
#if (SIZEOF___INT64 == 8)
#ifndef HAVE_INT64_T
typedef signed __int64 int64_t;
#define HAVE_INT64_T
#endif
#ifndef HAVE_UINT64_T
typedef unsigned __int64 uint64_t;
#define HAVE_UINT64_T
#endif
#endif
#if (SIZEOF_VOID_P > 4 && SIZEOF_VOID_P <= 8)
#ifndef HAVE_INTPTR_T
typedef int64_t intptr_t;
#endif
#ifndef HAVE_UINTPTR_T
typedef uint64_t uintptr_t;
#endif
#elif (SIZEOF_VOID_P > 2 && SIZEOF_VOID_P <= 4)
#ifndef HAVE_INTPTR_T
typedef int32_t intptr_t;
#endif
#ifndef HAVE_UINTPTR_T
typedef uint32_t uintptr_t;
#endif
#else
#error "void * is either >8 bytes or <= 2. In either case, I am confused."
#endif
#ifndef HAVE_INT8_T
#error "Missing type int8_t"
#endif
#ifndef HAVE_UINT8_T
#error "Missing type uint8_t"
#endif
#ifndef HAVE_INT16_T
#error "Missing type int16_t"
#endif
#ifndef HAVE_UINT16_T
#error "Missing type uint16_t"
#endif
#ifndef HAVE_INT32_T
#error "Missing type int32_t"
#endif
#ifndef HAVE_UINT32_T
#error "Missing type uint32_t"
#endif
#ifndef HAVE_INT64_T
#error "Missing type int64_t"
#endif
#ifndef HAVE_UINT64_T
#error "Missing type uint64_t"
#endif
#endif /* __TORINT_H */
/*
Local Variables:
mode:c
indent-tabs-mode:nil
c-basic-offset:2
End:
*/
+790
View File
@@ -0,0 +1,790 @@
/* Copyright 2003 Roger Dingledine. */
/* See LICENSE for licensing information */
/* $Id$ */
/**
* \file tortls.c
*
* \brief TLS wrappers for Tor.
**/
/* (Unlike other tor functions, these
* are prefixed with tor_ in order to avoid conflicting with OpenSSL
* functions and variables.)
*/
#include "./crypto.h"
#include "./tortls.h"
#include "./util.h"
#include "./log.h"
#include <string.h>
/* Copied from or.h */
#define LEGAL_NICKNAME_CHARACTERS "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
#include <assert.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <openssl/tls1.h>
#include <openssl/asn1.h>
#include <openssl/bio.h>
/** How long do identity certificates live? (sec) */
#define IDENTITY_CERT_LIFETIME (365*24*60*60)
/** How much clock skew do we tolerate when checking certificates? (sec) */
#define CERT_ALLOW_SKEW (90*60)
typedef struct tor_tls_context_st {
SSL_CTX *ctx;
SSL_CTX *client_only_ctx;
} tor_tls_context;
/** Holds a SSL object and its associated data. Members are only
* accessed from within tortls.c.
*/
struct tor_tls_st {
SSL *ssl; /**< An OpenSSL SSL object. */
int socket; /**< The underlying file descriptor for this TLS connection. */
enum {
TOR_TLS_ST_HANDSHAKE, TOR_TLS_ST_OPEN, TOR_TLS_ST_GOTCLOSE,
TOR_TLS_ST_SENTCLOSE, TOR_TLS_ST_CLOSED
} state; /**< The current SSL state, depending on which operations have
* completed successfully. */
int isServer;
int wantwrite_n; /**< 0 normally, >0 if we returned wantwrite last time. */
};
static X509* tor_tls_create_certificate(crypto_pk_env_t *rsa,
crypto_pk_env_t *rsa_sign,
const char *cname,
const char *cname_sign,
unsigned int lifetime);
/** Global tls context. We keep it here because nobody else needs to
* touch it. */
static tor_tls_context *global_tls_context = NULL;
/** True iff tor_tls_init() has been called. */
static int tls_library_is_initialized = 0;
/* Module-internal error codes. */
#define _TOR_TLS_SYSCALL -6
#define _TOR_TLS_ZERORETURN -5
/* These functions are declared in crypto.c but not exported. */
EVP_PKEY *_crypto_pk_env_get_evp_pkey(crypto_pk_env_t *env, int private);
crypto_pk_env_t *_crypto_new_pk_env_rsa(RSA *rsa);
DH *_crypto_dh_env_get_dh(crypto_dh_env_t *dh);
/** Log all pending tls errors at level <b>severity</b>. Use
* <b>doing</b> to describe our current activities.
*/
static void
tls_log_errors(int severity, const char *doing)
{
int err;
const char *msg, *lib, *func;
while ((err = ERR_get_error()) != 0) {
msg = (const char*)ERR_reason_error_string(err);
lib = (const char*)ERR_lib_error_string(err);
func = (const char*)ERR_func_error_string(err);
if (!msg) msg = "(null)";
if (doing) {
log(severity, "TLS error while %s: %s (in %s:%s)", doing, msg, lib,func);
} else {
log(severity, "TLS error: %s (in %s:%s)", msg, lib, func);
}
}
}
#define CATCH_SYSCALL 1
#define CATCH_ZERO 2
/** Given a TLS object and the result of an SSL_* call, use
* SSL_get_error to determine whether an error has occurred, and if so
* which one. Return one of TOR_TLS_{DONE|WANTREAD|WANTWRITE|ERROR}.
* If extra&CATCH_SYSCALL is true, return _TOR_TLS_SYSCALL instead of
* reporting syscall errors. If extra&CATCH_ZERO is true, return
* _TOR_TLS_ZERORETURN instead of reporting zero-return errors.
*
* If an error has occurred, log it at level <b>severity</b> and describe the
* current action as <b>doing</b>.
*/
static int
tor_tls_get_error(tor_tls *tls, int r, int extra,
const char *doing, int severity)
{
int err = SSL_get_error(tls->ssl, r);
switch (err) {
case SSL_ERROR_NONE:
return TOR_TLS_DONE;
case SSL_ERROR_WANT_READ:
return TOR_TLS_WANTREAD;
case SSL_ERROR_WANT_WRITE:
return TOR_TLS_WANTWRITE;
case SSL_ERROR_SYSCALL:
if (extra&CATCH_SYSCALL)
return _TOR_TLS_SYSCALL;
if (r == 0)
log(severity, "TLS error: unexpected close while %s", doing);
else {
int e = tor_socket_errno(tls->socket);
log(severity, "TLS error: <syscall error while %s> (errno=%d: %s)",
doing, e, tor_socket_strerror(e));
}
tls_log_errors(severity, doing);
return TOR_TLS_ERROR;
case SSL_ERROR_ZERO_RETURN:
if (extra&CATCH_ZERO)
return _TOR_TLS_ZERORETURN;
log(severity, "TLS error: Zero return");
tls_log_errors(severity, doing);
return TOR_TLS_ERROR;
default:
tls_log_errors(severity, doing);
return TOR_TLS_ERROR;
}
}
/** Initialize OpenSSL, unless it has already been initialized.
*/
static void
tor_tls_init() {
if (!tls_library_is_initialized) {
SSL_library_init();
SSL_load_error_strings();
crypto_global_init();
OpenSSL_add_all_algorithms();
tls_library_is_initialized = 1;
}
}
/** We need to give OpenSSL a callback to verify certificates. This is
* it: We always accept peer certs and complete the handshake. We
* don't validate them until later.
*/
static int always_accept_verify_cb(int preverify_ok,
X509_STORE_CTX *x509_ctx)
{
return 1;
}
/** Generate and sign an X509 certificate with the public key <b>rsa</b>,
* signed by the private key <b>rsa_sign</b>. The commonName of the
* certificate will be <b>cname</b>; the commonName of the issuer will be
* <b>cname_sign</b>. The cert will be valid for <b>cert_lifetime</b> seconds
* starting from now. Return a certificate on success, NULL on
* failure.
*/
static X509 *
tor_tls_create_certificate(crypto_pk_env_t *rsa,
crypto_pk_env_t *rsa_sign,
const char *cname,
const char *cname_sign,
unsigned int cert_lifetime)
{
time_t start_time, end_time;
EVP_PKEY *sign_pkey = NULL, *pkey=NULL;
X509 *x509 = NULL;
X509_NAME *name = NULL, *name_issuer=NULL;
int nid;
tor_tls_init();
start_time = time(NULL);
tor_assert(rsa && cname && rsa_sign && cname_sign);
if (!(sign_pkey = _crypto_pk_env_get_evp_pkey(rsa_sign,1)))
goto error;
if (!(pkey = _crypto_pk_env_get_evp_pkey(rsa,0)))
goto error;
if (!(x509 = X509_new()))
goto error;
if (!(X509_set_version(x509, 2)))
goto error;
if (!(ASN1_INTEGER_set(X509_get_serialNumber(x509), (long)start_time)))
goto error;
if (!(name = X509_NAME_new()))
goto error;
if ((nid = OBJ_txt2nid("organizationName")) == NID_undef) goto error;
if (!(X509_NAME_add_entry_by_NID(name, nid, MBSTRING_ASC,
"TOR", -1, -1, 0))) goto error;
if ((nid = OBJ_txt2nid("commonName")) == NID_undef) goto error;
if (!(X509_NAME_add_entry_by_NID(name, nid, MBSTRING_ASC,
(char*)cname, -1, -1, 0))) goto error;
if (!(X509_set_subject_name(x509, name)))
goto error;
if (!(name_issuer = X509_NAME_new()))
goto error;
if ((nid = OBJ_txt2nid("organizationName")) == NID_undef) goto error;
if (!(X509_NAME_add_entry_by_NID(name_issuer, nid, MBSTRING_ASC,
"TOR", -1, -1, 0))) goto error;
if ((nid = OBJ_txt2nid("commonName")) == NID_undef) goto error;
if (!(X509_NAME_add_entry_by_NID(name_issuer, nid, MBSTRING_ASC,
(char*)cname_sign, -1, -1, 0))) goto error;
if (!(X509_set_issuer_name(x509, name_issuer)))
goto error;
if (!X509_time_adj(X509_get_notBefore(x509),0,&start_time))
goto error;
end_time = start_time + cert_lifetime;
if (!X509_time_adj(X509_get_notAfter(x509),0,&end_time))
goto error;
if (!X509_set_pubkey(x509, pkey))
goto error;
if (!X509_sign(x509, sign_pkey, EVP_sha1()))
goto error;
goto done;
error:
tls_log_errors(LOG_WARN, "generating certificate");
if (x509) {
X509_free(x509);
x509 = NULL;
}
done:
if (sign_pkey)
EVP_PKEY_free(sign_pkey);
if (pkey)
EVP_PKEY_free(pkey);
if (name)
X509_NAME_free(name);
if (name_issuer)
X509_NAME_free(name_issuer);
return x509;
}
#ifdef EVERYONE_HAS_AES
/* Everybody is running OpenSSL 0.9.7 or later, so no backward compatibility
* is needed. */
#define CIPHER_LIST TLS1_TXT_DHE_RSA_WITH_AES_128_SHA
#elif defined(TLS1_TXT_DHE_RSA_WITH_AES_128_SHA)
/* Some people are running OpenSSL before 0.9.7, but we aren't.
* We can support AES and 3DES.
*/
#define CIPHER_LIST (TLS1_TXT_DHE_RSA_WITH_AES_128_SHA ":" \
SSL3_TXT_EDH_RSA_DES_192_CBC3_SHA)
#else
/* We're running OpenSSL before 0.9.7. We only support 3DES. */
#define CIPHER_LIST SSL3_TXT_EDH_RSA_DES_192_CBC3_SHA
#endif
/** Create a new TLS context. If we are going to be using it as a
* server, it must have isServer set to true, <b>identity</b> set to the
* identity key used to sign that certificate, and <b>nickname</b> set to
* the server's nickname. If we're only going to be a client,
* isServer should be false, identity should be NULL, and nickname
* should be NULL. Return -1 if failure, else 0.
*
* You can call this function multiple times. Each time you call it,
* it generates new certificates; all new connections will use
* the new SSL context.
*/
int
tor_tls_context_new(crypto_pk_env_t *identity,
int isServer, const char *nickname,
unsigned int key_lifetime)
{
crypto_pk_env_t *rsa = NULL;
crypto_dh_env_t *dh = NULL;
EVP_PKEY *pkey = NULL;
tor_tls_context *result = NULL;
X509 *cert = NULL, *idcert = NULL;
char nn2[1024];
int client_only;
SSL_CTX **ctx;
sprintf(nn2, "%s <identity>", nickname);
tor_tls_init();
if (isServer) {
/* Generate short-term RSA key. */
if (!(rsa = crypto_new_pk_env()))
goto error;
if (crypto_pk_generate_key(rsa)<0)
goto error;
/* Create certificate signed by identity key. */
cert = tor_tls_create_certificate(rsa, identity, nickname, nn2,
key_lifetime);
/* Create self-signed certificate for identity key. */
idcert = tor_tls_create_certificate(identity, identity, nn2, nn2,
IDENTITY_CERT_LIFETIME);
if (!cert || !idcert) {
log(LOG_WARN, "Error creating certificate");
goto error;
}
}
result = tor_malloc(sizeof(tor_tls_context));
result->ctx = result->client_only_ctx = NULL;
for (client_only=0; client_only <= 1; ++client_only) {
ctx = client_only ? &result->client_only_ctx : &result->ctx;
#ifdef EVERYONE_HAS_AES
/* Tell OpenSSL to only use TLS1 */
if (!(*ctx = SSL_CTX_new(TLSv1_method())))
goto error;
#else
/* Tell OpenSSL to use SSL3 or TLS1 but not SSL2. */
if (!(*ctx = SSL_CTX_new(SSLv23_method())))
goto error;
SSL_CTX_set_options(*ctx, SSL_OP_NO_SSLv2);
#endif
if (!SSL_CTX_set_cipher_list(*ctx, CIPHER_LIST))
goto error;
if (!client_only) {
if (cert && !SSL_CTX_use_certificate(*ctx,cert))
goto error;
if (idcert && !SSL_CTX_add_extra_chain_cert(*ctx,idcert))
goto error;
}
SSL_CTX_set_session_cache_mode(*ctx, SSL_SESS_CACHE_OFF);
if (isServer && !client_only) {
tor_assert(rsa);
if (!(pkey = _crypto_pk_env_get_evp_pkey(rsa,1)))
goto error;
if (!SSL_CTX_use_PrivateKey(*ctx, pkey))
goto error;
EVP_PKEY_free(pkey);
pkey = NULL;
if (cert) {
if (!SSL_CTX_check_private_key(*ctx))
goto error;
}
}
dh = crypto_dh_new();
SSL_CTX_set_tmp_dh(*ctx, _crypto_dh_env_get_dh(dh));
crypto_dh_free(dh);
SSL_CTX_set_verify(*ctx, SSL_VERIFY_PEER,
always_accept_verify_cb);
/* let us realloc bufs that we're writing from */
SSL_CTX_set_mode(*ctx, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
}
/* Free the old context if one exists. */
if (global_tls_context) {
/* This is safe even if there are open connections: OpenSSL does
* reference counting with SSL and SSL_CTX objects. */
SSL_CTX_free(global_tls_context->ctx);
SSL_CTX_free(global_tls_context->client_only_ctx);
tor_free(global_tls_context);
}
global_tls_context = result;
return 0;
error:
tls_log_errors(LOG_WARN, "creating TLS context");
if (pkey)
EVP_PKEY_free(pkey);
if (rsa)
crypto_free_pk_env(rsa);
if (dh)
crypto_dh_free(dh);
if (result && result->ctx)
SSL_CTX_free(result->ctx);
if (result && result->client_only_ctx)
SSL_CTX_free(result->client_only_ctx);
if (result)
free(result);
if (cert)
X509_free(cert);
if (idcert)
X509_free(cert);
return -1;
}
/** Create a new TLS object from a file descriptor, and a flag to
* determine whether it is functioning as a server.
*/
tor_tls *
tor_tls_new(int sock, int isServer, int use_no_cert)
{
tor_tls *result = tor_malloc(sizeof(tor_tls));
SSL_CTX *ctx;
tor_assert(global_tls_context); /* make sure somebody made it first */
ctx = use_no_cert ? global_tls_context->client_only_ctx
: global_tls_context->ctx;
if (!(result->ssl = SSL_new(ctx)))
return NULL;
result->socket = sock;
SSL_set_fd(result->ssl, sock);
result->state = TOR_TLS_ST_HANDSHAKE;
result->isServer = isServer;
result->wantwrite_n = 0;
return result;
}
/** Release resources associated with a TLS object. Does not close the
* underlying file descriptor.
*/
void
tor_tls_free(tor_tls *tls)
{
SSL_free(tls->ssl);
free(tls);
}
/** Underlying function for TLS reading. Reads up to <b>len</b>
* characters from <b>tls</b> into <b>cp</b>. On success, returns the
* number of characters read. On failure, returns TOR_TLS_ERROR,
* TOR_TLS_CLOSE, TOR_TLS_WANTREAD, or TOR_TLS_WANTWRITE.
*/
int
tor_tls_read(tor_tls *tls, char *cp, int len)
{
int r, err;
tor_assert(tls && tls->ssl);
tor_assert(tls->state == TOR_TLS_ST_OPEN);
r = SSL_read(tls->ssl, cp, len);
if (r > 0)
return r;
err = tor_tls_get_error(tls, r, CATCH_ZERO, "reading", LOG_INFO);
log_fn(LOG_DEBUG,"returned r=%d, err=%d",r,err);
if (err == _TOR_TLS_ZERORETURN) {
tls->state = TOR_TLS_ST_CLOSED;
return TOR_TLS_CLOSE;
} else {
tor_assert(err != TOR_TLS_DONE);
return err;
}
}
/** Underlying function for TLS writing. Write up to <b>n</b>
* characters from <b>cp</b> onto <b>tls</b>. On success, returns the
* number of characters written. On failure, returns TOR_TLS_ERROR,
* TOR_TLS_WANTREAD, or TOR_TLS_WANTWRITE.
*/
int
tor_tls_write(tor_tls *tls, char *cp, int n)
{
int r, err;
tor_assert(tls && tls->ssl);
tor_assert(tls->state == TOR_TLS_ST_OPEN);
if (n == 0)
return 0;
if(tls->wantwrite_n) {
/* if WANTWRITE last time, we must use the _same_ n as before */
tor_assert(n >= tls->wantwrite_n);
log_fn(LOG_DEBUG,"resuming pending-write, (%d to flush, reusing %d)",
n, tls->wantwrite_n);
n = tls->wantwrite_n;
tls->wantwrite_n = 0;
}
r = SSL_write(tls->ssl, cp, n);
err = tor_tls_get_error(tls, r, 0, "writing", LOG_INFO);
if (err == TOR_TLS_DONE) {
return r;
}
if (err == TOR_TLS_WANTWRITE || err == TOR_TLS_WANTREAD) {
// log_fn(LOG_INFO,"wantwrite or wantread. remembering the number %d.",n);
tls->wantwrite_n = n;
}
return err;
}
/** Perform initial handshake on <b>tls</b>. When finished, returns
* TOR_TLS_DONE. On failure, returns TOR_TLS_ERROR, TOR_TLS_WANTREAD,
* or TOR_TLS_WANTWRITE.
*/
int
tor_tls_handshake(tor_tls *tls)
{
int r;
tor_assert(tls && tls->ssl);
tor_assert(tls->state == TOR_TLS_ST_HANDSHAKE);
if (tls->isServer) {
r = SSL_accept(tls->ssl);
} else {
r = SSL_connect(tls->ssl);
}
r = tor_tls_get_error(tls,r,0, "handshaking", LOG_INFO);
if (r == TOR_TLS_DONE) {
tls->state = TOR_TLS_ST_OPEN;
}
return r;
}
/** Shut down an open tls connection <b>tls</b>. When finished, returns
* TOR_TLS_DONE. On failure, returns TOR_TLS_ERROR, TOR_TLS_WANTREAD,
* or TOR_TLS_WANTWRITE.
*/
int
tor_tls_shutdown(tor_tls *tls)
{
int r, err;
char buf[128];
tor_assert(tls && tls->ssl);
while (1) {
if (tls->state == TOR_TLS_ST_SENTCLOSE) {
/* If we've already called shutdown once to send a close message,
* we read until the other side has closed too.
*/
do {
r = SSL_read(tls->ssl, buf, 128);
} while (r>0);
err = tor_tls_get_error(tls, r, CATCH_ZERO, "reading to shut down",
LOG_INFO);
if (err == _TOR_TLS_ZERORETURN) {
tls->state = TOR_TLS_ST_GOTCLOSE;
/* fall through... */
} else {
return err;
}
}
r = SSL_shutdown(tls->ssl);
if (r == 1) {
/* If shutdown returns 1, the connection is entirely closed. */
tls->state = TOR_TLS_ST_CLOSED;
return TOR_TLS_DONE;
}
err = tor_tls_get_error(tls, r, CATCH_SYSCALL|CATCH_ZERO, "shutting down",
LOG_INFO);
if (err == _TOR_TLS_SYSCALL) {
/* The underlying TCP connection closed while we were shutting down. */
tls->state = TOR_TLS_ST_CLOSED;
return TOR_TLS_DONE;
} else if (err == _TOR_TLS_ZERORETURN) {
/* The TLS connection says that it sent a shutdown record, but
* isn't done shutting down yet. Make sure that this hasn't
* happened before, then go back to the start of the function
* and try to read.
*/
if (tls->state == TOR_TLS_ST_GOTCLOSE ||
tls->state == TOR_TLS_ST_SENTCLOSE) {
log(LOG_WARN,
"TLS returned \"half-closed\" value while already half-closed");
return TOR_TLS_ERROR;
}
tls->state = TOR_TLS_ST_SENTCLOSE;
/* fall through ... */
} else {
return err;
}
} /* end loop */
}
/** Return true iff this TLS connection is authenticated.
*/
int
tor_tls_peer_has_cert(tor_tls *tls)
{
X509 *cert;
if (!(cert = SSL_get_peer_certificate(tls->ssl)))
return 0;
X509_free(cert);
return 1;
}
/** Return the nickname (if any) that the peer connected on <b>tls</b>
* claims to have.
*/
int
tor_tls_get_peer_cert_nickname(tor_tls *tls, char *buf, int buflen)
{
X509 *cert = NULL;
X509_NAME *name = NULL;
int nid;
int lenout;
if (!(cert = SSL_get_peer_certificate(tls->ssl))) {
log_fn(LOG_WARN, "Peer has no certificate");
goto error;
}
if (!(name = X509_get_subject_name(cert))) {
log_fn(LOG_WARN, "Peer certificate has no subject name");
goto error;
}
if ((nid = OBJ_txt2nid("commonName")) == NID_undef)
goto error;
lenout = X509_NAME_get_text_by_NID(name, nid, buf, buflen);
if (lenout == -1)
goto error;
if (((int)strspn(buf, LEGAL_NICKNAME_CHARACTERS)) < lenout) {
log_fn(LOG_WARN, "Peer certificate nickname has illegal characters.");
goto error;
}
return 0;
error:
if (cert)
X509_free(cert);
if (name)
X509_NAME_free(name);
return -1;
}
static void log_cert_lifetime(X509 *cert, const char *problem)
{
BIO *bio = NULL;
BUF_MEM *buf;
char *s1=NULL, *s2=NULL;
char mytime[33];
time_t now = time(NULL);
if (problem)
log_fn(LOG_WARN,"Certificate %s: is your system clock set incorrectly?",
problem);
if (!(bio = BIO_new(BIO_s_mem()))) {
log_fn(LOG_WARN, "Couldn't allocate BIO!"); goto end;
}
if (!(ASN1_TIME_print(bio, X509_get_notBefore(cert)))) {
tls_log_errors(LOG_WARN, "printing certificate lifetime");
goto end;
}
BIO_get_mem_ptr(bio, &buf);
s1 = tor_strndup(buf->data, buf->length);
BIO_reset(bio);
if (!(ASN1_TIME_print(bio, X509_get_notAfter(cert)))) {
tls_log_errors(LOG_WARN, "printing certificate lifetime");
goto end;
}
BIO_get_mem_ptr(bio, &buf);
s2 = tor_strndup(buf->data, buf->length);
strftime(mytime, 32, "%b %d %H:%M:%S %Y GMT", gmtime(&now));
log_fn(LOG_WARN, "(certificate lifetime runs from %s through %s. Your time is %s.)",s1,s2,mytime);
end:
if (bio)
BIO_free(bio);
if (s1)
tor_free(s1);
if (s2)
tor_free(s2);
}
/** If the provided tls connection is authenticated and has a
* certificate that is currently valid and signed, then set
* *<b>identity_key</b> to the identity certificate's key and return
* 0. Else, return -1.
*/
int
tor_tls_verify(tor_tls *tls, crypto_pk_env_t **identity_key)
{
X509 *cert = NULL, *id_cert = NULL;
STACK_OF(X509) *chain = NULL;
EVP_PKEY *id_pkey = NULL;
RSA *rsa;
int num_in_chain;
time_t now, t;
int r = -1, i;
*identity_key = NULL;
if (!(cert = SSL_get_peer_certificate(tls->ssl)))
goto done;
if (!(chain = SSL_get_peer_cert_chain(tls->ssl)))
goto done;
num_in_chain = sk_X509_num(chain);
log_fn(LOG_DEBUG,"Number of certs in chain: %d", num_in_chain);
/* 1 means we're receiving (server-side), and it's just the id_cert.
* 2 means we're connecting (client-side), and it's both the link
* cert and the id_cert.
*/
if (num_in_chain < 1) {
log_fn(LOG_WARN,"Unexpected number of certificates in chain (%d)",
num_in_chain);
goto done;
}
for (i=0; i<num_in_chain; ++i) {
id_cert = sk_X509_value(chain, i);
if (X509_cmp(id_cert, cert) != 0)
break;
}
if (!id_cert) {
log_fn(LOG_WARN,"No distinct identity certificate found");
goto done;
}
now = time(NULL);
t = now + CERT_ALLOW_SKEW;
if (X509_cmp_time(X509_get_notBefore(cert), &t) > 0) {
log_cert_lifetime(cert, "not yet valid");
goto done;
}
t = now - CERT_ALLOW_SKEW;
if (X509_cmp_time(X509_get_notAfter(cert), &t) < 0) {
log_cert_lifetime(cert, "already expired");
goto done;
}
if (!(id_pkey = X509_get_pubkey(id_cert)) ||
X509_verify(cert, id_pkey) <= 0) {
log_fn(LOG_WARN,"X509_verify on cert and pkey returned <= 0");
tls_log_errors(LOG_WARN,"verifying certificate");
goto done;
}
rsa = EVP_PKEY_get1_RSA(id_pkey);
if (!rsa)
goto done;
*identity_key = _crypto_new_pk_env_rsa(rsa);
r = 0;
done:
if (cert)
X509_free(cert);
if (id_pkey)
EVP_PKEY_free(id_pkey);
/* This should never get invoked, but let's make sure in case OpenSSL
* acts unexpectedly. */
tls_log_errors(LOG_WARN, "finishing tor_tls_verify");
return r;
}
/** Return the number of bytes available for reading from <b>tls</b>.
*/
int
tor_tls_get_pending_bytes(tor_tls *tls)
{
tor_assert(tls);
#if OPENSSL_VERSION_NUMBER < 0x0090700fl
if (tls->ssl->rstate == SSL_ST_READ_BODY)
return 0;
if (tls->ssl->s3->rrec.type != SSL3_RT_APPLICATION_DATA)
return 0;
#endif
return SSL_pending(tls->ssl);
}
/** Return the number of bytes read across the underlying socket. */
unsigned long tor_tls_get_n_bytes_read(tor_tls *tls)
{
tor_assert(tls);
return BIO_number_read(SSL_get_rbio(tls->ssl));
}
/** Return the number of bytes written across the underlying socket. */
unsigned long tor_tls_get_n_bytes_written(tor_tls *tls)
{
tor_assert(tls);
return BIO_number_written(SSL_get_wbio(tls->ssl));
}
/** Implement assert_no_tls_errors: If there are any pending OpenSSL
* errors, log an error message and assert(0). */
void _assert_no_tls_errors(const char *fname, int line)
{
if (ERR_peek_error() == 0)
return;
log_fn(LOG_ERR, "Unhandled OpenSSL errors found at %s:%d: ",
fname, line);
tls_log_errors(LOG_ERR, NULL);
tor_assert(0);
}
/*
Local Variables:
mode:c
indent-tabs-mode:nil
c-basic-offset:2
End:
*/
+55
View File
@@ -0,0 +1,55 @@
/* Copyright 2003 Roger Dingledine */
/* See LICENSE for licensing information */
/* $Id$ */
#ifndef _TORTLS_H
#define _TORTLS_H
/**
* \file tortls.h
* \brief Headers for tortls.c
**/
#include "../common/crypto.h"
/* Opaque structure to hold a TLS connection. */
typedef struct tor_tls_st tor_tls;
/* Possible return values for most tor_tls_* functions. */
#define TOR_TLS_ERROR -4
#define TOR_TLS_CLOSE -3
#define TOR_TLS_WANTREAD -2
#define TOR_TLS_WANTWRITE -1
#define TOR_TLS_DONE 0
int tor_tls_context_new(crypto_pk_env_t *rsa, int isServer,
const char *nickname, unsigned int key_lifetime);
tor_tls *tor_tls_new(int sock, int is_server, int use_no_cert);
void tor_tls_free(tor_tls *tls);
int tor_tls_peer_has_cert(tor_tls *tls);
int tor_tls_get_peer_cert_nickname(tor_tls *tls, char *buf, int buflen);
int tor_tls_verify(tor_tls *tls, crypto_pk_env_t **identity);
int tor_tls_read(tor_tls *tls, char *cp, int len);
int tor_tls_write(tor_tls *tls, char *cp, int n);
int tor_tls_handshake(tor_tls *tls);
int tor_tls_shutdown(tor_tls *tls);
int tor_tls_get_pending_bytes(tor_tls *tls);
unsigned long tor_tls_get_n_bytes_read(tor_tls *tls);
unsigned long tor_tls_get_n_bytes_written(tor_tls *tls);
/* Log and abort if there are unhandled TLS errors in OpenSSL's error stack.
*/
#define assert_no_tls_errors() _assert_no_tls_errors(__FILE__,__LINE__)
void _assert_no_tls_errors(const char *fname, int line);
#endif
/*
Local Variables:
mode:c
indent-tabs-mode:nil
c-basic-offset:2
End:
*/
File diff suppressed because it is too large Load Diff
+283
View File
@@ -0,0 +1,283 @@
/* Copyright 2003 Roger Dingledine */
/* See LICENSE for licensing information */
/* $Id$ */
/**
* \file util.h
* \brief Headers for util.c
**/
#ifndef __UTIL_H
#define __UTIL_H
#include "orconfig.h"
#include "torint.h"
#include <stdio.h>
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
#endif
#ifdef HAVE_TIME_H
#include <time.h>
#endif
#if _MSC_VER > 1300
#include <winsock2.h>
#include <ws2tcpip.h>
#elif defined(_MSC_VER)
#include <winsock.h>
#endif
#ifndef HAVE_GETTIMEOFDAY
#ifdef HAVE_FTIME
#define USING_FAKE_TIMEVAL
#include <sys/timeb.h>
struct timeval {
time_t tv_sec;
unsigned int tv_usec;
};
#endif
#endif
#ifdef MS_WINDOWS
/* Windows names string functions differently from most other platforms. */
#define strncasecmp strnicmp
#define strcasecmp stricmp
/* "inline" is __inline on windows. " */
#define INLINE __inline
/* Windows compilers before VC7 don't have __FUNCTION__. */
#if _MSC_VER < 1300
#define __FUNCTION__ "???"
#endif
#else
#define INLINE inline
#endif
/** Replace assert() with a variant that sends failures to the log before
* calling assert() normally.
*/
#ifdef NDEBUG
#define tor_assert(expr) do {} while(0)
#else
#define tor_assert(expr) do { \
if (!(expr)) { \
log(LOG_ERR, "%s:%d: %s: Assertion %s failed; aborting.", \
__FILE__, __LINE__, __FUNCTION__, #expr); \
assert(expr); /* write to console too. */ \
abort(); /* unreached */ \
} } while (0)
#endif
#ifdef MS_WINDOWS
/** On windows, you have to call close() on fds returned by open(),
* and closesocket() on fds returned by socket(). On Unix, everything
* gets close()'d. We abstract this difference by always using
* tor_close_socket to close sockets, and always using close() on
* files.
*/
#define tor_close_socket(s) closesocket(s)
#else
#define tor_close_socket(s) close(s)
#endif
/** Legal characters in a filename */
#ifdef MS_WINDOWS
#define CONFIG_LEGAL_FILENAME_CHARACTERS "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.-_/\\ "
#else
#define CONFIG_LEGAL_FILENAME_CHARACTERS "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.-_/ "
#endif
size_t strlcat(char *dst, const char *src, size_t siz);
size_t strlcpy(char *dst, const char *src, size_t siz);
void *tor_malloc(size_t size);
void *tor_malloc_zero(size_t size);
void *tor_realloc(void *ptr, size_t size);
char *tor_strdup(const char *s);
char *tor_strndup(const char *s, size_t n);
#define tor_free(p) do {if(p) {free(p); (p)=NULL;}} while(0)
void tor_strlower(char *s);
/* Some platforms segfault when you try to access a multi-byte type
* that isn't aligned to a word boundary. The macros and/or functions
* below can be used to access unaligned data on any platform.
*/
#ifdef UNALIGNED_INT_ACCESS_OK
#define get_uint16(cp) (*(uint16_t*)(cp))
#define get_uint32(cp) (*(uint32_t*)(cp))
#define set_uint16(cp,v) do { *(uint16_t*)(cp) = (v); } while (0)
#define set_uint32(cp,v) do { *(uint32_t*)(cp) = (v); } while (0)
#else
#if 1
uint16_t get_uint16(const char *cp);
uint32_t get_uint32(const char *cp);
void set_uint16(char *cp, uint16_t v);
void set_uint32(char *cp, uint32_t v);
#else
#define get_uint16(cp) \
( ((*(((uint8_t*)(cp))+0))<<8) + \
((*(((uint8_t*)(cp))+1)) ) )
#define get_uint32(cp) \
( ((*(((uint8_t*)(cp))+0))<<24) + \
((*(((uint8_t*)(cp))+1))<<16) + \
((*(((uint8_t*)(cp))+2))<<8 ) + \
((*(((uint8_t*)(cp))+3)) ) )
#define set_uint16(cp,v) \
do { \
uint16_t u16v = (v); \
*(((uint8_t*)(cp))+0) = (v >> 8)&0xff; \
*(((uint8_t*)(cp))+1) = (v >> 0)&0xff; \
} while (0)
#define set_uint32(cp,val) \
do { \
uint32_t u32v = (v); \
*(((uint8_t*)(cp))+0) = s32 >> 24)&0xff; \
*(((uint8_t*)(cp))+1) = s32 >> 16)&0xff; \
*(((uint8_t*)(cp))+2) = s32 >> 8)&0xff; \
*(((uint8_t*)(cp))+3) = s32 >> 0)&0xff; \
} while (0)
#endif
#endif
void hex_encode(const char *from, int fromlen, char *to);
const char *hex_str(const char *from, int fromlen);
/** Generic resizeable array. */
typedef struct smartlist_t smartlist_t;
smartlist_t *smartlist_create();
void smartlist_free(smartlist_t *sl);
void smartlist_set_capacity(smartlist_t *sl, int n);
void smartlist_clear(smartlist_t *sl);
void smartlist_truncate(smartlist_t *sl, int n);
void smartlist_add(smartlist_t *sl, void *element);
void smartlist_add_all(smartlist_t *sl, const smartlist_t *s2);
void smartlist_remove(smartlist_t *sl, void *element);
int smartlist_isin(const smartlist_t *sl, void *element);
int smartlist_overlap(const smartlist_t *sl1, const smartlist_t *sl2);
void smartlist_intersect(smartlist_t *sl1, const smartlist_t *sl2);
void smartlist_subtract(smartlist_t *sl1, const smartlist_t *sl2);
void *smartlist_choose(const smartlist_t *sl);
void *smartlist_get(const smartlist_t *sl, int idx);
void *smartlist_set(smartlist_t *sl, int idx, void *val);
void *smartlist_del(smartlist_t *sl, int idx);
void *smartlist_del_keeporder(smartlist_t *sl, int idx);
void smartlist_insert(smartlist_t *sl, int idx, void *val);
int smartlist_len(const smartlist_t *sl);
#define SMARTLIST_FOREACH(sl, type, var, cmd) \
do { \
int sl_idx, sl_len=smartlist_len(sl); \
type var; \
for(sl_idx = 0; sl_idx < sl_len; ++sl_idx) { \
var = smartlist_get((sl),sl_idx); \
do {cmd;} while(0); \
} } while (0)
/* Map from const char * to void*. Implemented with a splay tree. */
typedef struct strmap_t strmap_t;
typedef struct strmap_entry_t strmap_entry_t;
typedef struct strmap_entry_t strmap_iter_t;
strmap_t* strmap_new(void);
void* strmap_set(strmap_t *map, const char *key, void *val);
void* strmap_get(strmap_t *map, const char *key);
void* strmap_remove(strmap_t *map, const char *key);
void* strmap_set_lc(strmap_t *map, const char *key, void *val);
void* strmap_get_lc(strmap_t *map, const char *key);
void* strmap_remove_lc(strmap_t *map, const char *key);
typedef void* (*strmap_foreach_fn)(const char *key, void *val, void *data);
void strmap_foreach(strmap_t *map, strmap_foreach_fn fn, void *data);
void strmap_free(strmap_t *map, void (*free_val)(void*));
strmap_iter_t *strmap_iter_init(strmap_t *map);
strmap_iter_t *strmap_iter_next(strmap_t *map, strmap_iter_t *iter);
strmap_iter_t *strmap_iter_next_rmv(strmap_t *map, strmap_iter_t *iter);
void strmap_iter_get(strmap_iter_t *iter, const char **keyp, void **valp);
int strmap_iter_done(strmap_iter_t *iter);
/* String manipulation */
const char *eat_whitespace(const char *s);
const char *eat_whitespace_no_nl(const char *s);
const char *find_whitespace(const char *s);
/* Time helpers */
void tor_gettimeofday(struct timeval *timeval);
long tv_udiff(struct timeval *start, struct timeval *end);
void tv_addms(struct timeval *a, long ms);
void tv_add(struct timeval *a, struct timeval *b);
int tv_cmp(struct timeval *a, struct timeval *b);
time_t tor_timegm(struct tm *tm);
int write_all(int fd, const char *buf, size_t count, int isSocket);
int read_all(int fd, char *buf, size_t count, int isSocket);
void set_socket_nonblocking(int socket);
typedef enum { FN_ERROR, FN_NOENT, FN_FILE, FN_DIR} file_status_t;
file_status_t file_status(const char *filename);
int check_private_dir(const char *dirname, int create);
int write_str_to_file(const char *fname, const char *str);
char *read_file_to_str(const char *filename);
int parse_line_from_file(char *line, int maxlen, FILE *f, char **key_out, char **value_out);
char *expand_filename(const char *filename);
int spawn_func(int (*func)(void *), void *data);
void spawn_exit();
/* Because we use threads instead of processes on Windows, we need locking on Windows.
* On Unixy platforms, these functions are no-ops. */
typedef struct tor_mutex_t tor_mutex_t;
tor_mutex_t *tor_mutex_new(void);
void tor_mutex_acquire(tor_mutex_t *m);
void tor_mutex_release(tor_mutex_t *m);
void tor_mutex_free(tor_mutex_t *m);
int tor_socketpair(int family, int type, int protocol, int fd[2]);
int is_internal_IP(uint32_t ip);
int is_local_IP(uint32_t ip);
const char *get_uname(void);
void start_daemon(const char *desired_cwd);
void finish_daemon(void);
void write_pidfile(char *filename);
int switch_id(char *user, char *group);
struct in_addr;
int tor_inet_aton(const char *cp, struct in_addr *addr);
int tor_lookup_hostname(const char *name, uint32_t *addr);
/* For stupid historical reasons, windows sockets have an independent
* set of errnos, and an independent way to get them. Also, you can't
* always believe WSAEWOULDBLOCK. Use the macros below to compare
* errnos against expected values, and use tor_socket_errno to find
* the actual errno after a socket operation fails.
*/
#ifdef MS_WINDOWS
/** Return true if e is EAGAIN or the local equivalent. */
#define ERRNO_IS_EAGAIN(e) ((e) == EAGAIN || (e) == WSAEWOULDBLOCK)
/** Return true if e is EINPROGRESS or the local equivalent. */
#define ERRNO_IS_EINPROGRESS(e) ((e) == WSAEINPROGRESS)
/** Return true if e is EINPROGRESS or the local equivalent as returned by
* a call to connect(). */
#define ERRNO_IS_CONN_EINPROGRESS(e) ((e) == WSAEINPROGRESS || (e)== WSAEINVAL)
int tor_socket_errno(int sock);
const char *tor_socket_strerror(int e);
#else
#define ERRNO_IS_EAGAIN(e) ((e) == EAGAIN)
#define ERRNO_IS_EINPROGRESS(e) ((e) == EINPROGRESS)
#define ERRNO_IS_CONN_EINPROGRESS(e) ((e) == EINPROGRESS)
#define tor_socket_errno(sock) (errno)
#define tor_socket_strerror(e) strerror(e)
#endif
#endif
/*
Local Variables:
mode:c
indent-tabs-mode:nil
c-basic-offset:2
End:
*/
+5
View File
@@ -0,0 +1,5 @@
Makefile
Makefile.in
sample-server-torrc
torrc
torrc.sample
@@ -0,0 +1,5 @@
confdir = $(sysconfdir)/tor
EXTRA_DIST = dirservers
conf_DATA = dirservers torrc.sample
+110
View File
@@ -0,0 +1,110 @@
# This is no longer a manually-editable file. It's just a
# concatenation of a bunch of signed router descriptors.
router moria1 18.244.0.188 9001 9021 9031
platform Tor 0.0.6rc1 on Linux moria.mit.edu i686
published 2004-04-25 21:54:28
bandwidth 800000 10000000
onion-key
-----BEGIN RSA PUBLIC KEY-----
MIGJAoGBANoIvHieyHUTzIacbnWOnyTyzGrLOdXqbcjz2GGMxyHEd5K1bO1ZBNHP
9i5qLQpN5viFk2K2rEGuG8tFgDEzSWZEtBqv3NVfUdiumdERWMBwlaQ0MVK4C+jf
y5gZ8KI3o9ZictgPS1AQF+Kk932/vIHTuRIUKb4ILTnQilNvID0NAgMBAAE=
-----END RSA PUBLIC KEY-----
signing-key
-----BEGIN RSA PUBLIC KEY-----
MIGJAoGBAMHa0ZC/jo2Q2DrwKYF/6ZbmZ27PFYG91u4gUzzmZ/VXLpZ8wNzEV3oW
nt+I61048fBiC1frT1/DZ351n2bLSk9zJbB6jyGZJn0380FPRX3+cXyXS0Gq8Ril
xkhMQf5XuNFUb8UmYPSOH4WErjvYjKvU+gfjbK/82Jo9SuHpYz+BAgMBAAE=
-----END RSA PUBLIC KEY-----
reject 0.0.0.0/255.0.0.0:*
reject 169.254.0.0/255.255.0.0:*
reject 127.0.0.0/255.0.0.0:*
reject 192.168.0.0/255.255.0.0:*
reject 10.0.0.0/255.0.0.0:*
reject 172.16.0.0/255.240.0.0:*
accept *:20-22
accept *:53
accept *:79-80
accept *:110
accept *:143
accept *:443
accept *:873
accept *:993
accept *:995
accept *:1024-65535
reject *:*
router-signature
-----BEGIN SIGNATURE-----
o1eAoRHDAEAXsnh5wN++vIwrupd+DbAJ2p3wxHDrmqxTpygzxxCnyQyhMfX03ua2
4iplyNlwyFwzWcw0sk31otlO2HBYXT1V9G0YxGtKMOeOBMHjfGbUjGvEALHzWi4z
8DXGJp13zgnUyP4ZA6xaGROwcT6oB5e7UlztvvpGxTg=
-----END SIGNATURE-----
router moria2 18.244.0.188 9002 9022 9032
platform Tor 0.0.6rc1 on Linux moria.mit.edu i686
published 2004-04-25 21:54:30
bandwidth 800000 10000000
onion-key
-----BEGIN RSA PUBLIC KEY-----
MIGJAoGBAM4Cc/npgYC54XrYLC+grVxJp7PDmNO2DRRJOxKttBBtvLpnR1UaueTi
kyknT5kmlx+ihgZF/jmye//2dDUp2+kK/kSkpRV4xnDLXZmed+sNSQxqmm9TtZQ9
/hjpxhp5J9HmUTYhntBs+4E4CUKokmrI6oRLoln4SA39AX9QLPcnAgMBAAE=
-----END RSA PUBLIC KEY-----
signing-key
-----BEGIN RSA PUBLIC KEY-----
MIGJAoGBAOcrht/y5rkaahfX7sMe2qnpqoPibsjTSJaDvsUtaNP/Bq0MgNDGOR48
rtwfqTRff275Edkp/UYw3G3vSgKCJr76/bqOHCmkiZrnPV1zxNfrK18gNw2Cxre0
nTA+fD8JQqpPtb8b0SnG9kwy75eS//sRu7TErie2PzGMxrf9LH0LAgMBAAE=
-----END RSA PUBLIC KEY-----
reject 0.0.0.0/255.0.0.0:*
reject 169.254.0.0/255.255.0.0:*
reject 127.0.0.0/255.0.0.0:*
reject 192.168.0.0/255.255.0.0:*
reject 10.0.0.0/255.0.0.0:*
reject 172.16.0.0/255.240.0.0:*
accept *:20-22
accept *:53
accept *:79-80
accept *:110
accept *:143
accept *:443
accept *:873
accept *:993
accept *:995
accept *:1024-65535
reject *:*
router-signature
-----BEGIN SIGNATURE-----
RKROLwP1ExjTZeg6wuN0pzYqed9IJUd5lAe9hp4ritbnmJAgS6qfww6jgx61CfUR
6SElhOLE7Q77jAdoL45Ji5pn/Y+Q+E+5lJm1E/ed9ha+YsOPaOc7z6GQ7E4mihCL
gI1vsw92+P1Ty4RHj6fyD9DhbV19nh2Qs+pvGJOS2FY=
-----END SIGNATURE-----
router tor26 62.116.124.106 9001 9050 9030
platform Tor 0.0.6 on Linux seppia i686
published 2004-05-06 21:33:23
bandwidth 500000 10000000
onion-key
-----BEGIN RSA PUBLIC KEY-----
MIGJAoGBAMEHdDnpj3ik1AF1xe/VqjoguH2DbANifYqXXfempu0fS+tU9FGo6dU/
fnVHAZwL9Ek9k2rMzumShi1RduK9p035R/Gk+PBBcLfvwYJ/Nat+ZO/L8jn/3bZe
ieQd9CKj2LjNGKpRNry37vkwMGIOIlegwK+2us8aXJ7sIvlNts0TAgMBAAE=
-----END RSA PUBLIC KEY-----
signing-key
-----BEGIN RSA PUBLIC KEY-----
MIGJAoGBAMQgV2gXLbXgesWgeAsj8P1Uvm/zibrFXqwDq27lLKNgWGYGX2ax3LyT
3nzI1Y5oLs4kPKTsMM5ft9aokwf417lKoCRlZc9ptfRbgxDx90c9GtWVmkrmDvCK
ae59TMoXIiGfZiwWT6KKq5Zm9/Fu2Il3B2vHGkKJYKixmiBJRKp/AgMBAAE=
-----END RSA PUBLIC KEY-----
accept 62.245.184.24:25
accept 62.116.124.106:6666-6670
accept *:48099
reject *:*
router-signature
-----BEGIN SIGNATURE-----
qh/xRoqfLNFzPaB8VdpbdMAwRyuk5qjx4LeLVQ2pDwTZ55PqmG99+VKUNte2WTTD
7dZEA7um2rueohGe4nYmvbhJWr20/I0ZxmWDRDvFy0b5nwzDMGvLvDw95Zu/XJQ2
md32NE3y9VZCfbCN+GlvETX3fdR3Svzcm8Kzesg2/s4=
-----END SIGNATURE-----
+12
View File
@@ -0,0 +1,12 @@
DataDirectory moria1
Nickname moria1
ORPort 9001
DirPort 9031
# List of routers
RouterFile ../config/dirservers
ExitPolicy reject 0.0.0.0/8,reject 127.0.0.0/8,reject 192.168.0.0/16,reject 10.0.0.0/8,reject 172.16.0.0/12,accept *:20-22,accept *:53,accept *:79-80,accept *:110,accept *:143,accept *:443,accept *:873,accept *:1024-65535,reject *:*
+12
View File
@@ -0,0 +1,12 @@
DataDirectory moria2
Nickname moria2
ORPort 9002
DirPort 9032
# List of routers
RouterFile ../config/dirservers
ExitPolicy reject 0.0.0.0/8,reject 127.0.0.0/8,reject 192.168.0.0/16,reject 10.0.0.0/8,reject 172.16.0.0/12,accept *:20-22,accept *:53,accept *:79-80,accept *:110,accept *:143,accept *:443,accept *:873,accept *:1024-65535,reject *:*
+12
View File
@@ -0,0 +1,12 @@
DataDirectory moria3
Nickname moria3
ORPort 9003
DirPort 9033
# List of routers
RouterFile ../config/dirservers
ExitPolicy reject 0.0.0.0/8,reject 127.0.0.0/8,reject 192.168.0.0/16,reject 10.0.0.0/8,reject 172.16.0.0/12,accept *:20-22,accept *:53,accept *:79-80,accept *:110,accept *:143,accept *:443,accept *:873,accept *:1024-65535,reject *:*
@@ -0,0 +1,78 @@
# Configuration file for a typical tor user
# List of routers. Tor nodes start out knowing about the directory
# servers, and from them they get a list of currently up nodes.
RouterFile @CONFDIR@/dirservers
# Comment out if you don't want to allow applications to connect.
SocksPort 9050
SocksBindAddress 127.0.0.1 # accept connections only from localhost
#SocksBindAddress 192.168.0.1:9100 # listen on a chosen IP/port
# Entry policies to allow/deny SOCKS requests based on IP. By default,
# we accept all requests to SocksBindAddress.
#
#SocksPolicy accept 192.168.0.1/16:*
#SocksPolicy reject *:*
# By default, we send log messages to stdout. If you want
# them to go somewhere else, uncomment one or more of these example
# configurations.
### Send all messages of level 'warn' or higher to /var/log/tor/warnings
#LogFile /var/log/tor/warnings
#LogLevel warn
### Send all debug and info messages to /var/log/tor/debug
#LogFile /var/log/tor/debug
#LogLevel debug-info
### Send all debug messages ONLY to /var/log/tor/debug
#LogFile /var/log/tor/debug
#LogLevel debug-debug
# Uncomment this to start the process in the background
#RunAsDaemon 1
##################### Below is just for servers #####################
## NOTE: If you enable these, you won't be able to use tor as a client
## or server until you've been added to the directory and can
## authenticate to the other nodes. See the README for details.
## The directory for keeping all the keys/etc for this server
#DataDirectory @LOCALSTATEDIR@/lib/tor
#Nickname moria # A unique handle for this server
#Address moria.seul.org # The IP or fqdn for this server
#ContactInfo 1024D/28988BF5 Roger Dingledine <arma@mit.edu>
#ORPort 9001 # where to listen for tor connections
#ORBindAddress 0.0.0.0 # accept connections from anywhere
#ORBindAddress 0.0.0.0:9090 # accept connections from anywhere, and
# listen on a port other than the one we
# advertised.
# Uncomment this to mirror the directory for others (please do)
#DirPort 9030
## A comma-separated list of exit policies. If you want to *replace*
## the default exit policy, end this with either a reject *:* or an
## accept *:*. Otherwise, you're *augmenting* (prepending to) the
## default exit policy. Leave commented to just use the default.
#ExitPolicy accept *:6660-6667
#ExitPolicy reject 192.168.0.1:*
#ExitPolicy reject *:*
##################### Below is just for location-hidden services ###
## Look in /tmp/hidden_service/hostname for the url to tell people.
## HiddenServicePort x y:z says to redirect a port x request from the
## client to y:z.
#HiddenServiceDir /tmp/hidden_service/
#HiddenServicePort 80 127.0.0.1:80
#HiddenServiceDir /tmp/other_hidden_service/
#HiddenServicePort 80 127.0.0.1:80
#HiddenServicePort 22 127.0.0.1:22
#HiddenServiceNodes moria1,moria2
#HiddenServiceExcludeNodes bad,otherbad
+5
View File
@@ -0,0 +1,5 @@
Makefile
Makefile.in
tor
test
.deps
+28
View File
@@ -0,0 +1,28 @@
TESTS = test
noinst_PROGRAMS = test
bin_PROGRAMS = tor
tor_SOURCES = buffers.c circuitbuild.c circuitlist.c \
circuituse.c command.c config.c \
connection.c connection_edge.c connection_or.c \
cpuworker.c directory.c dirserv.c dns.c main.c \
onion.c relay.c rendcommon.c rendclient.c rendmid.c \
rendservice.c rephist.c router.c routerlist.c routerparse.c \
tor_main.c
tor_LDADD = ../common/libor.a
test_SOURCES = buffers.c circuitbuild.c circuitlist.c \
circuituse.c command.c config.c \
connection.c connection_edge.c connection_or.c \
cpuworker.c directory.c dirserv.c dns.c main.c \
onion.c relay.c rendcommon.c rendclient.c rendmid.c \
rendservice.c rephist.c router.c routerlist.c routerparse.c \
test.c
test_LDADD = ../common/libor.a
noinst_HEADERS = or.h tree.h
+628
View File
@@ -0,0 +1,628 @@
/* Copyright 2001 Matej Pfajfar, 2001-2004 Roger Dingledine. */
/* See LICENSE for licensing information */
/* $Id$ */
/**
* \file buffers.c
* \brief Abstractions for buffered IO.
**/
#include "or.h"
#define BUFFER_MAGIC 0xB0FFF312u
struct buf_t {
uint32_t magic; /**< Magic cookie for debugging: Must be set to BUFFER_MAGIC */
char *mem; /**< Storage for data in the buffer */
size_t len; /**< Maximum amount of data that <b>mem</b> can hold. */
size_t datalen; /**< Number of bytes currently in <b>mem</b>. */
};
/** Size, in bytes, for newly allocated buffers. Should be a power of 2. */
#define INITIAL_BUF_SIZE (4*1024)
/** Maximum size, in bytes, for resized buffers. */
#define MAX_BUF_SIZE (1024*1024*10)
/** Size, in bytes, for minimum 'shrink' size for buffers. Buffers may start
* out smaller than this, but they will never autoshrink to less
* than this size. */
#define MIN_BUF_SHRINK_SIZE (16*1024)
/** Change a buffer's capacity. <b>new_capacity</b> must be \<= buf->datalen. */
static INLINE void buf_resize(buf_t *buf, size_t new_capacity)
{
tor_assert(buf->datalen <= new_capacity);
tor_assert(new_capacity);
buf->mem = tor_realloc(buf->mem, new_capacity);
buf->len = new_capacity;
}
/** If the buffer is not large enough to hold <b>capacity</b> bytes, resize
* it so that it can. (The new size will be a power of 2 times the old
* size.)
*/
static INLINE int buf_ensure_capacity(buf_t *buf, size_t capacity)
{
size_t new_len;
if (buf->len >= capacity) /* Don't grow if we're already big enough. */
return 0;
if (capacity > MAX_BUF_SIZE) /* Don't grow past the maximum. */
return -1;
/* Find the smallest new_len equal to (2**X)*len for some X; such that
* new_len is at least capacity.
*/
new_len = buf->len*2;
while (new_len < capacity)
new_len *= 2;
/* Resize the buffer. */
log_fn(LOG_DEBUG,"Growing buffer from %d to %d bytes.",
(int)buf->len, (int)new_len);
buf_resize(buf,new_len);
return 0;
}
/** If the buffer is at least 2*MIN_BUF_SHRINK_SIZE bytes in capacity,
* and if the buffer is less than 1/4 full, shrink the buffer until
* one of the above no longer holds. (We shrink the buffer by
* dividing by powers of 2.)
*/
static INLINE void buf_shrink_if_underfull(buf_t *buf) {
size_t new_len;
/* If the buffer is at least .25 full, or if shrinking the buffer would
* put it onder MIN_BUF_SHRINK_SIZE, don't do it. */
if (buf->datalen >= buf->len/4 || buf->len < 2*MIN_BUF_SHRINK_SIZE)
return;
/* Shrink new_len by powers of 2 until: datalen is at least 1/4 of
* new_len, OR shrinking new_len more would put it under
* MIN_BUF_SHRINK_SIZE.
*/
new_len = buf->len / 2;
while (buf->datalen < new_len/4 && new_len/2 > MIN_BUF_SHRINK_SIZE)
new_len /= 2;
log_fn(LOG_DEBUG,"Shrinking buffer from %d to %d bytes.",
(int)buf->len, (int)new_len);
buf_resize(buf, new_len);
}
/** Remove the first <b>n</b> bytes from buf.
*/
static INLINE void buf_remove_from_front(buf_t *buf, size_t n) {
tor_assert(buf->datalen >= n);
buf->datalen -= n;
memmove(buf->mem, buf->mem+n, buf->datalen);
buf_shrink_if_underfull(buf);
}
/** Make sure that the memory in buf ends with a zero byte. */
static INLINE int buf_nul_terminate(buf_t *buf)
{
if (buf_ensure_capacity(buf,buf->datalen+1)<0)
return -1;
buf->mem[buf->datalen] = '\0';
return 0;
}
/** Create and return a new buf with capacity <b>size</b>.
*/
buf_t *buf_new_with_capacity(size_t size) {
buf_t *buf;
buf = tor_malloc(sizeof(buf_t));
buf->magic = BUFFER_MAGIC;
buf->mem = tor_malloc(size);
buf->len = size;
buf->datalen = 0;
// memset(buf->mem,0,size);
assert_buf_ok(buf);
return buf;
}
/** Allocate and return a new buffer with default capacity. */
buf_t *buf_new()
{
return buf_new_with_capacity(INITIAL_BUF_SIZE);
}
/** Remove all data from <b>buf</b> */
void buf_clear(buf_t *buf)
{
buf->datalen = 0;
}
/** Return the number of bytes stored in <b>buf</b> */
size_t buf_datalen(const buf_t *buf)
{
return buf->datalen;
}
/** Return the maximum bytes that can be stored in <b>buf</b> before buf
* needs to resize. */
size_t buf_capacity(const buf_t *buf)
{
return buf->len;
}
/** For testing only: Return a pointer to the raw memory stored in <b>buf</b>.
*/
const char *_buf_peek_raw_buffer(const buf_t *buf)
{
return buf->mem;
}
/** Release storage held by <b>buf</b>.
*/
void buf_free(buf_t *buf) {
assert_buf_ok(buf);
buf->magic = 0xDEADBEEF;
tor_free(buf->mem);
tor_free(buf);
}
/** Read from socket <b>s</b>, writing onto end of <b>buf</b>. Read at most
* <b>at_most</b> bytes, resizing the buffer as necessary. If read()
* returns 0, set <b>*reached_eof</b> to 1 and return 0. Return -1 on error;
* else return the number of bytes read. Return 0 if read() would
* block.
*/
int read_to_buf(int s, size_t at_most, buf_t *buf, int *reached_eof) {
int read_result;
assert_buf_ok(buf);
tor_assert(reached_eof && (s>=0));
if (buf_ensure_capacity(buf,buf->datalen+at_most))
return -1;
if(at_most + buf->datalen > buf->len)
at_most = buf->len - buf->datalen; /* take the min of the two */
if(at_most == 0)
return 0; /* we shouldn't read anything */
// log_fn(LOG_DEBUG,"reading at most %d bytes.",at_most);
read_result = recv(s, buf->mem+buf->datalen, at_most, 0);
if (read_result < 0) {
if(!ERRNO_IS_EAGAIN(tor_socket_errno(s))) { /* it's a real error */
return -1;
}
return 0; /* would block. */
} else if (read_result == 0) {
log_fn(LOG_DEBUG,"Encountered eof");
*reached_eof = 1;
return 0;
} else { /* we read some bytes */
buf->datalen += read_result;
log_fn(LOG_DEBUG,"Read %d bytes. %d on inbuf.",read_result,
(int)buf->datalen);
return read_result;
}
}
/** As read_to_buf, but reads from a TLS connection.
*/
int read_to_buf_tls(tor_tls *tls, size_t at_most, buf_t *buf) {
int r;
tor_assert(tls);
assert_buf_ok(buf);
log_fn(LOG_DEBUG,"start: %d on buf, %d pending, at_most %d.",
(int)buf_datalen(buf), (int)tor_tls_get_pending_bytes(tls),
(int)at_most);
if (buf_ensure_capacity(buf, at_most+buf->datalen))
return TOR_TLS_ERROR;
if (at_most + buf->datalen > buf->len)
at_most = buf->len - buf->datalen;
if (at_most == 0)
return 0;
log_fn(LOG_DEBUG,"before: %d on buf, %d pending, at_most %d.",
(int)buf_datalen(buf), (int)tor_tls_get_pending_bytes(tls),
(int)at_most);
assert_no_tls_errors();
r = tor_tls_read(tls, buf->mem+buf->datalen, at_most);
if (r<0)
return r;
buf->datalen += r;
log_fn(LOG_DEBUG,"Read %d bytes. %d on inbuf; %d pending",r,
(int)buf->datalen,(int)tor_tls_get_pending_bytes(tls));
return r;
}
/** Write data from <b>buf</b> to the socket <b>s</b>. Write at most
* <b>*buf_flushlen</b> bytes, decrement <b>*buf_flushlen</b> by
* the number of bytes actually written, and remove the written bytes
* from the buffer. Return the number of bytes written on success,
* -1 on failure. Return 0 if write() would block.
*/
int flush_buf(int s, buf_t *buf, int *buf_flushlen)
{
int write_result;
assert_buf_ok(buf);
tor_assert(buf_flushlen && (s>=0) && ((unsigned)*buf_flushlen <= buf->datalen));
if(*buf_flushlen == 0) /* nothing to flush */
return 0;
write_result = send(s, buf->mem, *buf_flushlen, 0);
if (write_result < 0) {
if(!ERRNO_IS_EAGAIN(tor_socket_errno(s))) { /* it's a real error */
return -1;
}
log_fn(LOG_DEBUG,"write() would block, returning.");
return 0;
} else {
*buf_flushlen -= write_result;
buf_remove_from_front(buf, write_result);
log_fn(LOG_DEBUG,"%d: flushed %d bytes, %d ready to flush, %d remain.",
s,write_result,*buf_flushlen,(int)buf->datalen);
return write_result;
}
}
/** As flush_buf, but writes data to a TLS connection.
*/
int flush_buf_tls(tor_tls *tls, buf_t *buf, int *buf_flushlen)
{
int r;
assert_buf_ok(buf);
tor_assert(tls && buf_flushlen);
/* we want to let tls write even if flushlen is zero, because it might
* have a partial record pending */
r = tor_tls_write(tls, buf->mem, *buf_flushlen);
if (r < 0) {
return r;
}
*buf_flushlen -= r;
buf_remove_from_front(buf, r);
log_fn(LOG_DEBUG,"flushed %d bytes, %d ready to flush, %d remain.",
r,*buf_flushlen,(int)buf->datalen);
return r;
}
/** Append <b>string_len</b> bytes from <b>string</b> to the end of
* <b>buf</b>.
*
* Return the new length of the buffer on success, -1 on failure.
*/
int write_to_buf(const char *string, int string_len, buf_t *buf) {
/* append string to buf (growing as needed, return -1 if "too big")
* return total number of bytes on the buf
*/
tor_assert(string);
assert_buf_ok(buf);
if (buf_ensure_capacity(buf, buf->datalen+string_len)) {
log_fn(LOG_WARN, "buflen too small, can't hold %d bytes.", (int)buf->datalen+string_len);
return -1;
}
memcpy(buf->mem+buf->datalen, string, string_len);
buf->datalen += string_len;
log_fn(LOG_DEBUG,"added %d bytes to buf (now %d total).",string_len, (int)buf->datalen);
return buf->datalen;
}
/** Remove <b>string_len</b> bytes from the front of <b>buf</b>, and store them
* into <b>string</b>. Return the new buffer size. <b>string_len</b> must be \<=
* the number of bytes on the buffer.
*/
int fetch_from_buf(char *string, size_t string_len, buf_t *buf) {
/* There must be string_len bytes in buf; write them onto string,
* then memmove buf back (that is, remove them from buf).
*
* Return the number of bytes still on the buffer. */
tor_assert(string);
tor_assert(string_len <= buf->datalen); /* make sure we don't ask for too much */
assert_buf_ok(buf);
memcpy(string,buf->mem,string_len);
buf_remove_from_front(buf, string_len);
return buf->datalen;
}
/** There is a (possibly incomplete) http statement on <b>buf</b>, of the
* form "\%s\\r\\n\\r\\n\%s", headers, body. (body may contain nuls.)
* If a) the headers include a Content-Length field and all bytes in
* the body are present, or b) there's no Content-Length field and
* all headers are present, then:
*
* - strdup headers into <b>*headers_out</b>, and nul-terminate it.
* - memdup body into <b>*body_out</b>, and nul-terminate it.
* - Then remove them from <b>buf</b>, and return 1.
*
* - If headers or body is NULL, discard that part of the buf.
* - If a headers or body doesn't fit in the arg, return -1.
*
* Else, change nothing and return 0.
*/
int fetch_from_buf_http(buf_t *buf,
char **headers_out, int max_headerlen,
char **body_out, int *body_used, int max_bodylen) {
char *headers, *body, *p;
int headerlen, bodylen, contentlen;
assert_buf_ok(buf);
headers = buf->mem;
if (buf_nul_terminate(buf)<0) {
log_fn(LOG_WARN,"Couldn't nul-terminate buffer");
return -1;
}
body = strstr(headers,"\r\n\r\n");
if (!body) {
log_fn(LOG_DEBUG,"headers not all here yet.");
return 0;
}
body += 4; /* Skip the the CRLFCRLF */
headerlen = body-headers; /* includes the CRLFCRLF */
bodylen = buf->datalen - headerlen;
log_fn(LOG_DEBUG,"headerlen %d, bodylen %d.", headerlen, bodylen);
if(headers_out && max_headerlen <= headerlen) {
log_fn(LOG_WARN,"headerlen %d larger than %d. Failing.", headerlen, max_headerlen-1);
return -1;
}
if(body_out && max_bodylen <= bodylen) {
log_fn(LOG_WARN,"bodylen %d larger than %d. Failing.", bodylen, max_bodylen-1);
return -1;
}
#define CONTENT_LENGTH "\r\nContent-Length: "
p = strstr(headers, CONTENT_LENGTH);
if (p) {
contentlen = atoi(p+strlen(CONTENT_LENGTH));
/* if content-length is malformed, then our body length is 0. fine. */
log_fn(LOG_DEBUG,"Got a contentlen of %d.",contentlen);
if(bodylen < contentlen) {
log_fn(LOG_DEBUG,"body not all here yet.");
return 0; /* not all there yet */
}
if(bodylen > contentlen) {
bodylen = contentlen;
log_fn(LOG_DEBUG,"bodylen reduced to %d.",bodylen);
}
}
/* all happy. copy into the appropriate places, and return 1 */
if(headers_out) {
*headers_out = tor_malloc(headerlen+1);
memcpy(*headers_out,buf->mem,headerlen);
(*headers_out)[headerlen] = 0; /* null terminate it */
}
if(body_out) {
tor_assert(body_used);
*body_used = bodylen;
*body_out = tor_malloc(bodylen+1);
memcpy(*body_out,buf->mem+headerlen,bodylen);
(*body_out)[bodylen] = 0; /* null terminate it */
}
buf_remove_from_front(buf, headerlen+bodylen);
return 1;
}
/** There is a (possibly incomplete) socks handshake on <b>buf</b>, of one
* of the forms
* - socks4: "socksheader username\\0"
* - socks4a: "socksheader username\\0 destaddr\\0"
* - socks5 phase one: "version #methods methods"
* - socks5 phase two: "version command 0 addresstype..."
* If it's a complete and valid handshake, and destaddr fits in
* MAX_SOCKS_ADDR_LEN bytes, then pull the handshake off the buf,
* assign to <b>req</b>, and return 1.
*
* If it's invalid or too big, return -1.
*
* Else it's not all there yet, leave buf alone and return 0.
*
* If you want to specify the socks reply, write it into <b>req->reply</b>
* and set <b>req->replylen</b>, else leave <b>req->replylen</b> alone.
*
* If returning 0 or -1, <b>req->address</b> and <b>req->port</b> are undefined.
*/
int fetch_from_buf_socks(buf_t *buf, socks_request_t *req) {
unsigned char len;
char *tmpbuf=NULL;
uint32_t destip;
enum {socks4, socks4a} socks4_prot = socks4a;
char *next, *startaddr;
struct in_addr in;
if(buf->datalen < 2) /* version and another byte */
return 0;
switch(*(buf->mem)) { /* which version of socks? */
case 5: /* socks5 */
if(req->socks_version != 5) { /* we need to negotiate a method */
unsigned char nummethods = (unsigned char)*(buf->mem+1);
tor_assert(!req->socks_version);
if(buf->datalen < 2u+nummethods)
return 0;
if(!nummethods || !memchr(buf->mem+2, 0, nummethods)) {
log_fn(LOG_WARN,"socks5: offered methods don't include 'no auth'. Rejecting.");
req->replylen = 2; /* 2 bytes of response */
req->reply[0] = 5; /* socks5 reply */
req->reply[1] = '\xFF'; /* reject all methods */
return -1;
}
buf_remove_from_front(buf,2+nummethods);/* remove packet from buf */
req->replylen = 2; /* 2 bytes of response */
req->reply[0] = 5; /* socks5 reply */
req->reply[1] = 0; /* choose the 'no auth' method */
req->socks_version = 5; /* remember that we've already negotiated auth */
log_fn(LOG_DEBUG,"socks5: accepted method 0");
return 0;
}
/* we know the method; read in the request */
log_fn(LOG_DEBUG,"socks5: checking request");
if(buf->datalen < 8) /* basic info plus >=2 for addr plus 2 for port */
return 0; /* not yet */
req->command = (unsigned char) *(buf->mem+1);
if(req->command != SOCKS_COMMAND_CONNECT &&
req->command != SOCKS_COMMAND_RESOLVE) {
/* not a connect or resolve? we don't support it. */
log_fn(LOG_WARN,"socks5: command %d not recognized. Rejecting.",
req->command);
return -1;
}
switch(*(buf->mem+3)) { /* address type */
case 1: /* IPv4 address */
log_fn(LOG_DEBUG,"socks5: ipv4 address type");
if(buf->datalen < 10) /* ip/port there? */
return 0; /* not yet */
destip = ntohl(*(uint32_t*)(buf->mem+4));
in.s_addr = htonl(destip);
tmpbuf = inet_ntoa(in);
if(strlen(tmpbuf)+1 > MAX_SOCKS_ADDR_LEN) {
log_fn(LOG_WARN,"socks5 IP takes %d bytes, which doesn't fit in %d. Rejecting.",
(int)strlen(tmpbuf)+1,(int)MAX_SOCKS_ADDR_LEN);
return -1;
}
strcpy(req->address,tmpbuf);
req->port = ntohs(*(uint16_t*)(buf->mem+8));
buf_remove_from_front(buf, 10);
return 1;
case 3: /* fqdn */
log_fn(LOG_DEBUG,"socks5: fqdn address type");
len = (unsigned char)*(buf->mem+4);
if(buf->datalen < 7u+len) /* addr/port there? */
return 0; /* not yet */
if(len+1 > MAX_SOCKS_ADDR_LEN) {
log_fn(LOG_WARN,"socks5 hostname is %d bytes, which doesn't fit in %d. Rejecting.",
len+1,MAX_SOCKS_ADDR_LEN);
return -1;
}
memcpy(req->address,buf->mem+5,len);
req->address[len] = 0;
req->port = ntohs(get_uint16(buf->mem+5+len));
buf_remove_from_front(buf, 5+len+2);
return 1;
default: /* unsupported */
log_fn(LOG_WARN,"socks5: unsupported address type %d. Rejecting.",*(buf->mem+3));
return -1;
}
tor_assert(0);
case 4: /* socks4 */
/* http://archive.socks.permeo.com/protocol/socks4.protocol */
/* http://archive.socks.permeo.com/protocol/socks4a.protocol */
req->socks_version = 4;
if(buf->datalen < SOCKS4_NETWORK_LEN) /* basic info available? */
return 0; /* not yet */
req->command = (unsigned char) *(buf->mem+1);
if(req->command != SOCKS_COMMAND_CONNECT &&
req->command != SOCKS_COMMAND_RESOLVE) {
/* not a connect or resolve? we don't support it. */
log_fn(LOG_WARN,"socks4: command %d not recognized. Rejecting.",
req->command);
return -1;
}
req->port = ntohs(*(uint16_t*)(buf->mem+2));
destip = ntohl(*(uint32_t*)(buf->mem+4));
if((!req->port && req->command!=SOCKS_COMMAND_RESOLVE) || !destip) {
log_fn(LOG_WARN,"socks4: Port or DestIP is zero. Rejecting.");
return -1;
}
if(destip >> 8) {
log_fn(LOG_DEBUG,"socks4: destip not in form 0.0.0.x.");
in.s_addr = htonl(destip);
tmpbuf = inet_ntoa(in);
if(strlen(tmpbuf)+1 > MAX_SOCKS_ADDR_LEN) {
log_fn(LOG_WARN,"socks4 addr (%d bytes) too long. Rejecting.",
(int)strlen(tmpbuf));
return -1;
}
log_fn(LOG_DEBUG,"socks4: successfully read destip (%s)", tmpbuf);
socks4_prot = socks4;
}
next = memchr(buf->mem+SOCKS4_NETWORK_LEN, 0,
buf->datalen-SOCKS4_NETWORK_LEN);
if(!next) {
log_fn(LOG_DEBUG,"socks4: Username not here yet.");
return 0;
}
startaddr = next+1;
if(socks4_prot == socks4a) {
next = memchr(startaddr, 0, buf->mem+buf->datalen-startaddr);
if(!next) {
log_fn(LOG_DEBUG,"socks4: Destaddr not here yet.");
return 0;
}
if(MAX_SOCKS_ADDR_LEN <= next-startaddr) {
log_fn(LOG_WARN,"socks4: Destaddr too long. Rejecting.");
return -1;
}
}
log_fn(LOG_DEBUG,"socks4: Everything is here. Success.");
strcpy(req->address, socks4_prot == socks4 ? tmpbuf : startaddr);
/* XXX on very old netscapes (socks4) the next line triggers an
* assert, because next-buf->mem+1 is greater than buf->datalen.
*/
buf_remove_from_front(buf, next-buf->mem+1); /* next points to the final \0 on inbuf */
return 1;
case 'G': /* get */
case 'H': /* head */
case 'P': /* put/post */
case 'C': /* connect */
strcpy(req->reply,
"HTTP/1.0 501 Tor is not an HTTP Proxy\r\n"
"Content-Type: text/html; charset=iso-8859-1\r\n\r\n"
"<html>\n"
"<head>\n"
"<title>Tor is not an HTTP Proxy</title>\n"
"</head>\n"
"<body>\n"
"<h1>Tor is not an HTTP Proxy</h1>\n"
"<p>\n"
"It appears you have configured your web browser to use Tor as an HTTP Proxy.\n"
"This is not correct: Tor provides a SOCKS proxy. Please configure your\n"
"client accordingly.\n"
"</p>\n"
"<p>\n"
"See <a href=\"http://freehaven.net/tor/cvs/INSTALL\">http://freehaven.net/tor/cvs/INSTALL</a> for more information.\n"
"<!-- Plus this comment, to make the body response more than 512 bytes, so IE will be willing to display it. Comment comment comment comment comment comment comment comment comment comment comment comment.-->\n"
"</p>\n"
"</body>\n"
"</html>\n"
);
req->replylen = strlen(req->reply)+1;
/* fall through */
default: /* version is not socks4 or socks5 */
log_fn(LOG_WARN,"Socks version %d not recognized. (Tor is not an http proxy.)",
*(buf->mem));
return -1;
}
}
/** Log an error and exit if <b>buf</b> is corrupted.
*/
void assert_buf_ok(buf_t *buf)
{
tor_assert(buf);
tor_assert(buf->magic == BUFFER_MAGIC);
tor_assert(buf->mem);
tor_assert(buf->datalen <= buf->len);
}
/*
Local Variables:
mode:c
indent-tabs-mode:nil
c-basic-offset:2
End:
*/

Some files were not shown because too many files have changed in this diff Show More