Control Port Filter Proxy Python (cpfpy) / anon-ws-disable-stacked-tor

Relaying “QUIT” as is to Tor’s ControlPort and relaying that answer back to the client seems like the most compatible method?

Relaying "QUIT" as is to Tor's ControlPort and relaying that answer back to the client seems like the most compatible method?

Yes. Then the anon-shared-helper-scripts are OK. stem is doing the work (writing “QUIT” when the request is successful).

I am running cpfp.py with a simplified TCP handler (client side).

The “QUIT” code block is commented, as it was returning “250 Closing connection” without actually closing Tor control port socket.

The “AUTHENTICATE” code block is commented too. All the requests are authenticated in the do_request_real() function.

Removed fake AUTHENTICATE in TCP handler (returning "250 OK"). Real a… · troubadoour/control-port-filter-python@349184d · GitHub

I find the following all a bit counter intuitive.

EXCESSIVE_STRING_LENGTH = 128

if LIMIT_STRING_LENGTH: # Used in check_answer() MAX_LINESIZE = EXCESSIVE_STRING_LENGTH else: # In my tests, the answer from "net_listeners_socks" was 1849 bytes long. MAX_LINESIZE = 2048

Especially having the DISABLE_FILTERING option effectively influence MAX_LINESIZE.

if DISABLE_FILTERING: # Some answers are longer than 8 Kb (arm). answer = sock.recv(16384) else: answer = sock.recv(MAX_LINESIZE)

Wouldn’t it be simpler to set a reasonable? 16384? And then not conditionally modify it anymore?

Wouldn't it be simpler to set a reasonable? 16384? And then not conditionally modify it anymore?

Yes, it makes sense. I just thought 16 KB might be long.
Removed fake AUTHENTICATE in TCP handler (returning "250 OK"). Real a… · troubadoour/control-port-filter-python@349184d · GitHub.

Also put back the fake “AUTHENTICATE” in TCP handler. It’s really required by Tor Browser.
Put back AUTHENTICATE in TCP handler · troubadoour/control-port-filter-python@424459a · GitHub

Pushed a batch of commits. Please review.

Will start with logging.

Thanks for splitting the git commits into logical changes. Made it much simpler to follow your thoughts. Didn’t do a practical test (could do if you think it’s ready), but looks good overall at the source level.

[I viewed commit by commit using git-showtool (version control - How can I view the output of `git show` in a diff viewer like meld, kdiff3, etc - Stack Overflow).]

This one is probably a bug.

if not DISABLE_FILTERING: if not answer.startswith("250"): raise UnexpectedAnswer("Request failed: " + request)

Why should we mind if someone test-wise added “test” to the white list?

For comparison, arms control port interpreter (as long as Damian does not remove that feature). (For some reason it shows own commands in upper case. Anyhow. Still useful because it does the authentication.)

Command.

test

Tor ControlPort reply.

510 Unrecognized command "test"

Looks totally legitimate to me. Raising an exception seems to make cpfp do something it’s not supposed to.

By the way, using nc as in the example below, you can directly talk to Tor’s ControlPort without involving arm. You need to manually authenticate then, though.

nc 127.0.0.1 9051

I would like to reintroduce some form of configurable max line size, so it’s not hardcoded to 16384.

Added two minor comment changes on top.

Pushed some commits for an initial logging implementation.

[I viewed commit by commit using git-showtool (http://stackoverflow.com/questions/17558221/how-can-i-view-the-output-of-git-show-in-a-diff-viewer-like-meld-kdiff3-etc).]

Thanks for the tip. Great one!

By the way, for “git diff”, I’m using kdiff3. I find that the output is much more readable than meld. The tip from Redirecting… stills works when just replacing meld by kdiff3. Another bonus is that kdiff3 do not install Gnome libraries.

This one is probably a bug.

if not DISABLE_FILTERING: if not answer.startswith("250"): raise UnexpectedAnswer("Request failed: " + request)

Removed the block in Commented answer check in do_request_real() function. · troubadoour/control-port-filter-python@a7e6c6f · GitHub.

I would like to reintroduce some form of configurable max line size, so it's not hardcoded to 16384.

Do we need both configuration variables CONTROL_PORT_FILTER_LIMIT_STRING_LENGTH and CONTROL_PORT_FILTER_EXCESSIVE_STRING_LENGTH? We could use the latter only and set it to 0 (zero) to use the max value (16384).

Looks good.

Do we need both configuration variables CONTROL_PORT_FILTER_LIMIT_STRING_LENGTH and CONTROL_PORT_FILTER_EXCESSIVE_STRING_LENGTH? We could use the latter only and set it to 0 (zero) to use the max value (16384).[/quote]
No, you’re right. Two options for this is too much. We support a magic value for CONTROL_PORT_FILTER_LIMIT_STRING_LENGTH such as “-1” to completely disable it. Default to 16384. Otherwise anything the user sets. How does that sound?

How does that sound?

Sensible. :slight_smile:

Pushed a few more commits (logging).

More commits. Error handling and logging.

Looks good overall. I am not sure about this. What reaction would be the most compatible one in that case. I guess we couldn’t mimic a real Tor ControlPort, because in that case they could not even open the socket. But to even know about the attempt, they already have a socket to cpfp open.

if not os.path.exists(SOCKET): #reply = "255 tor is not running" #print "tor is not running" #return reply + '\r\n' logger.critical('Tor is not running')

Anyhow. Such details corner cases can be sorted out later. But in any case, I would think we should not claim “tor is not running”, but rather stay to what we really know “/path/to/socket does not exist”. I am thinking ahead here. If someone wanted to use on Fedora or so and if they hypothetically have the Tor ControlSocket in another file location, I’d rather let them know that in the logs and not claim something that is not necessarily the case (Tor not running).

Right. When saying “Tor is not running”, we are definitely extrapolating. Changed it, along with some cleaning/comments in another commit.

Pushed two commits.

Added LIMIT_STRING_LENGTH. If the configuration variable is set to “-1”, it falls back to default (16384) which is also the maximum that will be allowed with this approach.

Does that make sense?

sock.recv() cannot be run without argument? It should use the maximum available. Currently -1 = default = 16384.

sock.recv() cannot be run without argument? It should use the maximum available. Currently -1 = default = 16384.

I do not know what the maximum available would be. I have tried 4GB, it 's accepted but it does not make much sense. It is set to 64KB for the moment, which should be enough for a control port, I believe.
"LIMIT_STRING_LENGTH = 65536" when disabled. · troubadoour/control-port-filter-python@f872414 · GitHub

Ok.