Main Page | Class List | Directories | File List | Class Members | File Members

libspamc.h File Reference

#include <stdio.h>
#include <stdarg.h>
#include <sys/types.h>
#include <netdb.h>
#include <sys/socket.h>
#include <netinet/in.h>

Go to the source code of this file.

Classes

struct  message
struct  transport

Defines

#define LIBSPAMC_H   1
#define EX_OK   0
#define EX_USAGE   64
#define EX_DATAERR   65
#define EX_NOINPUT   66
#define EX_NOUSER   67
#define EX_NOHOST   68
#define EX_UNAVAILABLE   69
#define EX_SOFTWARE   70
#define EX_OSERR   71
#define EX_OSFILE   72
#define EX_CANTCREAT   73
#define EX_IOERR   74
#define EX_TEMPFAIL   75
#define EX_PROTOCOL   76
#define EX_NOPERM   77
#define EX_CONFIG   78
#define STDIN_FILENO   0
#define STDOUT_FILENO   1
#define LOG_EMERG   0
#define LOG_ALERT   1
#define LOG_CRIT   2
#define LOG_ERR   3
#define LOG_WARNING   4
#define LOG_NOTICE   5
#define LOG_INFO   6
#define LOG_DEBUG   7
#define EX_NOTSPAM   0
#define EX_ISSPAM   1
#define EX_TOOBIG   866
#define SPAMC_MODE_MASK   1
#define SPAMC_RAW_MODE   0
#define SPAMC_BSMTP_MODE   1
#define SPAMC_USE_SSL   (1<<27)
#define SPAMC_SAFE_FALLBACK   (1<<28)
#define SPAMC_CHECK_ONLY   (1<<29)
#define SPAMC_REPORT   (1<<26)
#define SPAMC_REPORT_IFSPAM   (1<<25)
#define SPAMC_SYMBOLS   (1<<24)
#define SPAMC_RANDOMIZE_HOSTS   (1<<23)
#define SPAMC_LOG_TO_STDERR   (1<<22)
#define SPAMC_LEARN   (1<<21)
#define SPAMC_REPORT_MSG   (1<<20)
#define SPAMC_PING   (1<<19)
#define SPAMC_SSLV2   (1<<18)
#define SPAMC_SSLV3   (1<<17)
#define SPAMC_USE_ZLIB   (1<<16)
#define SPAMC_HEADERS   (1<<15)
#define SPAMC_MESSAGE_CLASS_SPAM   1
#define SPAMC_MESSAGE_CLASS_HAM   2
#define SPAMC_SET_LOCAL   1
#define SPAMC_SET_REMOTE   2
#define SPAMC_REMOVE_LOCAL   4
#define SPAMC_REMOVE_REMOTE   8
#define SPAMC_MAX_MESSAGE_LEN   (256 * 1024 * 1024)
#define TRANSPORT_LOCALHOST   0x01
#define TRANSPORT_TCP   0x02
#define TRANSPORT_UNIX   0x03
#define TRANSPORT_MAX_HOSTS   256

Enumerations

enum  message_type_t {
  MESSAGE_NONE, MESSAGE_ERROR, MESSAGE_RAW, MESSAGE_BSMTP,
  MAX_MESSAGE_TYPE
}

Functions

void transport_init (struct transport *tp)
int transport_setup (struct transport *tp, int flags)
int message_read (int in_fd, int flags, struct message *m)
long message_write (int out_fd, struct message *m)
int message_filter (struct transport *tp, const char *username, int flags, struct message *m)
int message_tell (struct transport *tp, const char *username, int flags, struct message *m, int msg_class, unsigned int tellflags, unsigned int *didtellflags)
void message_dump (int in_fd, int out_fd, struct message *m)
int message_process (struct transport *trans, char *username, int max_size, int in_fd, int out_fd, const int flags)
void message_cleanup (struct message *m)
int process_message (struct transport *tp, char *username, int max_size, int in_fd, int out_fd, const int check_only, const int safe_fallback)
void libspamc_log (int flags, int level, char *msg,...)


Define Documentation

#define EX_CANTCREAT   73
 

Definition at line 62 of file libspamc.h.

#define EX_CONFIG   78
 

Definition at line 67 of file libspamc.h.

Referenced by combine_args().

#define EX_DATAERR   65
 

Definition at line 54 of file libspamc.h.

Referenced by _message_read_bsmtp(), message_filter(), and message_tell().

