LocalNet implemented

git-svn-id: file:///var/lib/svn/clamav-devel/branches/milter-v2.0@4498 77e5149b-7576-45b1-b177-96237e5ba77b
remotes/push_mirror/0.95
aCaB 17 years ago
parent c8dec3e372
commit 5c832d5edf
  1. 2
      clamav-milter/clamav-milter.c
  2. 47
      clamav-milter/clamfi.c
  3. 1
      clamav-milter/clamfi.h
  4. 62
      clamav-milter/netcode.c
  5. 6
      clamav-milter/netcode.h

@ -48,7 +48,7 @@ struct smfiDesc descr = {
"ClamAV", /* filter name */
SMFI_VERSION, /* milter version */
SMFIF_ADDHDRS|SMFIF_ADDRCPT, /* flags */
NULL, /* connection info filter */
clamfi_connect, /* connection info filter */
NULL, /* SMTP HELO command filter */
NULL, /* envelope sender filter */
NULL, /* envelope recipient filter */

@ -104,20 +104,15 @@ sfsistat clamfi_header(SMFICTX *ctx, char *headerf, char *headerv) {
struct CLAMFI *cf;
sfsistat ret;
if(!(cf = (struct CLAMFI *)smfi_getpriv(ctx))) {
cf = (struct CLAMFI *)malloc(sizeof(*cf));
if(!cf) {
logg("!Failed to allocate CLAMFI struct\n");
return SMFIS_TEMPFAIL;
}
cf->totsz = 0;
cf->bufsz = 0;
if(!(cf = (struct CLAMFI *)smfi_getpriv(ctx)))
return SMFIS_CONTINUE; /* whatever */
if(!cf->totsz) {
if(nc_connect_rand(&cf->main, &cf->alt, &cf->local)) {
logg("!Failed to initiate streaming/fdpassing\n");
free(cf);
return SMFIS_TEMPFAIL;
}
smfi_setpriv(ctx, (void *)cf);
if((ret = sendchunk(cf, (unsigned char *)"From clamav-milter\n", 19, ctx)) != SMFIS_CONTINUE)
return ret;
}
@ -206,6 +201,40 @@ sfsistat clamfi_eom(SMFICTX *ctx) {
return ret;
}
sfsistat clamfi_connect(SMFICTX *ctx, char *hostname, _SOCK_ADDR *hostaddr) {
struct CLAMFI *cf;
while(1) {
/* Postfix doesn't seem to honor passing a NULL hostaddr and hostname
set to "localhost" for non-smtp messages (they still appear as SMTP
messages from 127.0.0.1). Here's a small workaround. */
if(hostaddr) {
if(islocalnet_sock(hostaddr)) {
logg("*Skipping scan for %s (in LocalNet)\n", hostname);
return SMFIS_ACCEPT;
}
break;
}
if(!strcasecmp(hostname, "localhost"))
hostname = NULL;
if(islocalnet_name(hostname)) {
logg("*Skipping scan for %s (in LocalNet)\n", hostname ? hostname : "local");
return SMFIS_ACCEPT;
}
break;
}
if(!(cf = (struct CLAMFI *)malloc(sizeof(*cf)))) {
logg("!Failed to allocate CLAMFI struct\n");
return SMFIS_TEMPFAIL;
}
cf->totsz = 0;
cf->bufsz = 0;
smfi_setpriv(ctx, (void *)cf);
return SMFIS_CONTINUE;
}
/*
* Local Variables:
* mode: c

@ -8,4 +8,5 @@ uint64_t maxfilesize;
sfsistat clamfi_body(SMFICTX *ctx, unsigned char *bodyp, size_t len);
sfsistat clamfi_eom(SMFICTX *ctx);
sfsistat clamfi_header(SMFICTX *ctx, char *headerf, char *headerv);
sfsistat clamfi_connect(SMFICTX *ctx, char *hostname, _SOCK_ADDR *hostaddr);
#endif

@ -338,10 +338,11 @@ int nc_connect_rand(int *main, int *alt, int *local) {
return 0;
}
int resolve(char *name, uint32_t *family, uint32_t *host) {
struct addrinfo hints, *res;
if(!strcasecmp("local", name)) {
if(!name) {
/* l->basehost[0] = l->basehost[1] = l->basehost[2] = l->basehost[3] = 0; DONT BOTHER*/
*family = NON_SMTP;
return 0;
@ -430,15 +431,10 @@ struct LOCALNET *localnet(char *name, char *mask) {
}
int islocalnet(char *name) {
uint32_t host[4], family;
static int islocalnet(uint32_t family, uint32_t *host) {
struct LOCALNET* l = lnet;
if(!l) return 0;
if(resolve(name, &family, host)) {
logg("^Cannot resolv %s\n", name);
return 0;
}
while(l) {
if(
(l->family == family) &&
@ -450,29 +446,73 @@ int islocalnet(char *name) {
return 0;
}
int islocalnet_name(char *name) {
uint32_t host[4], family;
if(!lnet) return 0;
if(resolve(name, &family, host)) {
logg("^Cannot resolv %s\n", name);
return 0;
}
return islocalnet(family, host);
}
int islocalnet_sock(struct sockaddr *sa) {
uint32_t host[4], family;
if(!lnet) return 0;
if(sa->sa_family == AF_INET) {
struct sockaddr_in *sa4 = (struct sockaddr_in *)sa;
family = INET_HOST;
host[0] = htonl(sa4->sin_addr.s_addr);
} else if(sa->sa_family == AF_INET6) {
struct sockaddr_in6 *sa6 = (struct sockaddr_in6 *)sa;
unsigned int i, j;
uint32_t u = 0;
family = INET6_HOST;
for(i=0, j=0; i<16; i++) {
u += (sa6->sin6_addr.s6_addr[i] << (8*j));
if(++j == 4) {
host[i>>2] = u;
j = u = 0;
}
}
} else return 0;
return islocalnet(family, host);
}
void localnets_free(void) {
while(lnet) {
struct LOCALNET *l = lnet->next;
free(lnet);
lnet = l;
}
}
int localnets_init(struct cfgstruct *copt) {
const struct cfgstruct *cpt;
if((cpt = cfgopt(copt, "LocalNet"))->enabled) {
while(cpt) {
char *lnet = cpt->strarg;
char *lnetname = cpt->strarg;
struct LOCALNET *l;
char *mask = strrchr(lnet, '/');
char *mask = strrchr(lnetname, '/');
if(mask) {
*mask='\0';
mask++;
}
if((l = localnet(lnet, mask)) == NULL) {
if(!strcasecmp(lnetname, "local")) lnetname = NULL;
if((l = localnet(lnetname, mask)) == NULL) {
localnets_free();
return 1;
}

@ -1,6 +1,9 @@
#ifndef _NETCODE_H
#define _NETCODE_H
#include <sys/types.h>
#include <sys/socket.h>
#include "shared/cfgparser.h"
#include "connpool.h"
@ -12,7 +15,8 @@ int nc_sendmsg(int s, int fd);
int nc_connect_entry(struct CP_ENTRY *cpe);
int localnets_init(struct cfgstruct *copt);
void localnets_free(void);
int islocalnet(char *name);
int islocalnet_name(char *name);
int islocalnet_sock(struct sockaddr *sa);
extern long readtimeout;

Loading…
Cancel
Save