aboutsummaryrefslogtreecommitdiffstats
path: root/src/de/mud/telnet/TelnetProtocolHandler.java
diff options
context:
space:
mode:
authorKenny Root <kenny@the-b.org>2014-10-01 23:04:51 +0100
committerKenny Root <kenny@the-b.org>2014-10-01 12:48:19 +0100
commit49b779dcaf03e3598d2709b321e20ea029b25163 (patch)
tree05af547b1f1433d7dd6f7373d0b25a455e053a03 /src/de/mud/telnet/TelnetProtocolHandler.java
parentd64786d9197090c74072b648e487e3d34817bb57 (diff)
downloadconnectbot-49b779dcaf03e3598d2709b321e20ea029b25163.tar.gz
connectbot-49b779dcaf03e3598d2709b321e20ea029b25163.tar.bz2
connectbot-49b779dcaf03e3598d2709b321e20ea029b25163.zip
Convert to gradle build system
Diffstat (limited to 'src/de/mud/telnet/TelnetProtocolHandler.java')
-rw-r--r--src/de/mud/telnet/TelnetProtocolHandler.java678
1 files changed, 0 insertions, 678 deletions
diff --git a/src/de/mud/telnet/TelnetProtocolHandler.java b/src/de/mud/telnet/TelnetProtocolHandler.java
deleted file mode 100644
index 74f08bb..0000000
--- a/src/de/mud/telnet/TelnetProtocolHandler.java
+++ /dev/null
@@ -1,678 +0,0 @@
-/*
- * This file is part of "JTA - Telnet/SSH for the JAVA(tm) platform".
- *
- * (c) Matthias L. Jugel, Marcus Meißner 1996-2005. All Rights Reserved.
- *
- * Please visit http://javatelnet.org/ for updates and contact.
- *
- * --LICENSE NOTICE--
- * This program 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
- * of the License, or (at your option) any later version.
- *
- * This program 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.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- * --LICENSE NOTICE--
- *
- */
-
-package de.mud.telnet;
-
-import java.io.IOException;
-/**
- * This is a telnet protocol handler. The handler needs implementations
- * for several methods to handle the telnet options and to be able to
- * read and write the buffer.
- * <P>
- * <B>Maintainer:</B> Marcus Meissner
- *
- * @version $Id: TelnetProtocolHandler.java 503 2005-10-24 07:34:13Z marcus $
- * @author Matthias L. Jugel, Marcus Meissner
- */
-public abstract class TelnetProtocolHandler {
- /** contains the current revision id */
- public final static String ID = "$Id: TelnetProtocolHandler.java 503 2005-10-24 07:34:13Z marcus $";
-
- /** debug level */
- private final static int debug = 0;
-
- /** temporary buffer for data-telnetstuff-data transformation */
- private byte[] tempbuf = new byte[0];
-
- /** the data sent on pressing <RETURN> \n */
- private byte[] crlf = new byte[2];
- /** the data sent on pressing <LineFeed> \r */
- private byte[] cr = new byte[2];
-
- /**
- * Create a new telnet protocol handler.
- */
- public TelnetProtocolHandler() {
- reset();
-
- crlf[0] = 13; crlf[1] = 10;
- cr[0] = 13; cr[1] = 0;
- }
-
- /**
- * Get the current terminal type for TTYPE telnet option.
- * @return the string id of the terminal
- */
- protected abstract String getTerminalType();
-
- /**
- * Get the current window size of the terminal for the
- * NAWS telnet option.
- * @return the size of the terminal as Dimension
- */
- protected abstract int[] getWindowSize();
-
- /**
- * Set the local echo option of telnet.
- * @param echo true for local echo, false for no local echo
- */
- protected abstract void setLocalEcho(boolean echo);
-
- /**
- * Generate an EOR (end of record) request. For use by prompt displaying.
- */
- protected abstract void notifyEndOfRecord();
-
- /**
- * Send data to the remote host.
- * @param b array of bytes to send
- */
- protected abstract void write(byte[] b) throws IOException;
-
- /**
- * Read the charset name from terminal.
- */
- protected abstract String getCharsetName();
-
- /**
- * Send one byte to the remote host.
- * @param b the byte to be sent
- * @see #write(byte[] b)
- */
- private static byte[] one = new byte[1];
- private void write(byte b) throws IOException {
- one[0] = b;
- write(one);
- }
-
- /**
- * Reset the protocol handler. This may be necessary after the
- * connection was closed or some other problem occured.
- */
- public void reset() {
- neg_state = 0;
- receivedDX = new byte[256];
- sentDX = new byte[256];
- receivedWX = new byte[256];
- sentWX = new byte[256];
- }
-
- // ===================================================================
- // the actual negotiation handling for the telnet protocol follows:
- // ===================================================================
-
- /** state variable for telnet negotiation reader */
- private byte neg_state = 0;
-
- /** constants for the negotiation state */
- private final static byte STATE_DATA = 0;
- private final static byte STATE_IAC = 1;
- private final static byte STATE_IACSB = 2;
- private final static byte STATE_IACWILL = 3;
- private final static byte STATE_IACDO = 4;
- private final static byte STATE_IACWONT = 5;
- private final static byte STATE_IACDONT = 6;
- private final static byte STATE_IACSBIAC = 7;
- private final static byte STATE_IACSBDATA = 8;
- private final static byte STATE_IACSBDATAIAC = 9;
-
- /** What IAC SB <xx> we are handling right now */
- private byte current_sb;
-
- /** current SB negotiation buffer */
- private byte[] sbbuf;
-
- /** IAC - init sequence for telnet negotiation. */
- private final static byte IAC = (byte)255;
- /** [IAC] End Of Record */
- private final static byte EOR = (byte)239;
- /** [IAC] WILL */
- private final static byte WILL = (byte)251;
- /** [IAC] WONT */
- private final static byte WONT = (byte)252;
- /** [IAC] DO */
- private final static byte DO = (byte)253;
- /** [IAC] DONT */
- private final static byte DONT = (byte)254;
- /** [IAC] Sub Begin */
- private final static byte SB = (byte)250;
- /** [IAC] Sub End */
- private final static byte SE = (byte)240;
- /** Telnet option: binary mode */
- private final static byte TELOPT_BINARY= (byte)0; /* binary mode */
- /** Telnet option: echo text */
- private final static byte TELOPT_ECHO = (byte)1; /* echo on/off */
- /** Telnet option: sga */
- private final static byte TELOPT_SGA = (byte)3; /* supress go ahead */
- /** Telnet option: End Of Record */
- private final static byte TELOPT_EOR = (byte)25; /* end of record */
- /** Telnet option: Negotiate About Window Size */
- private final static byte TELOPT_NAWS = (byte)31; /* NA-WindowSize*/
- /** Telnet option: Terminal Type */
- private final static byte TELOPT_TTYPE = (byte)24; /* terminal type */
- /** Telnet option: CHARSET */
- private final static byte TELOPT_CHARSET= (byte)42; /* charset */
-
- private final static byte[] IACWILL = { IAC, WILL };
- private final static byte[] IACWONT = { IAC, WONT };
- private final static byte[] IACDO = { IAC, DO };
- private final static byte[] IACDONT = { IAC, DONT };
- private final static byte[] IACSB = { IAC, SB };
- private final static byte[] IACSE = { IAC, SE };
-
- private final static byte CHARSET_ACCEPTED = (byte)2;
- private final static byte CHARSET_REJECTED = (byte)3;
-
- /** Telnet option qualifier 'IS' */
- private final static byte TELQUAL_IS = (byte)0;
- /** Telnet option qualifier 'SEND' */
- private final static byte TELQUAL_SEND = (byte)1;
-
- /** What IAC DO(NT) request do we have received already ? */
- private byte[] receivedDX;
- /** What IAC WILL/WONT request do we have received already ? */
- private byte[] receivedWX;
- /** What IAC DO/DONT request do we have sent already ? */
- private byte[] sentDX;
- /** What IAC WILL/WONT request do we have sent already ? */
- private byte[] sentWX;
-
- /**
- * Send a Telnet Escape character (IAC <code>)
- */
- public void sendTelnetControl(byte code)
- throws IOException {
- byte[] b = new byte[2];
-
- b[0] = IAC;
- b[1] = code;
- write(b);
- }
-
- /**
- * Send the new Window Size (via NAWS)
- */
- public void setWindowSize(int columns,int rows)
- throws IOException {
- if(debug > 2) System.err.println("sending NAWS");
-
- if (receivedDX[TELOPT_NAWS] != DO) {
- System.err.println("not allowed to send NAWS? (DONT NAWS)");
- return;
- }
- write(IAC);write(SB);write(TELOPT_NAWS);
- write((byte) (columns >> 8));
- write((byte) (columns & 0xff));
- write((byte) (rows >> 8));
- write((byte) (rows & 0xff));
- write(IAC);write(SE);
- }
-
-
- /**
- * Handle an incoming IAC SB &lt;type&gt; &lt;bytes&gt; IAC SE
- * @param type type of SB
- * @param sbata byte array as &lt;bytes&gt;
- */
- private void handle_sb(byte type, byte[] sbdata)
- throws IOException {
- if(debug > 1)
- System.err.println("TelnetIO.handle_sb("+type+")");
- switch (type) {
- case TELOPT_TTYPE:
- if (sbdata.length>0 && sbdata[0]==TELQUAL_SEND) {
- write(IACSB);write(TELOPT_TTYPE);write(TELQUAL_IS);
- /* FIXME: need more logic here if we use
- * more than one terminal type
- */
- String ttype = getTerminalType();
- if(ttype == null) ttype = "dumb";
- write(ttype.getBytes());
- write(IACSE);
- }
- break;
- case TELOPT_CHARSET:
- System.out.println("Got SB CHARSET");
-
- String charsetStr = new String(sbdata, "US-ASCII");
- if (charsetStr.startsWith("TTABLE ")) {
- charsetStr = charsetStr.substring(7);
- }
- String[] charsets = charsetStr.split(charsetStr.substring(0,0));
- String myCharset = getCharsetName();
- for (String charset : charsets) {
- if (charset.equals(myCharset)) {
- write(IACSB);write(TELOPT_CHARSET);write(CHARSET_ACCEPTED);
- write(charset.getBytes());
- write(IACSE);
- System.out.println("Sent our charset!");
- return;
- }
- }
- write(IACSB);write(TELOPT_CHARSET);write(CHARSET_REJECTED);
- write(IACSE);
- break;
- }
- }
-
- /**
- * Do not send any notifications at startup. We do not know,
- * whether the remote client understands telnet protocol handling,
- * so we are silent.
- * (This used to send IAC WILL SGA, but this is false for a compliant
- * client.)
- */
- public void startup() throws IOException {
- }
- /**
- * Transpose special telnet codes like 0xff or newlines to values
- * that are compliant to the protocol. This method will also send
- * the buffer immediately after transposing the data.
- * @param buf the data buffer to be sent
- */
- public void transpose(byte[] buf) throws IOException {
- int i;
-
- byte[] nbuf,xbuf;
- int nbufptr=0;
- nbuf = new byte[buf.length*2]; // FIXME: buffer overflows possible
-
- for (i = 0; i < buf.length ; i++) {
- switch (buf[i]) {
- // Escape IAC twice in stream ... to be telnet protocol compliant
- // this is there in binary and non-binary mode.
- case IAC:
- nbuf[nbufptr++]=IAC;
- nbuf[nbufptr++]=IAC;
- break;
- // We need to heed RFC 854. LF (\n) is 10, CR (\r) is 13
- // we assume that the Terminal sends \n for lf+cr and \r for just cr
- // linefeed+carriage return is CR LF */
- case 10: // \n
- if (receivedDX[TELOPT_BINARY + 128 ] != DO) {
- while (nbuf.length - nbufptr < crlf.length) {
- xbuf = new byte[nbuf.length*2];
- System.arraycopy(nbuf,0,xbuf,0,nbufptr);
- nbuf = xbuf;
- }
- for (int j=0;j<crlf.length;j++)
- nbuf[nbufptr++]=crlf[j];
- break;
- } else {
- // copy verbatim in binary mode.
- nbuf[nbufptr++]=buf[i];
- }
- break;
- // carriage return is CR NUL */
- case 13: // \r
- if (receivedDX[TELOPT_BINARY + 128 ] != DO) {
- while (nbuf.length - nbufptr < cr.length) {
- xbuf = new byte[nbuf.length*2];
- System.arraycopy(nbuf,0,xbuf,0,nbufptr);
- nbuf = xbuf;
- }
- for (int j=0;j<cr.length;j++)
- nbuf[nbufptr++]=cr[j];
- } else {
- // copy verbatim in binary mode.
- nbuf[nbufptr++]=buf[i];
- }
- break;
- // all other characters are just copied
- default:
- nbuf[nbufptr++]=buf[i];
- break;
- }
- }
- xbuf = new byte[nbufptr];
- System.arraycopy(nbuf,0,xbuf,0,nbufptr);
- write(xbuf);
- }
-
- public void setCRLF(String xcrlf) { crlf = xcrlf.getBytes(); }
- public void setCR(String xcr) { cr = xcr.getBytes(); }
-
- /**
- * Handle telnet protocol negotiation. The buffer will be parsed
- * and necessary actions are taken according to the telnet protocol.
- * See <A HREF="RFC-Telnet-URL">RFC-Telnet</A>
- * @param nbuf the byte buffer put out after negotiation
- * @return number of bytes processed, 0 for none, and -1 for end of buffer.
- */
- public int negotiate(byte nbuf[], int offset)
- throws IOException
- {
- int count = tempbuf.length;
- byte[] buf = tempbuf;
- byte sendbuf[] = new byte[3];
- byte b,reply;
- int boffset = 0, noffset = offset;
- boolean dobreak = false;
-
- if (count == 0) // buffer is empty.
- return -1;
-
- while(!dobreak && (boffset < count) && (noffset < nbuf.length)) {
- b=buf[boffset++];
- // of course, byte is a signed entity (-128 -> 127)
- // but apparently the SGI Netscape 3.0 doesn't seem
- // to care and provides happily values up to 255
- if (b>=128)
- b=(byte)(b-256);
- if(debug > 2) {
- Byte B = new Byte(b);
- System.err.print("byte: " + B.intValue()+ " ");
- }
- switch (neg_state) {
- case STATE_DATA:
- if (b==IAC) {
- neg_state = STATE_IAC;
- dobreak = true; // leave the loop so we can sync.
- } else
- nbuf[noffset++]=b;
- break;
- case STATE_IAC:
- switch (b) {
- case IAC:
- if(debug > 2) System.err.print("IAC ");
- neg_state = STATE_DATA;
- nbuf[noffset++]=IAC;
- break;
- case WILL:
- if(debug > 2) System.err.print("WILL ");
- neg_state = STATE_IACWILL;
- break;
- case WONT:
- if(debug > 2) System.err.print("WONT ");
- neg_state = STATE_IACWONT;
- break;
- case DONT:
- if(debug > 2) System.err.print("DONT ");
- neg_state = STATE_IACDONT;
- break;
- case DO:
- if(debug > 2) System.err.print("DO ");
- neg_state = STATE_IACDO;
- break;
- case EOR:
- if(debug > 1) System.err.print("EOR ");
- notifyEndOfRecord();
- dobreak = true; // leave the loop so we can sync.
- neg_state = STATE_DATA;
- break;
- case SB:
- if(debug > 2) System.err.print("SB ");
- neg_state = STATE_IACSB;
- break;
- default:
- if(debug > 2) System.err.print("<UNKNOWN "+b+" > ");
- neg_state = STATE_DATA;
- break;
- }
- break;
- case STATE_IACWILL:
- switch(b) {
- case TELOPT_ECHO:
- if(debug > 2) System.err.println("ECHO");
- reply = DO;
- setLocalEcho(false);
- break;
- case TELOPT_SGA:
- if(debug > 2) System.err.println("SGA");
- reply = DO;
- break;
- case TELOPT_EOR:
- if(debug > 2) System.err.println("EOR");
- reply = DO;
- break;
- case TELOPT_BINARY:
- if(debug > 2) System.err.println("BINARY");
- reply = DO;
- break;
- default:
- if(debug > 2) System.err.println("<UNKNOWN,"+b+">");
- reply = DONT;
- break;
- }
- if(debug > 1) System.err.println("<"+b+", WILL ="+WILL+">");
- if (reply != sentDX[b+128] || WILL != receivedWX[b+128]) {
- sendbuf[0]=IAC;
- sendbuf[1]=reply;
- sendbuf[2]=b;
- write(sendbuf);
- sentDX[b+128] = reply;
- receivedWX[b+128] = WILL;
- }
- neg_state = STATE_DATA;
- break;
- case STATE_IACWONT:
- switch(b) {
- case TELOPT_ECHO:
- if(debug > 2) System.err.println("ECHO");
- setLocalEcho(true);
- reply = DONT;
- break;
- case TELOPT_SGA:
- if(debug > 2) System.err.println("SGA");
- reply = DONT;
- break;
- case TELOPT_EOR:
- if(debug > 2) System.err.println("EOR");
- reply = DONT;
- break;
- case TELOPT_BINARY:
- if(debug > 2) System.err.println("BINARY");
- reply = DONT;
- break;
- default:
- if(debug > 2) System.err.println("<UNKNOWN,"+b+">");
- reply = DONT;
- break;
- }
- if(reply != sentDX[b+128] || WONT != receivedWX[b+128]) {
- sendbuf[0]=IAC;
- sendbuf[1]=reply;
- sendbuf[2]=b;
- write(sendbuf);
- sentDX[b+128] = reply;
- receivedWX[b+128] = WILL;
- }
- neg_state = STATE_DATA;
- break;
- case STATE_IACDO:
- switch (b) {
- case TELOPT_ECHO:
- if(debug > 2) System.err.println("ECHO");
- reply = WILL;
- setLocalEcho(true);
- break;
- case TELOPT_SGA:
- if(debug > 2) System.err.println("SGA");
- reply = WILL;
- break;
- case TELOPT_TTYPE:
- if(debug > 2) System.err.println("TTYPE");
- reply = WILL;
- break;
- case TELOPT_BINARY:
- if(debug > 2) System.err.println("BINARY");
- reply = WILL;
- break;
- case TELOPT_NAWS:
- if(debug > 2) System.err.println("NAWS");
- int[] size = getWindowSize();
- receivedDX[b] = DO;
- if(size == null) {
- // this shouldn't happen
- write(IAC);
- write(WONT);
- write(TELOPT_NAWS);
- reply = WONT;
- sentWX[b] = WONT;
- break;
- }
- reply = WILL;
- sentWX[b] = WILL;
- sendbuf[0]=IAC;
- sendbuf[1]=WILL;
- sendbuf[2]=TELOPT_NAWS;
- write(sendbuf);
- write(IAC);write(SB);write(TELOPT_NAWS);
- write((byte) (size[0] >> 8));
- write((byte) (size[0] & 0xff));
- write((byte) (size[1] >> 8));
- write((byte) (size[1] & 0xff));
- write(IAC);write(SE);
- break;
- default:
- if(debug > 2) System.err.println("<UNKNOWN,"+b+">");
- reply = WONT;
- break;
- }
- if(reply != sentWX[128+b] || DO != receivedDX[128+b]) {
- sendbuf[0]=IAC;
- sendbuf[1]=reply;
- sendbuf[2]=b;
- write(sendbuf);
- sentWX[b+128] = reply;
- receivedDX[b+128] = DO;
- }
- neg_state = STATE_DATA;
- break;
- case STATE_IACDONT:
- switch (b) {
- case TELOPT_ECHO:
- if(debug > 2) System.err.println("ECHO");
- reply = WONT;
- setLocalEcho(false);
- break;
- case TELOPT_SGA:
- if(debug > 2) System.err.println("SGA");
- reply = WONT;
- break;
- case TELOPT_NAWS:
- if(debug > 2) System.err.println("NAWS");
- reply = WONT;
- break;
- case TELOPT_BINARY:
- if(debug > 2) System.err.println("BINARY");
- reply = WONT;
- break;
- default:
- if(debug > 2) System.err.println("<UNKNOWN,"+b+">");
- reply = WONT;
- break;
- }
- if(reply != sentWX[b+128] || DONT != receivedDX[b+128]) {
- write(IAC);write(reply);write(b);
- sentWX[b+128] = reply;
- receivedDX[b+128] = DONT;
- }
- neg_state = STATE_DATA;
- break;
- case STATE_IACSBIAC:
- if(debug > 2) System.err.println(""+b+" ");
- if (b == IAC) {
- sbbuf = new byte[0];
- current_sb = b;
- neg_state = STATE_IACSBDATA;
- } else {
- System.err.println("(bad) "+b+" ");
- neg_state = STATE_DATA;
- }
- break;
- case STATE_IACSB:
- if(debug > 2) System.err.println(""+b+" ");
- switch (b) {
- case IAC:
- neg_state = STATE_IACSBIAC;
- break;
- default:
- current_sb = b;
- sbbuf = new byte[0];
- neg_state = STATE_IACSBDATA;
- break;
- }
- break;
- case STATE_IACSBDATA:
- if (debug > 2) System.err.println(""+b+" ");
- switch (b) {
- case IAC:
- neg_state = STATE_IACSBDATAIAC;
- break;
- default:
- byte[] xsb = new byte[sbbuf.length+1];
- System.arraycopy(sbbuf,0,xsb,0,sbbuf.length);
- sbbuf = xsb;
- sbbuf[sbbuf.length-1] = b;
- break;
- }
- break;
- case STATE_IACSBDATAIAC:
- if (debug > 2) System.err.println(""+b+" ");
- switch (b) {
- case IAC:
- neg_state = STATE_IACSBDATA;
- byte[] xsb = new byte[sbbuf.length+1];
- System.arraycopy(sbbuf,0,xsb,0,sbbuf.length);
- sbbuf = xsb;
- sbbuf[sbbuf.length-1] = IAC;
- break;
- case SE:
- handle_sb(current_sb,sbbuf);
- current_sb = 0;
- neg_state = STATE_DATA;
- break;
- case SB:
- handle_sb(current_sb,sbbuf);
- neg_state = STATE_IACSB;
- break;
- default:
- neg_state = STATE_DATA;
- break;
- }
- break;
- default:
- if (debug > 1)
- System.err.println("This should not happen: "+neg_state+" ");
- neg_state = STATE_DATA;
- break;
- }
- }
- // shrink tempbuf to new processed size.
- byte[] xb = new byte[count-boffset];
- System.arraycopy(tempbuf,boffset,xb,0,count-boffset);
- tempbuf = xb;
- return noffset - offset;
- }
-
- public void inputfeed(byte[] b, int offset, int len) {
- byte[] xb = new byte[tempbuf.length+len];
-
- System.arraycopy(tempbuf,0,xb,0,tempbuf.length);
- System.arraycopy(b,offset,xb,tempbuf.length,len);
- tempbuf = xb;
- }
-}