#define EX_IOERR   74
 

Definition at line 63 of file libspamc.h.

Referenced by _message_read_bsmtp(), _message_read_raw(), and _spamc_read_full_line().

#define EX_ISSPAM   1
 

Definition at line 85 of file libspamc.h.

Referenced by _handle_spamd_header(), and message_write().

#define EX_NOHOST   68
 

Definition at line 57 of file libspamc.h.

Referenced by main(), and transport_setup().

#define EX_NOINPUT   66
 

Definition at line 55 of file libspamc.h.

#define EX_NOPERM   77
 

Definition at line 66 of file libspamc.h.

Referenced by _opensocket(), and _translate_connect_errno().

#define EX_NOTSPAM   0
 

Definition at line 84 of file libspamc.h.

Referenced by _handle_spamd_header(), get_current_user(), message_filter(), message_process(), and message_write().

#define EX_NOUSER   67
 

Definition at line 56 of file libspamc.h.

#define EX_OK   0
 

Definition at line 52 of file libspamc.h.

Referenced by _append_original_body(), _handle_spamd_header(), _message_read_bsmtp(), _message_read_raw(), _spamc_read_full_line(), _try_to_connect_tcp(), _try_to_connect_unix(), _zlib_compress(), combine_args(), get_current_user(), main(), message_filter(), message_process(), message_read(), message_tell(), read_args(), and transport_setup().

#define EX_OSERR   71
 

Definition at line 60 of file libspamc.h.

Referenced by _message_read_bsmtp(), _message_read_raw(), _opensocket(), _try_to_connect_unix(), _zlib_compress(), check_malloc(), get_current_user(), get_output_fd(), message_filter(), message_read(), message_tell(), read_args(), and transport_setup().

#define EX_OSFILE   72
 

Definition at line 61 of file libspamc.h.

#define EX_PROTOCOL   76
 

Definition at line 65 of file libspamc.h.

Referenced by _handle_spamd_header(), message_filter(), and message_tell().

#define EX_SOFTWARE   70
 

Definition at line 59 of file libspamc.h.

Referenced by _append_original_body(), _message_read_bsmtp(), _opensocket(), _translate_connect_errno(), _zlib_compress(), main(), message_filter(), message_process(), and message_tell().

#define EX_TEMPFAIL   75
 

Definition at line 64 of file libspamc.h.

Referenced by main(), read_args(), and transport_setup().

#define EX_TOOBIG   866
 

Definition at line 86 of file libspamc.h.

Referenced by _clear_message(), _message_read_bsmtp(), _message_read_raw(), _spamc_read_full_line(), main(), message_filter(), message_process(), and message_tell().

#define EX_UNAVAILABLE   69
 

Definition at line 58 of file libspamc.h.

Referenced by _translate_connect_errno().

#define EX_USAGE   64
 

Definition at line 53 of file libspamc.h.

Referenced by message_read(), and read_args().

#define LIBSPAMC_H   1
 

Definition at line 19 of file libspamc.h.

#define LOG_ALERT   1
 

Definition at line 74 of file libspamc.h.

#define LOG_CRIT   2
 

Definition at line 75 of file libspamc.h.

Referenced by get_output_fd().

#define LOG_DEBUG   7
 

Definition at line 80 of file libspamc.h.

Referenced by _try_to_connect_tcp(), and transport_setup().

#define LOG_EMERG   0
 

Definition at line 73 of file libspamc.h.

#define LOG_ERR   3
 

Definition at line 76 of file libspamc.h.

Referenced by _append_original_body(), _handle_spamd_header(), _message_read_raw(), _opensocket(), _spamc_read_full_line(), _try_to_connect_tcp(), _try_to_connect_unix(), _zlib_compress(), check_malloc(), get_output_fd(), message_dump(), message_filter(), message_read(), message_tell(), message_write(), read_args(), and transport_setup().

#define LOG_INFO   6
 

Definition at line 79 of file libspamc.h.

#define LOG_NOTICE   5
 

Definition at line 78 of file libspamc.h.

Referenced by transport_setup().

#define LOG_WARNING   4
 

Definition at line 77 of file libspamc.h.

#define SPAMC_BSMTP_MODE   1
 

Definition at line 91 of file libspamc.h.

Referenced by message_read(), and read_args().

#define SPAMC_CHECK_ONLY   (1<<29)
 

Definition at line 95 of file libspamc.h.

