- k5printf(("krb5: conn_read_cancel: releasing event handler for %s\n",
- kc->hostname));
- event_release(kc->ev_read);
- kc->ev_read = NULL;
-}
-
-/*
- * frees a handle allocated by the above
- */
-static void
-krb5_close(
- void * inst)
-{
- struct krb5_handle *kh = inst;
-
- assert(kh != NULL);
-
- k5printf(("krb5: closing handle to %s\n", kh->hostname));
-
- if (kh->ks != NULL) {
- /* This may be null if we get here on an error */
- krb5_recvpkt_cancel(kh);
- security_stream_close(&kh->ks->secstr);
- }
- amfree(kh->hostname);
- amfree(kh);
-}
-
-/*
- * Transmit a packet. Encrypt first.
- */
-static ssize_t
-krb5_sendpkt(
- void * cookie,
- pkt_t * pkt)
-{
- struct krb5_handle *kh = cookie;
- gss_buffer_desc tok;
- int rval;
- unsigned char *buf;
-
- assert(kh != NULL);
- assert(pkt != NULL);
-
- k5printf(("krb5: sendpkt: enter\n"));
-
- if (pkt->body[0] == '\0') {
- tok.length = 1;
- tok.value = alloc(SIZEOF(pkt->type));
- memcpy(tok.value, &pkt->type, sizeof(unsigned char));
- } else {
- tok.length = strlen(pkt->body) + 2;
- tok.value = alloc(tok.length);
- buf = tok.value;
- *buf++ = (unsigned char)pkt->type;
- strncpy((char *)buf, pkt->body, tok.length - 2);
- buf[tok.length - 2] = '\0';
- }
-
- k5printf(("krb5: sendpkt: %s (%d) pkt_t (len %d) contains:\n\n\"%s\"\n\n",
- pkt_type2str(pkt->type), pkt->type, strlen(pkt->body), pkt->body));
-
- rval = krb5_stream_write(kh->ks, tok.value, tok.length);
- if (rval < 0)
- security_seterror(&kh->sech, security_stream_geterror(&kh->ks->secstr));
- /*@ignore@*/
- amfree(tok.value);
- /*@end@*/
- return (rval);
-}
-
-/*
- * Set up to receive a packet asyncronously, and call back when
- * it has been read.
- */
-static void
-krb5_recvpkt(
- void * cookie,
- void (*fn)(void *, pkt_t *, security_status_t),
- void * arg,
- int timeout)
-{
- struct krb5_handle *kh = cookie;
-
- assert(kh != NULL);
-
- k5printf(("krb5: recvpkt registered for %s\n", kh->hostname));
-
- /*
- * Reset any pending timeout on this handle
- */
- if (kh->ev_timeout != NULL)
- event_release(kh->ev_timeout);
-
- /*
- * Negative timeouts mean no timeout
- */
- if (timeout < 0)
- kh->ev_timeout = NULL;
- else
- kh->ev_timeout = event_register((event_id_t)timeout, EV_TIME,
- recvpkt_timeout, kh);
-
- kh->fn.recvpkt = fn;
- kh->arg = arg;
- krb5_stream_read(kh->ks, recvpkt_callback, kh);
-}
-
-/*
- * Remove a async receive request from the queue
- */
-static void
-krb5_recvpkt_cancel(
- void * cookie)
-{
- struct krb5_handle *kh = cookie;
-
- k5printf(("krb5: cancelling recvpkt for %s\n", kh->hostname));
-
- assert(kh != NULL);
-
- krb5_stream_read_cancel(kh->ks);
- if (kh->ev_timeout != NULL) {
- event_release(kh->ev_timeout);
- kh->ev_timeout = NULL;
- }
-}
-
-/*
- * This is called when a handle is woken up because data read off of the
- * net is for it.
- */
-static void
-recvpkt_callback(
- void *cookie,
- void *buf,
- ssize_t bufsize)
-{
- pkt_t pkt;
- struct krb5_handle *kh = cookie;
-
- assert(kh != NULL);
-
- /*
- * We need to cancel the recvpkt request before calling
- * the callback because the callback may reschedule us.
- */
- krb5_recvpkt_cancel(kh);
-
- switch (bufsize) {
- case 0:
- security_seterror(&kh->sech,
- "EOF on read from %s", kh->hostname);
- (*kh->fn.recvpkt)(kh->arg, NULL, S_ERROR);
- return;
- case -1:
- security_seterror(&kh->sech, security_stream_geterror(&kh->ks->secstr));
- (*kh->fn.recvpkt)(kh->arg, NULL, S_ERROR);
- return;
- default:
- parse_pkt(&pkt, buf, (size_t)bufsize);
- k5printf(("krb5: received %s pkt (%d) from %s, contains:\n\n\"%s\"\n\n",
- pkt_type2str(pkt.type), pkt.type, kh->hostname, pkt.body));
- (*kh->fn.recvpkt)(kh->arg, &pkt, S_OK);