Opened 6 years ago

Closed 4 years ago

#6609 closed enhancement (wontfix)

Proposal to add tor-connect utility to tor-core distribution

Reported by: tri Owned by:
Priority: Medium Milestone: Tor: 0.2.5.x-final
Component: Core Tor/Tor Version:
Severity: Keywords: tor-client
Cc: Actual Points:
Parent ID: Points:
Reviewer: Sponsor:

Description

I've been using tor on and off for years, but there has been one utility
that I've been missing in tor tools. That utility is tor-connect that
could be used as a proxy command for various utilities that otherwise
lack proxy capability. It is also often that "torify" kind of patching
of the shared libraries in run time doesn't really do the trick.

So silent wishing got me nowhere, so I wrote it myself by using
tor-0.2.2.38/src/tools/tor-resolve.c as a template. It needed quite mych
hacking, but at least it provided with a "style guide" so my stuff
doesn't appear totally different when compared to other tor code.

The idea was plain and simple to have an utility that could be called
from ssh client using following configuration in .ssh/config

Host *.onion

ProxyCommand tor-connect %h %p

And maybe for some other hosts too that user logs in but doesn't want to
tell his ip.

Host *.cn *.ru *.gov

ProxyCommand tor-connect %h %p

The utility is also usable with all other software that provide tcp
connection opening using proxy commands. I've used at least some email
client in Linux that provide exactly that for IMAP and SMTP connections.
With those I've of course mainly used ssh to relay connections, but
there is no reason why tor-connect wouldn't work there too.

Full usage is extremely simple:

tor-resolve [-4 | -5] [-v] [-p port] hostname port [sockshost:socksport]

I propose to include tor-connect.c to tor-0.2.X/src/tools directory and
making it installable to $prefix/bin along with tor-resolve. For
automake stuff it probably needs check for existence of sys/select.h
somewhere. Other than that, it seems to work fine. As I write, I have
also ssh connection going over tor opened via tor-connect. So far it
has worked flawlessly. At least I find this utility very useful.

Actually I'd like to see it also in browser bundle, because browser
bundle is something that people (or at least I) run in laptops rather
than separate tor instance. However the ssh ProxyCommand would be very
usable in this case too. One just has to start TorBrowser / Vidalia
first, but then it rocks like a dream.

Please find the source code attached and notify proper person about the
stuff. I hereby contribute the code included in this mail to Tor Project.

Child Tickets

Attachments (2)

tor-connect.c (15.6 KB) - added by tri 6 years ago.
tor-connect.c
tor-connect.patch (17.6 KB) - added by tri 6 years ago.
Complete patch against current head of master branch in tor git.

Download all attachments as: .zip

Change History (20)

Changed 6 years ago by tri

Attachment: tor-connect.c added

tor-connect.c

comment:1 Changed 6 years ago by tri

From: Robert Ransom <rransom.8774@…>

  • Please open a Trac ticket. Your code might be useful, but it'll get

lost in the flood on tor-assistants if you don't post it to Trac.

  • There are already several programs which perform this task,

including =E2=80=98socat=E2=80=99, at least some of the several (all subtly
incompatible) programs called =E2=80=98nc=E2=80=99 (usually packaged as =E2=
=80=98netcat=E2=80=99), and
a program known variously as =E2=80=98proxy-connect=E2=80=99, =E2=80=98conn=
ect-proxy=E2=80=99, or
=E2=80=98connect=E2=80=99.

  • Tools of this form are only suitable for use with programs which

support using an external program as a =E2=80=98proxy=E2=80=99. OpenSSH su=
pports
this, as does PuTTY (but that has seemingly good SOCKS support
built-in anyway), but most of the programs that people want to point
at Tor do not support using external commands as proxies.

  • On every operating system on which using an external command as a

proxy is likely to work (i.e. Linux and MacOS), the copy of Tor
packaged in TBB is configured to choose a random SOCKS server port
every time it runs. There is no good way to communicate Tor's current
SocksPort to any program run separately from the bundle.

Robert Ransom

comment:2 in reply to:  1 ; Changed 6 years ago by tri

  • Please open a Trac ticket. Your code might be useful, but it'll get

lost in the flood on tor-assistants if you don't post it to Trac.

Said and done

  • There are already several programs which perform this task,

including ‘socat’, at least some of the several (all subtly
incompatible) programs called ‘nc’ (usually packaged as ‘netcat’), and
a program known variously as ‘proxy-connect’, ‘connect-proxy’, or
‘connect’.