Referenced by _handle_spamd_header(), get_current_user(), main(), message_filter(), message_process(), message_write(), process_message(), and read_args().

#define SPAMC_HEADERS   (1<<15)
 

Definition at line 129 of file libspamc.h.

Referenced by message_filter(), and read_args().

#define SPAMC_LEARN   (1<<21)
 

Definition at line 111 of file libspamc.h.

Referenced by main(), and read_args().

#define SPAMC_LOG_TO_STDERR   (1<<22)
 

Definition at line 108 of file libspamc.h.

Referenced by libspamc_log(), and read_args().

#define SPAMC_MAX_MESSAGE_LEN   (256 * 1024 * 1024)
 

Definition at line 140 of file libspamc.h.

Referenced by message_filter(), message_tell(), and read_args().

#define SPAMC_MESSAGE_CLASS_HAM   2
 

Definition at line 132 of file libspamc.h.

Referenced by main().

#define SPAMC_MESSAGE_CLASS_SPAM   1
 

Definition at line 131 of file libspamc.h.

Referenced by main(), and message_tell().

#define SPAMC_MODE_MASK   1
 

Definition at line 89 of file libspamc.h.

Referenced by message_read(), and read_args().

#define SPAMC_PING   (1<<19)
 

Definition at line 117 of file libspamc.h.

Referenced by main(), message_filter(), message_read(), message_write(), and read_args().

#define SPAMC_RANDOMIZE_HOSTS   (1<<23)
 

Definition at line 105 of file libspamc.h.

Referenced by main(), read_args(), and transport_setup().

#define SPAMC_RAW_MODE   0
 

Definition at line 90 of file libspamc.h.

Referenced by message_read(), and process_message().

#define SPAMC_REMOVE_LOCAL   4
 

Definition at line 137 of file libspamc.h.

Referenced by _handle_spamd_header(), main(), and message_tell().

#define SPAMC_REMOVE_REMOTE   8
 

Definition at line 138 of file libspamc.h.

Referenced by _handle_spamd_header(), main(), and message_tell().

#define SPAMC_REPORT   (1<<26)
 

Definition at line 98 of file libspamc.h.

Referenced by _handle_spamd_header(), main(), message_filter(), and read_args().

#define SPAMC_REPORT_IFSPAM   (1<<25)
 

Definition at line 99 of file libspamc.h.

Referenced by _handle_spamd_header(), main(), message_filter(), and read_args().

#define SPAMC_REPORT_MSG   (1<<20)
 

Definition at line 114 of file libspamc.h.

Referenced by main(), and read_args().

#define SPAMC_SAFE_FALLBACK   (1<<28)
 

Definition at line 94 of file libspamc.h.

Referenced by main(), process_message(), read_args(), and transport_setup().

#define SPAMC_SET_LOCAL   1
 

Definition at line 134 of file libspamc.h.

Referenced by _handle_spamd_header(), main(), and message_tell().

#define SPAMC_SET_REMOTE   2
 

Definition at line 135 of file libspamc.h.

Referenced by _handle_spamd_header(), main(), and message_tell().

#define SPAMC_SSLV2   (1<<18)
 

Definition at line 122 of file libspamc.h.

Referenced by message_filter(), and read_args().

#define SPAMC_SSLV3   (1<<17)
 

Definition at line 123 of file libspamc.h.

Referenced by message_filter(), and read_args().

#define SPAMC_SYMBOLS   (1<<24)
 

Definition at line 102 of file libspamc.h.

Referenced by main(), message_filter(), and read_args().

#define SPAMC_USE_SSL   (1<<27)
 

Definition at line 93 of file libspamc.h.

Referenced by _spamc_read_full_line(), message_filter(), message_tell(), and read_args().

#define SPAMC_USE_ZLIB   (1<<16)
 

Definition at line 126 of file libspamc.h.

Referenced by message_filter(), and read_args().

#define STDIN_FILENO   0
 

Definition at line 69 of file libspamc.h.

Referenced by get_output_fd(), and main().

#define STDOUT_FILENO   1
 

Definition at line 70 of file libspamc.h.

Referenced by get_output_fd(), and main().

#define TRANSPORT_LOCALHOST   0x01
 

Definition at line 210 of file libspamc.h.

Referenced by transport_init(), and transport_setup().

#define TRANSPORT_MAX_HOSTS   256
 

Definition at line 214 of file libspamc.h.

