Exemplo n.º 1
0
  public void receiveLoop() throws IOException {
    byte[] msg = new byte[35000];

    while (true) {
      int msglen;
      try {
        msglen = tc.receiveMessage(msg, 0, msg.length);
      } catch (SocketTimeoutException e) {
        // Timeout in read
        if (idle) {
          log.debug("Ignoring socket timeout");
          continue;
        }
        throw e;
      }
      idle = true;

      int type = msg[0] & 0xff;

      if (type == Packets.SSH_MSG_IGNORE) {
        continue;
      }

      if (type == Packets.SSH_MSG_DEBUG) {
        if (log.isDebugEnabled()) {
          TypesReader tr = new TypesReader(msg, 0, msglen);
          tr.readByte();
          tr.readBoolean();
          StringBuilder debugMessageBuffer = new StringBuilder();
          debugMessageBuffer.append(tr.readString("UTF-8"));

          for (int i = 0; i < debugMessageBuffer.length(); i++) {
            char c = debugMessageBuffer.charAt(i);

            if ((c >= 32) && (c <= 126)) {
              continue;
            }
            debugMessageBuffer.setCharAt(i, '\uFFFD');
          }

          log.debug("DEBUG Message from remote: '" + debugMessageBuffer.toString() + "'");
        }
        continue;
      }

      if (type == Packets.SSH_MSG_UNIMPLEMENTED) {
        throw new IOException("Peer sent UNIMPLEMENTED message, that should not happen.");
      }

      if (type == Packets.SSH_MSG_DISCONNECT) {
        TypesReader tr = new TypesReader(msg, 0, msglen);
        tr.readByte();
        int reason_code = tr.readUINT32();
        StringBuilder reasonBuffer = new StringBuilder();
        reasonBuffer.append(tr.readString("UTF-8"));

        /*
         * Do not get fooled by servers that send abnormal long error
         * messages
         */

        if (reasonBuffer.length() > 255) {
          reasonBuffer.setLength(255);
          reasonBuffer.setCharAt(254, '.');
          reasonBuffer.setCharAt(253, '.');
          reasonBuffer.setCharAt(252, '.');
        }

        /*
         * Also, check that the server did not send characters that may
         * screw up the receiver -> restrict to reasonable US-ASCII
         * subset -> "printable characters" (ASCII 32 - 126). Replace
         * all others with 0xFFFD (UNICODE replacement character).
         */

        for (int i = 0; i < reasonBuffer.length(); i++) {
          char c = reasonBuffer.charAt(i);

          if ((c >= 32) && (c <= 126)) {
            continue;
          }
          reasonBuffer.setCharAt(i, '\uFFFD');
        }

        throw new IOException(
            "Peer sent DISCONNECT message (reason code "
                + reason_code
                + "): "
                + reasonBuffer.toString());
      }

      /*
       * Is it a KEX Packet?
       */

      if ((type == Packets.SSH_MSG_KEXINIT)
          || (type == Packets.SSH_MSG_NEWKEYS)
          || ((type >= 30) && (type <= 49))) {
        km.handleMessage(msg, msglen);
        continue;
      }

      MessageHandler mh = null;

      for (int i = 0; i < messageHandlers.size(); i++) {
        HandlerEntry he = messageHandlers.get(i);
        if ((he.low <= type) && (type <= he.high)) {
          mh = he.mh;
          break;
        }
      }

      if (mh == null) {
        throw new IOException("Unexpected SSH message (type " + type + ")");
      }

      mh.handleMessage(msg, msglen);
    }
  }
Exemplo n.º 2
0
  public void initialize(
      String identification,
      CryptoWishList cwl,
      ServerHostKeyVerifier verifier,
      DHGexParameters dhgex,
      int connectTimeout,
      SecureRandom rnd,
      ProxyData proxyData)
      throws IOException {
    /* First, establish the TCP connection to the SSH-2 server */

    establishConnection(proxyData, connectTimeout);

    /* Parse the server line and say hello - important: this information is later needed for the
     * key exchange (to stop man-in-the-middle attacks) - that is why we wrap it into an object
     * for later use.
     */

    ClientServerHello csh =
        new ClientServerHello(identification, sock.getInputStream(), sock.getOutputStream());

    tc = new TransportConnection(sock.getInputStream(), sock.getOutputStream(), rnd);

    km = new KexManager(this, csh, cwl, hostname, port, verifier, rnd);
    km.initiateKEX(cwl, dhgex);

    receiveThread =
        new Thread(
            new Runnable() {
              public void run() {
                try {
                  receiveLoop();
                } catch (IOException e) {
                  close(e, false);

                  log.warning("Receive thread: error in receiveLoop: " + e.getMessage());
                }

                if (log.isDebugEnabled()) {
                  log.debug("Receive thread: back from receiveLoop");
                }

                /* Tell all handlers that it is time to say goodbye */

                if (km != null) {
                  try {
                    km.handleMessage(null, 0);
                  } catch (IOException ignored) {
                  }
                }

                for (HandlerEntry he : messageHandlers) {
                  try {
                    he.mh.handleMessage(null, 0);
                  } catch (Exception ignore) {
                  }
                }
              }
            });

    receiveThread.setDaemon(true);
    receiveThread.start();
  }
Exemplo n.º 3
0
 public void forceKeyExchange(CryptoWishList cwl, DHGexParameters dhgex) throws IOException {
   km.initiateKEX(cwl, dhgex);
 }
Exemplo n.º 4
0
 public ConnectionInfo getConnectionInfo(int kexNumber) throws IOException {
   return km.getOrWaitForConnectionInfo(kexNumber);
 }