AbstractConnector.java
- /*
- * Copyright (C) 2021, Thomas Wolf <thomas.wolf@paranor.ch> and others
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Distribution License v. 1.0 which is available at
- * https://www.eclipse.org/org/documents/edl-v10.php.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
- package org.eclipse.jgit.transport.sshd.agent;
- import java.io.IOException;
- import java.text.MessageFormat;
- import java.util.Objects;
- import org.apache.sshd.agent.SshAgentConstants;
- import org.apache.sshd.common.SshException;
- import org.apache.sshd.common.util.buffer.BufferUtils;
- import org.eclipse.jgit.internal.transport.sshd.SshdText;
- /**
- * Provides some utility methods for implementing {@link Connector}s.
- *
- * @since 6.0
- */
- public abstract class AbstractConnector implements Connector {
- // A somewhat sane lower bound for the maximum reply length
- private static final int MIN_REPLY_LENGTH = 8 * 1024;
- /**
- * Default maximum reply length. 256kB is the OpenSSH limit.
- */
- protected static final int DEFAULT_MAX_REPLY_LENGTH = 256 * 1024;
- private final int maxReplyLength;
- /**
- * Creates a new instance using the {@link #DEFAULT_MAX_REPLY_LENGTH}.
- */
- protected AbstractConnector() {
- this(DEFAULT_MAX_REPLY_LENGTH);
- }
- /**
- * Creates a new instance.
- *
- * @param maxReplyLength
- * maximum number of payload bytes we're ready to accept
- */
- protected AbstractConnector(int maxReplyLength) {
- if (maxReplyLength < MIN_REPLY_LENGTH) {
- throw new IllegalArgumentException(
- "Maximum payload length too small"); //$NON-NLS-1$
- }
- this.maxReplyLength = maxReplyLength;
- }
- /**
- * Retrieves the maximum message length this {@link AbstractConnector} is
- * configured for.
- *
- * @return the maximum message length
- */
- protected int getMaximumMessageLength() {
- return this.maxReplyLength;
- }
- /**
- * Prepares a message for sending by inserting the command and message
- * length.
- *
- * @param command
- * SSH agent command the request is for
- * @param message
- * about to be sent, including the 5 spare bytes at the front
- * @throws IllegalArgumentException
- * if {@code message} has less than 5 bytes
- */
- protected void prepareMessage(byte command, byte[] message)
- throws IllegalArgumentException {
- Objects.requireNonNull(message);
- if (message.length < 5) {
- // No translation; internal error
- throw new IllegalArgumentException("Message buffer for " //$NON-NLS-1$
- + SshAgentConstants.getCommandMessageName(command)
- + " must have at least 5 bytes; have only " //$NON-NLS-1$
- + message.length);
- }
- BufferUtils.putUInt(message.length - 4, message);
- message[4] = command;
- }
- /**
- * Checks the received length of a reply.
- *
- * @param command
- * SSH agent command the reply is for
- * @param length
- * length as received: number of payload bytes
- * @return the length as an {@code int}
- * @throws IOException
- * if the length is invalid
- */
- protected int toLength(byte command, byte[] length)
- throws IOException {
- long l = BufferUtils.getUInt(length);
- if (l <= 0 || l > maxReplyLength - 4) {
- throw new SshException(MessageFormat.format(
- SshdText.get().sshAgentReplyLengthError,
- Long.toString(l),
- SshAgentConstants.getCommandMessageName(command)));
- }
- return (int) l;
- }
- }