Referenced by transport_setup().

#define TRANSPORT_TCP   0x02
 

Definition at line 211 of file libspamc.h.

Referenced by read_args(), and transport_setup().

#define TRANSPORT_UNIX   0x03
 

Definition at line 212 of file libspamc.h.

Referenced by read_args(), and transport_setup().


Enumeration Type Documentation

enum message_type_t
 

Enumerator:
MESSAGE_NONE 
MESSAGE_ERROR 
MESSAGE_RAW 
MESSAGE_BSMTP 
MAX_MESSAGE_TYPE 

Definition at line 143 of file libspamc.h.

00144 {
00145     MESSAGE_NONE,
00146     MESSAGE_ERROR,
00147     MESSAGE_RAW,
00148     MESSAGE_BSMTP,
00149     MAX_MESSAGE_TYPE
00150 } message_type_t;


Function Documentation

void libspamc_log int  flags,
int  level,
char *  msg,
  ...
 

Definition at line 2031 of file libspamc.c.

References LOG_BUFSIZ, and SPAMC_LOG_TO_STDERR.

Referenced by _append_original_body(), _handle_spamd_header(), _message_read_raw(), _opensocket(), _spamc_read_full_line(), _try_to_connect_tcp(), _try_to_connect_unix(), _zlib_compress(), check_malloc(), get_output_fd(), message_dump(), message_filter(), message_read(), message_tell(), message_write(), read_args(), and transport_setup().

02032 {
02033     va_list ap;
02034     char buf[LOG_BUFSIZ+1];
02035     int len = 0;
02036 
02037     va_start(ap, msg);
02038 
02039     if ((flags & SPAMC_LOG_TO_STDERR) != 0) {
02040         /* create a log-line buffer */
02041         len = snprintf(buf, LOG_BUFSIZ, "spamc: ");
02042         len += vsnprintf(buf+len, LOG_BUFSIZ-len, msg, ap);
02043 
02044         /* avoid buffer overflow */
02045         if (len > (LOG_BUFSIZ-2)) { len = (LOG_BUFSIZ-3); }
02046 
02047         len += snprintf(buf+len, LOG_BUFSIZ-len, "\n");
02048         buf[LOG_BUFSIZ] = '\0';     /* ensure termination */
02049         (void) write (2, buf, len);
02050 
02051     } else {
02052         vsnprintf(buf, LOG_BUFSIZ, msg, ap);
02053         buf[LOG_BUFSIZ] = '\0';     /* ensure termination */
02054 #ifndef _WIN32
02055         syslog (level, "%s", buf);
02056 #else
02057         (void) level;  /* not used. suppress compiler warning */
02058         fprintf (stderr, "%s\n", buf);
02059 #endif
02060     }
02061 
02062     va_end(ap);
02063 }

void message_cleanup struct message m  ) 
 

Definition at line 1693 of file libspamc.c.

References _clear_message(), message::outbuf, message::priv, and message::raw.

Referenced by main(), and message_process().

01694 {
01695     assert(m != NULL);
01696     if (m->outbuf != NULL)
01697         free(m->outbuf);
01698     if (m->raw != NULL)
01699         free(m->raw);
01700     if (m->priv != NULL)
01701         free(m->priv);
01702     _clear_message(m);
01703 }

void message_dump int  in_fd,
int  out_fd,
struct message m
 

Definition at line 841 of file libspamc.c.

References libspamc_private_message::flags, full_read(), full_write(), libspamc_log(), LOG_ERR, MESSAGE_NONE, message_write(), message::priv, and message::type.

Referenced by main(), and message_process().

00842 {
00843     char buf[8196];
00844     int bytes;
00845 
00846     if (m != NULL && m->type != MESSAGE_NONE) {
00847         message_write(out_fd, m);
00848     }
00849     while ((bytes = full_read(in_fd, 1, buf, 8192, 8192)) > 0) {
00850         if (bytes != full_write(out_fd, 1, buf, bytes)) {
00851             libspamc_log(m->priv->flags, LOG_ERR, "oops! message_dump of %d returned different",
00852                    bytes);
00853         }
00854     }
00855 }

int message_filter struct transport tp,
const char *  username,
int  flags,
struct message m
 

Definition at line 1144 of file libspamc.c.

