user/dev discussion of public-inbox itself
 help / color / mirror / code / Atom feed
Search results ordered by [date|relevance]  view[summary|nested|Atom feed]
thread overview below | download mbox.gz: |
* [PATCH 6/8] lei: IMAP .onion support via --proxy=s switch
  2021-04-30  9:24  7% [PATCH 0/8] lei NNTP/IMAP .onion support and misc fixes Eric Wong
@ 2021-04-30  9:24  5% ` Eric Wong
  0 siblings, 0 replies; 2+ results
From: Eric Wong @ 2021-04-30  9:24 UTC (permalink / raw)
  To: meta

Mail::IMAPClient provides the ability to pass a pre-connected
Socket to it.  We can rely on this functionality to use
IO::Socket::Socks in place whatever socket class
Mail::IMAPClient chooses to use.

The --proxy=s is shared with curl(1), though we only support
socks5h:// at the moment.  Is there any need for SOCKS4 or SOCKS5
without name resolution?  Tor .onions require socks5h:// for
name resolution and to prevent data leakage.
---
 lib/PublicInbox/LEI.pm       | 12 ++++++++----
 lib/PublicInbox/LeiInput.pm  |  2 +-
 lib/PublicInbox/LeiToMail.pm |  4 ++--
 lib/PublicInbox/NetReader.pm | 31 ++++++++++++++++++++++++++++---
 4 files changed, 39 insertions(+), 10 deletions(-)

diff --git a/lib/PublicInbox/LEI.pm b/lib/PublicInbox/LEI.pm
index 6a82d497..bb67fc0b 100644
--- a/lib/PublicInbox/LEI.pm
+++ b/lib/PublicInbox/LEI.pm
@@ -188,7 +188,8 @@ our %CMD = ( # sorted in order of importance/use:
 	qw(stdin| threads|t from|f=s mid=s oid=s), @c_opt ],
 'tag' => [ 'KEYWORDS...',
 	'set/unset keywords and/or labels on message(s)',
-	qw(stdin| in-format|F=s input|i=s@ oid=s@ mid=s@), @c_opt,
+	qw(stdin| in-format|F=s input|i=s@ oid=s@ mid=s@),
+	qw(no-torsocks torsocks=s), PublicInbox::LeiQuery::curl_opt(), @c_opt,
 	pass_through('-kw:foo for delete') ],
 'forget' => [ '[--stdin|--oid=OID|--by-mid=MID]',
 	"exclude message(s) on stdin from `q' search results",
@@ -211,11 +212,12 @@ our %CMD = ( # sorted in order of importance/use:
 'import' => [ 'LOCATION...|--stdin',
 	'one-time import/update from URL or filesystem',
 	qw(stdin| offset=i recursive|r exclude=s include|I=s
-	lock=s@ in-format|F=s kw! verbose|v+ incremental! mail-sync!), @c_opt ],
+	lock=s@ in-format|F=s kw! verbose|v+ incremental! mail-sync!),
+	qw(no-torsocks torsocks=s), PublicInbox::LeiQuery::curl_opt(), @c_opt ],
 'convert' => [ 'LOCATION...|--stdin',
 	'one-time conversion from URL or filesystem to another format',
-	qw(stdin| in-format|F=s out-format|f=s output|mfolder|o=s
-	lock=s@ kw!), @c_opt ],
+	qw(stdin| in-format|F=s out-format|f=s output|mfolder|o=s lock=s@ kw!),
+	qw(no-torsocks torsocks=s), PublicInbox::LeiQuery::curl_opt(), @c_opt ],
 'p2q' => [ 'FILE|COMMIT_OID|--stdin',
 	"use a patch to generate a query for `lei q --stdin'",
 	qw(stdin| want|w=s@ uri debug), @c_opt ],
