Line data Source code
1 : /* 2 : * Licensed to the Apache Software Foundation (ASF) under one 3 : * or more contributor license agreements. See the NOTICE file 4 : * distributed with this work for additional information 5 : * regarding copyright ownership. The ASF licenses this file 6 : * to you under the Apache License, Version 2.0 (the 7 : * "License"); you may not use this file except in compliance 8 : * with the License. You may obtain a copy of the License at 9 : * 10 : * http://www.apache.org/licenses/LICENSE-2.0 11 : * 12 : * Unless required by applicable law or agreed to in writing, 13 : * software distributed under the License is distributed on an 14 : * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 : * KIND, either express or implied. See the License for the 16 : * specific language governing permissions and limitations 17 : * under the License. 18 : */ 19 : 20 : /** 21 : * This file is based on sshd-contrib Apache SSHD Mina project. Original commit: 22 : * https://github.com/apache/mina-sshd/commit/11b33dee37b5b9c71a40a8a98a42007e3687131e 23 : */ 24 : package com.google.gerrit.sshd; 25 : 26 : import com.google.common.flogger.FluentLogger; 27 : import java.io.IOException; 28 : import org.apache.sshd.common.AttributeRepository.AttributeKey; 29 : import org.apache.sshd.common.SshConstants; 30 : import org.apache.sshd.common.channel.Channel; 31 : import org.apache.sshd.common.channel.ChannelListener; 32 : import org.apache.sshd.common.channel.exception.SshChannelNotFoundException; 33 : import org.apache.sshd.common.session.ConnectionService; 34 : import org.apache.sshd.common.session.Session; 35 : import org.apache.sshd.common.session.helpers.DefaultUnknownChannelReferenceHandler; 36 : import org.apache.sshd.common.util.buffer.Buffer; 37 : 38 : /** 39 : * Makes sure that the referenced "unknown" channel identifier is one that was assigned in 40 : * the past. <B>Note:</B> it relies on the fact that the default {@code ConnectionService} 41 : * implementation assigns channels identifiers in ascending order. 42 : * 43 : * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a> 44 : */ 45 : public class ChannelIdTrackingUnknownChannelReferenceHandler 46 : extends DefaultUnknownChannelReferenceHandler implements ChannelListener { 47 17 : private static final FluentLogger logger = FluentLogger.forEnclosingClass(); 48 17 : public static final AttributeKey<Long> LAST_CHANNEL_ID_KEY = new AttributeKey<>(); 49 : 50 17 : public static final ChannelIdTrackingUnknownChannelReferenceHandler TRACKER = 51 : new ChannelIdTrackingUnknownChannelReferenceHandler(); 52 : 53 : public ChannelIdTrackingUnknownChannelReferenceHandler() { 54 17 : super(); 55 17 : } 56 : 57 : @Override 58 : public void channelInitialized(Channel channel) { 59 0 : long channelId = channel.getChannelId(); 60 0 : Session session = channel.getSession(); 61 0 : Long lastTracked = session.setAttribute(LAST_CHANNEL_ID_KEY, channelId); 62 0 : logger.atFine().log( 63 : "channelInitialized(%s) updated last tracked channel ID %s => %s", 64 0 : channel, lastTracked, channelId); 65 0 : } 66 : 67 : @Override 68 : public Channel handleUnknownChannelCommand( 69 : ConnectionService service, byte cmd, long channelId, Buffer buffer) throws IOException { 70 1 : Session session = service.getSession(); 71 1 : Long lastTracked = session.getAttribute(LAST_CHANNEL_ID_KEY); 72 1 : if ((lastTracked != null) && (channelId <= lastTracked.intValue())) { 73 : // Use TRACE level in order to avoid messages flooding 74 0 : logger.atFinest().log( 75 : "handleUnknownChannelCommand(%s) apply default handling for %s on channel=%s (lastTracked=%s)", 76 0 : session, SshConstants.getCommandMessageName(cmd), channelId, lastTracked); 77 0 : return super.handleUnknownChannelCommand(service, cmd, channelId, buffer); 78 : } 79 : 80 1 : throw new SshChannelNotFoundException( 81 : channelId, 82 : "Received " 83 1 : + SshConstants.getCommandMessageName(cmd) 84 : + " on unassigned channel " 85 : + channelId 86 : + " (last assigned=" 87 : + lastTracked 88 : + ")"); 89 : } 90 : }