References _append_original_body(), _handle_spamd_header(), _locale_safe_string_to_float(), _spamc_read_full_line(), _try_to_connect_tcp(), _try_to_connect_unix(), _use_msg_for_out(), _zlib_compress(), libspamc_private_message::alloced_size, closesocket, message::content_length, EX_DATAERR, EX_NOTSPAM, EX_OK, EX_OSERR, EX_PROTOCOL, EX_SOFTWARE, EX_TOOBIG, EXPANSION_ALLOWANCE, full_read(), full_read_ssl(), full_write(), message::is_spam, libspamc_log(), libspamc_timeout, LOG_ERR, message::max_len, message::msg, message::msg_len, message::out, message::out_len, message::outbuf, message::priv, PROTOCOL_VERSION, message::score, SHUT_RD, SHUT_WR, transport::socketpath, SPAMC_CHECK_ONLY, SPAMC_HEADERS, SPAMC_MAX_MESSAGE_LEN, SPAMC_PING, SPAMC_REPORT, SPAMC_REPORT_IFSPAM, SPAMC_SSLV2, SPAMC_SSLV3, SPAMC_SYMBOLS, SPAMC_USE_SSL, SPAMC_USE_ZLIB, message::threshold, message::timeout, and UNUSED_VARIABLE.

Referenced by main(), and message_process().

