123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187 |
- package de.tudarmstadt.informatik.hostage.protocol;
- import java.util.ArrayList;
- import java.util.List;
- import javax.net.ssl.SSLContext;
- import de.tudarmstadt.informatik.hostage.commons.HelperUtils;
- import de.tudarmstadt.informatik.hostage.wrapper.ByteArray;
- /**
- * TELNET protocol
- * @author Wulf Pfeiffer
- */
- public final class TELNET implements Protocol<ByteArray> {
- /**
- * Represents the states of the protocol
- */
- private static enum STATE {
- NONE, OPEN, CLOSED, LOGIN, AUTHENTICATE, LOGGED_IN
- };
-
- /**
- * Denotes in which state the protocol is right now
- */
- private STATE state = STATE.NONE;
- /** user entered by the client */
- private byte[] user;
- /** last command sent by the client */
- private byte[] command;
- /** name of the server */
- private String server = "raspberrypi";
- /** command line prefix */
- private byte[] sessionToken = null;
- @Override
- public int getPort() {
- return 23;
- }
- @Override
- public TALK_FIRST whoTalksFirst() {
- return TALK_FIRST.SERVER;
- }
- @Override
- public List<ByteArray> processMessage(ByteArray message) {
- byte[] request = null;
- if(message != null) request = message.get();
- List<ByteArray> response = new ArrayList<ByteArray>();
- switch (state) {
- case NONE:
- response.add(new ByteArray(optionRequest));
- state = STATE.OPEN;
- break;
- case OPEN:
- if(request != null) {
- response.add(new ByteArray(getOptionResponse(request)));
- response.add(new ByteArray("Debian GNU/Linux 7.0\r\n"));
- response.add(new ByteArray(server + "login: "));
- state = STATE.LOGIN;
- }
- break;
- case LOGIN:
- if(request == null) break;
- else if(request[0] == 0x0d) {
- response.add(new ByteArray("\r\n"));
- response.add(new ByteArray("Password: "));
- state = STATE.AUTHENTICATE;
- sessionToken = HelperUtils.concat(sessionPrefix, "@".getBytes(), server.getBytes(), sessionMiddle, "@".getBytes(), server.getBytes(), sessionSuffix);
- break;
- } else if (request[0] == 0x7f) {
- byte[] tmp = new byte[user.length - 1];
- System.arraycopy(user, 0, tmp, 0, user.length - 1);
- user = tmp;
- response.add(new ByteArray("\b \b"));
- } else if (request[0] != (byte) 0xff){
- if(user == null)
- user = request;
- else
- user = HelperUtils.concat(user, request);
- response.add(message);
- }
- break;
- case AUTHENTICATE:
- if(request == null) break;
- else if(request[0] == 0x0d) {
- response.add(new ByteArray("Last Login: \r\nLinux" + server + " 3.6.11+\r\n"));
- response.add(new ByteArray(sessionToken));
- state = STATE.LOGGED_IN;
- } else if (request[0] == 0x7f) {
- response.add(new ByteArray("\b \b"));
- }
- break;
- case LOGGED_IN:
- if(request == null) break;
- else if(request[0] == 0x0d) {
- if(command == null) {
- response.add(new ByteArray("\r\n"));
- response.add(new ByteArray(sessionToken));
- } else if (new String(command).contains("exit")) {
- response.add(new ByteArray("\r\nlogout\r\n"));
- state = STATE.CLOSED;
- } else {
- String bash = "\r\n-bash: " + new String(command)+ ": command not found";
- response.add(new ByteArray(bash));
- response.add(new ByteArray("\r\n"));
- response.add(new ByteArray(sessionToken));
- command = null;
- }
- } else if (request[0] == 0x7f) {
- byte[] tmp = new byte[command.length - 1];
- System.arraycopy(command, 0, tmp, 0, command.length - 1);
- command = tmp;
- response.add(new ByteArray("\b \b"));
- } else if (request[0] != (byte) 0xff){
- if(command == null)
- command = request;
- else
- command = HelperUtils.concat(command, request);
- response.add(message);
- }
- break;
- default:
- response.add(new ByteArray("\r\nlogout\r\n"));
- state = STATE.CLOSED;
- break;
- }
- return response;
- }
- @Override
- public boolean isClosed() {
- return (state == STATE.CLOSED);
- }
- @Override
- public boolean isSecure() {
- return false;
- }
- @Override
- public String toString() {
- return "TELNET";
- }
-
- @Override
- public Class<ByteArray> getType() {
- return ByteArray.class;
- }
- /**
- * Determines which options that are requested by the client will be done and which not
- * @param request requested options
- * @return accepted and unaccepted options
- */
- private byte[] getOptionResponse(byte[] request) {
- List<byte[]> respList = new ArrayList<byte[]>();
- byte[] cmdResp;
- for(int i = 0; i < request.length - 2; i += 3) {
- if(request[i] == (byte) 0xff && request[i+2] != 0x03 && request[i+2] != 0x01) {
- cmdResp = new byte[3];
- cmdResp[0] = request[i];
- cmdResp[1] = request[i + 1] == (byte) 0xfd ? (byte) 0xfc : (byte) 0xfe;
- cmdResp[2] = request[i+2];
- respList.add(cmdResp);
- }
- }
- byte[] response = new byte[0];
- for(byte[] resp : respList) {
- response = HelperUtils.concat(response, resp);
- }
- return response;
- }
- /** options requested by the server */
- private final byte[] optionRequest = {(byte) 0xff, (byte) 0xfb, 0x03,
- (byte) 0xff, (byte) 0xfb, 0x01};
- //session token prefix, mid and suffix
- private final byte[] sessionPrefix = {0x1b, 0x5d, 0x30, 0x3b};
- private final byte[] sessionMiddle = {0x40, 0x72, 0x61, 0x73,
- 0x70, 0x62, 0x65, 0x72, 0x72, 0x79, 0x70, 0x69, 0x3a, 0x20, 0x7e, 0x07, 0x1b, 0x5b, 0x30, 0x31,
- 0x3b, 0x33, 0x32, 0x6d};
- private final byte[] sessionSuffix = {0x1b, 0x5b, 0x30, 0x30, 0x6d, 0x20, 0x1b, 0x5b, 0x30, 0x31,
- 0x3b, 0x33, 0x34, 0x6d, 0x7e, 0x20, 0x24, 0x1b, 0x5b, 0x30, 0x30, 0x6d, 0x20};
- }
|