Skip to content

Commit ad33816

Browse files
committed
Added login auditing appenders
Added login auditing appenders. Examples in log4j.xml
1 parent 78e1389 commit ad33816

4 files changed

Lines changed: 46 additions & 23 deletions

File tree

src/main/java/com/keybox/manage/action/LoginAction.java

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,14 @@
2121
import com.keybox.manage.model.Auth;
2222
import com.keybox.manage.model.User;
2323
import com.keybox.manage.util.OTPUtil;
24-
import com.keybox.manage.util.PasswordUtil;
2524
import com.opensymphony.xwork2.ActionSupport;
2625
import org.apache.commons.lang3.StringUtils;
2726
import org.apache.struts2.convention.annotation.Action;
2827
import org.apache.struts2.convention.annotation.Result;
2928
import org.apache.struts2.interceptor.ServletRequestAware;
3029
import org.apache.struts2.interceptor.ServletResponseAware;
31-
import sun.misc.SharedSecrets;
30+
import org.slf4j.Logger;
31+
import org.slf4j.LoggerFactory;
3232

3333
import javax.servlet.http.HttpServletRequest;
3434
import javax.servlet.http.HttpServletResponse;
@@ -39,10 +39,12 @@
3939
*/
4040
public class LoginAction extends ActionSupport implements ServletRequestAware, ServletResponseAware {
4141

42+
private static Logger loginAuditLogger = LoggerFactory.getLogger("com.keybox.manage.action.LoginAudit");
4243
HttpServletResponse servletResponse;
4344
HttpServletRequest servletRequest;
4445
Auth auth;
4546
private final String AUTH_ERROR="Authentication Failed : Login credentials are invalid";
47+
private final String AUTH_ERROR_NO_PROFILE="Authentication Failed : There are no profiles assigned to this account";
4648
//check if otp is enabled
4749
boolean otpEnabled = ("required".equals(AppConfig.getProperty("oneTimePassword")) || "optional".equals(AppConfig.getProperty("oneTimePassword")));
4850

@@ -79,6 +81,11 @@ public String loginSubmit() {
7981
String retVal = SUCCESS;
8082

8183
String authToken = AuthDB.login(auth);
84+
85+
String clientIP = servletRequest.getHeader("X-FORWARDED-FOR");
86+
if (StringUtils.isEmpty(clientIP)) {
87+
clientIP = servletRequest.getRemoteAddr();
88+
}
8289
if (authToken != null) {
8390

8491
User user = AuthDB.getUserByAuthToken(authToken);
@@ -87,13 +94,15 @@ public String loginSubmit() {
8794
if (otpEnabled) {
8895
sharedSecret = AuthDB.getSharedSecret(user.getId());
8996
if (StringUtils.isNotEmpty(sharedSecret) && (auth.getOtpToken() == null || !OTPUtil.verifyToken(sharedSecret, auth.getOtpToken()))) {
97+
loginAuditLogger.info(clientIP + " " + AUTH_ERROR);
9098
addActionError(AUTH_ERROR);
9199
return INPUT;
92100
}
93101
}
94102
//check to see if admin has any assigned profiles
95103
if(!User.MANAGER.equals(user.getUserType()) && (user.getProfileList()==null || user.getProfileList().size()<=0)){
96-
addActionError("Authentication Failed : There are no profiles assigned to this account");
104+
loginAuditLogger.info(clientIP + " " + AUTH_ERROR_NO_PROFILE);
105+
addActionError(AUTH_ERROR_NO_PROFILE);
97106
return INPUT;
98107
}
99108

@@ -104,19 +113,19 @@ public String loginSubmit() {
104113

105114
//for first time login redirect to set OTP
106115
if (otpEnabled && StringUtils.isEmpty(sharedSecret)) {
107-
return "otp";
116+
retVal = "otp";
108117
} else if ("changeme".equals(auth.getPassword()) && Auth.AUTH_BASIC.equals(user.getAuthType())) {
109118
retVal = "change_password";
110119
}
120+
loginAuditLogger.info(clientIP + " Authentication Success");
111121
}
112122

113123
} else {
124+
loginAuditLogger.info(clientIP + " " + AUTH_ERROR);
114125
addActionError(AUTH_ERROR);
115126
retVal = INPUT;
116127
}
117128

118-
119-
120129
return retVal;
121130
}
122131

src/main/java/com/keybox/manage/util/SessionOutputUtil.java

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -40,15 +40,8 @@ public class SessionOutputUtil {
4040

4141
private static Map<Long, UserSessionsOutput> userSessionsOutputMap = new ConcurrentHashMap<Long, UserSessionsOutput>();
4242
public static boolean enableInternalAudit = "true".equals(AppConfig.getProperty("enableInternalAudit"));
43-
private static String auditLogAppender = StringUtils.isNotEmpty(AppConfig.getProperty("auditLogAppender")) ? AppConfig.getProperty("auditLogAppender") : null;
4443
private static Gson gson = new GsonBuilder().registerTypeAdapter(AuditWrapper.class, new SessionOutputSerializer()).create();
45-
private static Logger auditLogger = null;
46-
47-
static {
48-
if (StringUtils.isNotEmpty(auditLogAppender)) {
49-
auditLogger = LoggerFactory.getLogger(auditLogAppender);
50-
}
51-
}
44+
private static Logger systemAuditLogger = LoggerFactory.getLogger("com.keybox.manage.util.SystemAudit");
5245

5346
/**
5447
* removes session for user session
@@ -137,10 +130,10 @@ public static List<SessionOutput> getOutput(Connection con, Long sessionId, User
137130

138131
if (StringUtils.isNotEmpty(sessionOutput.getOutput())) {
139132
outputList.add(sessionOutput);
140-
//send to audit logger if set
141-
if(auditLogger!=null) {
142-
auditLogger.info(gson.toJson(new AuditWrapper(user, sessionOutput)));
143-
}
133+
134+
//send to audit logger
135+
systemAuditLogger.info(gson.toJson(new AuditWrapper(user, sessionOutput)));
136+
144137
if(enableInternalAudit) {
145138
SessionAuditDB.insertTerminalLog(con, sessionOutput);
146139
}

src/main/resources/KeyBoxConfig.properties

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,6 @@ defaultSSHPassphrase=${randomPassphrase}
1818
enableInternalAudit=false
1919
#keep audit logs for in days
2020
deleteAuditLogAfter=90
21-
#set an audit log server using log4j (ex: logstash). Edit the log4j.xml to configure appender.
22-
auditLogAppender=
2321
#The number of seconds that the client will wait before sending a null packet to the server to keep the connection alive
2422
serverAliveInterval=60
2523
#default timeout in minutes for websocket connection (no timeout for <=0)

src/main/resources/log4j.xml

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,27 +4,50 @@
44

55
<appender name="console" class="org.apache.log4j.ConsoleAppender">
66
<param name="encoding" value="UTF-8"/>
7-
<param name="Threshold" value="WARN"/>
87
<param name="Target" value="System.out"/>
98
<layout class="org.apache.log4j.PatternLayout">
109
<param name="ConversionPattern" value="%-5p %c{1} - %m%n"/>
1110
</layout>
1211
</appender>
1312

14-
<!--
13+
<!-- System audit example using logstash
1514
<appender name="logstash-socket-appender" class="org.apache.log4j.net.SocketAppender">
1615
<param name="RemoteHost" value="127.0.0.1"/>
1716
<param name="Port" value="5300"/>
1817
<param name="ReconnectionDelay" value="50000"/>
1918
<param name="Threshold" value="INFO"/>
2019
</appender>
2120
22-
<logger name="logstash">
21+
<logger name="com.keybox.manage.util.SystemAudit" additivity="false">
2322
<level value="info"/>
2423
<appender-ref ref="logstash-socket-appender"/>
2524
</logger>
2625
-->
2726

27+
<!-- Alternative login audit appender example
28+
<appender name="login-appender" class="org.apache.log4j.FileAppender">
29+
<param name="encoding" value="UTF-8"/>
30+
<param name="File" value="/var/log/keybox-login-audit.log" />
31+
<param name="Append" value="true" />
32+
<layout class="org.apache.log4j.PatternLayout">
33+
<param name="ConversionPattern" value="%-5p %c{1} - %m%n"/>
34+
</layout>
35+
</appender>
36+
-->
37+
38+
<appender name="login-appender" class="org.apache.log4j.ConsoleAppender">
39+
<param name="encoding" value="UTF-8"/>
40+
<param name="Target" value="System.out"/>
41+
<layout class="org.apache.log4j.PatternLayout">
42+
<param name="ConversionPattern" value="%-5p %c{1} - %m%n"/>
43+
</layout>
44+
</appender>
45+
46+
<logger name="com.keybox.manage.action.LoginAudit" additivity="false">
47+
<level value="info"/>
48+
<appender-ref ref="login-appender"/>
49+
</logger>
50+
2851
<root>
2952
<level value="warn"/>
3053
<appender-ref ref="console"/>

0 commit comments

Comments
 (0)