01146 {
01147     char buf[8192];
01148     size_t bufsiz = (sizeof(buf) / sizeof(*buf)) - 4; /* bit of breathing room */
01149     size_t len;
01150     int sock = -1;
01151     int rc;
01152     char versbuf[20];
01153     float version;
01154     int response;
01155     int failureval;
01156     unsigned int throwaway;
01157     SSL_CTX *ctx = NULL;
01158     SSL *ssl = NULL;
01159     SSL_METHOD *meth;
01160     char zlib_on = 0;
01161     unsigned char *zlib_buf = NULL;
01162     int zlib_bufsiz = 0;
01163     unsigned char *towrite_buf;
01164     int towrite_len;
01165 
01166     assert(tp != NULL);
01167     assert(m != NULL);
01168 
01169     if ((flags & SPAMC_USE_ZLIB) != 0) {
01170       zlib_on = 1;
01171     }
01172 
01173     if (flags & SPAMC_USE_SSL) {
01174 #ifdef SPAMC_SSL
01175         SSLeay_add_ssl_algorithms();
01176         if ((flags & SPAMC_SSLV2) && (flags & SPAMC_SSLV3)) {
01177           meth = TLSv1_client_method(); /* both flag bits on means use TLSv1 */
01178         } else if (flags & SPAMC_SSLV2) {
01179           meth = SSLv2_client_method();
01180         } else if (flags & SPAMC_SSLV3) {
01181           meth = SSLv3_client_method();
01182         } else {
01183           meth = SSLv23_client_method(); /* no flag bits, default SSLv23 */
01184         }
01185         SSL_load_error_strings();
01186         ctx = SSL_CTX_new(meth);
01187 #else
01188         UNUSED_VARIABLE(ssl);
01189         UNUSED_VARIABLE(meth);
01190         UNUSED_VARIABLE(ctx);
01191         libspamc_log(flags, LOG_ERR, "spamc not built with SSL support");
01192         return EX_SOFTWARE;
01193 #endif
01194     }
01195 
01196     m->is_spam = EX_TOOBIG;
01197     m->priv->alloced_size = m->max_len + EXPANSION_ALLOWANCE + 1;
01198     if ((m->outbuf = malloc(m->priv->alloced_size)) == NULL) {
01199         failureval = EX_OSERR;
01200         goto failure;
01201     }
01202     m->out = m->outbuf;
01203     m->out_len = 0;
01204 
01205     /* Build spamd protocol header */
01206     if (flags & SPAMC_CHECK_ONLY)
01207         strcpy(buf, "CHECK ");
01208     else if (flags & SPAMC_REPORT_IFSPAM)
01209         strcpy(buf, "REPORT_IFSPAM ");
01210     else if (flags & SPAMC_REPORT)
01211         strcpy(buf, "REPORT ");
01212     else if (flags & SPAMC_SYMBOLS)
01213         strcpy(buf, "SYMBOLS ");
01214     else if (flags & SPAMC_PING)
01215         strcpy(buf, "PING ");
01216     else if (flags & SPAMC_HEADERS)
01217         strcpy(buf, "HEADERS ");
01218     else
01219         strcpy(buf, "PROCESS ");
01220 
01221     len = strlen(buf);
01222     if (len + strlen(PROTOCOL_VERSION) + 2 >= bufsiz) {
01223         _use_msg_for_out(m);
01224         return EX_OSERR;
01225     }
01226 
01227     strcat(buf, PROTOCOL_VERSION);
01228     strcat(buf, "\r\n");
01229     len = strlen(buf);
01230 
01231     towrite_buf = (unsigned char *) m->msg;
01232     towrite_len = (int) m->msg_len;
01233     if (zlib_on) {
01234         if (_zlib_compress(m->msg, m->msg_len, &zlib_buf, &zlib_bufsiz, flags) != EX_OK)
01235         {
01236             return EX_OSERR;
01237         }
01238         towrite_buf = zlib_buf;
01239         towrite_len = zlib_bufsiz;
01240     }
01241 
01242     if (!(flags & SPAMC_PING)) {
01243       if (username != NULL) {
01244         if (strlen(username) + 8 >= (bufsiz - len)) {
01245           _use_msg_for_out(m);
01246           return EX_OSERR;
01247         }
01248         strcpy(buf + len, "User: ");
01249         strcat(buf + len, username);
01250         strcat(buf + len, "\r\n");
01251         len += strlen(buf + len);
01252       }
01253       if (zlib_on) {
01254         len += snprintf(buf + len, 8192-len, "Compress: zlib\r\n");
01255       }
01256       if ((m->msg_len > SPAMC_MAX_MESSAGE_LEN) || ((len + 27) >= (bufsiz - len))) {
01257         _use_msg_for_out(m);
01258         return EX_DATAERR;
01259       }
01260       len += snprintf(buf + len, 8192-len, "Content-length: %d\r\n\r\n", (int) towrite_len);
01261     }
01262 
01263     libspamc_timeout = m->timeout;
01264 
01265     if (tp->socketpath)
01266         rc = _try_to_connect_unix(tp, &sock);
01267     else
01268         rc = _try_to_connect_tcp(tp, &sock);
01269 
01270     if (rc != EX_OK) {
01271         _use_msg_for_out(m);
01272         return rc;      /* use the error code try_to_connect_*() gave us. */
01273     }
01274 
01275     if (flags & SPAMC_USE_SSL) {
01276 #ifdef SPAMC_SSL
01277         ssl = SSL_new(ctx);
01278         SSL_set_fd(ssl, sock);
01279         SSL_connect(ssl);
01280 #endif
01281     }
01282 
01283     /* Send to spamd */
01284     if (flags & SPAMC_USE_SSL) {
01285 #ifdef SPAMC_SSL
01286         SSL_write(ssl, buf, len);
01287         SSL_write(ssl, towrite_buf, towrite_len);
01288 #endif
01289     }
01290     else {
01291         full_write(sock, 0, buf, len);
01292         full_write(sock, 0, towrite_buf, towrite_len);
01293         shutdown(sock, SHUT_WR);
01294     }
01295 
01296     /* ok, now read and parse it.  SPAMD/1.2 line first... */
01297     failureval =
01298         _spamc_read_full_line(m, flags, ssl, sock, buf, &len, bufsiz);
01299     if (failureval != EX_OK) {
01300         goto failure;
01301     }
01302 
01303     if (sscanf(buf, "SPAMD/%18s %d %*s", versbuf, &response) != 2) {
01304         libspamc_log(flags, LOG_ERR, "spamd responded with bad string '%s'", buf);
01305         failureval = EX_PROTOCOL;
01306         goto failure;
01307     }
01308 
01309     versbuf[19] = '\0';
01310     version = _locale_safe_string_to_float(versbuf, 20);
01311     if (version < 1.0) {
01312         libspamc_log(flags, LOG_ERR, "spamd responded with bad version string '%s'",
01313                versbuf);
01314         failureval = EX_PROTOCOL;
01315         goto failure;
01316     }
01317 
01318     if (flags & SPAMC_PING) {
01319         closesocket(sock);
01320         sock = -1;
01321         m->out_len = sprintf(m->out, "SPAMD/%s %d\n", versbuf, response);
01322         m->is_spam = EX_NOTSPAM;
01323         return EX_OK;
01324     }
01325 
01326     m->score = 0;
01327     m->threshold = 0;
01328     m->is_spam = EX_TOOBIG;
01329     while (1) {
01330         failureval =
01331             _spamc_read_full_line(m, flags, ssl, sock, buf, &len, bufsiz);
01332         if (failureval != EX_OK) {
01333             goto failure;
01334         }
01335 
01336         if (len == 0 && buf[0] == '\0') {
01337             break;              /* end of headers */
01338         }
01339 
01340         if (_handle_spamd_header(m, flags, buf, len, &throwaway) < 0) {
01341             failureval = EX_PROTOCOL;
01342             goto failure;
01343         }
01344     }
01345 
01346     len = 0;                    /* overwrite those headers */
01347 
01348     if (flags & SPAMC_CHECK_ONLY) {
01349         closesocket(sock);
01350         sock = -1;
01351         if (m->is_spam == EX_TOOBIG) {
01352             /* We should have gotten headers back... Damnit. */
01353             failureval = EX_PROTOCOL;
01354             goto failure;
01355         }
01356         return EX_OK;
01357     }
01358     else {
01359         if (m->content_length < 0) {
01360             /* should have got a length too. */
01361             failureval = EX_PROTOCOL;
01362             goto failure;
01363         }
01364 
01365         /* have we already got something in the buffer (e.g. REPORT and
01366          * REPORT_IFSPAM both create a line from the "Spam:" hdr)?  If
01367          * so, add the size of that so our sanity check passes.
01368          */
01369         if (m->out_len > 0) {
01370             m->content_length += m->out_len;
01371         }
01372 
01373         if (flags & SPAMC_USE_SSL) {
01374             len = full_read_ssl(ssl, (unsigned char *) m->out + m->out_len,
01375                                 m->priv->alloced_size - m->out_len,
01376                                 m->priv->alloced_size - m->out_len);
01377         }
01378         else {
01379             len = full_read(sock, 0, m->out + m->out_len,
01380                             m->priv->alloced_size - m->out_len,
01381                             m->priv->alloced_size - m->out_len);
01382         }
01383 
01384 
01385         if (len + m->out_len > (m->priv->alloced_size-1)) {
01386             failureval = EX_TOOBIG;
01387             goto failure;
01388         }
01389         m->out_len += len;
01390 
01391         shutdown(sock, SHUT_RD);
01392         closesocket(sock);
01393         sock = -1;
01394     }
01395     libspamc_timeout = 0;
01396 
01397     if (m->out_len != m->content_length) {
01398         libspamc_log(flags, LOG_ERR,
01399                "failed sanity check, %d bytes claimed, %d bytes seen",
01400                m->content_length, m->out_len);
01401         failureval = EX_PROTOCOL;
01402         goto failure;
01403     }
01404 
01405     if (flags & SPAMC_HEADERS) {
01406         if (_append_original_body(m, flags) != EX_OK) {
01407             goto failure;
01408         }
01409     }
01410 
01411     return EX_OK;
01412 
01413   failure:
01414         _use_msg_for_out(m);
01415     if (sock != -1) {
01416         closesocket(sock);
01417     }
01418     libspamc_timeout = 0;
01419 
01420     if (flags & SPAMC_USE_SSL) {
01421 #ifdef SPAMC_SSL
01422         SSL_free(ssl);
01423         SSL_CTX_free(ctx);
01424 #endif
01425     }
01426     return failureval;
01427 }

int message_process struct transport trans,
char *  username,
int  max_size,
int  in_fd,
int  out_fd,
const int  flags
 

Definition at line 1429 of file libspamc.c.

References EX_NOTSPAM, EX_OK, EX_SOFTWARE, EX_TOOBIG, full_write(), message::is_spam, message::max_len, message_cleanup(), message_dump(), message_filter(), MESSAGE_NONE, message_read(), message_write(), SPAMC_CHECK_ONLY, and message::type.

Referenced by process_message().

01431 {
01432     int ret;
01433     struct message m;
01434 
01435     assert(trans != NULL);
01436 
01437     m.type = MESSAGE_NONE;
01438 
01439     /* enforce max_size being unsigned, therefore >= 0 */
01440     if (max_size < 0) {
01441         ret = EX_SOFTWARE;
01442         goto FAIL;
01443     }
01444     m.max_len = (unsigned int) max_size;
01445 
01446     ret = message_read(in_fd, flags, &m);
01447     if (ret != EX_OK)
01448         goto FAIL;
01449     ret = message_filter(trans, username, flags, &m);
01450     if (ret != EX_OK)
01451         goto FAIL;
01452     if (message_write(out_fd, &m) < 0)
01453         goto FAIL;
<