Exemple #1
0
  void write(Packet packet) throws Exception {
    if (reply) {
      channel.reply = -1;
    }
    session.write(packet);
    if (reply) {
      long start = System.currentTimeMillis();
      long timeout = channel.connectTimeout;

      while (channel.isConnected() && channel.reply == -1) {
        try {
          Thread.sleep(10);
        } catch (Exception ee) {
        }
        if (timeout > 0L && (System.currentTimeMillis() - start) > timeout) {
          channel.reply = 0;
          throw new JSchException("channel request: timeout");
        }
      }

      if (channel.reply == 0) {
        throw new JSchException("failed to send channel request");
      }
    }
  }
  public void init(Session session, byte[] V_S, byte[] V_C, byte[] I_S, byte[] I_C)
      throws Exception {
    this.session = session;
    this.V_S = V_S;
    this.V_C = V_C;
    this.I_S = I_S;
    this.I_C = I_C;

    try {
      Class c = Class.forName(session.getConfig(hash));
      sha = (HASH) (c.newInstance());
      sha.init();
    } catch (Exception e) {
      System.err.println(e);
    }

    buf = new Buffer();
    packet = new Packet(buf);

    try {
      Class c = Class.forName(session.getConfig("dh"));
      // Since JDK8, SunJCE has lifted the keysize restrictions
      // from 1024 to 2048 for DH.
      preferred = max = check2048(c, max);
      dh = (com.jcraft.jsch.DH) (c.newInstance());
      dh.init();
    } catch (Exception e) {
      throw e;
    }

    packet.reset();
    buf.putByte((byte) SSH_MSG_KEX_DH_GEX_REQUEST);
    buf.putInt(min);
    buf.putInt(preferred);
    buf.putInt(max);
    session.write(packet);

    if (JSch.getLogger().isEnabled(Logger.INFO)) {
      JSch.getLogger()
          .log(
              Logger.INFO,
              "SSH_MSG_KEX_DH_GEX_REQUEST(" + min + "<" + preferred + "<" + max + ") sent");
      JSch.getLogger().log(Logger.INFO, "expecting SSH_MSG_KEX_DH_GEX_GROUP");
    }

    state = SSH_MSG_KEX_DH_GEX_GROUP;
  }
  private Session sendCommandAndGetSession(Transaction[] txs) throws FatalSessionException {

    Session session = null;
    Command command = txs[0].getCommand();
    int failCount = 0;

    while (state != SMState.STOPPED) {
      try {
        session = sessionPool.getSession(txs);
        txs[0].start();
        session.write(command);
        session.getStatsManager().incCommandCounter(command.getCommandType());
        return session;
      } catch (ParsingException pe) {
        txs[0].setState(TransactionState.FATAL_ERROR);
        txs[0].setCause(pe.getCause());
        return session;
      } catch (IOException ioe) {
        sessionPool.releaseSession(session);
        if (failCount < MAX_ACCEPTABLE_FAIL_COUNT) {
          failCount++;
        } else {
          throw new FatalSessionException(ioe);
        }
      } catch (InterruptedException ie) {
        sessionPool.releaseSession(session);
        userLogger.warning(ie.getMessage());
      } catch (SessionConfigurationException sce) {
        sessionPool.releaseSession(session);
        throw new FatalSessionException(sce);
      } catch (SessionOpenException soe) {
        sessionPool.releaseSession(session);
        throw new FatalSessionException(soe);
      }
    }

    throw new IllegalStateException();
  }
  public void request(Session session, Channel channel) throws Exception {
    Buffer buf = new Buffer();
    Packet packet = new Packet(buf);

    // byte      SSH_MSG_CHANNEL_REQUEST
    // uint32    recipient_channel
    // string    "window-change"
    // boolean   FALSE
    // uint32    terminal width, columns
    // uint32    terminal height, rows
    // uint32    terminal width, pixels
    // uint32    terminal height, pixels
    packet.reset();
    buf.putByte((byte) Session.SSH_MSG_CHANNEL_REQUEST);
    buf.putInt(channel.getRecipient());
    buf.putString("window-change".getBytes());
    buf.putByte((byte) (waitForReply() ? 1 : 0));
    buf.putInt(width_columns);
    buf.putInt(height_rows);
    buf.putInt(width_pixels);
    buf.putInt(height_pixels);
    session.write(packet);
  }
  /** Return the index of the last transaction considered for sending. */
  private int send(Transaction[] txs, Session session, StatsManager statsManager)
      throws IOException {

    for (int i = 1; i < txs.length; i++) {
      switch (txs[i].getState()) {
        case PROCESSED:
        case FATAL_ERROR:
          continue;
        default:
      }

      Command command = txs[i].getCommand();
      txs[i].start();

      try {
        session.write(command);
        statsManager.incCommandCounter(command.getCommandType());
      } catch (ParsingException pe) {
        txs[i].setState(TransactionState.FATAL_ERROR);
        if (pe.getCause() instanceof SAXException) {
          SAXException saxe = (SAXException) pe.getCause();
          userLogger.warning(saxe.getMessage());
          txs[i].setCause(saxe);
        } else {
          userLogger.warning(pe.getMessage());
          txs[i].setCause(pe);
        }
      } catch (IOException ioe) {
        userLogger.severe(ioe.getMessage());
        txs[i].setState(TransactionState.RETRY);
        txs[i].setCause(ioe);
        throw ioe;
      }
    }

    return txs.length - 1;
  }
  /**
   * Try to process a single transaction. Up to {@code MAX_ACCEPTABLE_FAIL_COUNT} attempts will be
   * made to process the transaction in cases where I/O errors or non-protocol server errors occur
   * during processing. Use of the underlying session is protected against concurrent use by other
   * threads by using the getSession/releaseSession features of this SessionManager's {@link
   * com.ausregistry.jtoolkit2.session.SessionPool}. This method guarantees that the session used
   * will be returned to the pool before the method returns.
   *
   * @throws FatalSessionException No session could be acquired to process the transaction. Check
   *     the exception message and log records for details.
   * @throws IOException Every attempt to execute the transaction command failed due to an
   *     IOException. This is the last such IOException.
   * @throws ParsingException Parsing of the response failed. Check the exception message for the
   *     cause.
   * @throws CommandFailedException The acceptable limit on the number of failed commands due to
   *     server error was exceeded in trying to process the command. This probably indicates a
   *     server limitation related to the command being processed.
   * @throws IllegalStateException The SessionManager had been shutdown or not started up prior to
   *     invoking this method.
   */
  @Override
  public void execute(Transaction tx)
      throws FatalSessionException, IOException, ParsingException, CommandFailedException,
          IllegalStateException {

    debugLogger.finest("enter");

    if (state == SMState.STOPPED) {
      throw new IllegalStateException();
    }

    Command cmd = tx.getCommand();
    Response response = tx.getResponse();

    int failCount = 0;
    boolean isExecuted = false;
    Session session = null;

    // if only processing one transaction, get a new session for each
    // attempt in case the session fails mid-transaction.
    while (!isExecuted && state != SMState.STOPPED) {
      try {
        session = sessionPool.getSession(cmd.getCommandType());
        StatsManager statsManager = session.getStatsManager();
        statsManager.incCommandCounter(cmd.getCommandType());

        tx.start();
        session.write(cmd);
        isExecuted = true;
        session.read(response);
        tx.setState(TransactionState.PROCESSED);
        statsManager.recordResponseTime(cmd.getCommandType(), tx.getResponseTime());

        Result[] results = response.getResults();
        assert results != null;
        if (results != null) {
          for (Result result : results) {
            assert result != null;
            statsManager.incResultCounter(result.getResultCode());
            int code = result.getResultCode();

            switch (code) {
              case ResultCode.CMD_FAILED:
                throw new CommandFailedException();
              case ResultCode.CMD_FAILED_CLOSING:
              default:
                throw new CommandFailedException();
            }
          }
        }
      } catch (CommandFailedException cfe) {
        userLogger.warning(cfe.getMessage());

        if (state != SMState.STOPPED && failCount < MAX_ACCEPTABLE_FAIL_COUNT) {

          failCount++;
        } else {
          throw cfe;
        }
      } catch (IOException ioe) {
        userLogger.warning(ioe.getMessage());
        userLogger.warning("net.socket.closed");
        session.close();
        if (state != SMState.STOPPED && failCount < MAX_ACCEPTABLE_FAIL_COUNT) {
          failCount++;
        } else {
          throw ioe;
        }
      } catch (InterruptedException ie) {
        // if interrupted by shutdown, then started will be false
        // Note: this still enters the finally block
        continue;
      } catch (SessionConfigurationException sce) {
        throw new FatalSessionException(sce);
      } catch (SessionOpenException soe) {
        throw new FatalSessionException(soe);
      } finally {
        sessionPool.releaseSession(session);
      }
    }

    if (!isExecuted && state == SMState.STOPPED) {
      throw new IllegalStateException();
    }

    debugLogger.finest("exit");
  }
  @Override
  public boolean start(Session session) throws Exception {
    super.start(session);

    if (userinfo != null && !(userinfo instanceof UIKeyboardInteractive)) {
      return false;
    }

    String dest = username + "@" + session.host;
    if (session.port != 22) {
      dest += (":" + session.port);
    }
    byte[] password = session.password;

    boolean cancel = false;

    byte[] _username = null;
    _username = Util.str2byte(username);

    while (true) {
      // send
      // byte SSH_MSG_USERAUTH_REQUEST(50)
      // string user name (ISO-10646 UTF-8, as defined in [RFC-2279])
      // string service name (US-ASCII) "ssh-userauth" ? "ssh-connection"
      // string "keyboard-interactive" (US-ASCII)
      // string language tag (as defined in [RFC-3066])
      // string submethods (ISO-10646 UTF-8)
      packet.reset();
      buf.putByte((byte) SSH_MSG_USERAUTH_REQUEST);
      buf.putString(_username);
      buf.putString("ssh-connection".getBytes());
      // buf.putString("ssh-userauth".getBytes());
      buf.putString("keyboard-interactive".getBytes());
      buf.putString("".getBytes());
      buf.putString("".getBytes());
      session.write(packet);

      boolean firsttime = true;
      loop:
      while (true) {
        buf = session.read(buf);
        int command = buf.getCommand() & 0xff;

        if (command == SSH_MSG_USERAUTH_SUCCESS) {
          return true;
        }
        if (command == SSH_MSG_USERAUTH_BANNER) {
          buf.getInt();
          buf.getByte();
          buf.getByte();
          byte[] _message = buf.getString();
          byte[] lang = buf.getString();
          String message = null;
          try {
            message = new String(_message, "UTF-8");
          } catch (java.io.UnsupportedEncodingException e) {
            message = new String(_message);
          }
          if (userinfo != null) {
            userinfo.showMessage(message);
          }
          continue loop;
        }
        if (command == SSH_MSG_USERAUTH_FAILURE) {
          buf.getInt();
          buf.getByte();
          buf.getByte();
          byte[] foo = buf.getString();
          int partial_success = buf.getByte();
          // System.err.println(new String(foo)+
          // " partial_success:"+(partial_success!=0));

          if (partial_success != 0) {
            throw new JSchPartialAuthException(new String(foo));
          }

          if (firsttime) {
            return false;
            // throw new JSchException("USERAUTH KI is not supported");
            // cancel=true; // ??
          }
          break;
        }
        if (command == SSH_MSG_USERAUTH_INFO_REQUEST) {
          firsttime = false;
          buf.getInt();
          buf.getByte();
          buf.getByte();
          String name = new String(buf.getString());
          String instruction = new String(buf.getString());
          String languate_tag = new String(buf.getString());
          int num = buf.getInt();
          String[] prompt = new String[num];
          boolean[] echo = new boolean[num];
          for (int i = 0; i < num; i++) {
            prompt[i] = new String(buf.getString());
            echo[i] = (buf.getByte() != 0);
          }

          byte[][] response = null;
          if (num > 0 || (name.length() > 0 || instruction.length() > 0)) {
            if (userinfo != null) {
              UIKeyboardInteractive kbi = (UIKeyboardInteractive) userinfo;
              String[] _response =
                  kbi.promptKeyboardInteractive(dest, name, instruction, prompt, echo);
              if (_response != null) {
                response = new byte[_response.length][];
                for (int i = 0; i < _response.length; i++) {
                  response[i] = Util.str2byte(_response[i]);
                }
              }
            } else if (password != null
                && prompt.length == 1
                && !echo[0]
                && prompt[0].toLowerCase().startsWith("password:"******"response.length="+response.length);
          // else
          // System.err.println("response is null");
          packet.reset();
          buf.putByte((byte) SSH_MSG_USERAUTH_INFO_RESPONSE);
          if (num > 0
              && (response == null
                  || // cancel
                  num != response.length)) {

            if (response == null) {
              // working around the bug in OpenSSH ;-<
              buf.putInt(num);
              for (int i = 0; i < num; i++) {
                buf.putString("".getBytes());
              }
            } else {
              buf.putInt(0);
            }

            if (response == null) cancel = true;
          } else {
            buf.putInt(num);
            for (int i = 0; i < num; i++) {
              // System.err.println("response: |"+new String(response[i])+"| <- replace here with
              // **** if you need");
              buf.putString(response[i]);
            }
          }
          session.write(packet);
          /*
           * if(cancel) break;
           */
          continue loop;
        }
        // throw new JSchException("USERAUTH fail ("+command+")");
        return false;
      }
      if (cancel) {
        throw new JSchAuthCancelException("keyboard-interactive");
        // break;
      }
    }
    // return false;
  }