/**
   * Notification message saying that the server supports TLS so confirm the server that we want to
   * secure the connection.
   *
   * @param required true when the server indicates that TLS is required.
   */
  void startTLSReceived(boolean required) {
    if (required && config.getSecurityMode() == ConnectionConfiguration.SecurityMode.disabled) {
      packetReader.notifyConnectionError(
          new IllegalStateException(
              "TLS required by server but not allowed by connection configuration"));
      return;
    }

    if (required && usingSSL) {
      packetReader.notifyConnectionError(
          new IllegalStateException("TLS required by server but legacy SSL already enabled"));
      return;
    }

    if ((config.getSecurityMode() == ConnectionConfiguration.SecurityMode.disabled)
        || (config.getSecurityMode() == ConnectionConfiguration.SecurityMode.legacy)) {
      // Do not secure the connection using TLS since TLS was disabled or we are using SSL.
      return;
    }

    try {
      writer.write("<starttls xmlns=\"urn:ietf:params:xml:ns:xmpp-tls\"/>");
      writer.flush();
    } catch (IOException e) {
      packetReader.notifyConnectionError(e);
    }
  }
  @Override
  public void run() {

    ServerSocket sSock = null;

    try {

      sSock = new ServerSocket(port);

      while (true) {

        try {

          PacketReader pr = new PacketReader(sockets);
          pr.socket = sSock.accept();
          pr.start();
        } catch (Exception ex) {
          ex.printStackTrace();
          Thread.sleep(5000);
        }
      }
    } catch (Exception ex) {
      ex.printStackTrace();
    }
  }
  /**
   * Closes the connection by setting presence to unavailable then closing the stream to the XMPP
   * server. The shutdown logic will be used during a planned disconnection or when dealing with an
   * unexpected disconnection. Unlike {@link #disconnect()} the connection's packet reader, packet
   * writer, and {@link Roster} will not be removed; thus connection's state is kept.
   *
   * @param unavailablePresence the presence packet to send during shutdown.
   */
  protected void shutdown(Presence unavailablePresence) {
    // Set presence to offline.
    PacketWriter packetWriter = this.packetWriter;
    if (packetWriter != null) {
      packetWriter.sendPacket(unavailablePresence);
    }

    this.setWasAuthenticated(authenticated);
    authenticated = false;
    connected = false;

    PacketReader packetReader = this.packetReader;
    if (packetReader != null) {
      packetReader.shutdown();
    }
    packetWriter = this.packetWriter;
    if (packetWriter != null) {
      packetWriter.shutdown();
    }
    // Wait 150 ms for processes to clean-up, then shutdown.
    try {
      Thread.sleep(150);
    } catch (Exception e) {
      // Ignore.
    }

    // Close down the readers and writers.
    Reader reader = this.reader;
    if (reader != null) {
      try {
        reader.close();
      } catch (Throwable ignore) {
        /* ignore */
      }
      this.reader = null;
    }
    Writer writer = this.writer;
    if (writer != null) {
      try {
        writer.close();
      } catch (Throwable ignore) {
        /* ignore */
      }
      this.writer = null;
    }

    try {
      socket.close();
    } catch (Exception e) {
      // Ignore.
    }

    saslAuthentication.init();
  }
 /**
  * Request the server that we want to start using stream compression. When using TLS then
  * negotiation of stream compression can only happen after TLS was negotiated. If TLS compression
  * is being used the stream compression should not be used.
  */
 private void requestStreamCompression() {
   try {
     writer.write("<compress xmlns='http://jabber.org/protocol/compress'>");
     writer.write("<method>zlib</method></compress>");
     writer.flush();
   } catch (IOException e) {
     packetReader.notifyConnectionError(e);
   }
 }
Beispiel #5
0
  @Test
  public void shouldFailWhenPacketLengthTooLarge() throws Exception {
    dataout.writeInt(Integer.MAX_VALUE);
    dataout.flush();

    try {
      reader.readPacket();
      fail("Should have failed to read packet of size " + Integer.MAX_VALUE);
    } catch (SSHException e) {
      e.printStackTrace();
      // success; indicated packet size was too large
    }
  }
Beispiel #6
0
  // FIXME What is the byte format for the size? Big endian? Little endian?
  @Test
  public void shouldReadPacket() throws Exception {
    byte[] bytes = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    dataout.writeInt(10);
    dataout.write(bytes);
    dataout.flush();

    SFTPPacket<Response> packet = reader.readPacket();
    assertEquals(packet.available(), 10);
    assertTrue(
        "actual=" + Arrays.toString(packet.array()),
        Arrays.equals(bytes, subArray(packet.array(), 0, 10)));
  }
  public void disconnect(Presence unavailablePresence) {
    // If not connected, ignore this request.
    PacketReader packetReader = this.packetReader;
    PacketWriter packetWriter = this.packetWriter;
    if (packetReader == null || packetWriter == null) {
      return;
    }

    shutdown(unavailablePresence);

    if (roster != null) {
      roster.cleanup();
      roster = null;
    }
    chatManager = null;

    wasAuthenticated = false;

    packetWriter.cleanup();
    this.packetWriter = null;
    packetReader.cleanup();
    this.packetReader = null;
  }
