This is an automated email from the ASF dual-hosted git repository. twolf pushed a commit to branch dev_3.0 in repository https://gitbox.apache.org/repos/asf/mina-sshd.git
commit b4a4a5b2960624fe7a68cabb0818c8f18a404347 Author: Thomas Wolf <tw...@apache.org> AuthorDate: Sun Apr 6 11:29:40 2025 +0200 Add a PacketLoggingFilter Re-instantiate the packet logging at TRACE level that was present in 2.X. --- .../session/filters/PacketLoggingFilter.java | 97 ++++++++++++++++++++++ .../common/session/filters/SshTransportFilter.java | 5 ++ 2 files changed, 102 insertions(+) diff --git a/sshd-core/src/main/java/org/apache/sshd/common/session/filters/PacketLoggingFilter.java b/sshd-core/src/main/java/org/apache/sshd/common/session/filters/PacketLoggingFilter.java new file mode 100644 index 000000000..a57fad789 --- /dev/null +++ b/sshd-core/src/main/java/org/apache/sshd/common/session/filters/PacketLoggingFilter.java @@ -0,0 +1,97 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.sshd.common.session.filters; + +import java.io.IOException; +import java.util.Objects; +import java.util.logging.Level; + +import org.apache.sshd.common.SshConstants; +import org.apache.sshd.common.filter.BufferInputHandler; +import org.apache.sshd.common.filter.InputHandler; +import org.apache.sshd.common.filter.IoFilter; +import org.apache.sshd.common.filter.OutputHandler; +import org.apache.sshd.common.io.IoWriteFuture; +import org.apache.sshd.common.session.Session; +import org.apache.sshd.common.util.buffer.Buffer; +import org.apache.sshd.common.util.logging.LoggingUtils; +import org.apache.sshd.common.util.logging.SimplifiedLog; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * A simple packet logging filter. The filter produces trace logs of the message contents for debugging purposes; it + * should be placed in the filter chain above the compression filter because otherwise it will log compressed or + * encrypted message data, which is useless for debugging. + */ +public class PacketLoggingFilter extends IoFilter { + + private static final Logger LOG = LoggerFactory.getLogger(PacketLoggingFilter.class); + + private static final SimplifiedLog SIMPLE = LoggingUtils.wrap(LOG); + + private final InputHandler input; + + private final OutputHandler output; + + public PacketLoggingFilter(Session session, CryptFilter crypt) { + Objects.requireNonNull(session); + Objects.requireNonNull(crypt); + this.input = new BufferInputHandler() { + + @Override + public void handleMessage(Buffer message) throws Exception { + int sequenceNumber = crypt.getInputSequenceNumber() - 1; + if (LOG.isTraceEnabled()) { + message.dumpHex(SIMPLE, Level.FINEST, + "receivePacket(" + session + ") packet #" + sequenceNumber, session); + } + owner().passOn(message); + } + + }; + this.output = new OutputHandler() { + + @Override + public synchronized IoWriteFuture send(int cmd, Buffer message) throws IOException { + if (message != null) { + if (LOG.isDebugEnabled()) { + LOG.debug("sendPacket({}) packet #{} command={}[{}] len={}", session, crypt.getOutputSequenceNumber(), + cmd, SshConstants.getCommandMessageName(cmd), message.available()); + } + if (SIMPLE.isTraceEnabled()) { + message.dumpHex(SIMPLE, Level.FINEST, + "sendPacket(" + session + ") packet #" + crypt.getOutputSequenceNumber(), session); + } + } + return owner().send(cmd, message); + } + }; + } + + @Override + public InputHandler in() { + return input; + } + + @Override + public OutputHandler out() { + return output; + } +} diff --git a/sshd-core/src/main/java/org/apache/sshd/common/session/filters/SshTransportFilter.java b/sshd-core/src/main/java/org/apache/sshd/common/session/filters/SshTransportFilter.java index c0180b951..e22dec21c 100644 --- a/sshd-core/src/main/java/org/apache/sshd/common/session/filters/SshTransportFilter.java +++ b/sshd-core/src/main/java/org/apache/sshd/common/session/filters/SshTransportFilter.java @@ -80,6 +80,8 @@ public class SshTransportFilter extends IoFilter { compressionFilter.setSession(session); filters.addLast(compressionFilter); + filters.addLast(new PacketLoggingFilter(session, cryptFilter)); + DelayKexInitFilter delayKexFilter = new DelayKexInitFilter(); delayKexFilter.setSession(session); filters.addLast(delayKexFilter); @@ -89,6 +91,7 @@ public class SshTransportFilter extends IoFilter { kexFilter = new KexFilter(session, random, cryptFilter, compressionFilter, events, proposer, checker); filters.addLast(kexFilter); + // Forward the protocol identification to the KexFilter; it's needed for KEX. ident.addIdentListener((peer, id) -> { if (peer == session.isServerSession()) { kexFilter.setClientIdent(id); @@ -96,6 +99,8 @@ public class SshTransportFilter extends IoFilter { kexFilter.setServerIdent(id); } }); + + // Connect the local filter chain to the one containing this SshTransportFilter filters.addFirst(new InConnector(this)); filters.addLast(new OutConnector(this)); }