irkerd: Handle missing usernames asyncio
authorW. Trevor King <wking@tremily.us>
Sat, 31 May 2014 00:09:48 +0000 (17:09 -0700)
committerW. Trevor King <wking@tremily.us>
Sat, 31 May 2014 00:28:04 +0000 (17:28 -0700)
Restore the default 'irker' username from the pre-asyncio code:

  username=target.username or username or 'irker',

We don't have a username argument, so it's currently either
target.username or the default.  This avoids a handshake with
ircs://:********@irc.example.net/chan that looks like:

  client: PASS ********
  client: NICK irker123
  client: USER  0 * :irker relaying client
               ^ empty, string
  server: :irc.example.net 461 irker123 USER :Syntax error

To make extra sure we don't have problems, we only submit PASS when we
have both a password and username [1], and only submit USER when we
have a username.  There's no sense in trying to authenticate yourself
with PASS if you don't have a username, although with the new code
it's impossibe to not have a username.

[1]: http://tools.ietf.org/html/rfc2812#section-3.1

irkerd

diff --git a/irkerd b/irkerd
index 9b1a63cd4ddbdcc6e0038e6d93f486448b6bd326..7f3233e6d4d671d90e9f5ad4dc9e2d62b2384ff2 100755 (executable)
--- a/irkerd
+++ b/irkerd
@@ -217,7 +217,7 @@ class Target(object):
             default_ircport = 6697
         else:
             default_ircport = 6667
-        self.username = parsed.username
+        self.username = parsed.username or 'irker'
         self.password = parsed.password
         self.hostname = parsed.hostname
         self.port = parsed.port or default_ircport
@@ -260,7 +260,7 @@ class Target(object):
             return
         if self.username or self.password:
             auth = '{}:{}@'.format(
-                self.username, '*' * len(self.password or ''))
+                self.username or '', '*' * len(self.password or ''))
         else:
             auth = ''
         if self.port:
@@ -628,11 +628,12 @@ class IRCProtocol(StateStringOwner, Lock, LineProtocol):
             loop = asyncio.get_event_loop()
             loop.call_later(delay=self._receive_ttl, callback=self._check_ttl)
             self._last_rx = time.time()
-        if self._password:
+        if self._password and self._username:
             self.writeline('PASS {}'.format(self._password))
         self.writeline('NICK {}'.format(self._nick))
-        self.writeline('USER {} 0 * :{}'.format(
-            self._username, self._realname))
+        if self._username:
+            self.writeline('USER {} 0 * :{}'.format(
+                self._username, self._realname))
 
     def connection_lost(self, exc):
         super(IRCProtocol, self).connection_lost(exc=exc)