//: AuthNewsGateWay.java /** Very simple server that takes care of the Authentication part of * logging into an authenticated news server so that older news * clients that don't know how to negotiate the authentication * protocol can still connect. Once authentication is complete, acts * as a simple news gateway (A.K.A. tunnel or relay). * * How it works: Listens for connections to the well known news port, * 119. Once a connection is established, it opens a new connection * to a real news server, which responds with a "200" message. The * "200" message is saved to be sent to the client once * authentication is complete. It then sends the username and * password on to the news server. Once these are accepted, the * original "200" message is sent back to the client and a relay * connection is created so the client thinks it's connected * correctly to a normal news server and any further communications * gets re-directed via the relay to/from the real news server. * * @author Mark Crocker * @author http://www.markcrocker.com/~mcrocker/ * @version 0.9.0.2 (Alpha) 2000-May-21 * Derived from @see c15.MultiJabberServer from 'Thinking in Java, * 2nd ed.' by Bruce Eckel www.BruceEckel.com. */ /* This is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. */ import java.io.*; import java.net.*; /** ConnectAndAuthenticate * @param Socket to listen to and Socket to send to * @return No return value * @exception IOException, InterruptedException thrown */ class ConnectAndAuthenticate { private Socket socket; private Socket replySocket; private BufferedReader in; private PrintWriter out; private PrintWriter replyPW; public ConnectAndAuthenticate(Socket s, Socket r) throws IOException { socket = s; replySocket = r; in = new BufferedReader( new InputStreamReader(socket.getInputStream())); // Enable auto-flush: out = new PrintWriter( new BufferedWriter( new OutputStreamWriter(socket.getOutputStream())), true); replyPW = new PrintWriter( new BufferedWriter( new OutputStreamWriter(replySocket.getOutputStream())), true); // If any of the above calls throw an // exception, the caller is responsible for // closing the socket. Otherwise the thread // will close it. //start(); // Calls run() } /** run * @param User name and pass word * A somewhat braindead authentication responder. */ public void run(String userName, String passWord) { try { String str = ""; String twoHundredResponse = ""; out.println("MODE READER"); while ( !twoHundredResponse.startsWith("200") ) { //out.println(""); twoHundredResponse = in.readLine(); System.out.println("Server Response: " + twoHundredResponse); } out.println("AUTHINFO user " + userName); while ( !str.startsWith("381") ) { str = in.readLine(); System.out.println("Server Response: " + str); } out.println("AUTHINFO pass " + passWord); while ( !str.startsWith("281") ) { str = in.readLine(); System.out.println("Server Response: " + str); } System.out.println("Replying to client with 200 response"); System.out.println(twoHundredResponse); replyPW.println(twoHundredResponse); } catch (IOException e) {} } } public class AuthNewsGateWay { /** Standard News Server Port */ public static final int PORT = 119; /** Host News server (or news firewall) lives on */ public static final String NEWSSERVERHOST = "192.168.0.4"; public static void main(String[] args) throws IOException, InterruptedException { if(args.length != 2) { System.err.println("Usage: AuthNewsGateWay userName passWord"); System.exit(1); } String userName = args[0]; String passWord = args[1]; // Server port ServerSocket s = new ServerSocket(PORT); System.out.println("Server started: " + s); try { while(true) { // Blocks until a connection occurs: Socket socketS = s.accept(); try { // Relay port InetAddress addr = InetAddress.getByName(NEWSSERVERHOST); System.out.println("relaying to addr = " + addr); Socket socketR = new Socket(addr, PORT); System.out.println("Relay socket started = " + socketR); ConnectAndAuthenticate caa = new ConnectAndAuthenticate(socketR, socketS); caa.run(userName, passWord); new RelayOneWay(socketS, socketR); new RelayOneWay(socketR, socketS); // If it fails, close the socket, // otherwise the thread will close it: } catch(IOException e) { System.out.println("Error establishing sockets..."); socketS.close(); //socketR.close(); } } } finally { s.close(); //socketR.close(); } } } ///:~ /* Todo: * 1. Command Line options -> almost have this working * 2. Popup window to fill in if no command line options supplied. * 3. Logging. * 4. Quiet mode. * 5. Debug mode. * 6. Add some error checking so it can recover from bad connections * and dropped info, unexpected server responses etc.. * 7. Clean-up documentation and generate Javadocs */