summaryrefslogtreecommitdiffstats
path: root/src/kdc
diff options
context:
space:
mode:
authorKen Raeburn <raeburn@mit.edu>2006-06-26 23:47:03 +0000
committerKen Raeburn <raeburn@mit.edu>2006-06-26 23:47:03 +0000
commitb0fcaccdf948c549c71a66f75d897ea25a909f67 (patch)
tree53ed77bdc924ca41a48faf4f18cf651f6c60ad95 /src/kdc
parent509e591a07a9d6f6053db1f2fb38ae37c602aa27 (diff)
downloadkrb5-b0fcaccdf948c549c71a66f75d897ea25a909f67.tar.gz
krb5-b0fcaccdf948c549c71a66f75d897ea25a909f67.tar.xz
krb5-b0fcaccdf948c549c71a66f75d897ea25a909f67.zip
* kdc/network.c (make_toolong_error): New function.
(process_tcp_connection): If the specified length exceeds the internal limit, stop reading and send back a FIELD_TOOLONG error. * tests/dejagnu/krb-standalone/standalone.exp (doit): When testing TCP mode, connect to the KDC and send a length of -1, and check that it sends back a non-empty message. ticket: 3923 tags: pullup git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@18233 dc483132-0cff-0310-8789-dd5450dbe970
Diffstat (limited to 'src/kdc')
-rw-r--r--src/kdc/network.c41
1 files changed, 40 insertions, 1 deletions
diff --git a/src/kdc/network.c b/src/kdc/network.c
index af5e7d036..f7bb958f3 100644
--- a/src/kdc/network.c
+++ b/src/kdc/network.c
@@ -891,6 +891,36 @@ kill_tcp_connection(struct connection *conn)
tcp_data_counter--;
}
+static krb5_error_code
+make_toolong_error (krb5_data **out)
+{
+ krb5_error errpkt;
+ krb5_error_code retval;
+ krb5_data *scratch;
+
+ retval = krb5_us_timeofday(kdc_context, &errpkt.stime, &errpkt.susec);
+ if (retval)
+ return retval;
+ errpkt.error = KRB_ERR_FIELD_TOOLONG;
+ errpkt.server = tgs_server;
+ errpkt.client = NULL;
+ errpkt.text.length = 0;
+ errpkt.text.data = 0;
+ errpkt.e_data.length = 0;
+ errpkt.e_data.data = 0;
+ scratch = malloc(sizeof(*scratch));
+ if (scratch == NULL)
+ return ENOMEM;
+ retval = krb5_mk_error(kdc_context, &errpkt, scratch);
+ if (retval) {
+ free(scratch);
+ return retval;
+ }
+
+ *out = scratch;
+ return 0;
+}
+
static void
process_tcp_connection(struct connection *conn, const char *prog, int selflags)
{
@@ -953,12 +983,20 @@ process_tcp_connection(struct connection *conn, const char *prog, int selflags)
| (p[2] << 8)
| p[3]);
if (conn->u.tcp.msglen > conn->u.tcp.bufsiz - 4) {
+ krb5_error_code err;
/* message too big */
krb5_klog_syslog(LOG_ERR, "TCP client %s wants %lu bytes, cap is %lu",
conn->u.tcp.addrbuf, (unsigned long) conn->u.tcp.msglen,
(unsigned long) conn->u.tcp.bufsiz - 4);
/* XXX Should return an error. */
- goto kill_tcp_connection;
+ err = make_toolong_error (&conn->u.tcp.response);
+ if (err) {
+ krb5_klog_syslog(LOG_ERR,
+ "error constructing KRB_ERR_FIELD_TOOLONG error! %s",
+ error_message(err));
+ goto kill_tcp_connection;
+ }
+ goto have_response;
}
}
} else {
@@ -987,6 +1025,7 @@ process_tcp_connection(struct connection *conn, const char *prog, int selflags)
com_err(prog, err, "while dispatching (tcp)");
goto kill_tcp_connection;
}
+ have_response:
conn->u.tcp.lenbuf[0] = 0xff & (conn->u.tcp.response->length >> 24);
conn->u.tcp.lenbuf[1] = 0xff & (conn->u.tcp.response->length >> 16);
conn->u.tcp.lenbuf[2] = 0xff & (conn->u.tcp.response->length >> 8);