package com.runjva.sourceforge.jsocks.server; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.Socket; /** * This class implements SOCKS5 User/Password authentication scheme as defined * in rfc1929,the server side of it. (see docs/rfc1929.txt) */ public class UserPasswordAuthenticator extends ServerAuthenticatorBase { static final int METHOD_ID = 2; UserValidation validator; /** * Construct a new UserPasswordAuthentication object, with given * UserVlaidation scheme. * * @param v * UserValidation to use for validating users. */ public UserPasswordAuthenticator(UserValidation validator) { this.validator = validator; } public ServerAuthenticator startSession(Socket s) throws IOException { final InputStream in = s.getInputStream(); final OutputStream out = s.getOutputStream(); if (in.read() != 5) { return null; // Drop non version 5 messages. } if (!selectSocks5Authentication(in, out, METHOD_ID)) { return null; } if (!doUserPasswordAuthentication(s, in, out)) { return null; } return new ServerAuthenticatorNone(in, out); } // Private Methods // //////////////// private boolean doUserPasswordAuthentication(Socket s, InputStream in, OutputStream out) throws IOException { final int version = in.read(); if (version != 1) { return false; } final int ulen = in.read(); if (ulen < 0) { return false; } final byte[] user = new byte[ulen]; in.read(user); final int plen = in.read(); if (plen < 0) { return false; } final byte[] password = new byte[plen]; in.read(password); if (validator.isUserValid(new String(user), new String(password), s)) { // System.out.println("user valid"); out.write(new byte[] { 1, 0 }); } else { // System.out.println("user invalid"); out.write(new byte[] { 1, 1 }); return false; } return true; } }