001: /* ====================================================================
002: * The LateralNZ Software License, Version 1.0
003: *
004: * Copyright (c) 2003 LateralNZ. All rights reserved.
005: *
006: * Redistribution and use in source and binary forms, with or without
007: * modification, are permitted provided that the following conditions
008: * are met:
009: *
010: * 1. Redistributions of source code must retain the above copyright
011: * notice, this list of conditions and the following disclaimer.
012: *
013: * 2. Redistributions in binary form must reproduce the above copyright
014: * notice, this list of conditions and the following disclaimer in
015: * the documentation and/or other materials provided with the
016: * distribution.
017: *
018: * 3. The end-user documentation included with the redistribution,
019: * if any, must include the following acknowledgment:
020: * "This product includes software developed by
021: * LateralNZ (http://www.lateralnz.org/) and other third parties."
022: * Alternately, this acknowledgment may appear in the software itself,
023: * if and wherever such third-party acknowledgments normally appear.
024: *
025: * 4. The names "LateralNZ" must not be used to endorse or promote
026: * products derived from this software without prior written
027: * permission. For written permission, please
028: * contact oss@lateralnz.org.
029: *
030: * 5. Products derived from this software may not be called "Panther",
031: * or "Lateral" or "LateralNZ", nor may "PANTHER" or "LATERAL" or
032: * "LATERALNZ" appear in their name, without prior written
033: * permission of LateralNZ.
034: *
035: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
036: * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
037: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
038: * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
039: * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
040: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
041: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
042: * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
043: * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
044: * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
045: * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
046: * SUCH DAMAGE.
047: * ====================================================================
048: *
049: * This software consists of voluntary contributions made by many
050: * individuals on behalf of LateralNZ. For more
051: * information on Lateral, please see http://www.lateralnz.com/ or
052: * http://www.lateralnz.org
053: *
054: */
055: package org.lateralnz.common.telnet;
056:
057: import java.io.*;
058: import java.lang.reflect.Constructor;
059: import java.net.ServerSocket;
060: import java.net.Socket;
061:
062: import org.lateralnz.common.util.IOUtils;
063: import org.lateralnz.common.util.StringUtils;
064:
065: public class Server extends Thread implements Constants {
066:
067: private static final String[] NAMES = new String[256];
068: private static final String UNKNOWN = "[UNK]";
069:
070: static {
071: for (int i = 0; i < NAMES.length; i++) {
072: NAMES[i] = UNKNOWN;
073: }
074: NAMES[0] = "NULL";
075: NAMES[1] = "echo";
076: NAMES[3] = "suppress go ahead";
077: NAMES[5] = "status";
078: NAMES[6] = "timing mark";
079: NAMES[8] = "backspace";
080: NAMES[24] = "terminal type";
081: NAMES[31] = "window size";
082: NAMES[32] = "terminal speed";
083: NAMES[33] = "remote flow control";
084: NAMES[34] = "linemode";
085: NAMES[36] = "environment variables";
086:
087: NAMES[240] = "SE";
088: NAMES[241] = "NOP";
089: NAMES[242] = "DM";
090: NAMES[243] = "BRK";
091: NAMES[244] = "IP";
092: NAMES[245] = "AO";
093: NAMES[246] = "AYT";
094: NAMES[247] = "EC";
095: NAMES[248] = "EL";
096: NAMES[249] = "GA";
097: NAMES[250] = "SB";
098: NAMES[251] = "WILL";
099: NAMES[252] = "WONT";
100: NAMES[253] = "DO";
101: NAMES[254] = "DONT";
102: NAMES[255] = "IAC";
103: }
104:
105: private static final String QUIT = "quit";
106:
107: private boolean running = true;
108: private int port;
109: private Class baseHandlerClass;
110: private String allowFromRegex;
111:
112: public Server(int port, Class baseHandlerClass,
113: String allowFromRegex) throws IOException {
114: super ();
115:
116: this .port = port;
117: this .baseHandlerClass = baseHandlerClass;
118:
119: if (StringUtils.isEmpty(allowFromRegex)) {
120: this .allowFromRegex = ".*";
121: } else {
122: this .allowFromRegex = allowFromRegex;
123: }
124:
125: start();
126: }
127:
128: public static final String getCommand(int b) {
129: if (b < 0 || b > NAMES.length) {
130: return UNKNOWN;
131: } else {
132: return NAMES[b];
133: }
134: }
135:
136: public static final String getCommandString(int b1, int b2, int b3) {
137: return getCommand(b1) + " " + getCommand(b2) + " "
138: + getCommand(b3);
139: }
140:
141: public void run() {
142: ServerSocket ss = null;
143: Socket socket;
144: try {
145: ss = new ServerSocket(port);
146: Constructor cons = baseHandlerClass
147: .getConstructor(new Class[] { Server.class,
148: Socket.class });
149:
150: while (running) {
151: socket = ss.accept();
152: if (!StringUtils.matches(socket.getInetAddress()
153: .getHostAddress(), allowFromRegex)) {
154: System.err.println("invalid access from "
155: + socket.getInetAddress());
156: socket.close();
157: continue;
158: }
159: BaseHandler bh = (BaseHandler) cons
160: .newInstance(new Object[] { this , socket });
161:
162: this .yield();
163: }
164: } catch (Exception e) {
165: e.printStackTrace();
166: } finally {
167: IOUtils.close(ss);
168: }
169: }
170:
171: public void shutdown() {
172: running = false;
173: try {
174: interrupt();
175: } catch (Exception e) {
176: }
177: }
178:
179: public static final void main(String[] args) throws Exception {
180: Server s = new Server(1111, BaseHandler.class, "");
181: }
182:
183: }
|