Skip to content
GitLab
探索
项目
群组
代码片段
项目
群组
代码片段
/
帮助
帮助
支持
社区论坛
快捷键
?
提交反馈
登录
切换导航
菜单
打开侧边栏
wazuh
Fwknop
提交
dc8a034a
提交
dc8a034a
编辑于
12年前
作者:
Michael Rash
浏览文件
操作
下载
差异文件
merged usage() information from master
上级
adbc6a8f
bc2e41fd
master
2.5.1-1
2.5.1.1
3.0_devel
CSGSYY
SCT230A
access_conf_includes
alotcer
android4.4_support
cmd_open_close_cycle
crypto_update
dstuart_capture_modes
dstuart_netfilter_queue
dstuart_refactor_autoconf
execvpe
gpgme_autoconf_macro
hmac_header_fixes
hmac_support
hmac_timing_bug_fix
ipv6
libfiu_fault_injection
mac_os_x_mavericks_build
ms_compatible_usernames
perl_module
rand_to_16bytes
readme_include_fwknop_gui
spa_destination_ip
spa_encoding_fuzzing
udp_listener
udp_server_destination
win32_fixes
2.6.11-pre1
2.6.10
2.6.9
2.6.9-pre1
2.6.8
2.6.7
2.6.7-pre1
2.6.6
2.6.5
2.6.4
2.6.4-pre1
2.6.3
2.6.2
2.6.1
2.6.0
2.6.0-pre1
2.5.1.1
2.5.1-1
fwknop-2.6.5
fwknop-2.6.4
fwknop-2.6.3
fwknop-2.5.1
fwknop-2.5.1-pre1
fwknop-2.5
fwknop-2.5-pre3
fwknop-2.5-pre2
fwknop-2.5-pre1
无相关合并请求
变更
10
隐藏空白变更内容
行内
左右并排
显示
10 个更改的文件
CREDITS
+6
-0
CREDITS
lib/fko.h
+4
-0
lib/fko.h
lib/fko_context.h
+6
-0
lib/fko_context.h
lib/fko_digest.c
+84
-19
lib/fko_digest.c
lib/fko_funcs.c
+3
-0
lib/fko_funcs.c
server/incoming_spa.c
+127
-25
server/incoming_spa.c
server/replay_cache.c
+99
-39
server/replay_cache.c
server/replay_cache.h
+6
-3
server/replay_cache.h
test/conf/dual_key_usage_access.conf
+9
-0
test/conf/dual_key_usage_access.conf
test/test-fwknop.pl
+135
-19
test/test-fwknop.pl
有
479 个添加
和
105 个删除
+479
-105
CREDITS
+
6
-
0
浏览文件 @
dc8a034a
...
...
@@ -18,3 +18,9 @@ Max Kastanas
Ted Wynnychenko
- Helped test fwknop PF support on OpenBSD.
Andy Rowland
- Reported a bug where the same encryption key used for two stanzas in the
access.conf file would result in access requests that matched the second
stanza to always be treated as a replay attack. This has been fixed for
the fwknop-2.0.1 release.
This diff is collapsed.
Click to expand it.
lib/fko.h
+
4
-
0
浏览文件 @
dc8a034a
...
...
@@ -224,6 +224,8 @@ DLL_API int fko_set_spa_server_auth(fko_ctx_t ctx, const char *server_auth);
DLL_API
int
fko_set_spa_client_timeout
(
fko_ctx_t
ctx
,
const
int
timeout
);
DLL_API
int
fko_set_spa_digest_type
(
fko_ctx_t
ctx
,
const
short
digest_type
);
DLL_API
int
fko_set_spa_digest
(
fko_ctx_t
ctx
);
DLL_API
int
fko_set_raw_spa_digest_type
(
fko_ctx_t
ctx
,
const
short
raw_digest_type
);
DLL_API
int
fko_set_raw_spa_digest
(
fko_ctx_t
ctx
);
DLL_API
int
fko_set_spa_encryption_type
(
fko_ctx_t
ctx
,
const
short
encrypt_type
);
DLL_API
int
fko_set_spa_encryption_mode
(
fko_ctx_t
ctx
,
const
int
encrypt_mode
);
DLL_API
int
fko_set_spa_data
(
fko_ctx_t
ctx
,
const
char
*
enc_msg
);
...
...
@@ -252,7 +254,9 @@ DLL_API int fko_get_spa_nat_access(fko_ctx_t ctx, char **nat_access);
DLL_API
int
fko_get_spa_server_auth
(
fko_ctx_t
ctx
,
char
**
server_auth
);
DLL_API
int
fko_get_spa_client_timeout
(
fko_ctx_t
ctx
,
int
*
client_timeout
);
DLL_API
int
fko_get_spa_digest_type
(
fko_ctx_t
ctx
,
short
*
spa_digest_type
);
DLL_API
int
fko_get_raw_spa_digest_type
(
fko_ctx_t
ctx
,
short
*
raw_spa_digest_type
);
DLL_API
int
fko_get_spa_digest
(
fko_ctx_t
ctx
,
char
**
spa_digest
);
DLL_API
int
fko_get_raw_spa_digest
(
fko_ctx_t
ctx
,
char
**
raw_spa_digest
);
DLL_API
int
fko_get_spa_encryption_type
(
fko_ctx_t
ctx
,
short
*
spa_enc_type
);
DLL_API
int
fko_get_spa_encryption_mode
(
fko_ctx_t
ctx
,
int
*
spa_enc_mode
);
DLL_API
int
fko_get_spa_data
(
fko_ctx_t
ctx
,
char
**
spa_data
);
...
...
This diff is collapsed.
Click to expand it.
lib/fko_context.h
+
6
-
0
浏览文件 @
dc8a034a
...
...
@@ -69,6 +69,12 @@ struct fko_context {
char
*
version
;
char
*
digest
;
/* Digest of raw encrypted/base64 data - this is used
* for replay attack detection
*/
char
*
raw_digest
;
short
raw_digest_type
;
/* Computed processed data (encodings, etc.) */
char
*
encoded_msg
;
char
*
encrypted_msg
;
...
...
This diff is collapsed.
Click to expand it.
lib/fko_digest.c
+
84
-
19
浏览文件 @
dc8a034a
...
...
@@ -36,8 +36,9 @@
/* Set the SPA digest type.
*/
int
fko_set_spa_digest_type
(
fko_ctx_t
ctx
,
const
short
digest_type
)
static
int
set_spa_digest_type
(
fko_ctx_t
ctx
,
short
*
digest_type_field
,
const
short
digest_type
)
{
/* Must be initialized
*/
...
...
@@ -47,13 +48,25 @@ fko_set_spa_digest_type(fko_ctx_t ctx, const short digest_type)
if
(
digest_type
<
1
||
digest_type
>=
FKO_LAST_DIGEST_TYPE
)
return
(
FKO_ERROR_INVALID_DATA
);
ctx
->
digest_type
=
digest_type
;
*
digest_type
_field
=
digest_type
;
ctx
->
state
|=
FKO_DIGEST_TYPE_MODIFIED
;
return
(
FKO_SUCCESS
);
}
int
fko_set_spa_digest_type
(
fko_ctx_t
ctx
,
const
short
digest_type
)
{
return
set_spa_digest_type
(
ctx
,
&
ctx
->
digest_type
,
digest_type
);
}
int
fko_set_raw_spa_digest_type
(
fko_ctx_t
ctx
,
const
short
raw_digest_type
)
{
return
set_spa_digest_type
(
ctx
,
&
ctx
->
raw_digest_type
,
raw_digest_type
);
}
/* Return the SPA digest type.
*/
int
...
...
@@ -69,22 +82,27 @@ fko_get_spa_digest_type(fko_ctx_t ctx, short *digest_type)
return
(
FKO_SUCCESS
);
}
/* Return the SPA digest type.
*/
int
fko_
s
et_spa_digest
(
fko_ctx_t
ctx
)
fko_
g
et_
raw_
spa_digest
_type
(
fko_ctx_t
ctx
,
short
*
raw_digest_type
)
{
char
*
md
=
NULL
;
/* Must be initialized
*/
if
(
!
CTX_INITIALIZED
(
ctx
))
return
(
FKO_ERROR_CTX_NOT_INITIALIZED
);
/* Must have encoded message data to start with.
*/
if
(
ctx
->
encoded_msg
==
NULL
)
return
(
FKO_ERROR_MISSING_ENCODED_DATA
);
*
raw_digest_type
=
ctx
->
raw_digest_type
;
return
(
FKO_SUCCESS
);
}
static
int
set_digest
(
char
*
data
,
char
**
digest
,
short
digest_type
)
{
char
*
md
=
NULL
;
switch
(
ctx
->
digest_type
)
switch
(
digest_type
)
{
case
FKO_DIGEST_MD5
:
md
=
malloc
(
MD_HEX_SIZE
(
MD5_DIGEST_LENGTH
)
+
1
);
...
...
@@ -92,7 +110,7 @@ fko_set_spa_digest(fko_ctx_t ctx)
return
(
FKO_ERROR_MEMORY_ALLOCATION
);
md5_base64
(
md
,
(
unsigned
char
*
)
ctx
->
encoded_msg
,
strlen
(
ctx
->
encoded_msg
));
(
unsigned
char
*
)
data
,
strlen
(
data
));
break
;
case
FKO_DIGEST_SHA1
:
...
...
@@ -101,7 +119,7 @@ fko_set_spa_digest(fko_ctx_t ctx)
return
(
FKO_ERROR_MEMORY_ALLOCATION
);
sha1_base64
(
md
,
(
unsigned
char
*
)
ctx
->
encoded_msg
,
strlen
(
ctx
->
encoded_msg
));
(
unsigned
char
*
)
data
,
strlen
(
data
));
break
;
case
FKO_DIGEST_SHA256
:
...
...
@@ -110,7 +128,7 @@ fko_set_spa_digest(fko_ctx_t ctx)
return
(
FKO_ERROR_MEMORY_ALLOCATION
);
sha256_base64
(
md
,
(
unsigned
char
*
)
ctx
->
encoded_msg
,
strlen
(
ctx
->
encoded_msg
));
(
unsigned
char
*
)
data
,
strlen
(
data
));
break
;
case
FKO_DIGEST_SHA384
:
...
...
@@ -119,7 +137,7 @@ fko_set_spa_digest(fko_ctx_t ctx)
return
(
FKO_ERROR_MEMORY_ALLOCATION
);
sha384_base64
(
md
,
(
unsigned
char
*
)
ctx
->
encoded_msg
,
strlen
(
ctx
->
encoded_msg
));
(
unsigned
char
*
)
data
,
strlen
(
data
));
break
;
case
FKO_DIGEST_SHA512
:
...
...
@@ -128,7 +146,7 @@ fko_set_spa_digest(fko_ctx_t ctx)
return
(
FKO_ERROR_MEMORY_ALLOCATION
);
sha512_base64
(
md
,
(
unsigned
char
*
)
ctx
->
encoded_msg
,
strlen
(
ctx
->
encoded_msg
));
(
unsigned
char
*
)
data
,
strlen
(
data
));
break
;
default:
...
...
@@ -138,14 +156,48 @@ fko_set_spa_digest(fko_ctx_t ctx)
/* Just in case this is a subsquent call to this function. We
* do not want to be leaking memory.
*/
if
(
ctx
->
digest
!=
NULL
)
free
(
ctx
->
digest
);
if
(
*
digest
!=
NULL
)
free
(
*
digest
);
ctx
->
digest
=
md
;
*
digest
=
md
;
return
(
FKO_SUCCESS
);
}
int
fko_set_spa_digest
(
fko_ctx_t
ctx
)
{
/* Must be initialized
*/
if
(
!
CTX_INITIALIZED
(
ctx
))
return
(
FKO_ERROR_CTX_NOT_INITIALIZED
);
/* Must have encoded message data to start with.
*/
if
(
ctx
->
encoded_msg
==
NULL
)
return
(
FKO_ERROR_MISSING_ENCODED_DATA
);
return
set_digest
(
ctx
->
encoded_msg
,
&
ctx
->
digest
,
ctx
->
digest_type
);
}
int
fko_set_raw_spa_digest
(
fko_ctx_t
ctx
)
{
/* Must be initialized
*/
if
(
!
CTX_INITIALIZED
(
ctx
))
return
(
FKO_ERROR_CTX_NOT_INITIALIZED
);
/* Must have encoded message data to start with.
*/
if
(
ctx
->
encrypted_msg
==
NULL
)
return
(
FKO_ERROR_MISSING_ENCODED_DATA
);
return
set_digest
(
ctx
->
encrypted_msg
,
&
ctx
->
raw_digest
,
ctx
->
raw_digest_type
);
}
int
fko_get_spa_digest
(
fko_ctx_t
ctx
,
char
**
md
)
{
...
...
@@ -159,4 +211,17 @@ fko_get_spa_digest(fko_ctx_t ctx, char **md)
return
(
FKO_SUCCESS
);
}
int
fko_get_raw_spa_digest
(
fko_ctx_t
ctx
,
char
**
md
)
{
/* Must be initialized
*/
if
(
!
CTX_INITIALIZED
(
ctx
))
return
(
FKO_ERROR_CTX_NOT_INITIALIZED
);
*
md
=
ctx
->
raw_digest
;
return
(
FKO_SUCCESS
);
}
/***EOF***/
This diff is collapsed.
Click to expand it.
lib/fko_funcs.c
+
3
-
0
浏览文件 @
dc8a034a
...
...
@@ -261,6 +261,9 @@ fko_destroy(fko_ctx_t ctx)
if
(
ctx
->
digest
!=
NULL
)
free
(
ctx
->
digest
);
if
(
ctx
->
raw_digest
!=
NULL
)
free
(
ctx
->
raw_digest
);
if
(
ctx
->
encoded_msg
!=
NULL
)
free
(
ctx
->
encoded_msg
);
...
...
This diff is collapsed.
Click to expand it.
server/incoming_spa.c
+
127
-
25
浏览文件 @
dc8a034a
...
...
@@ -110,6 +110,64 @@ preprocess_spa_data(fko_srv_options_t *opts, const char *src_ip)
return
(
FKO_SUCCESS
);
}
/* For replay attack detection
*/
static
int
get_raw_digest
(
char
**
digest
,
char
*
pkt_data
)
{
fko_ctx_t
ctx
=
NULL
;
char
*
tmp_digest
=
NULL
;
int
res
=
FKO_SUCCESS
;
/* initialize an FKO context with no decryption key just so
* we can get the outer message digest
*/
res
=
fko_new_with_data
(
&
ctx
,
(
char
*
)
pkt_data
,
NULL
);
if
(
res
!=
FKO_SUCCESS
)
{
log_msg
(
LOG_WARNING
,
"Error initializing FKO context from SPA data: %s"
,
fko_errstr
(
res
));
fko_destroy
(
ctx
);
return
(
SPA_MSG_FKO_CTX_ERROR
);
}
res
=
fko_set_raw_spa_digest_type
(
ctx
,
FKO_DEFAULT_DIGEST
);
if
(
res
!=
FKO_SUCCESS
)
{
log_msg
(
LOG_WARNING
,
"Error setting digest type for SPA data: %s"
,
fko_errstr
(
res
));
fko_destroy
(
ctx
);
return
(
SPA_MSG_DIGEST_ERROR
);
}
res
=
fko_set_raw_spa_digest
(
ctx
);
if
(
res
!=
FKO_SUCCESS
)
{
log_msg
(
LOG_WARNING
,
"Error setting digest for SPA data: %s"
,
fko_errstr
(
res
));
fko_destroy
(
ctx
);
return
(
SPA_MSG_DIGEST_ERROR
);
}
res
=
fko_get_raw_spa_digest
(
ctx
,
&
tmp_digest
);
if
(
res
!=
FKO_SUCCESS
)
{
log_msg
(
LOG_WARNING
,
"Error getting digest from SPA data: %s"
,
fko_errstr
(
res
));
fko_destroy
(
ctx
);
return
(
SPA_MSG_DIGEST_ERROR
);
}
*
digest
=
strdup
(
tmp_digest
);
if
(
digest
==
NULL
)
return
SPA_MSG_ERROR
;
fko_destroy
(
ctx
);
return
res
;
}
/* Popluate a spa_data struct from an initialized (and populated) FKO context.
*/
static
int
...
...
@@ -152,6 +210,22 @@ get_spa_data_fields(fko_ctx_t ctx, spa_data_t *spdat)
return
(
res
);
}
/* Check for access.conf stanza SOURCE match based on SPA packet
* source IP
*/
static
int
is_src_match
(
acc_stanza_t
*
acc
,
const
uint32_t
ip
)
{
while
(
acc
)
{
if
(
compare_addr_list
(
acc
->
source_list
,
ip
))
return
1
;
acc
=
acc
->
next
;
}
return
0
;
}
/* Process the SPA packet data
*/
void
...
...
@@ -162,9 +236,10 @@ incoming_spa(fko_srv_options_t *opts)
*/
fko_ctx_t
ctx
=
NULL
;
char
*
spa_ip_demark
,
*
gpg_id
;
char
*
spa_ip_demark
,
*
gpg_id
,
*
raw_digest
=
NULL
;
time_t
now_ts
;
int
res
,
status
,
ts_diff
,
enc_type
,
found_acc_sip
=
0
,
stanza_num
=
0
;
int
res
,
status
,
ts_diff
,
enc_type
,
stanza_num
=
0
;
int
added_replay_digest
=
0
;
spa_pkt_info_t
*
spa_pkt
=
&
(
opts
->
spa_pkt
);
...
...
@@ -192,6 +267,36 @@ incoming_spa(fko_srv_options_t *opts)
return
;
}
if
(
is_src_match
(
opts
->
acc_stanzas
,
ntohl
(
spa_pkt
->
packet_src_ip
)))
{
if
(
strncasecmp
(
opts
->
config
[
CONF_ENABLE_DIGEST_PERSISTENCE
],
"Y"
,
1
)
==
0
)
/* Check for a replay attack
*/
res
=
get_raw_digest
(
&
raw_digest
,
(
char
*
)
spa_pkt
->
packet_data
);
if
(
res
!=
FKO_SUCCESS
)
{
if
(
raw_digest
!=
NULL
)
free
(
raw_digest
);
return
;
}
if
(
raw_digest
==
NULL
)
return
;
if
(
is_replay
(
opts
,
raw_digest
)
!=
SPA_MSG_SUCCESS
)
return
;
}
else
{
log_msg
(
LOG_WARNING
,
"No access data found for source IP: %s"
,
spadat
.
pkt_source_ip
);
return
;
}
/* Now that we know there is a matching access.conf stanza and the
* incoming SPA packet is not a replay, see if we should grant any
* access
*/
while
(
acc
)
{
stanza_num
++
;
...
...
@@ -204,8 +309,6 @@ incoming_spa(fko_srv_options_t *opts)
continue
;
}
found_acc_sip
=
1
;
log_msg
(
LOG_INFO
,
"(stanza #%d) SPA Packet from IP: %s received with access source match"
,
stanza_num
,
spadat
.
pkt_source_ip
);
...
...
@@ -332,7 +435,7 @@ incoming_spa(fko_srv_options_t *opts)
continue
;
}
/* Do we have a valid FKO context?
/* Do we have a valid FKO context?
Did the SPA decrypt properly?
*/
if
(
res
!=
FKO_SUCCESS
)
{
...
...
@@ -349,6 +452,23 @@ incoming_spa(fko_srv_options_t *opts)
continue
;
}
/* Add this SPA packet into the replay detection cache
*/
if
(
!
added_replay_digest
)
{
res
=
add_replay
(
opts
,
raw_digest
);
if
(
res
!=
SPA_MSG_SUCCESS
)
{
log_msg
(
LOG_WARNING
,
"(stanza #%d) Could not add digest to replay cache"
,
stanza_num
);
if
(
ctx
!=
NULL
)
fko_destroy
(
ctx
);
acc
=
acc
->
next
;
continue
;
}
added_replay_digest
=
1
;
}
/* At this point, we assume the SPA data is valid. Now we need to see
* if it meets our access criteria.
*/
...
...
@@ -389,20 +509,6 @@ incoming_spa(fko_srv_options_t *opts)
}
}
/* Check for replays if so configured.
*/
if
(
strncasecmp
(
opts
->
config
[
CONF_ENABLE_DIGEST_PERSISTENCE
],
"Y"
,
1
)
==
0
)
{
res
=
replay_check
(
opts
,
ctx
);
if
(
res
!=
0
)
/* non-zero means we have seen this packet before. */
{
if
(
ctx
!=
NULL
)
fko_destroy
(
ctx
);
acc
=
acc
->
next
;
continue
;
}
}
/* Populate our spa data struct for future reference.
*/
res
=
get_spa_data_fields
(
ctx
,
&
spadat
);
...
...
@@ -636,12 +742,8 @@ incoming_spa(fko_srv_options_t *opts)
break
;
}
if
(
!
found_acc_sip
)
{
log_msg
(
LOG_WARNING
,
"No access data found for source IP: %s"
,
spadat
.
pkt_source_ip
);
}
if
(
raw_digest
!=
NULL
)
free
(
raw_digest
);
return
;
}
...
...
This diff is collapsed.
Click to expand it.
server/replay_cache.c
+
99
-
39
浏览文件 @
dc8a034a
...
...
@@ -420,44 +420,45 @@ replay_db_cache_init(fko_srv_options_t *opts)
#endif
/* USE_FILE_CACHE */
/* Take an fko context, pull the digest and use it as the key to check the
* replay db (digest cache). Returns 1 if there was a match (a replay),
* 0 for no match, and -1 on error.
* replay db (digest cache).
*/
int
replay
_check
(
fko_srv_options_t
*
opts
,
fko_ctx_t
ctx
)
is_
replay
(
fko_srv_options_t
*
opts
,
char
*
digest
)
{
#ifdef NO_DIGEST_CACHE
return
(
-
1
);
#else
#if USE_FILE_CACHE
return
replay_
check_
file_cache
(
opts
,
ctx
);
return
is_
replay_file_cache
(
opts
,
digest
);
#else
return
replay_
check_
dbm_cache
(
opts
,
ctx
);
return
is_
replay_dbm_cache
(
opts
,
digest
);
#endif
#endif
/* NO_DIGEST_CACHE */
}
#if USE_FILE_CACHE
int
replay
_check_file_cache
(
fko_srv_options_t
*
opts
,
fko_ctx_t
ctx
)
add_
replay
(
fko_srv_options_t
*
opts
,
char
*
digest
)
{
char
*
digest
=
NULL
;
char
src_ip
[
INET_ADDRSTRLEN
+
1
]
=
{
0
};
char
dst_ip
[
INET_ADDRSTRLEN
+
1
]
=
{
0
};
int
res
=
0
,
digest_len
=
0
;
FILE
*
digest_file_ptr
=
NULL
;
#ifdef NO_DIGEST_CACHE
return
(
-
1
);
#else
struct
digest_cache_list
*
digest_list_ptr
=
NULL
,
*
digest_elm
=
NULL
;
#if USE_FILE_CACHE
return
add_replay_file_cache
(
opts
,
digest
);
#else
return
add_replay_dbm_cache
(
opts
,
digest
);
#endif
#endif
/* NO_DIGEST_CACHE */
}
res
=
fko_get_spa_digest
(
ctx
,
&
digest
);
if
(
res
!=
FKO_SUCCESS
)
{
log_msg
(
LOG_WARNING
,
"Error getting digest from SPA data: %s"
,
fko_errstr
(
res
))
;
#if USE_FILE_CACHE
int
is_replay_file_cache
(
fko_srv_options_t
*
opts
,
char
*
digest
)
{
int
digest_len
=
0
;
return
(
SPA_MSG_DIGEST_ERROR
);
}
struct
digest_cache_list
*
digest_list_ptr
=
NULL
;
digest_len
=
strlen
(
digest
);
...
...
@@ -474,11 +475,21 @@ replay_check_file_cache(fko_srv_options_t *opts, fko_ctx_t ctx)
return
(
SPA_MSG_REPLAY
);
}
}
return
(
SPA_MSG_SUCCESS
);
}
int
add_replay_file_cache
(
fko_srv_options_t
*
opts
,
char
*
digest
)
{
FILE
*
digest_file_ptr
=
NULL
;
int
digest_len
=
0
;
char
src_ip
[
INET_ADDRSTRLEN
+
1
]
=
{
0
};
char
dst_ip
[
INET_ADDRSTRLEN
+
1
]
=
{
0
};
struct
digest_cache_list
*
digest_elm
=
NULL
;
digest_len
=
strlen
(
digest
);
/* If we make it here, then this is a new SPA packet that needs to be
* added to the cache. We've already decrypted the data, so we know that
* the contents are valid.
*/
if
((
digest_elm
=
calloc
(
1
,
sizeof
(
struct
digest_cache_list
)))
==
NULL
)
{
log_msg
(
LOG_WARNING
,
"Error calloc() returned NULL for digest cache element"
,
...
...
@@ -537,7 +548,7 @@ replay_check_file_cache(fko_srv_options_t *opts, fko_ctx_t ctx)
#if !USE_FILE_CACHE
int
replay_
check_
dbm_cache
(
fko_srv_options_t
*
opts
,
fko_ctx_t
ctx
)
is_
replay_dbm_cache
(
fko_srv_options_t
*
opts
,
char
*
digest
)
{
#ifdef NO_DIGEST_CACHE
return
0
;
...
...
@@ -550,20 +561,11 @@ replay_check_dbm_cache(fko_srv_options_t *opts, fko_ctx_t ctx)
#endif
datum
db_key
,
db_ent
;
char
*
digest
;
int
digest_len
,
res
;
char
*
digest
=
NULL
;
int
digest_len
,
res
=
SPA_MSG_SUCCESS
;
digest_cache_info_t
dc_info
;
res
=
fko_get_spa_digest
(
ctx
,
&
digest
);
if
(
res
!=
FKO_SUCCESS
)
{
log_msg
(
LOG_WARNING
,
"Error getting digest from SPA data: %s"
,
fko_errstr
(
res
));
return
(
SPA_MSG_DIGEST_ERROR
);
}
digest_len
=
strlen
(
digest
);
db_key
.
dptr
=
digest
;
...
...
@@ -609,9 +611,65 @@ replay_check_dbm_cache(fko_srv_options_t *opts, fko_ctx_t ctx)
#ifdef HAVE_LIBGDBM
free
(
db_ent
.
dptr
);
#endif
res
=
SPA_MSG_REPLAY
;
}
else
{
}
MY_DBM_CLOSE
(
rpdb
);
return
(
res
);
#endif
/* NO_DIGEST_CACHE */
}
int
add_replay_dbm_cache
(
fko_srv_options_t
*
opts
,
char
*
digest
)
{
#ifdef NO_DIGEST_CACHE
return
0
;
#else
#ifdef HAVE_LIBGDBM
GDBM_FILE
rpdb
;
#elif HAVE_LIBNDBM
DBM
*
rpdb
;
#endif
datum
db_key
,
db_ent
;
char
*
digest
=
NULL
;
int
digest_len
,
res
=
SPA_MSG_SUCCESS
;
digest_cache_info_t
dc_info
;
digest_len
=
strlen
(
digest
);
db_key
.
dptr
=
digest
;
db_key
.
dsize
=
digest_len
;
/* Check the db for the key
*/
#ifdef HAVE_LIBGDBM
rpdb
=
gdbm_open
(
opts
->
config
[
CONF_DIGEST_DB_FILE
],
512
,
GDBM_WRCREAT
,
S_IRUSR
|
S_IWUSR
,
0
);
#elif HAVE_LIBNDBM
rpdb
=
dbm_open
(
opts
->
config
[
CONF_DIGEST_DB_FILE
],
O_RDWR
,
0
);
#endif
if
(
!
rpdb
)
{
log_msg
(
LOG_WARNING
,
"Error opening digest_cache: '%s': %s"
,
opts
->
config
[
CONF_DIGEST_DB_FILE
],
MY_DBM_STRERROR
(
errno
)
);
return
(
SPA_MSG_DIGEST_CACHE_ERROR
);
}
db_ent
=
MY_DBM_FETCH
(
rpdb
,
db_key
);
/* If the datum is null, we have a new entry.
*/
if
(
db_ent
.
dptr
==
NULL
)
{
/* This is a new SPA packet that needs to be added to the cache.
*/
dc_info
.
src_ip
=
opts
->
spa_pkt
.
packet_src_ip
;
...
...
@@ -636,12 +694,14 @@ replay_check_dbm_cache(fko_srv_options_t *opts, fko_ctx_t ctx)
res
=
SPA_MSG_SUCCESS
;
}
else
res
=
SPA_MSG_DIGEST_CACHE_ERROR
;
MY_DBM_CLOSE
(
rpdb
);
return
(
res
);
#endif
/* NO_DIGEST_CACHE */
}
#endif
/* USE_FILE_CACHE */
#if USE_FILE_CACHE
...
...
This diff is collapsed.
Click to expand it.
server/replay_cache.h
+
6
-
3
浏览文件 @
dc8a034a
...
...
@@ -59,14 +59,17 @@ struct digest_cache_list {
/* Prototypes
*/
int
replay_cache_init
(
fko_srv_options_t
*
opts
);
int
replay_check
(
fko_srv_options_t
*
opts
,
fko_ctx_t
ctx
);
int
is_replay
(
fko_srv_options_t
*
opts
,
char
*
digest
);
int
add_replay
(
fko_srv_options_t
*
opts
,
char
*
digest
);
#ifdef USE_FILE_CACHE
int
replay_file_cache_init
(
fko_srv_options_t
*
opts
);
int
replay_check_file_cache
(
fko_srv_options_t
*
opts
,
fko_ctx_t
ctx
);
int
is_replay_file_cache
(
fko_srv_options_t
*
opts
,
char
*
digest
);
int
add_replay_file_cache
(
fko_srv_options_t
*
opts
,
char
*
digest
);
void
free_replay_list
(
fko_srv_options_t
*
opts
);
#else
int
replay_db_cache_init
(
fko_srv_options_t
*
opts
);
int
replay_check_dbm_cache
(
fko_srv_options_t
*
opts
,
fko_ctx_t
ctx
);
int
is_replay_dbm_cache
(
fko_srv_options_t
*
opts
,
char
*
digest
);
int
add_replay_dbm_cache
(
fko_srv_options_t
*
opts
,
char
*
digest
);
#endif
#endif
/* REPLAY_CACHE_H */
This diff is collapsed.
Click to expand it.
test/conf/dual_key_usage_access.conf
0 → 100644
+
9
-
0
浏览文件 @
dc8a034a
SOURCE
:
ANY
;
KEY
:
fwknoptest
;
OPEN_PORTS
:
tcp
/
22
;
FW_ACCESS_TIMEOUT
:
2
;
SOURCE
:
ANY
;
KEY
:
fwknoptest
;
OPEN_PORTS
:
tcp
/
80
;
FW_ACCESS_TIMEOUT
:
3
;
This diff is collapsed.
Click to expand it.
test/test-fwknop.pl
+
135
-
19
浏览文件 @
dc8a034a
...
...
@@ -33,6 +33,7 @@ my $expired_epoch_access_conf = "$conf_dir/expired_epoch_stanza_access.conf";
my
$invalid_expire_access_conf
=
"
$conf_dir
/invalid_expire_access.conf
";
my
$invalid_source_access_conf
=
"
$conf_dir
/invalid_source_access.conf
";
my
$force_nat_access_conf
=
"
$conf_dir
/force_nat_access.conf
";
my
$dual_key_usage_access_conf
=
"
$conf_dir
/dual_key_usage_access.conf
";
my
$gpg_access_conf
=
"
$conf_dir
/gpg_access.conf
";
my
$default_digest_file
=
"
$run_dir
/digest.cache
";
my
$default_pid_file
=
"
$run_dir
/fwknopd.pid
";
...
...
@@ -76,7 +77,11 @@ my $test_include = '';
my
@tests_to_include
=
();
my
$test_exclude
=
'';
my
@tests_to_exclude
=
();
my
%valgrind_flagged_fcns
=
();
my
%valgrind_flagged_fcns_unique
=
();
my
$list_mode
=
0
;
my
$diff_dir1
=
'';
my
$diff_dir2
=
'';
my
$loopback_intf
=
'';
my
$anonymize_results
=
0
;
my
$current_test_file
=
"
$output_dir
/init
";
...
...
@@ -123,7 +128,10 @@ exit 1 unless GetOptions(
'
List-mode
'
=>
\
$list_mode
,
'
enable-valgrind
'
=>
\
$use_valgrind
,
'
valgrind-path=s
'
=>
\
$valgrindCmd
,
'
output-dir=s
'
=>
\
$output_dir
,
'
diff
'
=>
\
$diff_mode
,
'
diff-dir1=s
'
=>
\
$diff_dir1
,
'
diff-dir2=s
'
=>
\
$diff_dir2
,
'
help
'
=>
\
$help
);
...
...
@@ -599,6 +607,25 @@ my @tests = (
'
fw_rule_removed
'
=>
$NEW_RULE_REMOVED
,
'
fatal
'
=>
$NO
},
{
'
category
'
=>
'
Rijndael SPA
',
'
subcategory
'
=>
'
client+server
',
'
detail
'
=>
'
dual usage access key (tcp/80 http)
',
'
err_msg
'
=>
'
could not complete SPA cycle
',
'
function
'
=>
\
&spa_cycle
,
'
cmdline
'
=>
"
LD_LIBRARY_PATH=
$lib_dir
$valgrind_str
"
.
"
$fwknopCmd
-A tcp/80 -a
$fake_ip
-D
$loopback_ip
--get-key
"
.
"
$local_key_file
--verbose --verbose
",
'
fwknopd_cmdline
'
=>
"
LD_LIBRARY_PATH=
$lib_dir
$valgrind_str
"
.
"
$fwknopdCmd
-c
$default_conf
-a
$dual_key_usage_access_conf
"
.
"
-d
$default_digest_file
-p
$default_pid_file
$intf_str
",
### check for the first stanza that does not allow tcp/80 - the
### second stanza allows this
'
server_positive_output_matches
'
=>
[
qr/stanza #1\)\sOne\sor\smore\srequested\sprotocol\/
ports
\
swas
\
sdenied
/
],
'
fw_rule_created
'
=>
$NEW_RULE_REQUIRED
,
'
fw_rule_removed
'
=>
$NEW_RULE_REMOVED
,
'
fatal
'
=>
$NO
},
{
'
category
'
=>
'
Rijndael SPA
',
'
subcategory
'
=>
'
client+server
',
...
...
@@ -1317,7 +1344,6 @@ my @tests = (
'
fwknopd_cmdline
'
=>
$default_server_gpg_args
,
'
fatal
'
=>
$NO
},
{
'
category
'
=>
'
GnuPG (GPG) SPA
',
'
subcategory
'
=>
'
server
',
...
...
@@ -1336,6 +1362,18 @@ my @tests = (
},
);
if
(
$use_valgrind
)
{
push
@tests
,
{
'
category
'
=>
'
valgrind output
',
'
subcategory
'
=>
'
flagged functions
',
'
detail
'
=>
'',
'
err_msg
'
=>
'
could not parse flagged functions
',
'
function
'
=>
\
&parse_valgrind_flagged_functions
,
'
fatal
'
=>
$NO
};
}
my
%test_keys
=
(
'
category
'
=>
$REQUIRED
,
'
subcategory
'
=>
$OPTIONAL
,
...
...
@@ -1431,7 +1469,8 @@ sub process_include_exclude() {
if
(
@tests_to_include
)
{
my
$found
=
0
;
for
my
$test
(
@tests_to_include
)
{
if
(
$msg
=~
/$test/
)
{
if
(
$msg
=~
/$test/
or
(
$use_valgrind
and
$msg
=~
/valgrind\soutput/
))
{
$found
=
1
;
last
;
}
...
...
@@ -1452,17 +1491,21 @@ sub process_include_exclude() {
}
sub
diff_test_results
()
{
$diff_dir1
=
"
${output_dir}
.last
"
unless
$diff_dir2
;
$diff_dir2
=
$output_dir
unless
$diff_dir1
;
die
"
[*] Need results from a previous run before running --diff
"
unless
-
d
"
${output_dir}
.last
"
;
die
"
[*] Current results set does not exist.
"
unless
-
d
$
output
_dir
;
unless
-
d
$diff_dir2
;
die
"
[*] Current results set does not exist.
"
unless
-
d
$
diff
_dir
1
;
my
%current_tests
=
();
my
%previous_tests
=
();
### Only diff results for matching tests (parse the logfile to see which
### test numbers match across the two test cycles).
&build_results_hash
(
\
%current_tests
,
$
output
_dir
);
&build_results_hash
(
\
%previous_tests
,
"
${output_dir}
.last
"
);
&build_results_hash
(
\
%current_tests
,
$
diff
_dir
1
);
&build_results_hash
(
\
%previous_tests
,
$diff_dir2
);
for
my
$test_msg
(
sort
{
$current_tests
{
$a
}{'
num
'}
<=>
$current_tests
{
$b
}{'
num
'}}
keys
%current_tests
)
{
...
...
@@ -1493,25 +1536,25 @@ sub diff_results() {
### remove CMD timestamps
my
$cmd_search_re
=
qr/^\S+\s.*?\s\d{4}\sCMD\:/
;
for
my
$file
("
$
{output_dir}
.last
/
${previous_num}
.test
",
"
$
{output_dir}
.last
/
${previous_num}
_fwknopd.test
",
"
$
{output
_dir
}
/
${current_num}
.test
",
"
$
{output
_dir
}
/
${current_num}
_fwknopd.test
",
for
my
$file
("
$
diff_dir1
/
${previous_num}
.test
",
"
$
diff_dir1
/
${previous_num}
_fwknopd.test
",
"
$
diff
_dir
2
/
${current_num}
.test
",
"
$
diff
_dir
2
/
${current_num}
_fwknopd.test
",
)
{
system
qq{perl -p -i -e 's|$valgrind_search_re||' $file}
if
-
e
$file
;
system
qq{perl -p -i -e 's|$cmd_search_re|CMD:|' $file}
if
-
e
$file
;
}
if
(
-
e
"
$
{output_dir}
.last
/
${previous_num}
.test
"
and
-
e
"
$
{output
_dir
}
/
${current_num}
.test
")
{
system
"
diff -u
$
{output_dir}
.last
/
${previous_num}
.test
"
.
"
$
{output
_dir
}
/
${current_num}
.test
";
if
(
-
e
"
$
diff_dir1
/
${previous_num}
.test
"
and
-
e
"
$
diff
_dir
2
/
${current_num}
.test
")
{
system
"
diff -u
$
diff_dir1
/
${previous_num}
.test
"
.
"
$
diff
_dir
2
/
${current_num}
.test
";
}
if
(
-
e
"
$
{output_dir}
.last
/
${previous_num}
_fwknopd.test
"
and
-
e
"
$
{output
_dir
}
/
${current_num}
_fwknopd.test
")
{
system
"
diff -u
$
{output_dir}
.last
/
${previous_num}
_fwknopd.test
"
.
"
$
{output
_dir
}
/
${current_num}
_fwknopd.test
";
if
(
-
e
"
$
diff_dir1
/
${previous_num}
_fwknopd.test
"
and
-
e
"
$
diff
_dir
2
/
${current_num}
_fwknopd.test
")
{
system
"
diff -u
$
diff_dir1
/
${previous_num}
_fwknopd.test
"
.
"
$
diff
_dir
2
/
${current_num}
_fwknopd.test
";
}
return
;
...
...
@@ -2722,6 +2765,42 @@ sub identify_loopback_intf() {
return
;
}
sub
parse_valgrind_flagged_functions
()
{
for
my
$file
(
glob
("
$output_dir
/*.test
"))
{
my
$type
=
'
server
';
$type
=
'
client
'
if
$file
=~
/\d\.test/
;
open
F
,
"
<
$file
"
or
die
$!
;
while
(
<
F
>
)
{
### ==30969== by 0x4E3983A: fko_set_username (fko_user.c:65)
if
(
/^==.*\sby\s\S+\:\s(\S+)\s(.*)/
)
{
$valgrind_flagged_fcns
{
$type
}{"
$1 $2
"}
++
;
$valgrind_flagged_fcns_unique
{
$type
}{
$
1
}
++
;
}
}
close
F
;
}
open
F
,
"
>>
$current_test_file
"
or
die
$!
;
for
my
$type
('
client
',
'
server
')
{
print
F
"
\n
[+] fwknop
$type
functions (unique view):
\n
";
next
unless
defined
$valgrind_flagged_fcns_unique
{
$type
};
for
my
$fcn
(
sort
{
$valgrind_flagged_fcns_unique
{
$type
}{
$b
}
<=>
$valgrind_flagged_fcns_unique
{
$type
}{
$a
}}
keys
%
{
$valgrind_flagged_fcns_unique
{
$type
}})
{
printf
F
"
%5d : %s
\n
",
$valgrind_flagged_fcns_unique
{
$type
}{
$fcn
},
$fcn
;
}
print
F
"
\n
[+] fwknop
$type
functions (with call line numbers):
\n
";
for
my
$fcn
(
sort
{
$valgrind_flagged_fcns
{
$type
}{
$b
}
<=>
$valgrind_flagged_fcns
{
$type
}{
$a
}}
keys
%
{
$valgrind_flagged_fcns
{
$type
}})
{
printf
F
"
%5d : %s
\n
",
$valgrind_flagged_fcns
{
$type
}{
$fcn
},
$fcn
;
}
next
unless
defined
$valgrind_flagged_fcns
{
$type
};
}
close
F
;
return
1
;
}
sub
is_fw_rule_active
()
{
my
$test_hr
=
shift
;
...
...
@@ -2839,5 +2918,42 @@ sub logr() {
}
sub
usage
()
{
return
;
print
<<_HELP_;
[+] $0 <options>
-A --Anonymize-results - Prepare anonymized results at:
$tarfile
--diff - Compare the results of one test run to
another. By default this compares output
in ${output_dir}.last to $output_dir
--diff-dir1=<path> - Left hand side of diff directory path,
default is: ${output_dir}.last
--diff-dir2=<path> - Right hand side of diff directory path,
default is: $output_dir
--include=<regex> - Specify a regex to be used over test
names that must match.
--exclude=<regex> - Specify a regex to be used over test
names that must not match.
--enable-recompile - Recompile fwknop sources and look for
compilation warnings.
--enable-valgrind - Run every test underneath valgrind.
--List - List test names.
--loopback-intf=<intf> - Specify loopback interface name (default
depends on the OS where the test suite
is executed).
--output-dir=<path> - Path to output directory, default is:
$output_dir
--fwknop-path=<path> - Path to fwknop binary, default is:
$fwknopCmd
--fwknopd-path=<path> - Path to fwknopd binary, default is:
$fwknopdCmd
--libfko-path=<path> - Path to libfko, default is:
$libfko_bin
--valgrind-path=<path> - Path to valgrind, default is:
$valgrindCmd
-h --help - Display usage on STDOUT and exit.
_HELP_
exit
0
;
}
This diff is collapsed.
Click to expand it.
编辑
预览
支持
Markdown
0%
请重试
或
添加新附件
.
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录
菜单
探索
项目
群组
代码片段