blob: daf3c1d2e5781f84f870eee786716404f255a9b9 [file] [log] [blame]
/*
* Copyright (C) 2019 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.googlesource.gerrit.plugins.auditsl4j.logsource;
import com.google.gerrit.server.AccessPath;
import com.google.gerrit.server.audit.SshAuditEvent;
import com.googlesource.gerrit.plugins.auditsl4j.AuditUser;
import com.googlesource.gerrit.plugins.auditsl4j.LoggerAudit;
import com.googlesource.gerrit.plugins.auditsl4j.TransformableAuditLogType;
import com.googlesource.gerrit.plugins.auditsl4j.TransformableLog;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Optional;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class SSHLog implements TransformableLog {
private static final Logger log = LoggerFactory.getLogger(SSHLog.class);
private String user;
private String session;
private String timestamp;
private String accountId;
private String command;
private String waitTime;
private String execTime;
private String result;
public SSHLog(
String timestamp,
String session,
String user,
String accountId,
String command,
String waitTime,
String execTime,
String result) {
this.user = user;
this.session = session;
this.timestamp = timestamp;
this.accountId = accountId;
this.command = command;
this.waitTime = waitTime;
this.execTime = execTime;
this.result = result;
}
public static Optional<SSHLog> createFromLog(String line) {
Matcher authCommand =
Pattern.compile(
"^\\[(?<timestamp>.*?)\\]\\s(?<session>.*?)\\s"
+ "(?<user>.*?)\\s(?<accountId>.*?)\\s(?<command>LOGOUT|LOGIN)(:?\\sFROM.*?)?$")
.matcher(line);
Matcher authFailure =
Pattern.compile(
"^\\[(?<timestamp>.*?)\\]\\s(?<session>.*?)\\s(?<user>.*?)\\s(?<command>AUTH FAILURE)(:?\\sFROM.*?)?$")
.matcher(line);
Matcher nonAuthCommand =
Pattern.compile(
"^\\[(?<timestamp>.*?)\\]\\s(?<session>.*?)\\s(?<user>.*?)\\s(?<accountId>.*?)\\s(?<command>.*?)(\\s(?<waitTime>\\d+ms)\\s(?<execTime>\\d+ms)\\s(?<result>.*?))?$")
.matcher(line);
if (authCommand.matches()) {
try {
return Optional.of(
new SSHLog(
authCommand.group("timestamp"),
authCommand.group("session"),
authCommand.group("user"),
authCommand.group("accountId"),
authCommand.group("command"),
null,
null,
"0"));
} catch (Exception e) {
log.error("Auth command match, but something wrong while parsing line: " + line);
}
} else if (authFailure.matches()) {
try {
return Optional.of(
new SSHLog(
authFailure.group("timestamp"),
authFailure.group("session"),
authFailure.group("user"),
null,
authFailure.group("command"),
null,
null,
"0"));
} catch (Exception e) {
log.error("Auth failure command match, but something wrong while parsing line: " + line);
}
} else if (nonAuthCommand.matches()) {
try {
return Optional.of(
new SSHLog(
nonAuthCommand.group("timestamp"),
nonAuthCommand.group("session"),
nonAuthCommand.group("user"),
nonAuthCommand.group("accountId"),
nonAuthCommand.group("command"),
nonAuthCommand.group("waitTime"),
nonAuthCommand.group("execTime"),
nonAuthCommand.group("result") != null ? nonAuthCommand.group("result") : "0"));
} catch (Exception e) {
log.error("Non Auth command match, but something wrong while parsing line: " + line);
}
} else {
log.error("Can't extract any info from line: " + line);
}
return Optional.empty();
}
private AuditUser getAuditUser() {
AuditUser au = new AuditUser();
au.setUserName(this.user);
au.setAccessPath(AccessPath.SSH_COMMAND);
return au;
}
private Optional<Long> getWhen() {
// Timestamp format example: 2019-01-23 12:44:04,723 +0100
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss,SSS Z");
try {
return Optional.of(format.parse(this.timestamp).getTime());
} catch (ParseException pe) {
log.error(
"Can't parse timestamp: '" + this.timestamp + "'. Error message: " + pe.getMessage());
}
return Optional.empty();
}
@Override
public Optional<String> toAuditLog(LoggerAudit loggerAudit) {
return getWhen()
.map(
when ->
new SshAuditEvent(
this.session, getAuditUser(), this.command, when, null, this.result))
.map(
sshAuditEvent ->
loggerAudit.getAuditString(sshAuditEvent, TransformableAuditLogType.SshAuditEvent));
}
public static String logFilenameBase() {
return "sshd_log";
}
public String getUser() {
return user;
}
public String getSession() {
return session;
}
public String getTimestamp() {
return timestamp;
}
public String getAccountId() {
return accountId;
}
public String getCommand() {
return command;
}
public String getWaitTime() {
return waitTime;
}
public String getExecTime() {
return execTime;
}
public String getResult() {
return result;
}
}