Changeset 31ace20


Ignore:
Timestamp:
Nov 27, 2015 12:46:45 AM (5 years ago)
Author:
zzz <zzz@…>
Branches:
master
Children:
e77c5bd
Parents:
4291450
Message:

auth and ssl support

Location:
apps/sam/java/src/net/i2p/sam/client
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • apps/sam/java/src/net/i2p/sam/client/SAMStreamSend.java

    r4291450 r31ace20  
    77import java.io.OutputStream;
    88import java.net.Socket;
     9import java.security.GeneralSecurityException;
    910import java.util.HashMap;
    1011import java.util.Map;
     12import javax.net.ssl.SSLSocket;
    1113
    1214import gnu.getopt.Getopt;
     
    1618import net.i2p.data.DataHelper;
    1719import net.i2p.util.I2PAppThread;
     20import net.i2p.util.I2PSSLSocketFactory;
    1821import net.i2p.util.Log;
    1922import net.i2p.util.VersionComparator;
     
    3942    /** Connection id (Integer) to peer (Flooder) */
    4043    private final Map<String, Sender> _remotePeers;
     44    private static I2PSSLSocketFactory _sslSocketFactory;
    4145   
    4246    private static final int STREAM=0, DG=1, V1DG=2, RAW=3, V1RAW=4;
    43     private static final String USAGE = "Usage: SAMStreamSend [-s] [-m mode] [-v version] [-b samHost] [-p samPort] peerDestFile dataDir\n" +
     47    private static final String USAGE = "Usage: SAMStreamSend [-s] [-m mode] [-v version] [-b samHost] [-p samPort] [-u user] [-w password] peerDestFile dataDir\n" +
    4448                                        "       modes: stream: 0; datagram: 1; v1datagram: 2; raw: 3; v1raw: 4\n" +
    4549                                        "       -s: use SSL";
    4650
    4751    public static void main(String args[]) {
    48         Getopt g = new Getopt("SAM", args, "sb:m:p:v:");
     52        Getopt g = new Getopt("SAM", args, "sb:m:p:u:v:w:");
    4953        boolean isSSL = false;
    5054        int mode = STREAM;
     
    5256        String host = "127.0.0.1";
    5357        String port = "7656";
     58        String user = null;
     59        String password = null;
    5460        int c;
    5561        while ((c = g.getopt()) != -1) {
     
    7783            case 'p':
    7884                port = g.getOptarg();
     85                break;
     86
     87            case 'u':
     88                user = g.getOptarg();
     89                break;
     90
     91            case 'w':
     92                password = g.getOptarg();
    7993                break;
    8094
     
    93107            return;
    94108        }
     109        if ((user == null && password != null) ||
     110            (user != null && password == null)) {
     111            System.err.println("both user and password or neither");
     112            return;
     113        }
     114        if (user != null && password != null && VersionComparator.comp(version, "3.2") < 0) {
     115            System.err.println("user/password require 3.2");
     116            return;
     117        }
    95118        I2PAppContext ctx = I2PAppContext.getGlobalContext();
    96119        SAMStreamSend sender = new SAMStreamSend(ctx, host, port,
    97120                                                      args[startArgs], args[startArgs + 1]);
    98         sender.startup(version, isSSL, mode);
     121        sender.startup(version, isSSL, mode, user, password);
    99122    }
    100123   
     
    111134    }
    112135   
    113     public void startup(String version, boolean isSSL, int mode) {
     136    public void startup(String version, boolean isSSL, int mode, String user, String password) {
    114137        if (_log.shouldLog(Log.DEBUG))
    115138            _log.debug("Starting up");
     
    122145                _log.debug("Reader created");
    123146            OutputStream out = sock.getOutputStream();
    124             String ourDest = handshake(out, version, true, eventHandler, mode);
     147            String ourDest = handshake(out, version, true, eventHandler, mode, user, password);
    125148            if (ourDest == null)
    126149                throw new IOException("handshake failed");
     
    135158                    _log.debug("Reader2 created");
    136159                out = sock2.getOutputStream();
    137                 String ok = handshake(out, version, false, eventHandler, mode);
     160                String ok = handshake(out, version, false, eventHandler, mode, user, password);
    138161                if (ok == null)
    139162                    throw new IOException("2nd handshake failed");
     
    173196   
    174197    private Socket connect(boolean isSSL) throws IOException {
    175         return new Socket(_samHost, Integer.parseInt(_samPort));
     198        int port = Integer.parseInt(_samPort);
     199        if (!isSSL)
     200            return new Socket(_samHost, port);
     201        synchronized(SAMStreamSink.class) {
     202            if (_sslSocketFactory == null) {
     203                try {
     204                    _sslSocketFactory = new I2PSSLSocketFactory(
     205                        _context, true, "certificates/sam");
     206                } catch (GeneralSecurityException gse) {
     207                    throw new IOException("SSL error", gse);
     208                }
     209            }
     210        }
     211        SSLSocket sock = (SSLSocket) _sslSocketFactory.createSocket(_samHost, port);
     212        I2PSSLSocketFactory.verifyHostname(_context, sock, _samHost);
     213        return sock;
    176214    }
    177215   
    178216    /** @return our b64 dest or null */
    179     private String handshake(OutputStream samOut, String version, boolean isMaster, SAMEventHandler eventHandler, int mode) {
     217    private String handshake(OutputStream samOut, String version, boolean isMaster,
     218                             SAMEventHandler eventHandler, int mode, String user, String password) {
    180219        synchronized (samOut) {
    181220            try {
    182                 samOut.write(("HELLO VERSION MIN=1.0 MAX=" + version + '\n').getBytes());
     221                if (user != null && password != null)
     222                    samOut.write(("HELLO VERSION MIN=1.0 MAX=" + version + " USER=" + user + " PASSWORD=" + password + '\n').getBytes());
     223                else
     224                    samOut.write(("HELLO VERSION MIN=1.0 MAX=" + version + '\n').getBytes());
    183225                samOut.flush();
    184226                if (_log.shouldLog(Log.DEBUG))
  • apps/sam/java/src/net/i2p/sam/client/SAMStreamSink.java

    r4291450 r31ace20  
    77import java.io.OutputStream;
    88import java.net.Socket;
     9import java.security.GeneralSecurityException;
    910import java.util.HashMap;
    1011import java.util.Map;
    1112import java.util.Properties;
     13import javax.net.ssl.SSLSocket;
    1214
    1315import gnu.getopt.Getopt;
     
    1719import net.i2p.data.DataHelper;
    1820import net.i2p.util.I2PAppThread;
     21import net.i2p.util.I2PSSLSocketFactory;
    1922import net.i2p.util.Log;
    2023import net.i2p.util.VersionComparator;
     
    4245    /** Connection id (Integer) to peer (Flooder) */
    4346    private final Map<String, Sink> _remotePeers;
     47    private static I2PSSLSocketFactory _sslSocketFactory;
    4448   
    4549    private static final int STREAM=0, DG=1, V1DG=2, RAW=3, V1RAW=4;
    46     private static final String USAGE = "Usage: SAMStreamSink [-s] [-m mode] [-v version] [-b samHost] [-p samPort] myDestFile sinkDir\n" +
     50    private static final String USAGE = "Usage: SAMStreamSink [-s] [-m mode] [-v version] [-b samHost] [-p samPort] [-u user] [-w password] myDestFile sinkDir\n" +
    4751                                        "       modes: stream: 0; datagram: 1; v1datagram: 2; raw: 3; v1raw: 4\n" +
    4852                                        "       -s: use SSL";
    4953
    5054    public static void main(String args[]) {
    51         Getopt g = new Getopt("SAM", args, "sb:m:p:v:");
     55        Getopt g = new Getopt("SAM", args, "sb:m:p:u:v:w:");
    5256        boolean isSSL = false;
    5357        int mode = STREAM;
     
    5559        String host = "127.0.0.1";
    5660        String port = "7656";
     61        String user = null;
     62        String password = null;
    5763        int c;
    5864        while ((c = g.getopt()) != -1) {
     
    8086            case 'p':
    8187                port = g.getOptarg();
     88                break;
     89
     90            case 'u':
     91                user = g.getOptarg();
     92                break;
     93
     94            case 'w':
     95                password = g.getOptarg();
    8296                break;
    8397
     
    96110            return;
    97111        }
     112        if ((user == null && password != null) ||
     113            (user != null && password == null)) {
     114            System.err.println("both user and password or neither");
     115            return;
     116        }
     117        if (user != null && password != null && VersionComparator.comp(version, "3.2") < 0) {
     118            System.err.println("user/password require 3.2");
     119            return;
     120        }
    98121        I2PAppContext ctx = I2PAppContext.getGlobalContext();
    99122        SAMStreamSink sink = new SAMStreamSink(ctx, host, port,
    100123                                                    args[startArgs], args[startArgs + 1]);
    101         sink.startup(version, isSSL, mode);
     124        sink.startup(version, isSSL, mode, user, password);
    102125    }
    103126   
     
    114137    }
    115138   
    116     public void startup(String version, boolean isSSL, int mode) {
     139    public void startup(String version, boolean isSSL, int mode, String user, String password) {
    117140        if (_log.shouldLog(Log.DEBUG))
    118141            _log.debug("Starting up");
     
    125148            if (_log.shouldLog(Log.DEBUG))
    126149                _log.debug("Reader created");
    127             String ourDest = handshake(out, version, true, eventHandler, mode);
     150            String ourDest = handshake(out, version, true, eventHandler, mode, user, password);
    128151            if (ourDest == null)
    129152                throw new IOException("handshake failed");
     
    143166                if (_log.shouldLog(Log.DEBUG))
    144167                    _log.debug("Reader2 created");
    145                 String ok = handshake(out, version, false, eventHandler, mode);
     168                String ok = handshake(out, version, false, eventHandler, mode, user, password);
    146169                if (ok == null)
    147170                    throw new IOException("2nd handshake failed");
     
    351374   
    352375    private Socket connect(boolean isSSL) throws IOException {
    353         return new Socket(_samHost, Integer.parseInt(_samPort));
     376        int port = Integer.parseInt(_samPort);
     377        if (!isSSL)
     378            return new Socket(_samHost, port);
     379        synchronized(SAMStreamSink.class) {
     380            if (_sslSocketFactory == null) {
     381                try {
     382                    _sslSocketFactory = new I2PSSLSocketFactory(
     383                        _context, true, "certificates/sam");
     384                } catch (GeneralSecurityException gse) {
     385                    throw new IOException("SSL error", gse);
     386                }
     387            }
     388        }
     389        SSLSocket sock = (SSLSocket) _sslSocketFactory.createSocket(_samHost, port);
     390        I2PSSLSocketFactory.verifyHostname(_context, sock, _samHost);
     391        return sock;
    354392    }
    355393   
    356394    /** @return our b64 dest or null */
    357     private String handshake(OutputStream samOut, String version, boolean isMaster, SAMEventHandler eventHandler, int mode) {
     395    private String handshake(OutputStream samOut, String version, boolean isMaster,
     396                             SAMEventHandler eventHandler, int mode, String user, String password) {
    358397        synchronized (samOut) {
    359398            try {
    360                 samOut.write(("HELLO VERSION MIN=1.0 MAX=" + version + '\n').getBytes());
     399                if (user != null && password != null)
     400                    samOut.write(("HELLO VERSION MIN=1.0 MAX=" + version + " USER=" + user + " PASSWORD=" + password + '\n').getBytes());
     401                else
     402                    samOut.write(("HELLO VERSION MIN=1.0 MAX=" + version + '\n').getBytes());
    361403                samOut.flush();
    362404                if (_log.shouldLog(Log.DEBUG))
Note: See TracChangeset for help on using the changeset viewer.