예제 #1
0
  public void requestSubSystem(Channel c, String subSystemName) throws IOException {
    PacketSessionSubsystemRequest ssr;

    synchronized (c) {
      if (c.state != Channel.STATE_OPEN)
        throw new IOException(
            "Cannot request subsystem on this channel (" + c.getReasonClosed() + ")");

      ssr = new PacketSessionSubsystemRequest(c.remoteID, true, subSystemName);

      c.successCounter = c.failedCounter = 0;
    }

    synchronized (c.channelSendLock) {
      if (c.closeMessageSent)
        throw new IOException(
            "Cannot request subsystem on this channel (" + c.getReasonClosed() + ")");
      tm.sendMessage(ssr.getPayload());
    }

    try {
      waitForChannelSuccessOrFailure(c);
    } catch (IOException e) {
      throw (IOException) new IOException("The subsystem request failed.").initCause(e);
    }
  }
예제 #2
0
  /**
   * @param charsetName The charset used to convert between Java Unicode Strings and byte encodings
   */
  public void requestExecCommand(Channel c, String cmd, String charsetName) throws IOException {
    PacketSessionExecCommand sm;

    synchronized (c) {
      if (c.state != Channel.STATE_OPEN)
        throw new IOException(
            "Cannot execute command on this channel (" + c.getReasonClosed() + ")");

      sm = new PacketSessionExecCommand(c.remoteID, true, cmd);

      c.successCounter = c.failedCounter = 0;
    }

    synchronized (c.channelSendLock) {
      if (c.closeMessageSent)
        throw new IOException(
            "Cannot execute command on this channel (" + c.getReasonClosed() + ")");
      tm.sendMessage(sm.getPayload(charsetName));
    }

    log.debug("Executing command (channel " + c.localID + ", '" + cmd + "')");

    try {
      waitForChannelSuccessOrFailure(c);
    } catch (IOException e) {
      throw (IOException) new IOException("The execute request failed.").initCause(e);
    }
  }
예제 #3
0
  private void waitForChannelSuccessOrFailure(Channel c) throws IOException {
    boolean wasInterrupted = false;

    try {
      synchronized (c) {
        while ((c.successCounter == 0) && (c.failedCounter == 0)) {
          if (c.state != Channel.STATE_OPEN) {
            String detail = c.getReasonClosed();

            if (detail == null) detail = "state: " + c.state;

            throw new IOException("This SSH2 channel is not open (" + detail + ")");
          }

          try {
            c.wait();
          } catch (InterruptedException ignore) {
            wasInterrupted = true;
          }
        }

        if (c.failedCounter != 0) {
          throw new IOException("The server denied the request.");
        }
      }
    } finally {
      if (wasInterrupted) Thread.currentThread().interrupt();
    }
  }
예제 #4
0
  private void waitUntilChannelOpen(Channel c) throws IOException {
    boolean wasInterrupted = false;

    synchronized (c) {
      while (c.state == Channel.STATE_OPENING) {
        try {
          c.wait();
        } catch (InterruptedException ignore) {
          wasInterrupted = true;
        }
      }

      if (c.state != Channel.STATE_OPEN) {
        removeChannel(c.localID);

        String detail = c.getReasonClosed();

        if (detail == null) detail = "state: " + c.state;

        throw new IOException("Could not open channel (" + detail + ")");
      }
    }

    if (wasInterrupted) Thread.currentThread().interrupt();
  }
예제 #5
0
  public void requestPTY(
      Channel c,
      String term,
      int term_width_characters,
      int term_height_characters,
      int term_width_pixels,
      int term_height_pixels,
      byte[] terminal_modes)
      throws IOException {
    PacketSessionPtyRequest spr;

    synchronized (c) {
      if (c.state != Channel.STATE_OPEN)
        throw new IOException("Cannot request PTY on this channel (" + c.getReasonClosed() + ")");

      spr =
          new PacketSessionPtyRequest(
              c.remoteID,
              true,
              term,
              term_width_characters,
              term_height_characters,
              term_width_pixels,
              term_height_pixels,
              terminal_modes);

      c.successCounter = c.failedCounter = 0;
    }

    synchronized (c.channelSendLock) {
      if (c.closeMessageSent)
        throw new IOException("Cannot request PTY on this channel (" + c.getReasonClosed() + ")");
      tm.sendMessage(spr.getPayload());
    }

    try {
      waitForChannelSuccessOrFailure(c);
    } catch (IOException e) {
      throw (IOException) new IOException("PTY request failed").initCause(e);
    }
  }
