All Implemented Interfaces:
Runnable, EventDispatcher

public class I2PTunnelIRCServerextends I2PTunnelServer implements Runnable
IRC server tunnel that filters registration to pass client destination hash as hostname.

Enables IRC servers to track users across nick changes. Requires IRC daemon to use client-provided hostname rather than IP. Many IRCds ignore hostname in USER message (easily spoofed) unless from another server. May require IRCd configuration; not configurable in unrealircd/ngircd.

Destination mangling options (in i2ptunnel custom options):

  ircserver.method unset:     Defaults to user method
  ircserver.method=user:       Use described method
  ircserver.method=webirc:     Use WEBIRC protocol
  ircserver.cloakKey unset:    Random persistent cloaking (default)
  ircserver.cloakKey=pass:     Consistent cloaking via passphrase hash
  ircserver.webircPassword=pw:  WEBIRC protocol password
  ircserver.webircSpoofIP=IP:   Spoofed IP for WEBIRC
  ircserver.fakeHostname=%f.b32.i2p: Fake hostname (%f=full B32, %c=cloaked)
Note: No quotes/spaces in passphrase for GUI compatibility. No outbound filtering.
  • Field Details

    • cloakKey

      private final byte[] cloakKey
      The key used to cloak the client addresses.
    • hostname

      private final String hostname
      The hostname sent to the IRC server.
    • method

      private final String method
      The webirc method name, if any.
    • webircPassword

      private final String webircPassword
      The webirc password, if any.
    • webircSpoofIP

      private final String webircSpoofIP
      The IP the webirc handshake spoofs.
    • PROP_METHOD

      public static final String PROP_METHOD
      Config key for the registration method, user (default) or webirc.
      See Also:
    • PROP_METHOD_DEFAULT

      public static final String PROP_METHOD_DEFAULT
      Default for PROP_METHOD, selecting the USER-based hostname mangling.
      See Also:
    • PROP_CLOAK

      public static final String PROP_CLOAK
      Config key for the cloak passphrase, where unset means random persistent cloaking.
      See Also:
    • PROP_WEBIRC_PASSWORD

      public static final String PROP_WEBIRC_PASSWORD
      Config key for the password sent in the WEBIRC handshake, with no quotes or spaces.
      See Also:
    • PROP_WEBIRC_SPOOF_IP

      public static final String PROP_WEBIRC_SPOOF_IP
      Config key for the IP address spoofed in the WEBIRC handshake.
      See Also:
    • PROP_WEBIRC_SPOOF_IP_DEFAULT

      public static final String PROP_WEBIRC_SPOOF_IP_DEFAULT
      Default for PROP_WEBIRC_SPOOF_IP, the loopback address.
      See Also:
    • PROP_HOSTNAME

      public static final String PROP_HOSTNAME
      Config key for the fake hostname template, where %f is the full B32 destination.
      See Also:
    • PROP_HOSTNAME_DEFAULT

      public static final String PROP_HOSTNAME_DEFAULT
      Default for PROP_HOSTNAME, the full B32 destination as a hostname.
      See Also:
    • HEADER_TIMEOUT

      private static final long HEADER_TIMEOUT
      Time allowed for one line of the server greeting.
      See Also:
    • TOTAL_HEADER_TIMEOUT

      private static final long TOTAL_HEADER_TIMEOUT
      Total time allowed for the server greeting.
      See Also:
    • MAX_LINE_LENGTH

      private static final int MAX_LINE_LENGTH
      Longest IRC line accepted.
      See Also:
    • DEFAULT_IRC_READ_TIMEOUT

      private static final long DEFAULT_IRC_READ_TIMEOUT
      Default idle time before the drop, the client should time out first.
      See Also:
    • ERR_UNAVAILABLE

      private static final String ERR_UNAVAILABLE
      Error line sent when the destination is unavailable.
      See Also:
    • ERR_REGISTRATION

      private static final String ERR_REGISTRATION
      Error line sent when the registration fails.
      See Also:
    • ERR_TIMEOUT

      private static final String ERR_TIMEOUT
      Error line sent when the connection times out.
      See Also:
    • ERR_EOF

      private static final String ERR_EOF
      Error line sent when the connection closes early.
      See Also:
    • BAD_PROTOCOLS

      private static final String[] BAD_PROTOCOLS
      IRC protocol options stripped from the client's request.
  • Constructor Details

    • I2PTunnelIRCServer

      public I2PTunnelIRCServer(InetAddress host, int port, File privkey, String privkeyname, Logging l, EventDispatcher notifyThis, I2PTunnel tunnel)
      Construct an IRC client tunnel server.

      The cloak key is generated on first use from a random 32 bytes when no passphrase is configured. The options supply the WEBIRC and cloaking settings, and the configuration must be valid to contact the router.

      Parameters:
      host - the IRC server to connect to on the far side of the tunnel
      port - the port on that server to connect to
      privkey - the file holding this tunnel's private key, or null if the
      privkeyname - the name to show for the key in the console and logs
      l - the logging implementation shared with the owning I2PTunnel
      notifyThis - dispatcher told about connection events for this client
      tunnel - the I2PTunnel this IRC client belongs to, whose client
      Throws:
      IllegalArgumentException - if the I2PTunnel does not contain
  • Method Details

    • blockingHandle

      protected void blockingHandle(I2PSocket socket)
      Register one incoming IRC client connection, blocking until it closes.
      Overrides:
      blockingHandle in class I2PTunnelServer
      Parameters:
      socket - the accepted connection from a local IRC client
      See Also:
    • cloakDest

      private String cloakDest(Destination d)
      (Optionally) append 32 bytes of crap to the destination then return the first few characters of the hash of the whole thing, + ".i2p". Or do we want the full hash if the ircd is going to use this for nickserv auto-login? Or even Base32 if it will be used in a case-insensitive manner?
      Parameters:
      d - the destination to cloak
      Returns:
      the hostname template with %f replaced by the destination hash prefix and %c by the cloaked hash prefix
    • filterRegistration

      private static String filterRegistration(I2PSocket socket, String newHostname) throws IOException
      Keep reading until we see USER or SERVER. This modifies the socket readTimeout, caller must save and restore.
      Parameters:
      socket - the client socket to read the registration lines from
      newHostname - the cloaked .i2p hostname substituted into the USER line
      Returns:
      the rewritten registration lines ending at the USER or SERVER line
      Throws:
      SocketTimeoutException - if timeout is reached before newline
      EOFException - if EOF is reached before newline
      I2PTunnelIRCServer.RegistrationException - if line too long
      IOException - on other errors in the underlying stream
    • readLine

      private static String readLine(I2PSocket socket, long timeout) throws IOException
      Read a line terminated by newline, with a total read timeout.

      Warning - strips \n but not \r Warning - 8KB line length limit as of 0.7.13, @throws IOException if exceeded Warning - not UTF-8.

      Parameters:
      socket - the socket to read one line from
      timeout - throws SocketTimeoutException immediately if zero or negative
      Returns:
      the line without the terminating newline, carriage returns kept
      Throws:
      SocketTimeoutException - if timeout is reached before newline
      EOFException - if EOF is reached before newline
      I2PTunnelIRCServer.RegistrationException - if line too long
      IOException - on other errors in the underlying stream