From: Ken Raeburn Date: Mon, 26 Jun 2006 23:47:03 +0000 (+0000) Subject: * kdc/network.c (make_toolong_error): New function. X-Git-Tag: krb5-1.6-alpha1~260 X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=b0fcaccdf948c549c71a66f75d897ea25a909f67;p=krb5.git * 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 --- 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); diff --git a/src/tests/dejagnu/krb-standalone/standalone.exp b/src/tests/dejagnu/krb-standalone/standalone.exp index dbe9b950c..554906e44 100644 --- a/src/tests/dejagnu/krb-standalone/standalone.exp +++ b/src/tests/dejagnu/krb-standalone/standalone.exp @@ -31,6 +31,8 @@ proc doit { } { global spawn_id global supported_enctypes global KRBIV + global portbase + global mode # Start up the kerberos and kadmind daemons. if ![start_kerberos_daemons 1] { @@ -143,6 +145,36 @@ proc doit { } { pass "kadmin.local correct high kvno" } } + + if { $mode == "tcp" } { + set response {} + set got_response 0 + set kdcsock "" + catch { + send_log "connecting to $hostname [expr 3 + $portbase]\n" + set kdcsock [socket $hostname [expr 3 + $portbase]] + fconfigure $kdcsock -encoding binary -blocking 0 -buffering none + puts -nonewline $kdcsock [binary format H* ffffffff] + # XXX + sleep 3 + set response [read $kdcsock] + set got_response 1 + } msg + if [string length $kdcsock] { catch "close $kdcsock" } + if $got_response { +# send_log [list sent length -1, got back $response] +# send_log "\n" + if [string length $response]>10 { + pass "too-long TCP request" + } else { + send_log "response too short\n" + fail "too-long TCP request" + } + } else { + send_log "too-long connect/exchange failure: $msg\n" + fail "too-long TCP request" + } + } } set status [catch doit msg]