Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
What's new
7
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Open sidebar
Knot projects
Knot DNS
Commits
fff23454
Commit
fff23454
authored
May 05, 2014
by
Jan Včelák
🚀
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
tsig verification in answer processing
parent
6332c2b8
Changes
13
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
121 additions
and
76 deletions
+121
-76
Knot.files
Knot.files
+2
-2
src/Makefile.am
src/Makefile.am
+2
-2
src/knot/nameserver/axfr.c
src/knot/nameserver/axfr.c
+4
-0
src/knot/nameserver/internet.c
src/knot/nameserver/internet.c
+2
-0
src/knot/nameserver/internet.h
src/knot/nameserver/internet.h
+5
-0
src/knot/nameserver/notify.c
src/knot/nameserver/notify.c
+4
-0
src/knot/nameserver/process_answer.c
src/knot/nameserver/process_answer.c
+6
-0
src/knot/nameserver/process_answer.h
src/knot/nameserver/process_answer.h
+2
-0
src/knot/nameserver/requestor.c
src/knot/nameserver/requestor.c
+5
-37
src/knot/nameserver/requestor.h
src/knot/nameserver/requestor.h
+1
-3
src/knot/nameserver/tsig_ctx.c
src/knot/nameserver/tsig_ctx.c
+56
-20
src/knot/nameserver/tsig_ctx.h
src/knot/nameserver/tsig_ctx.h
+16
-7
src/knot/zone/events.c
src/knot/zone/events.c
+16
-5
No files found.
Knot.files
View file @
fff23454
...
...
@@ -127,8 +127,8 @@ src/knot/nameserver/query_module.c
src/knot/nameserver/query_module.h
src/knot/nameserver/requestor.c
src/knot/nameserver/requestor.h
src/knot/nameserver/
requestor_
tsig.c
src/knot/nameserver/
requestor_
tsig.h
src/knot/nameserver/tsig
_ctx
.c
src/knot/nameserver/tsig
_ctx
.h
src/knot/nameserver/update.c
src/knot/nameserver/update.h
src/knot/other/debug.h
...
...
src/Makefile.am
View file @
fff23454
...
...
@@ -240,14 +240,14 @@ libknotd_la_SOURCES = \
knot/nameserver/process_answer.h
\
knot/nameserver/requestor.c
\
knot/nameserver/requestor.h
\
knot/nameserver/requestor_tsig.c
\
knot/nameserver/requestor_tsig.h
\
knot/nameserver/query_module.c
\
knot/nameserver/query_module.h
\
knot/nameserver/update.c
\
knot/nameserver/update.h
\
knot/nameserver/notify.c
\
knot/nameserver/notify.h
\
knot/nameserver/tsig_ctx.c
\
knot/nameserver/tsig_ctx.h
\
knot/modules/synth_record.c
\
knot/modules/synth_record.h
\
knot/other/debug.h
\
...
...
src/knot/nameserver/axfr.c
View file @
fff23454
...
...
@@ -318,10 +318,14 @@ int axfr_process_answer(knot_pkt_t *pkt, struct answer_data *data)
/* Initialize processing with first packet. */
int
ret
=
KNOT_EOK
;
if
(
data
->
ext
==
NULL
)
{
NS_NEED_TSIG_SIGNED
(
&
data
->
param
->
tsig_ctx
,
0
);
ret
=
axfr_answer_init
(
data
);
if
(
ret
!=
KNOT_EOK
)
{
return
NS_PROC_FAIL
;
}
}
else
{
NS_NEED_TSIG_SIGNED
(
&
data
->
param
->
tsig_ctx
,
100
);
}
/* Process answer packet. */
...
...
src/knot/nameserver/internet.c
View file @
fff23454
...
...
@@ -899,6 +899,8 @@ int internet_process_answer(knot_pkt_t *pkt, struct answer_data *data)
return
NS_PROC_FAIL
;
}
NS_NEED_TSIG_SIGNED
(
&
data
->
param
->
tsig_ctx
,
0
);
/* As of now, server can only issue SOA queries. */
switch
(
knot_pkt_qtype
(
pkt
))
{
case
KNOT_RRTYPE_SOA
:
...
...
src/knot/nameserver/internet.h
View file @
fff23454
...
...
@@ -127,6 +127,11 @@ int ns_put_rr(knot_pkt_t *pkt, const knot_rrset_t *rr,
} \
}
#define NS_NEED_TSIG_SIGNED(tsig_ctx, max_unsigned) \
if (tsig_unsigned_count(tsig_ctx) > max_unsigned) { \
return NS_PROC_FAIL; \
}
#endif
/* _KNOT_INTERNET_H_ */
/*! @} */
src/knot/nameserver/notify.c
View file @
fff23454
...
...
@@ -33,6 +33,8 @@
#include "knot/nameserver/internet.h"
#include "common/debug.h"
#include "knot/nameserver/process_query.h"
#include "knot/nameserver/tsig_ctx.h"
#include "knot/nameserver/process_answer.h"
#include "libknot/dnssec/random.h"
#include "libknot/rdata/soa.h"
...
...
@@ -84,5 +86,7 @@ int notify_query(knot_pkt_t *pkt, struct query_data *qdata)
int
notify_process_answer
(
knot_pkt_t
*
pkt
,
struct
answer_data
*
data
)
{
NS_NEED_TSIG_SIGNED
(
&
data
->
param
->
tsig_ctx
,
0
);
return
NS_PROC_DONE
;
/* No processing. */
}
src/knot/nameserver/process_answer.c
View file @
fff23454
...
...
@@ -103,6 +103,12 @@ static int process_answer(knot_pkt_t *pkt, knot_process_t *ctx)
/* Class specific answer processing. */
ANSWER_REQUIRES
(
knot_pkt_qclass
(
pkt
)
==
KNOT_CLASS_IN
,
NS_PROC_NOOP
);
/* Verify incoming packet. */
int
ret
=
tsig_verify_packet
(
&
data
->
param
->
tsig_ctx
,
pkt
);
if
(
ret
!=
KNOT_EOK
)
{
return
NS_PROC_FAIL
;
}
/* Call appropriate processing handler. */
int
next_state
=
NS_PROC_NOOP
;
switch
(
knot_pkt_type
(
pkt
))
{
...
...
src/knot/nameserver/process_answer.h
View file @
fff23454
...
...
@@ -17,6 +17,7 @@
#pragma once
#include "knot/nameserver/process_query.h"
#include "knot/nameserver/tsig_ctx.h"
/* Query processing module implementation. */
const
knot_process_module_t
*
process_answer_get_module
(
void
);
...
...
@@ -35,6 +36,7 @@ struct process_answer_param {
zone_t
*
zone
;
const
knot_pkt_t
*
query
;
const
struct
sockaddr_storage
*
remote
;
tsig_ctx_t
tsig_ctx
;
};
struct
answer_data
...
...
src/knot/nameserver/requestor.c
View file @
fff23454
...
...
@@ -55,7 +55,6 @@ static void request_close(mm_ctx_t *mm, struct request *request)
knot_process_finish
(
&
request
->
process
);
rem_node
(
&
request
->
data
.
node
);
requestor_tsig_cleanup
(
&
request
->
data
.
tsig_ctx
);
close
(
request
->
data
.
fd
);
knot_pkt_free
(
&
request
->
data
.
query
);
mm_free
(
mm
,
request
->
pkt_buf
);
...
...
@@ -155,11 +154,12 @@ struct request *requestor_make(struct requestor *requestor,
return
NULL
;
}
memcpy
(
&
request
->
data
.
origin
,
&
remote
->
via
,
sizeof
(
remote
->
via
));
memcpy
(
&
request
->
data
.
remote
,
&
remote
->
addr
,
sizeof
(
remote
->
addr
));
request
->
state
=
NS_PROC_DONE
;
request
->
data
.
remote
=
remote
;
request
->
data
.
fd
=
-
1
;
request
->
data
.
query
=
query
;
requestor_tsig_init
(
&
request
->
data
.
tsig_ctx
,
remote
->
key
);
return
request
;
}
...
...
@@ -170,8 +170,8 @@ int requestor_enqueue(struct requestor *requestor, struct request * request, voi
}
/* Fetch a bound socket. */
int
fd
=
net_connected_socket
(
SOCK_STREAM
,
&
request
->
data
.
remote
->
addr
,
&
request
->
data
.
remote
->
via
,
O_NONBLOCK
);
int
fd
=
net_connected_socket
(
SOCK_STREAM
,
&
request
->
data
.
remote
,
&
request
->
data
.
origin
,
O_NONBLOCK
);
if
(
fd
<
0
)
{
return
KNOT_ECONN
;
}
...
...
@@ -199,39 +199,12 @@ int requestor_dequeue(struct requestor *requestor)
return
KNOT_EOK
;
}
/*!
* \brief Sign outbound packet using TSIG.
*/
static
int
request_sign
(
struct
request
*
request
)
{
assert
(
request
);
return
requestor_tsig_sign_packet
(
&
request
->
data
.
tsig_ctx
,
request
->
data
.
query
);
}
/*!
* \brief Check inbound packet TSIG signature.
*/
static
int
request_verify
(
struct
request
*
request
)
{
assert
(
request
);
return
requestor_tsig_verify_packet
(
&
request
->
data
.
tsig_ctx
,
request
->
data
.
query
);
}
static
int
exec_request
(
struct
request
*
last
,
struct
timeval
*
timeout
)
{
int
ret
=
KNOT_EOK
;
/* Process any pending data. */
if
(
last
->
state
==
NS_PROC_FULL
)
{
ret
=
request_sign
(
last
);
if
(
ret
!=
KNOT_EOK
)
{
return
ret
;
}
ret
=
request_send
(
last
,
timeout
);
if
(
ret
!=
KNOT_EOK
)
{
return
ret
;
...
...
@@ -246,11 +219,6 @@ static int exec_request(struct request *last, struct timeval *timeout)
return
rcvd
;
}
ret
=
request_verify
(
last
);
if
(
ret
!=
KNOT_EOK
)
{
return
ret
;
}
last
->
state
=
knot_process_in
(
last
->
pkt_buf
,
rcvd
,
&
last
->
process
);
if
(
last
->
state
==
NS_PROC_FAIL
)
{
return
KNOT_EMALF
;
...
...
src/knot/nameserver/requestor.h
View file @
fff23454
...
...
@@ -18,7 +18,6 @@
#include "knot/nameserver/process_query.h"
#include "knot/nameserver/process_answer.h"
#include "knot/nameserver/requestor_tsig.h"
#include "common/lists.h"
struct
request
;
...
...
@@ -41,9 +40,8 @@ struct requestor {
struct
request_data
{
node_t
node
;
int
fd
;
const
conf_iface_t
*
remote
;
struct
sockaddr_storage
remote
,
origin
;
knot_pkt_t
*
query
;
requestor_tsig_ctx_t
tsig_ctx
;
};
/*!
...
...
src/knot/nameserver/
requestor_
tsig.c
→
src/knot/nameserver/tsig
_ctx
.c
View file @
fff23454
...
...
@@ -21,9 +21,9 @@
#include "common/errcode.h"
#include "libknot/rdata/tsig.h"
#include "libknot/tsig-op.h"
#include "knot/nameserver/
requestor_
tsig.h"
#include "knot/nameserver/tsig
_ctx
.h"
void
requestor_tsig_init
(
requestor_
tsig_ctx_t
*
ctx
,
const
knot_tsig_key_t
*
key
)
void
tsig_init
(
tsig_ctx_t
*
ctx
,
const
knot_tsig_key_t
*
key
)
{
if
(
!
ctx
)
{
return
;
...
...
@@ -31,19 +31,12 @@ void requestor_tsig_init(requestor_tsig_ctx_t *ctx, const knot_tsig_key_t *key)
memset
(
ctx
,
0
,
sizeof
(
*
ctx
));
ctx
->
key
=
key
;
}
void
requestor_tsig_cleanup
(
requestor_tsig_ctx_t
*
ctx
)
{
if
(
!
ctx
)
{
return
;
}
free
(
ctx
->
digest
);
memset
(
ctx
,
0
,
sizeof
(
*
ctx
));
}
int
requestor_
tsig_sign_packet
(
requestor_
tsig_ctx_t
*
ctx
,
knot_pkt_t
*
packet
)
int
tsig_sign_packet
(
tsig_ctx_t
*
ctx
,
knot_pkt_t
*
packet
)
{
if
(
!
ctx
||
!
packet
)
{
return
KNOT_EINVAL
;
...
...
@@ -54,14 +47,8 @@ int requestor_tsig_sign_packet(requestor_tsig_ctx_t *ctx, knot_pkt_t *packet)
}
int
ret
=
KNOT_ERROR
;
if
(
ctx
->
digest_size
==
0
)
{
ctx
->
digest_size
=
knot_tsig_digest_length
(
ctx
->
key
->
algorithm
);
ctx
->
digest
=
malloc
(
ctx
->
digest_size
);
if
(
!
ctx
->
digest
)
{
return
KNOT_ENOMEM
;
}
ret
=
knot_tsig_sign
(
packet
->
wire
,
&
packet
->
size
,
packet
->
max_size
,
NULL
,
0
,
ctx
->
digest
,
&
ctx
->
digest_size
,
...
...
@@ -79,7 +66,23 @@ int requestor_tsig_sign_packet(requestor_tsig_ctx_t *ctx, knot_pkt_t *packet)
return
ret
;
}
int
requestor_tsig_verify_packet
(
requestor_tsig_ctx_t
*
ctx
,
knot_pkt_t
*
packet
)
static
int
update_ctx_after_verify
(
tsig_ctx_t
*
ctx
,
knot_rrset_t
*
tsig_rr
)
{
assert
(
ctx
);
assert
(
tsig_rr
);
if
(
ctx
->
digest_size
!=
tsig_rdata_mac_length
(
tsig_rr
))
{
return
KNOT_EMALF
;
}
memcpy
(
ctx
->
digest
,
tsig_rdata_mac
(
tsig_rr
),
ctx
->
digest_size
);
ctx
->
last_signed
=
tsig_rdata_time_signed
(
tsig_rr
);
ctx
->
unsigned_count
=
0
;
return
KNOT_EOK
;
}
int
tsig_verify_packet
(
tsig_ctx_t
*
ctx
,
knot_pkt_t
*
packet
)
{
if
(
!
ctx
||
!
packet
)
{
return
KNOT_EINVAL
;
...
...
@@ -89,7 +92,40 @@ int requestor_tsig_verify_packet(requestor_tsig_ctx_t *ctx, knot_pkt_t *packet)
return
KNOT_EOK
;
}
#warning "TODO: TSIG verify invocation."
//return KNOT_ENOTSUP;
if
(
packet
->
tsig_rr
==
NULL
)
{
ctx
->
unsigned_count
+=
1
;
return
KNOT_EOK
;
}
int
ret
=
KNOT_ERROR
;
if
(
ctx
->
last_signed
==
0
)
{
ret
=
knot_tsig_client_check
(
packet
->
tsig_rr
,
packet
->
wire
,
packet
->
size
,
ctx
->
digest
,
ctx
->
digest_size
,
ctx
->
key
,
0
);
}
else
{
ret
=
knot_tsig_client_check_next
(
packet
->
tsig_rr
,
packet
->
wire
,
packet
->
size
,
ctx
->
digest
,
ctx
->
digest_size
,
ctx
->
key
,
ctx
->
last_signed
);
}
if
(
ret
!=
KNOT_EOK
)
{
return
ret
;
}
ret
=
update_ctx_after_verify
(
ctx
,
packet
->
tsig_rr
);
if
(
ret
!=
KNOT_EOK
)
{
return
ret
;
}
return
KNOT_EOK
;
}
unsigned
tsig_unsigned_count
(
tsig_ctx_t
*
ctx
)
{
if
(
!
ctx
)
{
return
-
1
;
}
return
ctx
->
unsigned_count
;
}
src/knot/nameserver/
requestor_
tsig.h
→
src/knot/nameserver/tsig
_ctx
.h
View file @
fff23454
...
...
@@ -21,17 +21,26 @@
#include "libknot/packet/pkt.h"
#include "libknot/rdata/tsig.h"
#include "libknot/tsig-op.h"
typedef
struct
requestor_tsig_ctx
{
#define TSIG_MAX_DIGEST_SIZE 64
typedef
struct
tsig_ctx
{
const
knot_tsig_key_t
*
key
;
uint8_t
*
digest
;
uint8_t
digest
[
TSIG_MAX_DIGEST_SIZE
]
;
size_t
digest_size
;
}
requestor_tsig_ctx_t
;
void
requestor_tsig_init
(
requestor_tsig_ctx_t
*
ctx
,
const
knot_tsig_key_t
*
key
);
uint64_t
last_signed
;
unsigned
unsigned_count
;
}
tsig_ctx_t
;
void
tsig_init
(
tsig_ctx_t
*
ctx
,
const
knot_tsig_key_t
*
key
);
void
requestor_tsig_cleanup
(
requestor_tsig_ctx_t
*
ctx
);
int
tsig_sign_packet
(
tsig_ctx_t
*
ctx
,
knot_pkt_t
*
packet
);
int
requestor_tsig_sign_packet
(
requestor_
tsig_ctx_t
*
ctx
,
knot_pkt_t
*
packet
);
int
tsig_verify_packet
(
tsig_ctx_t
*
ctx
,
knot_pkt_t
*
packet
);
int
requestor_tsig_verify_packet
(
requestor_tsig_ctx_t
*
ctx
,
knot_pkt_t
*
packet
);
/*!
* \brief Get number of unsigned packets since the last signed one.
*/
unsigned
tsig_unsigned_count
(
tsig_ctx_t
*
ctx
);
src/knot/zone/events.c
View file @
fff23454
...
...
@@ -34,6 +34,7 @@
#include "knot/nameserver/update.h"
#include "knot/nameserver/notify.h"
#include "knot/nameserver/requestor.h"
#include "knot/nameserver/tsig_ctx.h"
#include "knot/nameserver/process_answer.h"
/* ------------------------- bootstrap timer logic -------------------------- */
...
...
@@ -108,6 +109,19 @@ static int zone_query_execute(zone_t *zone, uint16_t pkt_type, const conf_iface_
knot_pkt_put
(
query
,
COMPR_HINT_QNAME
,
&
soa_rr
,
0
);
}
/* Answer processing parameters. */
struct
process_answer_param
param
=
{
0
};
param
.
zone
=
zone
;
param
.
query
=
query
;
param
.
remote
=
&
remote
->
addr
;
tsig_init
(
&
param
.
tsig_ctx
,
remote
->
key
);
ret
=
tsig_sign_packet
(
&
param
.
tsig_ctx
,
query
);
if
(
ret
!=
KNOT_EOK
)
{
mp_delete
(
mm
.
ctx
);
return
ret
;
}
/* Create requestor instance. */
struct
requestor
re
;
requestor_init
(
&
re
,
NS_PROC_ANSWER
,
&
mm
);
...
...
@@ -115,13 +129,10 @@ static int zone_query_execute(zone_t *zone, uint16_t pkt_type, const conf_iface_
/* Create a request. */
struct
request
*
req
=
requestor_make
(
&
re
,
remote
,
query
);
if
(
req
==
NULL
)
{
mp_delete
(
mm
.
ctx
);
return
KNOT_ENOMEM
;
}
struct
process_answer_param
param
;
param
.
zone
=
zone
;
param
.
query
=
query
;
param
.
remote
=
&
remote
->
addr
;
requestor_enqueue
(
&
re
,
req
,
&
param
);
/* Send the queries and process responses. */
...
...
@@ -330,7 +341,7 @@ static int event_update(zone_t *zone)
/* Create minimal query data context. */
struct
process_query_param
param
=
{
0
};
param
.
remote
=
&
update
->
remote
->
addr
;
param
.
remote
=
&
update
->
remote
;
struct
query_data
qdata
=
{
0
};
qdata
.
param
=
&
param
;
qdata
.
query
=
update
->
query
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment