Exemple #1
0
 void dump(Buffer buf) {
   buf.putInt(flags);
   if ((flags & SSH_FILEXFER_ATTR_SIZE) != 0) {
     buf.putLong(size);
   }
   if ((flags & SSH_FILEXFER_ATTR_UIDGID) != 0) {
     buf.putInt(uid);
     buf.putInt(gid);
   }
   if ((flags & SSH_FILEXFER_ATTR_PERMISSIONS) != 0) {
     buf.putInt(permissions);
   }
   if ((flags & SSH_FILEXFER_ATTR_ACMODTIME) != 0) {
     buf.putInt(atime);
   }
   if ((flags & SSH_FILEXFER_ATTR_ACMODTIME) != 0) {
     buf.putInt(mtime);
   }
   if ((flags & SSH_FILEXFER_ATTR_EXTENDED) != 0) {
     int count = extended.length / 2;
     if (count > 0) {
       for (int i = 0; i < count; i++) {
         buf.putString(Util.str2byte(extended[i * 2]));
         buf.putString(Util.str2byte(extended[i * 2 + 1]));
       }
     }
   }
 }
Exemple #2
0
  public void request(Session session, Channel channel) throws Exception {
    super.request(session, channel);

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

    // byte      SSH_MSG_CHANNEL_REQUEST(98)
    // uint32 recipient channel
    // string request type        // "x11-req"
    // boolean want reply         // 0
    // boolean   single connection
    // string    x11 authentication protocol // "MIT-MAGIC-COOKIE-1".
    // string    x11 authentication cookie
    // uint32    x11 screen number
    packet.reset();
    buf.putByte((byte) Session.SSH_MSG_CHANNEL_REQUEST);
    buf.putInt(channel.getRecipient());
    buf.putString(Util.str2byte("x11-req"));
    buf.putByte((byte) (waitForReply() ? 1 : 0));
    buf.putByte((byte) 0);
    buf.putString(Util.str2byte("MIT-MAGIC-COOKIE-1"));
    buf.putString(ChannelX11.getFakedCookie(session));
    buf.putInt(0);
    write(packet);

    session.x11_forwarding = true;
  }
  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;
  }
Exemple #4
0
  private void updateRecord(PropertyRecord record, PersistenceWindow window) {
    long id = record.getId();
    registerIdFromUpdateRecord(id);
    Buffer buffer = window.getOffsettedBuffer(id);
    if (record.inUse()) {
      // Set up the record header
      short prevModifier =
          record.getPrevProp() == Record.NO_NEXT_RELATIONSHIP.intValue()
              ? 0
              : (short) ((record.getPrevProp() & 0xF00000000L) >> 28);
      short nextModifier =
          record.getNextProp() == Record.NO_NEXT_RELATIONSHIP.intValue()
              ? 0
              : (short) ((record.getNextProp() & 0xF00000000L) >> 32);
      byte modifiers = (byte) (prevModifier | nextModifier);
      /*
       * [pppp,nnnn] previous, next high bits
       */
      buffer.put(modifiers);
      buffer.putInt((int) record.getPrevProp()).putInt((int) record.getNextProp());

      // Then go through the blocks
      int longsAppended = 0; // For marking the end of blocks
      for (PropertyBlock block : record.getPropertyBlocks()) {
        long[] propBlockValues = block.getValueBlocks();
        for (long propBlockValue : propBlockValues) {
          buffer.putLong(propBlockValue);
        }

        longsAppended += propBlockValues.length;
        /*
         * For each block we need to update its dynamic record chain if
         * it is just created. Deleted dynamic records are in the property
         * record and dynamic records are never modified. Also, they are
         * assigned as a whole, so just checking the first should be enough.
         */
        if (!block.isLight() && block.getValueRecords().get(0).isCreated()) {
          updateDynamicRecords(block.getValueRecords());
        }
      }
      if (longsAppended < PropertyType.getPayloadSizeLongs()) {
        buffer.putLong(0);
      }
    } else {
      if (!isInRecoveryMode()) {
        freeId(id);
      }
      // skip over the record header, nothing useful there
      buffer.setOffset(buffer.getOffset() + 9);
      buffer.putLong(0);
    }
    updateDynamicRecords(record.getDeletedRecords());
  }
  /** Sends an out-of-band datagram */
  public static void Netchan_OutOfBand(
      int net_socket, NetworkAddress adr, int length, byte data[]) {

    // write the packet header
    Buffer send = Buffer.allocate(Constants.MAX_MSGLEN);

    send.putInt(-1); // -1 sequence means out of band
    Buffers.Write(send, data, length);

    // send the datagram
    NET.SendPacket(net_socket, send.cursize, send.data, adr);
  }
  public void request(Session session, Channel channel) throws Exception {
    super.request(session, channel);

    Buffer buf = new Buffer();
    Packet packet = new Packet(buf);
    packet.reset();
    buf.putByte((byte) Session.SSH_MSG_CHANNEL_REQUEST);
    buf.putInt(channel.getRecipient());
    buf.putString(Util.str2byte("subsystem"));
    buf.putByte((byte) (waitForReply() ? 1 : 0));
    buf.putString(Util.str2byte("sftp"));
    write(packet);
  }
  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);
  }
  public void request(Session session, Channel channel) throws Exception {
    super.request(session, channel);

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

    // send
    // byte     SSH_MSG_CHANNEL_REQUEST(98)
    // uint32 recipient channel
    // string request type       // "shell"
    // boolean want reply        // 0
    packet.reset();
    buf.putByte((byte) Session.SSH_MSG_CHANNEL_REQUEST);
    buf.putInt(channel.getRecipient());
    buf.putString(Util.str2byte("shell"));
    buf.putByte((byte) (waitForReply() ? 1 : 0));
    write(packet);
  }
  public boolean next(Buffer _buf) throws Exception {
    int i, j;
    switch (state) {
      case SSH_MSG_KEX_DH_GEX_GROUP:
        // byte  SSH_MSG_KEX_DH_GEX_GROUP(31)
        // mpint p, safe prime
        // mpint g, generator for subgroup in GF (p)
        _buf.getInt();
        _buf.getByte();
        j = _buf.getByte();
        if (j != SSH_MSG_KEX_DH_GEX_GROUP) {
          System.err.println("type: must be SSH_MSG_KEX_DH_GEX_GROUP " + j);
          return false;
        }

        p = _buf.getMPInt();
        g = _buf.getMPInt();

        dh.setP(p);
        dh.setG(g);
        // The client responds with:
        // byte  SSH_MSG_KEX_DH_GEX_INIT(32)
        // mpint e <- g^x mod p
        //         x is a random number (1 < x < (p-1)/2)

        e = dh.getE();

        packet.reset();
        buf.putByte((byte) SSH_MSG_KEX_DH_GEX_INIT);
        buf.putMPInt(e);
        session.write(packet);

        if (JSch.getLogger().isEnabled(Logger.INFO)) {
          JSch.getLogger().log(Logger.INFO, "SSH_MSG_KEX_DH_GEX_INIT sent");
          JSch.getLogger().log(Logger.INFO, "expecting SSH_MSG_KEX_DH_GEX_REPLY");
        }

        state = SSH_MSG_KEX_DH_GEX_REPLY;
        return true;
        // break;

      case SSH_MSG_KEX_DH_GEX_REPLY:
        // The server responds with:
        // byte      SSH_MSG_KEX_DH_GEX_REPLY(33)
        // string    server public host key and certificates (K_S)
        // mpint     f
        // string    signature of H
        j = _buf.getInt();
        j = _buf.getByte();
        j = _buf.getByte();
        if (j != SSH_MSG_KEX_DH_GEX_REPLY) {
          System.err.println("type: must be SSH_MSG_KEX_DH_GEX_REPLY " + j);
          return false;
        }

        K_S = _buf.getString();

        byte[] f = _buf.getMPInt();
        byte[] sig_of_H = _buf.getString();

        dh.setF(f);

        dh.checkRange();

        K = normalize(dh.getK());

        // The hash H is computed as the HASH hash of the concatenation of the
        // following:
        // string    V_C, the client's version string (CR and NL excluded)
        // string    V_S, the server's version string (CR and NL excluded)
        // string    I_C, the payload of the client's SSH_MSG_KEXINIT
        // string    I_S, the payload of the server's SSH_MSG_KEXINIT
        // string    K_S, the host key
        // uint32    min, minimal size in bits of an acceptable group
        // uint32   n, preferred size in bits of the group the server should send
        // uint32    max, maximal size in bits of an acceptable group
        // mpint     p, safe prime
        // mpint     g, generator for subgroup
        // mpint     e, exchange value sent by the client
        // mpint     f, exchange value sent by the server
        // mpint     K, the shared secret
        // This value is called the exchange hash, and it is used to authenti-
        // cate the key exchange.

        buf.reset();
        buf.putString(V_C);
        buf.putString(V_S);
        buf.putString(I_C);
        buf.putString(I_S);
        buf.putString(K_S);
        buf.putInt(min);
        buf.putInt(preferred);
        buf.putInt(max);
        buf.putMPInt(p);
        buf.putMPInt(g);
        buf.putMPInt(e);
        buf.putMPInt(f);
        buf.putMPInt(K);

        byte[] foo = new byte[buf.getLength()];
        buf.getByte(foo);
        sha.update(foo, 0, foo.length);

        H = sha.digest();

        // System.err.print("H -> "); dump(H, 0, H.length);

        i = 0;
        j = 0;
        j =
            ((K_S[i++] << 24) & 0xff000000)
                | ((K_S[i++] << 16) & 0x00ff0000)
                | ((K_S[i++] << 8) & 0x0000ff00)
                | ((K_S[i++]) & 0x000000ff);
        String alg = Util.byte2str(K_S, i, j);
        i += j;

        boolean result = verify(alg, K_S, i, sig_of_H);

        state = STATE_END;
        return result;
    }
    return false;
  }
 protected void writeRecord(T record, Buffer buffer) {
   buffer.putInt(record.getNameId());
 }
  /**
   * tries to send an unreliable message to a connection, and handles the transmition /
   * retransmition of the reliable messages.
   *
   * <p>A 0 length will still generate a packet and deal with the reliable messages.
   */
  public static void Transmit(NetworkChannel chan, int length, byte data[]) {
    int send_reliable;
    int w1, w2;

    // check for message overflow
    if (chan.message.overflowed) {
      chan.fatal_error = true;
      Com.Printf(NET.AdrToString(chan.remote_address) + ":Outgoing message overflow\n");
      return;
    }

    send_reliable = chan.Netchan_NeedReliable() ? 1 : 0;

    if (chan.reliable_length == 0 && chan.message.cursize != 0) {
      System.arraycopy(chan.message_buf, 0, chan.reliable_buf, 0, chan.message.cursize);
      chan.reliable_length = chan.message.cursize;
      chan.message.cursize = 0;
      chan.reliable_sequence ^= 1;
    }

    // write the packet header
    Buffer send = Buffer.wrap(send_buf).order(ByteOrder.LITTLE_ENDIAN);

    w1 = (chan.outgoing_sequence & ~(1 << 31)) | (send_reliable << 31);
    w2 = (chan.incoming_sequence & ~(1 << 31)) | (chan.incoming_reliable_sequence << 31);

    chan.outgoing_sequence++;
    chan.last_sent = (int) Globals.curtime;

    send.putInt(w1);
    send.putInt(w2);

    // send the qport if we are a client
    if (chan.sock == Constants.NS_CLIENT) send.WriteShort((int) consoleQport.value);

    // copy the reliable message to the packet first
    if (send_reliable != 0) {
      Buffers.Write(send, chan.reliable_buf, chan.reliable_length);
      chan.last_reliable_sequence = chan.outgoing_sequence;
    }

    // add the unreliable part if space is available
    if (send.maxsize - send.cursize >= length) Buffers.Write(send, data, length);
    else Com.Printf("Netchan_Transmit: dumped unreliable\n");

    // send the datagram
    NET.SendPacket(chan.sock, send.cursize, send.data, chan.remote_address);

    if (showpackets.value != 0) {
      if (send_reliable != 0)
        Com.Printf(
            // "send %4i : s=%i reliable=%i ack=%i rack=%i\n"
            "send "
                + send.cursize
                + " : s="
                + (chan.outgoing_sequence - 1)
                + " reliable="
                + chan.reliable_sequence
                + " ack="
                + chan.incoming_sequence
                + " rack="
                + chan.incoming_reliable_sequence
                + "\n");
      else
        Com.Printf(
            // "send %4i : s=%i ack=%i rack=%i\n"
            "send "
                + send.cursize
                + " : s="
                + (chan.outgoing_sequence - 1)
                + " ack="
                + chan.incoming_sequence
                + " rack="
                + chan.incoming_reliable_sequence
                + "\n");
    }
  }