Signature example::
alert krb5 any any -> any any (msg:"Kerberos 5 AS-REQ message"; krb5_msg_type:10; sid:3; rev:1;)
+
+krb5_cname
+----------
+
+Kerberos client name, provided in the ticket (for AS-REQ and TGS-REQ messages).
+
+If the client name from the Kerberos message is composed of several parts, the
+name is compared to each part and the match will succeed if any is identical.
+
+Comparison is case-sensitive.
+
+Syntax::
+
+ krb5_cname:[!]<name>
+
+Signature example::
+
+ alert krb5 any any -> any any (msg:"Kerberos 5 des server name"; krb5_cname; content:"des"; sid:4; rev:1;)
+
+``krb5_cname`` is a 'sticky buffer'.
+
+``krb5_cname`` can be used as ``fast_pattern``.
+
+krb5_sname
+----------
+
+Kerberos server name, provided in the ticket (for AS-REQ and TGS-REQ messages)
+or in the error message.
+
+If the server name from the Kerberos message is composed of several parts, the
+name is compared to each part and the match will succeed if any is identical.
+
+Comparison is case-sensitive.
+
+Syntax::
+
+ krb5_sname:[!]<name>
+
+Signature example::
+
+ alert krb5 any any -> any any (msg:"Kerberos 5 krbtgt server name"; krb5_sname; content:"krbtgt"; sid:5; rev:1;)
+
+``krb5_sname`` is a 'sticky buffer'.
+
+``krb5_sname`` can be used as ``fast_pattern``.
{
*ptr = tx.msg_type.0;
}
+
+#[no_mangle]
+pub unsafe extern "C" fn rs_krb5_tx_get_cname(tx: &mut KRB5Transaction,
+ i: libc::uint16_t,
+ buffer: *mut *const libc::uint8_t,
+ buffer_len: *mut libc::uint32_t)
+ -> libc::uint8_t
+{
+ if let Some(ref s) = tx.cname {
+ if (i as usize) < s.name_string.len() {
+ let value = &s.name_string[i as usize];
+ *buffer = value.as_ptr();
+ *buffer_len = value.len() as u32;
+ return 1;
+ }
+ }
+ 0
+}
+
+#[no_mangle]
+pub unsafe extern "C" fn rs_krb5_tx_get_sname(tx: &mut KRB5Transaction,
+ i: libc::uint16_t,
+ buffer: *mut *const libc::uint8_t,
+ buffer_len: *mut libc::uint32_t)
+ -> libc::uint8_t
+{
+ if let Some(ref s) = tx.sname {
+ if (i as usize) < s.name_string.len() {
+ let value = &s.name_string[i as usize];
+ *buffer = value.as_ptr();
+ *buffer_len = value.len() as u32;
+ return 1;
+ }
+ }
+ 0
+}
detect-iprep.c detect-iprep.h \
detect-isdataat.c detect-isdataat.h \
detect-itype.c detect-itype.h \
+detect-krb5-cname.c detect-krb5-cname.h \
detect-krb5-msgtype.c detect-krb5-msgtype.h \
+detect-krb5-sname.c detect-krb5-sname.h \
detect-l3proto.c detect-l3proto.h \
detect-lua.c detect-lua.h \
detect-lua-extensions.c detect-lua-extensions.h \
#include "detect-geoip.h"
#include "detect-app-layer-protocol.h"
#include "detect-template.h"
+#include "detect-krb5-cname.h"
#include "detect-krb5-msgtype.h"
+#include "detect-krb5-sname.h"
#include "detect-target.h"
#include "detect-template-buffer.h"
#include "detect-bypass.h"
DetectBase64DecodeRegister();
DetectBase64DataRegister();
DetectTemplateRegister();
+ DetectKrb5CNameRegister();
DetectKrb5MsgTypeRegister();
+ DetectKrb5SNameRegister();
DetectTargetRegister();
DetectTemplateBufferRegister();
DetectBypassRegister();
DETECT_BASE64_DATA,
DETECT_AL_KRB5_MSGTYPE,
+ DETECT_AL_KRB5_CNAME,
+ DETECT_AL_KRB5_SNAME,
DETECT_TEMPLATE,
DETECT_FTPDATA,
--- /dev/null
+/* Copyright (C) 2018 Open Information Security Foundation
+ *
+ * You can copy, redistribute or modify this Program under the terms of
+ * the GNU General Public License version 2 as published by the Free
+ * Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+/**
+ * \file
+ *
+ * \author Pierre Chifflier <chifflier@wzdftpd.net>
+ */
+
+#include "suricata-common.h"
+#include "util-unittest.h"
+
+#include "detect-parse.h"
+#include "detect-engine.h"
+#include "detect-engine-mpm.h"
+#include "detect-engine-state.h"
+#include "detect-engine-prefilter.h"
+#include "detect-engine-content-inspection.h"
+
+#include "detect-krb5-cname.h"
+
+#ifdef HAVE_RUST
+#include "rust.h"
+#include "app-layer-krb5.h"
+#include "rust-krb-detect-gen.h"
+
+static int g_krb5_cname_buffer_id = 0;
+
+struct Krb5PrincipalNameDataArgs {
+ int local_id; /**< used as index into thread inspect array */
+ void *txv;
+};
+
+static int DetectKrb5CNameSetup(DetectEngineCtx *de_ctx, Signature *s, const char *arg)
+{
+ DetectBufferSetActiveList(s, g_krb5_cname_buffer_id);
+
+ if (DetectSignatureSetAppProto(s, ALPROTO_KRB5) != 0)
+ return -1;
+
+ return 0;
+}
+
+/** \brief get an InspectionBuffer. Make space if we have to. */
+static InspectionBuffer *GetBuffer(InspectionBufferMultipleForList *fb, uint32_t id)
+{
+ if (id >= fb->size) {
+ uint32_t old_size = fb->size;
+ uint32_t new_size = id + 1;
+ uint32_t grow_by = new_size - old_size;
+ SCLogDebug("size is %u, need %u, so growing by %u",
+ old_size, new_size, grow_by);
+
+ void *ptr = SCRealloc(fb->inspection_buffers, (id + 1) * sizeof(InspectionBuffer));
+ if (ptr == NULL)
+ return NULL;
+
+ InspectionBuffer *to_zero = (InspectionBuffer *)ptr + old_size;
+ SCLogDebug("fb->inspection_buffers %p ptr %p to_zero %p",
+ fb->inspection_buffers, ptr, to_zero);
+ memset((uint8_t *)to_zero, 0, (grow_by * sizeof(InspectionBuffer)));
+ fb->inspection_buffers = ptr;
+ fb->size = new_size;
+ }
+
+ InspectionBuffer *buffer = &fb->inspection_buffers[id];
+ SCLogDebug("using file_data buffer %p", buffer);
+ return buffer;
+}
+
+static InspectionBuffer *GetKrb5CNameData(DetectEngineThreadCtx *det_ctx,
+ const DetectEngineTransforms *transforms,
+ Flow *_f, const struct Krb5PrincipalNameDataArgs *cbdata,
+ int list_id, bool first)
+{
+ SCEnter();
+
+ InspectionBufferMultipleForList *fb = &det_ctx->multi_inspect_buffers[list_id];
+ InspectionBuffer *buffer = GetBuffer(fb, cbdata->local_id);
+ if (buffer == NULL)
+ return NULL;
+ if (!first && buffer->inspect != NULL)
+ return buffer;
+
+ uint32_t b_len = 0;
+ uint8_t *b = NULL;
+
+ if (rs_krb5_tx_get_cname(cbdata->txv, (uint16_t)cbdata->local_id, &b, &b_len) != 1)
+ return NULL;
+ if (b == NULL || b_len == 0)
+ return NULL;
+
+ InspectionBufferSetup(buffer, b, b_len);
+ InspectionBufferApplyTransforms(buffer, transforms);
+
+ SCReturnPtr(buffer, "InspectionBuffer");
+}
+
+static int DetectEngineInspectKrb5CName(
+ DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx,
+ const DetectEngineAppInspectionEngine *engine,
+ const Signature *s,
+ Flow *f, uint8_t flags, void *alstate, void *txv, uint64_t tx_id)
+{
+ int local_id = 0;
+
+ const DetectEngineTransforms *transforms = NULL;
+ if (!engine->mpm) {
+ transforms = engine->v2.transforms;
+ }
+
+ while (1) {
+ struct Krb5PrincipalNameDataArgs cbdata = { local_id, txv, };
+ InspectionBuffer *buffer = GetKrb5CNameData(det_ctx,
+ transforms, f, &cbdata, engine->sm_list, false);
+
+ if (buffer == NULL || buffer->inspect == NULL)
+ break;
+
+ det_ctx->buffer_offset = 0;
+ det_ctx->discontinue_matching = 0;
+ det_ctx->inspection_recursion_counter = 0;
+
+ const int match = DetectEngineContentInspection(de_ctx, det_ctx, s, engine->smd,
+ f,
+ (uint8_t *)buffer->inspect,
+ buffer->inspect_len,
+ buffer->inspect_offset, DETECT_CI_FLAGS_SINGLE,
+ DETECT_ENGINE_CONTENT_INSPECTION_MODE_STATE, NULL);
+ if (match == 1) {
+ return DETECT_ENGINE_INSPECT_SIG_MATCH;
+ }
+ local_id++;
+ }
+
+ return DETECT_ENGINE_INSPECT_SIG_NO_MATCH;
+}
+
+typedef struct PrefilterMpmKrb5Name {
+ int list_id;
+ const MpmCtx *mpm_ctx;
+ const DetectEngineTransforms *transforms;
+} PrefilterMpmKrb5Name;
+
+/** \brief Krb5CName Krb5CName Mpm prefilter callback
+ *
+ * \param det_ctx detection engine thread ctx
+ * \param p packet to inspect
+ * \param f flow to inspect
+ * \param txv tx to inspect
+ * \param pectx inspection context
+ */
+static void PrefilterTxKrb5CName(DetectEngineThreadCtx *det_ctx,
+ const void *pectx,
+ Packet *p, Flow *f, void *txv,
+ const uint64_t idx, const uint8_t flags)
+{
+ SCEnter();
+
+ const PrefilterMpmKrb5Name *ctx = (const PrefilterMpmKrb5Name *)pectx;
+ const MpmCtx *mpm_ctx = ctx->mpm_ctx;
+ const int list_id = ctx->list_id;
+
+ int local_id = 0;
+
+ while(1) {
+ // loop until we get a NULL
+
+ struct Krb5PrincipalNameDataArgs cbdata = { local_id, txv };
+ InspectionBuffer *buffer = GetKrb5CNameData(det_ctx, ctx->transforms,
+ f, &cbdata, list_id, true);
+ if (buffer == NULL)
+ break;
+
+ if (buffer->inspect_len >= mpm_ctx->minlen) {
+ (void)mpm_table[mpm_ctx->mpm_type].Search(mpm_ctx,
+ &det_ctx->mtcu, &det_ctx->pmq,
+ buffer->inspect, buffer->inspect_len);
+ }
+
+ local_id++;
+ }
+}
+
+static void PrefilterMpmKrb5NameFree(void *ptr)
+{
+ SCFree(ptr);
+}
+
+static int PrefilterMpmKrb5CNameRegister(DetectEngineCtx *de_ctx,
+ SigGroupHead *sgh, MpmCtx *mpm_ctx,
+ const DetectMpmAppLayerRegistery *mpm_reg, int list_id)
+{
+ PrefilterMpmKrb5Name *pectx = SCCalloc(1, sizeof(*pectx));
+ if (pectx == NULL)
+ return -1;
+ pectx->list_id = list_id;
+ pectx->mpm_ctx = mpm_ctx;
+ pectx->transforms = &mpm_reg->v2.transforms;
+
+ return PrefilterAppendTxEngine(de_ctx, sgh, PrefilterTxKrb5CName,
+ mpm_reg->v2.alproto, mpm_reg->v2.tx_min_progress,
+ pectx, PrefilterMpmKrb5NameFree, mpm_reg->name);
+}
+
+void DetectKrb5CNameRegister(void)
+{
+ sigmatch_table[DETECT_AL_KRB5_CNAME].name = "krb5_cname";
+ sigmatch_table[DETECT_AL_KRB5_CNAME].Setup = DetectKrb5CNameSetup;
+ sigmatch_table[DETECT_AL_KRB5_CNAME].flags |= SIGMATCH_NOOPT;
+ sigmatch_table[DETECT_AL_KRB5_CNAME].desc = "sticky buffer to match on Kerberos 5 client name";
+
+ DetectAppLayerMpmRegister2("krb5_cname", SIG_FLAG_TOCLIENT, 2,
+ PrefilterMpmKrb5CNameRegister, NULL,
+ ALPROTO_KRB5, 1);
+
+ DetectAppLayerInspectEngineRegister2("krb5_cname",
+ ALPROTO_KRB5, SIG_FLAG_TOCLIENT, 0,
+ DetectEngineInspectKrb5CName, NULL);
+
+ DetectBufferTypeSetDescriptionByName("krb5_cname",
+ "Kerberos 5 ticket client name");
+
+ g_krb5_cname_buffer_id = DetectBufferTypeGetByName("krb5_cname");
+}
+
+#else /* NO RUST */
+
+void DetectKrb5CNameRegister(void) {}
+
+#endif
--- /dev/null
+/* Copyright (C) 2015-2017 Open Information Security Foundation
+ *
+ * You can copy, redistribute or modify this Program under the terms of
+ * the GNU General Public License version 2 as published by the Free
+ * Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+/**
+ * \file
+ *
+ * \author Pierre Chifflier <chifflier@wzdftpd.net>
+ */
+
+#ifndef __DETECT_KRB5_CNAME_H__
+#define __DETECT_KRB5_CNAME_H__
+
+void DetectKrb5CNameRegister(void);
+
+#endif /* __DETECT_KRB5_CNAME_H__ */
--- /dev/null
+/* Copyright (C) 2018 Open Information Security Foundation
+ *
+ * You can copy, redistribute or modify this Program under the terms of
+ * the GNU General Public License version 2 as published by the Free
+ * Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+/**
+ * \file
+ *
+ * \author Pierre Chifflier <chifflier@wzdftpd.net>
+ */
+
+#include "suricata-common.h"
+#include "util-unittest.h"
+
+#include "detect-parse.h"
+#include "detect-engine.h"
+#include "detect-engine-mpm.h"
+#include "detect-engine-state.h"
+#include "detect-engine-prefilter.h"
+#include "detect-engine-content-inspection.h"
+
+#include "detect-krb5-sname.h"
+
+#ifdef HAVE_RUST
+#include "rust.h"
+#include "app-layer-krb5.h"
+#include "rust-krb-detect-gen.h"
+
+static int g_krb5_sname_buffer_id = 0;
+
+struct Krb5PrincipalNameDataArgs {
+ int local_id; /**< used as index into thread inspect array */
+ void *txv;
+};
+
+static int DetectKrb5SNameSetup(DetectEngineCtx *de_ctx, Signature *s, const char *arg)
+{
+ DetectBufferSetActiveList(s, g_krb5_sname_buffer_id);
+
+ if (DetectSignatureSetAppProto(s, ALPROTO_KRB5) != 0)
+ return -1;
+
+ return 0;
+}
+
+/** \brief get an InspectionBuffer. Make space if we have to. */
+static InspectionBuffer *GetBuffer(InspectionBufferMultipleForList *fb, uint32_t id)
+{
+ if (id >= fb->size) {
+ uint32_t old_size = fb->size;
+ uint32_t new_size = id + 1;
+ uint32_t grow_by = new_size - old_size;
+ SCLogDebug("size is %u, need %u, so growing by %u",
+ old_size, new_size, grow_by);
+
+ void *ptr = SCRealloc(fb->inspection_buffers, (id + 1) * sizeof(InspectionBuffer));
+ if (ptr == NULL)
+ return NULL;
+
+ InspectionBuffer *to_zero = (InspectionBuffer *)ptr + old_size;
+ SCLogDebug("fb->inspection_buffers %p ptr %p to_zero %p",
+ fb->inspection_buffers, ptr, to_zero);
+ memset((uint8_t *)to_zero, 0, (grow_by * sizeof(InspectionBuffer)));
+ fb->inspection_buffers = ptr;
+ fb->size = new_size;
+ }
+
+ InspectionBuffer *buffer = &fb->inspection_buffers[id];
+ SCLogDebug("using file_data buffer %p", buffer);
+ return buffer;
+}
+
+static InspectionBuffer *GetKrb5SNameData(DetectEngineThreadCtx *det_ctx,
+ const DetectEngineTransforms *transforms,
+ Flow *_f, const struct Krb5PrincipalNameDataArgs *cbdata,
+ int list_id, bool first)
+{
+ SCEnter();
+
+ InspectionBufferMultipleForList *fb = &det_ctx->multi_inspect_buffers[list_id];
+ InspectionBuffer *buffer = GetBuffer(fb, cbdata->local_id);
+ if (buffer == NULL)
+ return NULL;
+ if (!first && buffer->inspect != NULL)
+ return buffer;
+
+ uint32_t b_len = 0;
+ uint8_t *b = NULL;
+
+ if (rs_krb5_tx_get_sname(cbdata->txv, (uint16_t)cbdata->local_id, &b, &b_len) != 1)
+ return NULL;
+ if (b == NULL || b_len == 0)
+ return NULL;
+
+ InspectionBufferSetup(buffer, b, b_len);
+ InspectionBufferApplyTransforms(buffer, transforms);
+
+ SCReturnPtr(buffer, "InspectionBuffer");
+}
+
+static int DetectEngineInspectKrb5SName(
+ DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx,
+ const DetectEngineAppInspectionEngine *engine,
+ const Signature *s,
+ Flow *f, uint8_t flags, void *alstate, void *txv, uint64_t tx_id)
+{
+ int local_id = 0;
+
+ const DetectEngineTransforms *transforms = NULL;
+ if (!engine->mpm) {
+ transforms = engine->v2.transforms;
+ }
+
+ while (1) {
+ struct Krb5PrincipalNameDataArgs cbdata = { local_id, txv, };
+ InspectionBuffer *buffer = GetKrb5SNameData(det_ctx,
+ transforms, f, &cbdata, engine->sm_list, false);
+
+ if (buffer == NULL || buffer->inspect == NULL)
+ break;
+
+ det_ctx->buffer_offset = 0;
+ det_ctx->discontinue_matching = 0;
+ det_ctx->inspection_recursion_counter = 0;
+
+ const int match = DetectEngineContentInspection(de_ctx, det_ctx, s, engine->smd,
+ f,
+ (uint8_t *)buffer->inspect,
+ buffer->inspect_len,
+ buffer->inspect_offset, DETECT_CI_FLAGS_SINGLE,
+ DETECT_ENGINE_CONTENT_INSPECTION_MODE_STATE, NULL);
+ if (match == 1) {
+ return DETECT_ENGINE_INSPECT_SIG_MATCH;
+ }
+ local_id++;
+ }
+
+ return DETECT_ENGINE_INSPECT_SIG_NO_MATCH;
+}
+
+typedef struct PrefilterMpmKrb5Name {
+ int list_id;
+ const MpmCtx *mpm_ctx;
+ const DetectEngineTransforms *transforms;
+} PrefilterMpmKrb5Name;
+
+/** \brief Krb5SName Krb5SName Mpm prefilter callback
+ *
+ * \param det_ctx detection engine thread ctx
+ * \param p packet to inspect
+ * \param f flow to inspect
+ * \param txv tx to inspect
+ * \param pectx inspection context
+ */
+static void PrefilterTxKrb5SName(DetectEngineThreadCtx *det_ctx,
+ const void *pectx,
+ Packet *p, Flow *f, void *txv,
+ const uint64_t idx, const uint8_t flags)
+{
+ SCEnter();
+
+ const PrefilterMpmKrb5Name *ctx = (const PrefilterMpmKrb5Name *)pectx;
+ const MpmCtx *mpm_ctx = ctx->mpm_ctx;
+ const int list_id = ctx->list_id;
+
+ int local_id = 0;
+
+ while(1) {
+ // loop until we get a NULL
+
+ struct Krb5PrincipalNameDataArgs cbdata = { local_id, txv };
+ InspectionBuffer *buffer = GetKrb5SNameData(det_ctx, ctx->transforms,
+ f, &cbdata, list_id, true);
+ if (buffer == NULL)
+ break;
+
+ if (buffer->inspect_len >= mpm_ctx->minlen) {
+ (void)mpm_table[mpm_ctx->mpm_type].Search(mpm_ctx,
+ &det_ctx->mtcu, &det_ctx->pmq,
+ buffer->inspect, buffer->inspect_len);
+ }
+
+ local_id++;
+ }
+}
+
+static void PrefilterMpmKrb5NameFree(void *ptr)
+{
+ SCFree(ptr);
+}
+
+static int PrefilterMpmKrb5SNameRegister(DetectEngineCtx *de_ctx,
+ SigGroupHead *sgh, MpmCtx *mpm_ctx,
+ const DetectMpmAppLayerRegistery *mpm_reg, int list_id)
+{
+ PrefilterMpmKrb5Name *pectx = SCCalloc(1, sizeof(*pectx));
+ if (pectx == NULL)
+ return -1;
+ pectx->list_id = list_id;
+ pectx->mpm_ctx = mpm_ctx;
+ pectx->transforms = &mpm_reg->v2.transforms;
+
+ return PrefilterAppendTxEngine(de_ctx, sgh, PrefilterTxKrb5SName,
+ mpm_reg->v2.alproto, mpm_reg->v2.tx_min_progress,
+ pectx, PrefilterMpmKrb5NameFree, mpm_reg->name);
+}
+
+void DetectKrb5SNameRegister(void)
+{
+ sigmatch_table[DETECT_AL_KRB5_SNAME].name = "krb5_sname";
+ sigmatch_table[DETECT_AL_KRB5_SNAME].Setup = DetectKrb5SNameSetup;
+ sigmatch_table[DETECT_AL_KRB5_SNAME].flags |= SIGMATCH_NOOPT;
+ sigmatch_table[DETECT_AL_KRB5_SNAME].desc = "sticky buffer to match on Kerberos 5 server name";
+
+ DetectAppLayerMpmRegister2("krb5_sname", SIG_FLAG_TOCLIENT, 2,
+ PrefilterMpmKrb5SNameRegister, NULL,
+ ALPROTO_KRB5, 1);
+
+ DetectAppLayerInspectEngineRegister2("krb5_sname",
+ ALPROTO_KRB5, SIG_FLAG_TOCLIENT, 0,
+ DetectEngineInspectKrb5SName, NULL);
+
+ DetectBufferTypeSetDescriptionByName("krb5_sname",
+ "Kerberos 5 ticket server name");
+
+ g_krb5_sname_buffer_id = DetectBufferTypeGetByName("krb5_sname");
+}
+
+#else /* NO RUST */
+
+void DetectKrb5SNameRegister(void) {}
+
+#endif
--- /dev/null
+/* Copyright (C) 2015-2017 Open Information Security Foundation
+ *
+ * You can copy, redistribute or modify this Program under the terms of
+ * the GNU General Public License version 2 as published by the Free
+ * Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+/**
+ * \file
+ *
+ * \author Pierre Chifflier <chifflier@wzdftpd.net>
+ */
+
+#ifndef __DETECT_KRB5_SNAME_H__
+#define __DETECT_KRB5_SNAME_H__
+
+void DetectKrb5SNameRegister(void);
+
+#endif /* __DETECT_KRB5_SNAME_H__ */