I think it's justified to have a tool to perform this task within the
tor core tools so that it's easily available with tor and can also
be enhanced to automatically detect tor proxy endpoint like other
tools should there be a method introduced for that in some later
point. tor-connect is also a great tool for testing connections
through tor and to hidden services, because it minimizes the
number of moving parts.

  • Tools of this form are only suitable for use with programs which

support using an external program as a ‘proxy’. OpenSSH supports
this, as does PuTTY (but that has seemingly good SOCKS support
built-in anyway), but most of the programs that people want t

Yes, I know. But for example OpenSSH doesn't support SOCKS in
the client side connections. And as I mentioned there are at least
a few programs with this capability commonly bundled in linux
distributions.

  • On every operating system on which using an external command as a

proxy is likely to work (i.e. Linux and MacOS), the copy of Tor
packaged in TBB is configured to choose a random SOCKS server port
every time it runs. There is no good way to communicate Tor's current
SocksPort to any program run separately from the bundle.

I know. That's why I'd put the command into the bundle and pass the
port information using the same'ish mechanism used when passing
the information to the browser. The port number anyways appears
semi-magically in the browser configuration.

comment:3 in reply to:  2 ; Changed 6 years ago by rransom

Replying to tri:

  • On every operating system on which using an external command as a

proxy is likely to work (i.e. Linux and MacOS), the copy of Tor
packaged in TBB is configured to choose a random SOCKS server port
every time it runs. There is no good way to communicate Tor's current
SocksPort to any program run separately from the bundle.

I know. That's why I'd put the command into the bundle and pass the
port information using the same'ish mechanism used when passing
the information to the browser. The port number anyways appears
semi-magically in the browser configuration.

Tor communicates its SocksPort to Vidalia using the Tor control-port protocol (how that gets set up is rather ugly). Vidalia then provides the SOCKS proxy port to TBB-Firefox by setting an environment variable. This technique cannot work for any process that is not started by Vidalia.

comment:4 in reply to:  3 ; Changed 6 years ago by tri

Replying to rransom:

Tor communicates its SocksPort to Vidalia using the Tor control-port protocol (how that gets set up is rather ugly). Vidalia then provides the SOCKS proxy port to TBB-Firefox by setting an environment variable. This technique cannot work for any process that is not started by Vidalia.

I know. However tor browser does write the socks configuration to disk so there aren't really too many security reasons not to store same information for example to some fixed file within tor browser tree in -r-------- mode.

e.g. Library/Application\ Support/generic/proxy.dat

But anyways. My main aim is to get the tool into tor distribution. Having it in tbb would be a big bonus.

comment:5 Changed 6 years ago by nickm

call me cautiously positive on the basic concept, I think.

comment:6 Changed 6 years ago by tri

{{{
$ ~/Downloads/TorBrowser_en-US.app> sed -n 's/.*user_pref("network.proxy.socks_port", \([0-9]*\));.*/\1/p' 'Library/Application Support/Firefox/Profiles/profile/prefs.js'
53432
}}}

comment:7 in reply to:  6 Changed 6 years ago by tri

Oh, my. The formatting woes, but just a demonstration how to dig the port number if the directory of the bundle is known.

comment:8 in reply to:  4 Changed 6 years ago by rransom

Replying to tri:

Replying to rransom:

Tor communicates its SocksPort to Vidalia using the Tor control-port protocol (how that gets set up is rather ugly). Vidalia then provides the SOCKS proxy port to TBB-Firefox by setting an environment variable. This technique cannot work for any process that is not started by Vidalia.

I know. However tor browser does write the socks configuration to disk so there aren't really too many security reasons not to store same information for example to some fixed file within tor browser tree in -r-------- mode.

The part of that idea that I thought would be unpleasant was that tor-connect would have to find that file -- but I taught start-tor-browser to find itself (and the rest of TBB) in shell script, and it's much easier in C. (man 3 realpath)

So the remaining issues are (a) which process should write the file, (b) what format the file should have, and (c) which Git repo tor-connect should live in. (Please read the description of ‘ControlPortWriteToFile’ in the tor(1) man page if you haven't already. But don't assume that that's the right format for a file containing Tor's SocksPort.)

But anyways. My main aim is to get the tool into tor distribution. Having it in tbb would be a big bonus.

I'm not sure that the same program will be suitable for inclusion in both Tor and TBB. (On the other hand, TBB applies patches to Vidalia and Firefox; applying a patch to a small tool in the Tor source tarball might be OK.)

comment:9 Changed 6 years ago by tri

I think the correct place is in tor (src/tools).

But doesn't the browser bundle include tor binary? Couldn't the tor-connect binary be just included alongside with that to TorBrowser_en-US.app/Contents/MacOS (or whatever is the place for different systems).

