+++ /dev/null
-/* $Id: libauth.c 7500 2006-03-20 01:52:44Z eagle $
-**
-** Common code for authenticators and resolvers.
-**
-** Collects common code to read information from nnrpd that should be done
-** the same for all authenticators, and common code to get information about
-** the incoming connection.
-*/
-
-#include "config.h"
-#include "clibrary.h"
-#include "libinn.h"
-
-#include "libauth.h"
-#include "inn/messages.h"
-
-#define NAMESTR "ClientAuthname: "
-#define PASSSTR "ClientPassword: "
-
-#define CLIHOST "ClientHost: "
-#define CLIIP "ClientIP: "
-#define CLIPORT "ClientPort: "
-#define LOCIP "LocalIP: "
-#define LOCPORT "LocalPort: "
-
-#ifdef HAVE_INET6
-# include <netdb.h>
-#endif
-
-/* Main loop. If res != NULL, expects to get resolver info from nnrpd, and
- writes it into the struct. If auth != NULL, expects to get authentication
- info from nnrpd, and writes it into the struct. */
-
-static bool
-get_connection_info(FILE *stream, struct res_info *res, struct auth_info *auth)
-{
- char buff[SMBUF];
- size_t length;
- char *cip = NULL, *sip = NULL, *cport = NULL, *sport = NULL;
-#ifdef HAVE_INET6
- struct addrinfo *r, hints;
-#else
- struct sockaddr_in *loc_sin, *cli_sin;
-#endif
-
- /* Zero fields first (anything remaining NULL after is missing data) */
- if (res != NULL) {
- res->clienthostname = NULL;
- res->client = NULL;
- res->local = NULL;
- }
- if (auth != NULL) {
- auth->username = NULL;
- auth->password = NULL;
- }
-
- /* Read input from nnrpd a line at a time, stripping \r\n. */
- while (fgets(buff, sizeof(buff), stream) != NULL) {
- length = strlen(buff);
- if (length == 0 || buff[length - 1] != '\n')
- goto error;
- buff[length - 1] = '\0';
- if (length > 1 && buff[length - 2] == '\r')
- buff[length - 2] = '\0';
-
- /* Parse */
- if (strncmp(buff, ".", 2) == 0)
- break;
- else if (auth != NULL && strncmp(buff, NAMESTR, strlen(NAMESTR)) == 0)
- auth->username = xstrdup(buff + strlen(NAMESTR));
- else if (auth != NULL && strncmp(buff, PASSSTR, strlen(PASSSTR)) == 0)
- auth->password = xstrdup(buff + strlen(PASSSTR));
- else if (res != NULL && strncmp(buff, CLIHOST, strlen(CLIHOST)) == 0)
- res->clienthostname = xstrdup(buff + strlen(CLIHOST));
- else if (res != NULL && strncmp(buff, CLIIP, strlen(CLIIP)) == 0)
- cip = xstrdup(buff + strlen(CLIIP));
- else if (res != NULL && strncmp(buff, CLIPORT, strlen(CLIPORT)) == 0)
- cport = xstrdup(buff + strlen(CLIPORT));
- else if (res != NULL && strncmp(buff, LOCIP, strlen(LOCIP)) == 0)
- sip = xstrdup(buff + strlen(LOCIP));
- else if (res != NULL && strncmp(buff, LOCPORT, strlen(LOCPORT)) == 0)
- sport = xstrdup(buff + strlen(LOCPORT));
- else {
- /**** We just ignore excess fields for now ****/
-
- /* warn("libauth: unexpected data from nnrpd: \"%s\"", buff); */
- /* goto error; */
- }
- }
-
- /* If some field is missing, free the rest and error out. */
- if (auth != NULL && (auth->username == NULL || auth->password == NULL)) {
- warn("libauth: requested authenticator data not sent by nnrpd");
- goto error;
- }
- if (res != NULL && (res->clienthostname == NULL || cip == NULL ||
- cport == NULL || sip == NULL || sport == NULL)) {
- warn("libauth: requested resolver data not sent by nnrpd");
- goto error;
- }
-
- /* Generate sockaddrs from IP and port strings */
- if (res != NULL) {
-#ifdef HAVE_INET6
- /* sockaddr_in6 may be overkill for PF_INET case, but oh well */
- res->client = xcalloc(1, sizeof(struct sockaddr_in6));
- res->local = xcalloc(1, sizeof(struct sockaddr_in6));
-
- memset( &hints, 0, sizeof( hints ) );
- hints.ai_flags = AI_NUMERICHOST;
- hints.ai_socktype = SOCK_STREAM;
-
- hints.ai_family = strchr( cip, ':' ) != NULL ? PF_INET6 : PF_INET;
- if( getaddrinfo( cip, cport, &hints, &r ) != 0)
- goto error;
- if( r->ai_addrlen > sizeof(struct sockaddr_in6) )
- goto error;
- memcpy( res->client, r->ai_addr, r->ai_addrlen );
- freeaddrinfo( r );
-
- hints.ai_family = strchr( sip, ':' ) != NULL ? PF_INET6 : PF_INET;
- if( getaddrinfo( sip, sport, &hints, &r ) != 0)
- goto error;
- if( r->ai_addrlen > sizeof(struct sockaddr_in6) )
- goto error;
- memcpy( res->local, r->ai_addr, r->ai_addrlen );
- freeaddrinfo( r );
-#else
- res->client = xcalloc(1, sizeof(struct sockaddr_in));
- res->local = xcalloc(1, sizeof(struct sockaddr_in));
-
- cli_sin = (struct sockaddr_in *)(res->client);
- loc_sin = (struct sockaddr_in *)(res->local);
- cli_sin->sin_family = AF_INET;
- if (!inet_aton(cip, &cli_sin->sin_addr))
- goto error;
- cli_sin->sin_port = htons( atoi(cport) );
-
- loc_sin->sin_family = AF_INET;
- if (!inet_aton(sip, &loc_sin->sin_addr))
- goto error;
- loc_sin->sin_port = htons( atoi(sport) );
-
-# ifdef HAVE_SOCKADDR_LEN
- cli_sin->sin_len = sizeof(struct sockaddr_in);
- loc_sin->sin_len = sizeof(struct sockaddr_in);
-# endif
-#endif
-
- free(sip);
- free(sport);
- free(cip);
- free(cport);
- }
-
- return true;
-
-error:
- if (auth != NULL && auth->username != NULL) free(auth->username);
- if (auth != NULL && auth->password != NULL) free(auth->password);
- if (res != NULL && res->clienthostname != NULL) free(res->clienthostname);
- if (res != NULL && res->client != NULL) free(res->client);
- if (res != NULL && res->local != NULL) free(res->local);
- if (sip != NULL) free(sip);
- if (sport != NULL) free(sport);
- if (cip != NULL) free(cip);
- if (cport != NULL) free(cport);
- return false;
-}
-
-
-/* Wrappers to read information from nnrpd, returning an allocated struct on
- success. */
-
-struct res_info *
-get_res_info(FILE *stream) {
- struct res_info *res = xmalloc(sizeof(struct res_info));
-
- if(get_connection_info(stream, res, NULL))
- return res;
-
- free(res);
- return NULL;
-}
-
-
-struct auth_info *
-get_auth_info(FILE *stream) {
- struct auth_info *auth = xmalloc(sizeof(struct auth_info));
-
- if(get_connection_info(stream, NULL, auth))
- return auth;
-
- free(auth);
- return NULL;
-}
-
-void
-free_res_info(struct res_info *res) {
- if(res == NULL)
- return;
- if(res->client != NULL) free(res->client);
- if(res->local != NULL) free(res->local);
- if(res->clienthostname != NULL) free(res->clienthostname);
- free(res);
-}
-
-void
-free_auth_info(struct auth_info *auth) {
- if(auth == NULL)
- return;
- if(auth->username != NULL) free(auth->username);
- if(auth->password != NULL) free(auth->password);
- free(auth);
-}
-