|
From: | shishi-commit |
Subject: | Fixes. |
Date: | Thu, 18 Dec 2003 11:17:57 +0100 |
Commit from jas | 2003-12-18 11:17 CET |
Fixes.
Module | File name | Revision | |||
---|---|---|---|---|---|
shishi | src/server.c | 1.26 | >>> | 1.27 |
shishi/src/server.c 1.26 >>> 1.27 |
---|
Line 19 |
* */ |
+ /* Note: only use syslog to report errors in this file. */ + |
/* Get Shishid stuff. */ #include "kdc.h" |
+ /* Accept new TCP connection in a new listenspec entry. */ + static void + kdc_accept (struct listenspec *ls) + { + struct listenspec *newls; + + newls = xzalloc (sizeof (*newls)); + newls->next = ls->next; + ls->next = newls; + + newls->bufpos = 0; + newls->type = ls->type; + newls->addrlen = sizeof (newls->addr); + newls->sockfd = accept (ls->sockfd, &newls->addr, &newls->addrlen); + newls->sin = (struct sockaddr_in *) &newls->addr; + asprintf (&newls->str, "%s peer %s", ls->str, + inet_ntoa (newls->sin->sin_addr)); + + syslog (LOG_DEBUG, "Accepted socket %d from socket %d as %s", + newls->sockfd, ls->sockfd, newls->str); + } + |
/* Destroy listenspec element and return pointer to element before the removed element, or NULL if the first element was removed (or the destroyed list element wasn't in the list). */ |
Line 31 |
struct listenspec *tmp; int rc; |
+ syslog (LOG_INFO, "Closing %s socket %d", ls->str, ls->sockfd); + |
if (ls->sockfd) { |
- if (!arg.quiet_flag) - syslog (LOG_INFO, "Closing %s...\n", ls->str); |
rc = close (ls->sockfd); if (rc != 0) |
- syslog (LOG_ERR, "Could not close connection to %s on socket %d", - ls->str, ls->sockfd); |
+ syslog (LOG_ERR, "Close failed to %s on socket %d (%d): %s", + ls->str, ls->sockfd, rc, strerror (rc)); |
} |
+ #ifdef USE_STARTTLS |
if (ls->usetls) { |
- gnutls_bye (ls->session, GNUTLS_SHUT_WR); |
+ do + rc = gnutls_bye (ls->session, GNUTLS_SHUT_RDWR); + while (rc == GNUTLS_E_AGAIN || rc == GNUTLS_E_INTERRUPTED); + + if (rc != GNUTLS_E_SUCCESS) + syslog (LOG_ERR, "TLS terminate failed to %s on socket %d (%d): %s", + ls->str, ls->sockfd, rc, gnutls_strerror (rc)); + |
gnutls_deinit (ls->session); } |
+ #endif |
if (ls->str) free (ls->str); |
Line 60 |
return tmp; } |
+ /* Send string to peer, via UDP/TCP/TLS, reporting any errors. */ + void + kdc_send1 (struct listenspec *ls) + { + ssize_t sent_bytes, read_bytes; + + do + #ifdef USE_STARTTLS + if (ls->usetls) + sent_bytes = gnutls_record_send (ls->session, ls->buf, ls->bufpos); + else + #endif + sent_bytes = sendto (ls->sockfd, ls->buf, ls->bufpos, + 0, &ls->addr, ls->addrlen); + while (sent_bytes == -1 && errno == EAGAIN); + + if (sent_bytes < 0) + syslog (LOG_ERR, "Error writing %d bytes to %s on socket %d: %s", + ls->bufpos, ls->str, ls->sockfd, strerror (errno)); + else if ((size_t) sent_bytes > ls->bufpos) + syslog (LOG_ERR, "Overlong write (%d > %d) to %s on socket %d", + sent_bytes, ls->bufpos); + else if ((size_t) sent_bytes < ls->bufpos) + syslog (LOG_ERR, "Short write (%d < %d) to %s on socket %d", + sent_bytes, ls->bufpos); + } + + /* Format response and send it to peer, via UDP/TCP/TLS, reporting any + errors. */ + static void + kdc_send (struct listenspec *ls) + { + if (ls->usetls) + syslog (LOG_DEBUG, "Sending %d bytes to %s socket %d via TLS", + ls->bufpos, ls->str, ls->sockfd); + else if (ls->type == SOCK_STREAM) + { + uint32_t len = htonl (ls->bufpos) + 4; + + syslog (LOG_DEBUG, "Sending %d bytes to %s socket %d via TCP", + ls->bufpos, ls->str, ls->sockfd); + + if (ls->bufpos + 4 >= sizeof (ls->buf)) + ls->bufpos = sizeof(ls->buf) - 4; + + memmove (ls->buf + 4, ls->buf, ls->bufpos); + memcpy (ls->buf, &len, 4); + ls->bufpos += 4; + } + else + syslog (LOG_DEBUG, "Sending %d bytes to %s socket %d via UDP", + ls->bufpos, ls->str, ls->sockfd); + + kdc_send1 (ls); + + ls->bufpos = 0; + } + + #define STARTTLS_CLIENT_REQUEST "\x70\x00\x00\x01" + #define STARTTLS_SERVER_ACCEPT "\x70\x00\x00\x02" + #define STARTTLS_LEN 4 + + /* Handle the high TCP length bit, currently only used for STARTTLS. */ |
static int kdc_extension (struct listenspec *ls) { |
Line 67 |
int rc; #ifdef USE_STARTTLS |
- if (!ls->usetls && - ls->type == SOCK_STREAM && - ls->bufpos == 4 && - memcmp (ls->buf, "\x70\x00\x00\x01", 4) == 0) |
+ if (!ls->usetls && ls->type == SOCK_STREAM && ls->bufpos == 4 && + memcmp (ls->buf, STARTTLS_CLIENT_REQUEST, STARTTLS_LEN) == 0) |
{ const int kx_prio[] = { GNUTLS_KX_ANON_DH, 0 }; |
- if (!arg.quiet_flag) - syslog (LOG_INFO, "Trying to upgrade to TLS..."); |
+ syslog (LOG_INFO, "Trying STARTTLS"); |
|
- sent_bytes = sendto (ls->sockfd, "\x70\x00\x00\x02", 4, - 0, &ls->addr, ls->addrlen); |
+ memcpy (ls->buf, STARTTLS_SERVER_ACCEPT, STARTTLS_LEN); + ls->bufpos = STARTTLS_LEN; + + kdc_send1 (ls); |
rc = gnutls_init (&ls->session, GNUTLS_SERVER); if (rc != GNUTLS_E_SUCCESS) |
- error (EXIT_FAILURE, 0, "gnutls_init %d", rc); |
+ { + syslog (LOG_ERR, "TLS initialization failed (%d): %s", rc, + gnutls_strerror (rc)); + return -1; + } + |
rc = gnutls_set_default_priority (ls->session); if (rc != GNUTLS_E_SUCCESS) |
- error (EXIT_FAILURE, 0, "gnutls_sdp %d", rc); |
+ { + syslog (LOG_ERR, "TLS failed, gnutls_sdp %d: %s", rc, + gnutls_strerror (rc)); + return -1; + } + |
rc = gnutls_kx_set_priority (ls->session, kx_prio); if (rc != GNUTLS_E_SUCCESS) |
- error (EXIT_FAILURE, 0, "gnutls_ksp %d", rc); |
+ { + syslog (LOG_ERR, "TLS failed, gnutls_ksp %d: %s", rc, + gnutls_strerror (rc)); + return -1; + } + |
rc = gnutls_credentials_set (ls->session, GNUTLS_CRD_ANON, anoncred); if (rc != GNUTLS_E_SUCCESS) |
- error (EXIT_FAILURE, 0, "gnutls_cs %d", rc); |
+ { + syslog (LOG_ERR, "TLS failed, gnutls_cs %d: %s", rc, + gnutls_strerror (rc)); + return -1; + } + |
gnutls_dh_set_prime_bits (ls->session, DH_BITS); gnutls_transport_set_ptr (ls->session, |
- (gnutls_transport_ptr) - ls->sockfd); |
+ (gnutls_transport_ptr) ls->sockfd); |
rc = gnutls_handshake (ls->session); if (rc < 0) { |
- printf ("Handshake has failed %d: %s\n", |
+ syslog (LOG_ERR, "TLS handshake failed (%d): %s\n", |
rc, gnutls_strerror (rc)); return -1; } |
- if (!arg.quiet_flag) - printf ("TLS successful\n"); |
+ syslog (LOG_INFO, "TLS successful"); |
ls->bufpos = 0; ls->usetls = 1; |
Line 117 |
return 0; } |
- static void - kdc_process (struct listenspec *ls) - { - ssize_t sent_bytes, read_bytes; - int rc; - char *p; - size_t plen; - - #ifdef USE_STARTTLS - if (ls->usetls) - { - plen = process (ls->buf, ls->bufpos, &p); - printf ("TLS process %d sending %d\n", ls->bufpos, plen); - } - else - #endif - { - if (ls->type == SOCK_STREAM) - plen = process (ls->buf + 4, ls->bufpos - 4, &p); - else - plen = process (ls->buf, ls->bufpos, &p); - } - - printf ("Process yielded %d bytes\n", plen); - - if (plen <= 0) - { - memcpy (ls->buf, fatal_krberror, fatal_krberror_len); - ls->bufpos = fatal_krberror_len; - } - else - { - memcpy (ls->buf, p, plen); - ls->bufpos = plen; - free (p); - } - } - - static void - kdc_send (struct listenspec *ls) - { - ssize_t sent_bytes, read_bytes; - int rc; - - printf ("Sending %d bytes on socket %d\n", ls->bufpos, ls->sockfd); - - #ifdef USE_STARTTLS - if (ls->usetls) - { - printf ("TLS sending %d\n", ls->bufpos); - - sent_bytes = gnutls_record_send (ls->session, ls->buf, ls->bufpos); - } - else - #endif - { - if (ls->type == SOCK_STREAM) - { - uint32_t len = htonl (ls->bufpos) + 4; - - do - sent_bytes = sendto (ls->sockfd, &len, 4, - 0, &ls->addr, ls->addrlen); - while (sent_bytes == -1 && errno == EAGAIN); - } - - do - sent_bytes = sendto (ls->sockfd, ls->buf, ls->bufpos, - 0, &ls->addr, ls->addrlen); - while (sent_bytes == -1 && errno == EAGAIN); - - printf ("sent %d\n", sent_bytes); - - if (sent_bytes < 0) - perror ("write"); - else if ((size_t) sent_bytes > ls->bufpos) - fprintf (stderr, "wrote %db but buffer only %db", - sent_bytes, ls->bufpos); - else if ((size_t) sent_bytes < ls->bufpos) - fprintf (stderr, - "short write (%db) writing %d bytes\n", - sent_bytes, ls->bufpos); - } - - ls->bufpos = 0; - } - - static int - kdc_ready (struct listenspec *ls) - { - ssize_t sent_bytes, read_bytes; - int rc; - - #ifdef USE_STARTTLS - if (ls->usetls && ls->bufpos > 0) - return 1; - else - #endif - if (ls->type == SOCK_DGRAM) - return 1; - else if (ls->bufpos > 4 && ntohl (*(int *) ls->buf) + 4 == ls->bufpos) - return 1; - - return 0; - } - |
+ /* Read data from peer, reporting any errors. */ |
static int kdc_read (struct listenspec *ls) { |
Line 239 |
if (read_bytes < 0) { if (ls->usetls) |
- error (0, 0, "Corrupted TLS data (%d): %s\n", read_bytes, - gnutls_strerror (read_bytes)); |
+ syslog (LOG_ERR, "Corrupt TLS data from %s on socket %d (%d): %s", + ls->str, ls->sockfd, read_bytes, gnutls_strerror (read_bytes)); |
else |
- error (0, errno, "Error from recvfrom (%d)", read_bytes); |
+ syslog (LOG_ERR, "Error reading from %s on socket %d (%d): %s", + ls->str, ls->sockfd, read_bytes, strerror (read_bytes)); |
return -1; } if (read_bytes == 0 && ls->type == SOCK_STREAM) { |
- if (!arg.quiet_flag) - printf ("Peer %s disconnected\n", ls->str); |
+ syslog (LOG_DEBUG, "Peer %s disconnected on socket %d\n", + ls->str, ls->sockfd); |
return -1; } ls->bufpos += read_bytes; |
- if (!arg.quiet_flag) - printf ("Has %d bytes from %s on socket %d\n", - ls->bufpos, ls->str, ls->sockfd); |
+ syslog (LOG_DEBUG, "Has %d bytes from %s on socket %d\n", + ls->bufpos, ls->str, ls->sockfd); |
return 0; } |
+ /* Have we read an entire request? */ + static int + kdc_ready (struct listenspec *ls) + { + if ((ls->usetls || ls->type == SOCK_DGRAM) && ls->bufpos > 0) + return 1; + else if (ls->bufpos > 4 && ntohl (*(int *) ls->buf) + 4 == ls->bufpos) + return 1; + + return 0; + } + + /* Process a request and store reply in same buffer. */ |
static void |
- kdc_accept (struct listenspec *ls) |
+ kdc_process (struct listenspec *ls) |
{ |
- struct listenspec *newls; |
+ ssize_t sent_bytes, read_bytes; + int rc; + char *p; + size_t plen; |
|
- newls = xzalloc (sizeof (*newls)); - newls->next = ls->next; - ls->next = newls; |
+ syslog (LOG_DEBUG, "Processing %d from %s on socket %d", + ls->bufpos, ls->str, ls->sockfd); |
|
- newls->bufpos = 0; - newls->type = ls->type; - newls->addrlen = sizeof (newls->addr); - newls->sockfd = accept (ls->sockfd, &newls->addr, &newls->addrlen); - newls->sin = (struct sockaddr_in *) &newls->addr; - asprintf (&newls->str, "%s peer %s", ls->str, - inet_ntoa (newls->sin->sin_addr)); |
+ if (ls->usetls || ls->type == SOCK_DGRAM) + plen = process (ls->buf, ls->bufpos, &p); + else + plen = process (ls->buf + 4, ls->bufpos - 4, &p); + + if (plen <= 0) + { + syslog (LOG_ERR, "Processing request failed for %s on socket %d (%d)", + ls->str, ls->sockfd, plen); + memcpy (ls->buf, fatal_krberror, fatal_krberror_len); + ls->bufpos = fatal_krberror_len; + } + else + { + memcpy (ls->buf, p, plen); + ls->bufpos = plen; + free (p); + } |
|
- if (!arg.quiet_flag) - printf ("Accepted socket %d from socket %d as %s\n", - newls->sockfd, ls->sockfd, newls->str); |
+ syslog (LOG_DEBUG, "Have %d bytes for %s on socket %d", + ls->bufpos, ls->str, ls->sockfd); |
} int quit = 0; |
Line 294 |
#define MAX(a,b) ((a) > (b) ? (a) : (b)) |
+ /* Main KDC logic, loop around select and call kdc_accept, kdc_read, + kdc_extension, kdc_process and kdc_send. This return when the + SIGINT or SIGTERM signals are received. */ |
void kdc_loop (void) { |
Line 315 |
{ maxfd = MAX(maxfd, ls->sockfd + 1); if (!arg.quiet_flag) |
- printf ("Listening on socket %d\n", ls->sockfd); |
+ syslog (LOG_DEBUG, "Listening on %s socket %d\n", + ls->str, ls->sockfd); |
FD_SET (ls->sockfd, &readfds); } } |
[Prev in Thread] | Current Thread | [Next in Thread] |