comment:10 Changed 6 years ago by tri

Stripped binary when compiled with default compilation flags (same as tor-resolve) in Linux (OpenSUSE 12.1) is 121984 bytes. However the text segment of the object is only 7112 bytes. Like tor-resolve, tor-connect relies on libraries in tor distribution so I guess that settles the issue on where it should live, unless it's discarded altogether or rewritten.

comment:11 Changed 6 years ago by tri

And actually there is a very nice feature in OSX that would go hand in hand with tor-connect. That feature is called Launch Agent. Most likely the same functionality can be achieved with inetd available in most unix derivatives.

In case of software without any proxy capability, Launch Agent can be configured to listen a local tcp port and when the incoming connection appears, then spawn the configured command so that stdin/stdout is bound to the connection socket. I've successfully used that with command like "ssh -W my.mail.intra.paranoid.com:143 firewall.paranoid.com" and configured Launch Agent to accept incoming connections to some predefined port and serving them with a command above. Then just configure a random mail software to use the said port as imap endpoint and it works as a dream.

With tor-connect this could be extremely easily applied to relay local port to some hidden service endpoint without application knowing anything about it.

Actually in addition to that, the same functionality could (and maybe should) be implemented directly to Vidalia. Another tab to settings having local relays to hidden services and columns local port, hidden service name, hidden service port. This could naturally be implemeted with help of tor-connect, but maybe it is simple enough to implement it as an integral part of Vidalia. However, it's all different story. Maybe I make another ticket about that.

Regardless of that, I'd import tor-connect to tor itself because it's also a handy testing tool.

comment:12 Changed 6 years ago by tri

Added #6611 to propose GUI configurable relays to Vidalia.

Changed 6 years ago by tri

Attachment: tor-connect.patch added

Complete patch against current head of master branch in tor git.

comment:13 Changed 6 years ago by tri

Even though proxy command functionality in software is somehow a bit kludgy, there is something to be said about it. It's trivial to implement. And in some cases you can do cool things with it, like enabling creating automatically nested ssh connections with openssh.

Just patched together an example code that can be used in opening a connection (returning a socket) but instead of really connecting somewhere, just creating a socketpair and executing the proxy process in the other end.

int proxy_command_connect(const char *proxy_command)
{
  int s[2];
  pid_t pid;
  char * const av[4] = { "/bin/sh", "-c", (char *)proxy_command, NULL };
  char * const ev[1] = { NULL };

  if (socketpair(AF_LOCAL, SOCK_STREAM, 0, s) != 0)
    return -1;
  pid = fork();
  if (pid < 0) {
    close(s[0]);
    close(s[1]);
    return -1;
  }

  if (pid == 0) {
#if 0
    /* This is just an example of how to drop possible root
       privileges.  More subtle approach is advisable. */
    setgroups(0, NULL);
    setgid(-1);
    setegid(-1);
    setuid(-1);
    seteuid(-1);
#endif
    close(s[0]);
    if (dup2(s[1], fileno(stdin)) < 0)
      goto child_error;
    if (dup2(s[1], fileno(stdout)) < 0)
      goto child_error;
    close(s[1]);
    s[1] = -1;
    execve(av[0], av, ev);
  child_error:
    if (s[1] >= 0)
      close(s[1]);
    close(fileno(stdin));
    close(fileno(stdout));
    close(fileno(stderr));
    exit(-1);
  }
  close(s[1]);
  return s[0];
}

One annoying thing exists, and that is almost no system can create TCP sockets with socketpair, and if the endpoint for some reason really must be a TCP socket, it's not nearly as trivial as the code above.

comment:14 Changed 6 years ago by nickm

Milestone: Tor: 0.2.4.x-final
Status: newneeds_review

comment:15 Changed 6 years ago by nickm

Keywords: tor-client added

comment:16 Changed 6 years ago by nickm

Component: Tor ClientTor

comment:17 Changed 5 years ago by nickm

Milestone: Tor: 0.2.4.x-finalTor: 0.2.5.x-final

Bumping to 0.2.5, along with other remaining noncritical enhancements.

comment:18 Changed 4 years ago by nickm

Resolution: wontfix
Status: needs_reviewclosed

Having looked over the code[*], and tried to find a good use case to justify this code with Tor, I think we should take a pass on merging unless there's some major point here that we're not seeing.

For nearly all use-cases, it's probably better to recommend that users use socat with appropriate options.

[*] BTW, you should know that "char" could be signed or unsigned, so doing tor_malloc(reply_buf[0]) is potentially disastrous.

Note: See TracTickets for help on using tickets.