예제 #6
0
  public void requestX11(
      Channel c,
      boolean singleConnection,
      String x11AuthenticationProtocol,
      String x11AuthenticationCookie,
      int x11ScreenNumber)
      throws IOException {
    PacketSessionX11Request psr;

    synchronized (c) {
      if (c.state != Channel.STATE_OPEN)
        throw new IOException("Cannot request X11 on this channel (" + c.getReasonClosed() + ")");

      psr =
          new PacketSessionX11Request(
              c.remoteID,
              true,
              singleConnection,
              x11AuthenticationProtocol,
              x11AuthenticationCookie,
              x11ScreenNumber);

      c.successCounter = c.failedCounter = 0;
    }

    synchronized (c.channelSendLock) {
      if (c.closeMessageSent)
        throw new IOException("Cannot request X11 on this channel (" + c.getReasonClosed() + ")");
      tm.sendMessage(psr.getPayload());
    }

    log.debug("Requesting X11 forwarding (Channel " + c.localID + "/" + c.remoteID + ")");

    try {
      waitForChannelSuccessOrFailure(c);
    } catch (IOException e) {
      throw (IOException) new IOException("The X11 request failed.").initCause(e);
    }
  }
예제 #7
0
  public void requestShell(Channel c) throws IOException {
    PacketSessionStartShell sm;

    synchronized (c) {
      if (c.state != Channel.STATE_OPEN)
        throw new IOException("Cannot start shell on this channel (" + c.getReasonClosed() + ")");

      sm = new PacketSessionStartShell(c.remoteID, true);

      c.successCounter = c.failedCounter = 0;
    }

    synchronized (c.channelSendLock) {
      if (c.closeMessageSent)
        throw new IOException("Cannot start shell on this channel (" + c.getReasonClosed() + ")");
      tm.sendMessage(sm.getPayload());
    }

    try {
      waitForChannelSuccessOrFailure(c);
    } catch (IOException e) {
      throw (IOException) new IOException("The shell request failed.").initCause(e);
    }
  }
예제 #8
0
  public void sendData(Channel c, byte[] buffer, int pos, int len) throws IOException {
    boolean wasInterrupted = false;

    try {
      while (len > 0) {
        int thislen = 0;
        byte[] msg;

        synchronized (c) {
          while (true) {
            if (c.state == Channel.STATE_CLOSED)
              throw new ChannelClosedException(
                  "SSH channel is closed. (" + c.getReasonClosed() + ")");

            if (c.state != Channel.STATE_OPEN)
              throw new ChannelClosedException("SSH channel in strange state. (" + c.state + ")");

            if (c.remoteWindow != 0) break;

            try {
              c.wait();
            } catch (InterruptedException ignore) {
              wasInterrupted = true;
            }
          }

          /* len > 0, no sign extension can happen when comparing */

          thislen = (c.remoteWindow >= len) ? len : (int) c.remoteWindow;

          int estimatedMaxDataLen = c.remoteMaxPacketSize - (tm.getPacketOverheadEstimate() + 9);

          /* The worst case scenario =) a true bottleneck */

          if (estimatedMaxDataLen <= 0) {
            estimatedMaxDataLen = 1;
          }

          if (thislen > estimatedMaxDataLen) thislen = estimatedMaxDataLen;

          c.remoteWindow -= thislen;

          msg = new byte[1 + 8 + thislen];

          msg[0] = Packets.SSH_MSG_CHANNEL_DATA;
          msg[1] = (byte) (c.remoteID >> 24);
          msg[2] = (byte) (c.remoteID >> 16);
          msg[3] = (byte) (c.remoteID >> 8);
          msg[4] = (byte) (c.remoteID);
          msg[5] = (byte) (thislen >> 24);
          msg[6] = (byte) (thislen >> 16);
          msg[7] = (byte) (thislen >> 8);
          msg[8] = (byte) (thislen);

          System.arraycopy(buffer, pos, msg, 9, thislen);
        }

        synchronized (c.channelSendLock) {
          if (c.closeMessageSent == true)
            throw new ChannelClosedException(
                "SSH channel is closed. (" + c.getReasonClosed() + ")");

          tm.sendMessage(msg);
        }

        pos += thislen;
        len -= thislen;
      }
    } finally {
      if (wasInterrupted) Thread.currentThread().interrupt();
    }
  }