Opened 5 years ago

Closed 5 years ago

#6383 closed project (fixed)

Email registration helper

Reported by: dcf Owned by: dcf
Priority: Medium Milestone:
Component: Archived/Flashproxy Version:
Severity: Keywords:
Cc: ln5 Actual Points:
Parent ID: Points:
Reviewer: Sponsor:

Description

Make a flashproxy-reg-email program.

My proposed idea for this: Make an SSL connection to smtp.gmail.com:587. Verify the certificate using the same pinned certificate used by Chromium from https://src.chromium.org/viewvc/chrome/trunk/src/net/base/transport_security_state_static.certs?view=markup (I think the order of that file is the same as enum SecondLevelDomainName in https://src.chromium.org/viewvc/chrome/trunk/src/net/base/transport_security_state.cc?view=markup). Encrypt the message body (containing the client IP address and port) using a public key generated specifically for this registration method. A backend program retrieves and decrypts the messages and sends them to the facilitator.

Most people probably use Gmail using a browser rather than STMP, so this may be conspicuous. I wouldn't want to take a chance of using a browser and possibly someone's identifiable cookies. Another possibility is for users to send their client registration using plaintext, manually with their own email client. But this has the big downsides of allowing Google to see all the registrations, and also we don't want to know people's email addresses.

Child Tickets

Change History (7)

comment:1 in reply to:  description ; Changed 5 years ago by dcf

Replying to dcf:

My proposed idea for this: Make an SSL connection to smtp.gmail.com:587.

Actually port 465 is the SSL port.

comment:2 in reply to:  1 ; Changed 5 years ago by dcf

Replying to dcf:

Replying to dcf:

My proposed idea for this: Make an SSL connection to smtp.gmail.com:587.

Actually port 465 is the SSL port.

smtp.gmail.com is for Gmail users to send from their @gmail.com address, and requires authenticating with a Google account username and password. To send mail to a designated Gmail address, you use gmail-smtp-in.l.google.com:

$ dig MX gmail.com
;; ANSWER SECTION:
gmail.com.              605     IN      MX      10 alt1.gmail-smtp-in.l.google.com.
gmail.com.              605     IN      MX      20 alt2.gmail-smtp-in.l.google.com.
gmail.com.              605     IN      MX      30 alt3.gmail-smtp-in.l.google.com.
gmail.com.              605     IN      MX      40 alt4.gmail-smtp-in.l.google.com.
gmail.com.              605     IN      MX      5 gmail-smtp-in.l.google.com.

But unfortunately, on first investigation this incoming SMTP doesn't support TLS, so our messages will be blockable just by grepping for whatever designated address we use.

comment:3 in reply to:  2 ; Changed 5 years ago by dcf

But unfortunately, on first investigation this incoming SMTP doesn't support TLS, so our messages will be blockable just by grepping for whatever designated address we use.

Ignoring the lack of TLS, here is a proof of concept for determining our external IP address and sending it in email to a Gmail address:

import re
import smtplib
import sys

smtp = smtplib.SMTP("gmail-smtp-in.l.google.com.", 25, "[127.0.0.1]")
smtp.set_debuglevel(1)

# Grep the EHLO response for our public IP address.
smtp.ehlo()
m = re.search(r'at your service, \[([\d.]+)\]', smtp.ehlo_resp)
if not m:
    print >> sys.stderr, "Could not determine external IP address."
    sys.exit(1)
client_spec = m.group(1)

smtp.sendmail("hoddwee@gmail.com", "hoddwee@gmail.com", """\
From: hoddwee@gmail.com
To: hoddwee@gmail.com
Subject: Flash proxy client registration

client=%s
""" % client_spec)
smtp.quit()

print "Registered %s." % client_spec

The messages end up in the spam folder, probably because we lack the authentication headers that gmail.com senders are supposed to have.

comment:4 in reply to:  3 Changed 5 years ago by dcf

Replying to dcf:

But unfortunately, on first investigation this incoming SMTP doesn't support TLS, so our messages will be blockable just by grepping for whatever designated address we use.

Ignoring the lack of TLS, here is a proof of concept for determining our external IP address and sending it in email to a Gmail address:

My bad, port 25 on gmail-smtp-in.l.google.com has STARTTLS. You can make it work by adding smtp.starttls() to the previous program. Then we have to make sure that the plaintext before STARTTLS is not fingerprintable, in addition to whatever fingerprinting concerns there are with the TLS connection itself.

comment:5 Changed 5 years ago by dcf

Status: newneeds_review
Type: defectproject

I have this implemented in a branch. I would appreciate review of the crypto aspects and the overall idea. I have the system running now.

The program flashproxy-reg-email makes a registration message like "client=1.2.3.4:9001" and encrypts it with a public key whose private counterpart is held by the facilitator. It connects to Gmail's incoming SMTP server over TLS, and sends an email message containing the encrypted message to a distinguished gmail.com address whose password is known by the facilitator. The program facilitator-email-poller, running on the facilitator, makes an IMAP connection over TLS to the distinguished account, and checks every 60 seconds for new mail. For every message, it decrypts the body, passes the client registration to the facilitator, and deletes the message.

You can test the registration program like this:

$ ./flashproxy-reg-email :7000
Registered "XXX.XXX.XXX.XXX:7000" with hoddwee@gmail.com.

If port 7000 (or whatever port you choose) is able to receive TCP connections, you should get a connection from a flash proxy within about 60 seconds.

Source code:

Documentation:

I call your attention to:

The reason for encrypting the registration messages, even inside of encrypted SMTP and IMAP, is to prevent Google from being able to read a historical record of client IP addresses, and to protect them from an attacker who may gain access to the Gmail account. Client registrations are not terribly secret (they are what we give to flash proxies after all, and Google can of course record the IP addresses of STMP connections), but it is better to be cautious. The M2Crypto library needed for this encryption is also used for the public key pinning.

The encrypted registration emails look like this:

To: hoddwee@gmail.com
From: nobody@localhost
Subject: client reg a412f8de63

q1lAw3jGmemeuI0kUGTYJZZcjx+EXbRzil42L8SabXH8NljPA8+/JtR+eJCO1cXdj2JLhtaJ23by
YvjJG2qrA1pmyp6P+gcTdLQRlQmkkaCYAfakbh/h7vliH6YEr30G7WtTT2BW7IAhSc8gLNMwiTsN
fh4R3qsE7rOD3VABE4lVZHTkoMA0TP/WQgzVxpu5Bk8tvo9qEKbH2flwjtLq3vX631PjDjexIM7t
9A/5n7eol2gVffK4rxB/1OQ/ZBTkOwvO/bzEYzo5YmMEgAU6e/prVP412srz9TSAUBnSWuNql2X9
ol0D2jf0Aw/XP7qi1ropSwU1IDDR+y/4YkehTQ==

comment:6 Changed 5 years ago by ln5

Cc: ln5 added

comment:7 Changed 5 years ago by dcf

Resolution: fixed
Status: needs_reviewclosed

Now merged into master. See tickets #6986 and #6987 for additional related tasks.

Note: See TracTickets for help on using tickets.