@@ -277,6 +279,8 @@ my %OPTDESC = (
 'path-a|a=s' => 'pre-image pathname associated with OID',
 'path-b|b=s' => 'post-image pathname associated with OID',
 'git-dir=s@' => 'additional git repository to scan',
+'proxy=s' => [ 'PROTO://HOST[:PORT]', # shared with curl(1)
+	"proxy for (e.g. `socks5h://0:9050')" ],
 'torsocks=s' => ['VAL|auto|no|yes',
 		'whether or not to wrap git and curl commands with torsocks'],
 'no-torsocks' => 'alias for --torsocks=no',
diff --git a/lib/PublicInbox/LeiInput.pm b/lib/PublicInbox/LeiInput.pm
index 277ad88d..86f300c3 100644
--- a/lib/PublicInbox/LeiInput.pm
+++ b/lib/PublicInbox/LeiInput.pm
@@ -294,7 +294,7 @@ $input is `eml', not --in-format=$in_fmt
 	}
 	if ($net) {
 		$net->{-can_die} = 1;
-		if (my $err = $net->errors) {
+		if (my $err = $net->errors($lei)) {
 			return $lei->fail($err);
 		}
 		$net->{quiet} = $lei->{opt}->{quiet};
diff --git a/lib/PublicInbox/LeiToMail.pm b/lib/PublicInbox/LeiToMail.pm
index fa3af710..eda4701c 100644
--- a/lib/PublicInbox/LeiToMail.pm
+++ b/lib/PublicInbox/LeiToMail.pm
@@ -351,14 +351,14 @@ sub new {
 		require PublicInbox::MboxReader;
 		$self->can("eml2$fmt") or die "bad mbox format: $fmt\n";
 		$self->{base_type} = 'mbox';
-	} elsif ($fmt =~ /\Aimaps?\z/) { # TODO .onion support
+	} elsif ($fmt =~ /\Aimaps?\z/) {
 		require PublicInbox::NetWriter;
 		require PublicInbox::URIimap;
 		my $net = PublicInbox::NetWriter->new;
 		$net->{quiet} = $lei->{opt}->{quiet};
 		my $uri = PublicInbox::URIimap->new($dst)->canonical;
 		$net->add_url($uri);
-		my $err = $net->errors;
+		my $err = $net->errors($lei);
 		return $lei->fail($err) if $err;
 		$uri->mailbox or return $lei->fail("No mailbox: $dst");
 		$self->{uri} = $uri;
diff --git a/lib/PublicInbox/NetReader.pm b/lib/PublicInbox/NetReader.pm
index b9365c05..ac23e701 100644
--- a/lib/PublicInbox/NetReader.pm
+++ b/lib/PublicInbox/NetReader.pm
@@ -7,6 +7,7 @@ use strict;
 use v5.10.1;
 use parent qw(Exporter PublicInbox::IPC);
 use PublicInbox::Eml;
+use PublicInbox::Config;
 our %IMAPflags2kw = map {; "\\\u$_" => $_ } qw(seen answered flagged draft);
 $IMAPflags2kw{'$Forwarded'} = 'forwarded';  # RFC 5550
 
@@ -51,7 +52,16 @@ sub mic_for ($$$$) { # mic = Mail::IMAPClient
 		%$common, # may set Starttls, Compress, Debug ....
 	};
 	require PublicInbox::IMAPClient;
-	my $mic = PublicInbox::IMAPClient->new(%$mic_arg) or
+	my %socks;
+	if ($lei && $lei->{socks5h}) {
+		my %opt = %{$lei->{socks5h}};
+		$opt{ConnectAddr} = delete $mic_arg->{Server};
+		$opt{ConnectPort} = delete $mic_arg->{Port};
+		$socks{Socket} = IO::Socket::Socks->new(%opt) or die
+			"E: <$url> ".eval('$IO::Socket::Socks::SOCKS_ERROR');
+		$self->{mic_socks5h} = \%opt;
+	}
+	my $mic = PublicInbox::IMAPClient->new(%$mic_arg, %socks) or
 		die "E: <$url> new: $@\n";
 
 	# default to using STARTTLS if it's available, but allow
@@ -331,7 +341,7 @@ sub add_url {
 }
 
 sub errors {
-	my ($self) = @_;
+	my ($self, $lei) = @_;
 	if (my $u = $self->{unsupported_url}) {
 		return "Unsupported URL(s): @$u";
 	}
@@ -343,6 +353,16 @@ sub errors {
 		eval { require Net::NNTP } or
 			die "Net::NNTP is required for NNTP:\n$@\n";
 	}
+	if ($lei && (($lei->{opt}->{proxy}//'') =~ m!\Asocks5h://
+				(?: \[ ([^\]]+) \] | ([^:/]+) )
+				(?::([0-9]+))?/?(?:,|\z)!ix)) {
+		my ($h, $p) = ($1 // $2, $3 + 0);
+		$h = '127.0.0.1' if $h eq '0';
+		eval { require IO::Socket::Socks } or die <<EOM;
+IO::Socket::Socks missing for socks5h://$h:$p
+EOM
+		$lei->{socks5h} = { ProxyAddr => $h, ProxyPort => $p };
+	}
 	undef;
 }
 
@@ -507,7 +527,12 @@ sub mic_get {
 			$mic_arg->{Authcallback} = $self->can($cb_name);
 		}
 	}
-	my $mic = PublicInbox::IMAPClient->new(%$mic_arg);
+	my %socks;
+	if (my $s5h = $self->{mic_socks5h}) {
+		$socks{Socket} = IO::Socket::Socks->new(%$s5h) or die
+			"E: <$$uri> ".eval('$IO::Socket::Socks::SOCKS_ERROR');
+	}
+	my $mic = PublicInbox::IMAPClient->new(%$mic_arg, %socks);
 	$cached //= {}; # invalid placeholder if no cache enabled
 	$mic && $mic->IsConnected ? ($cached->{$sec} = $mic) : undef;
 }

^ permalink raw reply related	[relevance 5%]

* [PATCH 0/8] lei NNTP/IMAP .onion support and misc fixes
@ 2021-04-30  9:24  7% Eric Wong
  2021-04-30  9:24  5% ` [PATCH 6/8] lei: IMAP .onion support via --proxy=s switch Eric Wong
  0 siblings, 1 reply; 2+ results
From: Eric Wong @ 2021-04-30  9:24 UTC (permalink / raw)
  To: meta

Attempting to use torsocks(1) for NNTP or IMAP could get tricky.
Fortunately, IO::Socket::Socks is packaged for on CentOS 7,
FreeBSD, and Debian, so it seems to be a reasonable way to
support NNTP and IMAP Tor onions.

--proxy= (shared with curl) is supported for one-off
command-line use, but imap.proxy and nntp.proxy are both
supported along with URL-matching variants with git 1.8.5 (or
git 2.26 for wildcard URL matching).

Only socks5h:// proxies are supported (the default with
IO::Socket::Socks), which is what Tor uses.  I doubt its worth
the effort (and potential for DNS request leaks) to support
prior versions of SOCKS in 2021.

