blob: 6eb39a5f08b23741650f90ae041d1ec96d190443 [file] [log] [blame]
// Copyright (C) 2009 The Android Open Source Project
//
// Licensed 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 com.google.gerrit.server.ssh;
import com.google.gerrit.client.reviewdb.Account;
import com.google.gerrit.client.rpc.Common;
import org.apache.mina.core.service.IoAcceptor;
import org.apache.mina.core.session.IoSession;
import org.apache.sshd.common.session.AbstractSession;
import org.kohsuke.args4j.Option;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
/** Show the current SSH connections. */
class AdminShowConnections extends AbstractCommand {
@Option(name = "--numeric", aliases = {"-n"}, usage = "don't resolve names")
private boolean numeric;
PrintWriter p;
@Override
protected void run() throws Failure, UnsupportedEncodingException {
assertIsAdministrator();
p = toPrintWriter(out);
final IoAcceptor acceptor = GerritSshDaemon.getIoAcceptor();
if (acceptor == null) {
throw new Failure(1, "fatal: sshd not running");
}
final List<IoSession> list =
new ArrayList<IoSession>(acceptor.getManagedSessions().values());
Collections.sort(list, new Comparator<IoSession>() {
@Override
public int compare(IoSession arg0, IoSession arg1) {
if (arg0.getCreationTime() < arg1.getCreationTime()) {
return -1;
} else if (arg0.getCreationTime() > arg1.getCreationTime()) {
return 1;
}
return (int) (arg0.getId() - arg1.getId());
}
});
final long now = System.currentTimeMillis();
p.print(String.format(" %8s %8s %-15s %s\n", "Start", "Idle", "User",
"Remote Host"));
p.print("--------------------------------------------------------------\n");
for (final IoSession io : list) {
final AbstractSession s = AbstractSession.getSession(io, true);
List<AbstractCommand> active =
s != null ? s.getAttribute(SshUtil.ACTIVE) : null;
final SocketAddress remoteAddress = io.getRemoteAddress();
final long start = io.getCreationTime();
final long idle = now - io.getLastIoTime();
p.print(String.format(" %8s %8s %-15.15s %.30s\n", time(now, start),
age(idle), username(s), hostname(remoteAddress)));
if (active != null) {
synchronized (active) {
for (final AbstractCommand cmd : active) {
p.print(String.format(" [ %s ]\n", cmd.getCommandLine()));
}
}
}
p.print("\n");
}
p.print("--\n");
p.flush();
}
private static String time(final long now, final long time) {
if (time - now < 24 * 60 * 60 * 1000L) {
return new SimpleDateFormat("HH:mm:ss").format(new Date(time));
}
return new SimpleDateFormat("MMM-dd").format(new Date(time));
}
private static String age(long age) {
age /= 1000;
final int sec = (int) (age % 60);
age /= 60;
final int min = (int) (age % 60);
age /= 60;
final int hr = (int) (age % 60);
return String.format("%02d:%02d:%02d", hr, min, sec);
}
private String username(final AbstractSession s) {
if (s == null) {
return "";
}
final Account.Id id = s.getAttribute(SshUtil.CURRENT_ACCOUNT);
if (id == null) {
return "";
}
if (numeric) {
return "a/" + id.toString();
}
final Account a = Common.getAccountCache().get(id);
return a != null ? a.getSshUserName() : "";
}
private String hostname(final SocketAddress remoteAddress) {
if (remoteAddress == null) {
return "?";
}
String host = null;
if (remoteAddress instanceof InetSocketAddress) {
final InetSocketAddress sa = (InetSocketAddress) remoteAddress;
final InetAddress in = sa.getAddress();
if (numeric) {
return in.getHostAddress();
}
if (in != null) {
host = in.getCanonicalHostName();
} else {
host = sa.getHostName();
}
}
if (host == null) {
host = remoteAddress.toString();
}
return host;
}
}