Beispiel #8
0
 protected void customRun() throws InterruptedException {
   if (outRunnable.reconnection.get()) {
     Thread.sleep(10L);
     return;
   }
   Packet packet;
   try {
     Connection oldConnection = connection;
     connection = client.connectionManager.getConnection();
     if (restoredConnection(oldConnection, connection)) {
       if (outRunnable.sendReconnectCall(connection)) {
         logger.log(Level.FINEST, "restoredConnection");
         if (oldConnection != null) {
           redoUnfinishedCalls(oldConnection);
         }
       }
       return;
     }
     if (connection == null) {
       outRunnable.clusterIsDown(oldConnection);
       Thread.sleep(10);
     } else {
       packet = reader.readPacket(connection);
       //                logger.log(Level.FINEST, "Reading " + packet.getOperation() + " Call id: "
       // + packet.getCallId());
       this.lastReceived = System.currentTimeMillis();
       Call call = callMap.remove(packet.getCallId());
       if (call != null) {
         call.received = System.nanoTime();
         call.setResponse(packet);
       } else {
         if (packet.getOperation().equals(ClusterOperation.EVENT)) {
           client.getListenerManager().enqueue(packet);
         }
         if (packet.getCallId() != -1) {
           logger.log(
               Level.SEVERE,
               "In Thread can not handle: " + packet.getOperation() + " : " + packet.getCallId());
         }
       }
     }
   } catch (Throwable e) {
     logger.log(
         Level.FINEST, "InRunnable [" + connection + "] got an exception:" + e.toString(), e);
     outRunnable.clusterIsDown(connection);
   }
 }
 /**
  * Establishes a connection to the XMPP server and performs an automatic login only if the
  * previous connection state was logged (authenticated). It basically creates and maintains a
  * socket connection to the server.
  *
  * <p>
  *
  * <p>Listeners will be preserved from a previous connection if the reconnection occurs after an
  * abrupt termination.
  *
  * @throws XMPPException if an error occurs while trying to establish the connection. Two possible
  *     errors can occur which will be wrapped by an XMPPException -- UnknownHostException (XMPP
  *     error code 504), and IOException (XMPP error code 502). The error codes and wrapped
  *     exceptions can be used to present more appropiate error messages to end-users.
  */
 public void connect() throws XMPPException {
   // Stablishes the connection, readers and writers
   connectUsingConfiguration(config);
   // Automatically makes the login if the user was previouslly connected successfully
   // to the server and the connection was terminated abruptly
   if (connected && wasAuthenticated) {
     // Make the login
     try {
       if (isAnonymous()) {
         // Make the anonymous login
         loginAnonymously();
       } else {
         login(config.getUsername(), config.getPassword(), config.getResource());
       }
       packetReader.notifyReconnection();
     } catch (XMPPException e) {
       e.printStackTrace();
     }
   }
 }
 @Override
 public void read(ByteBuffer inBuffer) throws Exception {
   packetReader.readPacket(inBuffer);
 }
  /**
   * Initializes the connection by creating a packet reader and writer and opening a XMPP stream to
   * the server.
   *
   * @throws XMPPException if establishing a connection to the server fails.
   */
  private void initConnection() throws XMPPException {
    PacketReader packetReader = this.packetReader;
    PacketWriter packetWriter = this.packetWriter;
    boolean isFirstInitialization = packetReader == null || packetWriter == null;
    usingCompression = false;

    // Set the reader and writer instance variables
    initReaderAndWriter();

    try {
      if (isFirstInitialization) {
        this.packetWriter = packetWriter = new PacketWriter(this);
        this.packetReader = packetReader = new PacketReader(this);

        // If debugging is enabled, we should start the thread that will listen for
        // all packets and then log them.
        if (config.isDebuggerEnabled()) {
          addPacketListener(debugger.getReaderListener(), null);
          if (debugger.getWriterListener() != null) {
            addPacketSendingListener(debugger.getWriterListener(), null);
          }
        }
      } else {
        packetWriter.init();
        packetReader.init();
      }

      // Start the packet writer. This will open a XMPP stream to the server
      packetWriter.startup();
      // Start the packet reader. The startup() method will block until we
      // get an opening stream packet back from server.
      packetReader.startup();

      // Make note of the fact that we're now connected.
      connected = true;

      // Start keep alive process (after TLS was negotiated - if available)
      packetWriter.startKeepAliveProcess();

      if (isFirstInitialization) {
        // Notify listeners that a new connection has been established
        for (ConnectionCreationListener listener : getConnectionCreationListeners()) {
          listener.connectionCreated(this);
        }
      } else if (!wasAuthenticated) {
        packetReader.notifyReconnection();
      }

    } catch (XMPPException ex) {
      // An exception occurred in setting up the connection. Make sure we shut down the
      // readers and writers and close the socket.

      if (packetWriter != null) {
        try {
          packetWriter.shutdown();
        } catch (Throwable ignore) {
          /* ignore */
        }
        this.packetWriter = null;
      }
      if (packetReader != null) {
        try {
          packetReader.shutdown();
        } catch (Throwable ignore) {
          /* ignore */
        }
        this.packetReader = null;
      }
      if (reader != null) {
        try {
          reader.close();
        } catch (Throwable ignore) {
          /* ignore */
        }
        reader = null;
      }
      if (writer != null) {
        try {
          writer.close();
        } catch (Throwable ignore) {
          /* ignore */
        }
        writer = null;
      }
      if (socket != null) {
        try {
          socket.close();
        } catch (Exception e) {
          /* ignore */
        }
        socket = null;
      }
      this.setWasAuthenticated(authenticated);
      chatManager = null;
      authenticated = false;
      connected = false;

      throw ex; // Everything stoppped. Now throw the exception.
    }
  }