Eric Wong (8):
  lei sucks: preserve utsname.machine, add "x86" where appropriate
  lei_curl: improve correctness of LD_PRELOAD check
  lei: kill old PIDs when dropping
  lei: ensure autoflush(1) is on STDERR
  net_reader: {nn,mic}_for: use prototypes for internal subs
  lei: IMAP .onion support via --proxy=s switch
  net_reader: Net::NNTP --proxy=socks5h:// support
  net_reader: support (imap|nntp).proxy in config file

 MANIFEST                        |  2 +
 lib/PublicInbox/Config.pm       |  1 +
 lib/PublicInbox/LEI.pm          | 24 ++++++++---
 lib/PublicInbox/LeiCurl.pm      |  2 +-
 lib/PublicInbox/LeiInput.pm     |  2 +-
 lib/PublicInbox/LeiSucks.pm     |  3 +-
 lib/PublicInbox/LeiToMail.pm    |  4 +-
 lib/PublicInbox/NetNNTPSocks.pm | 33 +++++++++++++++
 lib/PublicInbox/NetReader.pm    | 72 +++++++++++++++++++++++++++------
 xt/net_nntp_socks.t             | 22 ++++++++++
 10 files changed, 141 insertions(+), 24 deletions(-)
 create mode 100644 lib/PublicInbox/NetNNTPSocks.pm
 create mode 100644 xt/net_nntp_socks.t

^ permalink raw reply	[relevance 7%]

Results 1-2 of 2 | reverse | options above
-- pct% links below jump to the message on this page, permalinks otherwise --
2021-04-30  9:24  7% [PATCH 0/8] lei NNTP/IMAP .onion support and misc fixes Eric Wong
2021-04-30  9:24  5% ` [PATCH 6/8] lei: IMAP .onion support via --proxy=s switch Eric Wong

Code repositories for project(s) associated with this public inbox

	https://80x24.org/public-inbox.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).