Skip to content

Commit a38e824

Browse files
author
madoll
committed
Extract peer certificate if client is verified
1 parent 810afe7 commit a38e824

File tree

4 files changed

+23
-10
lines changed

4 files changed

+23
-10
lines changed

lib/logstash/inputs/tcp.rb

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
# #### Accepting log4j2 logs
2424
#
2525
# Log4j2 can send JSON over a socket, and we can use that combined with our tcp
26-
# input to accept the logs.
26+
# input to accept the logs.
2727
#
2828
# First, we need to configure your application to send logs in JSON over a
2929
# socket. The following log4j2.xml accomplishes this task.
@@ -179,13 +179,13 @@ def close
179179
end
180180

181181
def decode_buffer(client_ip_address, client_address, client_port, codec, proxy_address,
182-
proxy_port, tbuf, socket)
182+
proxy_port, tbuf, socket, cert_subject = "")
183183
codec.decode(tbuf) do |event|
184184
if @proxy_protocol
185185
event.set(PROXY_HOST_FIELD, proxy_address) unless event.get(PROXY_HOST_FIELD)
186186
event.set(PROXY_PORT_FIELD, proxy_port) unless event.get(PROXY_PORT_FIELD)
187187
end
188-
enqueue_decorated(event, client_ip_address, client_address, client_port, socket)
188+
enqueue_decorated(event, client_ip_address, client_address, client_port, socket, cert_subject)
189189
end
190190
end
191191

@@ -257,15 +257,15 @@ def handle_socket(socket)
257257
flush_codec(codec, client_ip_address, client_address, client_port, socket)
258258
end
259259

260-
def enqueue_decorated(event, client_ip_address, client_address, client_port, socket)
260+
def enqueue_decorated(event, client_ip_address, client_address, client_port, socket, cert_subject = "")
261261
event.set(HOST_FIELD, client_address) unless event.get(HOST_FIELD)
262262
event.set(HOST_IP_FIELD, client_ip_address) unless event.get(HOST_IP_FIELD)
263263
event.set(PORT_FIELD, client_port) unless event.get(PORT_FIELD)
264-
event.set(SSLSUBJECT_FIELD, socket.peer_cert.subject.to_s) if socket && @ssl_enable && @ssl_verify && event.get(SSLSUBJECT_FIELD).nil?
264+
event.set(SSLSUBJECT_FIELD, cert_subject) if !cert_subject.empty? && @ssl_enable && @ssl_verify && event.get(SSLSUBJECT_FIELD).nil?
265265
decorate(event)
266266
@output_queue << event
267267
end
268-
268+
269269
def server?
270270
@mode == "server"
271271
end

lib/logstash/inputs/tcp/decoder_impl.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ def initialize(codec, tcp)
1313
@first_read = true
1414
end
1515

16-
def decode(channel_addr, data)
16+
def decode(channel_addr, data, cert_subject = "")
1717
bytes = Java::byte[data.readableBytes].new
1818
data.getBytes(0, bytes)
1919
data.release
@@ -22,7 +22,7 @@ def decode(channel_addr, data)
2222
tbuf = init_first_read(channel_addr, tbuf)
2323
end
2424
@tcp.decode_buffer(@ip_address, @address, @port, @codec,
25-
@proxy_address, @proxy_port, tbuf, nil)
25+
@proxy_address, @proxy_port, tbuf, nil, cert_subject)
2626
end
2727

2828
def copy

src/main/java/org/logstash/tcp/Decoder.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,9 @@ public interface Decoder {
1212
* Decode data coming from specific {@link SocketAddress} session.
1313
* @param key {@link SocketAddress}
1414
* @param message Data {@link ByteBuf} for this address
15+
* @param peerSslCertSubject String The subject of the peer's SSL certificate
1516
*/
16-
void decode(SocketAddress key, ByteBuf message);
17+
void decode(SocketAddress key, ByteBuf message, String peerSslCertSubject);
1718

1819
/**
1920
* Creates a copy of this decoder, that has all internal meta data cleared.

src/main/java/org/logstash/tcp/InputLoop.java

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
import io.netty.channel.socket.SocketChannel;
1313
import io.netty.channel.socket.nio.NioServerSocketChannel;
1414
import io.netty.handler.ssl.SslContext;
15+
import io.netty.handler.ssl.SslHandler;
16+
import javax.net.ssl.SSLPeerUnverifiedException;
1517
import io.netty.util.concurrent.Future;
1618
import io.netty.util.concurrent.GenericFutureListener;
1719
import org.apache.logging.log4j.Logger;
@@ -201,7 +203,17 @@ private static final class DecoderAdapter extends ChannelInboundHandlerAdapter {
201203

202204
@Override
203205
public void channelRead(final ChannelHandlerContext ctx, final Object msg) {
204-
decoder.decode(ctx.channel().remoteAddress(), (ByteBuf) msg);
206+
String sslPeerCertSubject = "";
207+
SslHandler sslhandler = (SslHandler) ctx.channel().pipeline().get(SslHandler.class);
208+
if (sslhandler != null) {
209+
try {
210+
sslPeerCertSubject = sslhandler.engine().getSession().getPeerCertificateChain()[0].getSubjectDN().getName();
211+
} catch(SSLPeerUnverifiedException e) {
212+
} catch(Exception e) {
213+
logger.error("Error when getting peer SSL certificate: " + e);
214+
}
215+
}
216+
decoder.decode(ctx.channel().remoteAddress(), (ByteBuf) msg, sslPeerCertSubject);
205217
}
206218

207219
@Override

0 commit comments

Comments
 (0)