Newer
Older
static void
js_ErrorReporter(JSContext *cx, const char *message, JSErrorReport *report)
{
char line[64];
char file[MAX_PATH+1];
char* warning;
jsrefcount rc;
int log_level;
return;
if(report==NULL) {
lprintf(LOG_ERR,"%04d %s %s !JavaScript: %s"
, p->sock, p->log_prefix, p->proc_name, message);
return;
}
if(report->filename)
SAFEPRINTF(file," %s",report->filename);
else
file[0]=0;
if(report->lineno)
SAFEPRINTF(line," line %u",report->lineno);
else
line[0]=0;
if(JSREPORT_IS_WARNING(report->flags)) {
if(JSREPORT_IS_STRICT(report->flags))
warning="strict warning";
else
warning="warning";
log_level=LOG_WARNING;
} else {
log_level=LOG_ERR;
warning="";
rc=JS_SUSPENDREQUEST(cx);
lprintf(log_level,"%04d %s %s !JavaScript %s%s%s: %s"
,p->sock, p->log_prefix, p->proc_name
,warning ,file, line, message);
JS_RESUMEREQUEST(cx, rc);
static JSBool
js_log(JSContext *cx, uintN argc, jsval *arglist)
{
jsval *argv=JS_ARGV(cx, arglist);
uintN i=0;
int32 level=LOG_INFO;
jsrefcount rc;
char *lstr=NULL;
size_t lstr_sz=0;
JS_SET_RVAL(cx, arglist, JSVAL_VOID);
return(JS_FALSE);
if(JSVAL_IS_NUMBER(argv[i])) {
if(!JS_ValueToInt32(cx,argv[i++],&level))
return JS_FALSE;
}
for(; i<argc; i++) {
JSVALUE_TO_RASTRING(cx, argv[i], lstr, &lstr_sz, NULL);
HANDLE_PENDING(cx, lstr);
return(JS_TRUE);
rc=JS_SUSPENDREQUEST(cx);
lprintf(level,"%04d %s %s %s"
JS_SET_RVAL(cx, arglist, argv[i]);
JS_RESUMEREQUEST(cx, rc);
}
return(JS_TRUE);
}
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
static JSBool
js_alert(JSContext *cx, uintN argc, jsval *arglist)
{
jsval *argv=JS_ARGV(cx, arglist);
private_t* p;
jsrefcount rc;
char *line;
JS_SET_RVAL(cx, arglist, JSVAL_VOID);
if((p=(private_t*)JS_GetContextPrivate(cx))==NULL)
return(JS_FALSE);
JSVALUE_TO_MSTRING(cx, argv[0], line, NULL);
if(line==NULL)
return(JS_FALSE);
rc=JS_SUSPENDREQUEST(cx);
lprintf(LOG_ERR,"%04d %s %s %s"
,p->sock, p->log_prefix, p->proc_name, line);
free(line);
JS_RESUMEREQUEST(cx, rc);
JS_SET_RVAL(cx, arglist, argv[0]);
return(JS_TRUE);
}
static JSFunctionSpec js_global_functions[] = {
{"write", js_log, 0},
{"writeln", js_log, 0},
{"print", js_log, 0},
{"log", js_log, 0},
{"alert", js_alert, 1},
{0}
};
static BOOL
js_mailproc(SOCKET sock, client_t* client, user_t* user, struct mailproc* mailproc
,char* cmdline
,char* msgtxt_fname, char* newtxt_fname, char* logtxt_fname
,char* rcpt_addr
,char* rcptlst_fname, char* proc_err_fname
,char* sender, char* sender_addr, char* reverse_path, char* hello_name
,JSRuntime** js_runtime
,JSContext** js_cx
,JSObject** js_glob
,const char* log_prefix
)
{
char* p;
char fname[MAX_PATH+1];
char path[MAX_PATH+1];
char arg[MAX_PATH+1];
BOOL success=FALSE;
JSObject* argv;
jsuint argc;
JSObject* js_script;
js_callback_t js_callback;
jsval val;
jsval rval=JSVAL_VOID;
ZERO_VAR(js_callback);
SAFECOPY(fname,cmdline);
truncstr(fname," \t");
if(getfext(fname)==NULL) /* No extension specified, assume '.js' */
strcat(fname,".js");
SAFECOPY(path,fname);

rswindell
committed
if(getfname(path)==path) { /* No path specified, assume mods or exec dir */
SAFEPRINTF2(path,"%s%s",scfg.mods_dir,fname);

rswindell
committed
if(scfg.mods_dir[0]==0 || !fexist(path))
SAFEPRINTF2(path,"%s%s",scfg.exec_dir,fname);

rswindell
committed
}
*result = 0;
if(*js_runtime==NULL) {
lprintf(LOG_DEBUG,"%04d %s JavaScript: Creating runtime: %lu bytes\n"
,sock, log_prefix, startup->js.max_bytes);
if((*js_runtime = jsrt_GetNew(startup->js.max_bytes, 1000, __FILE__, __LINE__))==NULL)
return FALSE;
if(*js_cx==NULL) {
lprintf(LOG_DEBUG,"%04d %s JavaScript: Initializing context (stack: %lu bytes)\n"
,sock, log_prefix, startup->js.cx_stack);
if((*js_cx = JS_NewContext(*js_runtime, startup->js.cx_stack))==NULL)
return FALSE;
}
JS_BEGINREQUEST(*js_cx);
JS_SetErrorReporter(*js_cx, js_ErrorReporter);
priv.sock=sock;
priv.log_prefix=log_prefix;
priv.proc_name=mailproc->name;
JS_SetContextPrivate(*js_cx, &priv);
if(*js_glob==NULL) {
/* Global Objects (including system, js, client, Socket, MsgBase, File, User, etc. */
if(!js_CreateCommonObjects(*js_cx, &scfg, &scfg, NULL
,&js_callback /* js */
,client, sock, -1 /* client */
,js_glob
))
if(!JS_DefineFunctions(*js_cx, *js_glob, js_global_functions))
break;
if(!js_CreateUserObjects(*js_cx, *js_glob, &scfg, user, client, NULL, NULL))
/* Mailproc "API" filenames */
JS_DefineProperty(*js_cx, *js_glob, "message_text_filename"
,STRING_TO_JSVAL(JS_NewStringCopyZ(*js_cx,msgtxt_fname))
,NULL,NULL,JSPROP_ENUMERATE|JSPROP_READONLY);
JS_DefineProperty(*js_cx, *js_glob, "new_message_text_filename"
,STRING_TO_JSVAL(JS_NewStringCopyZ(*js_cx,newtxt_fname))
,NULL,NULL,JSPROP_ENUMERATE|JSPROP_READONLY);
JS_DefineProperty(*js_cx, *js_glob, "log_text_filename"
,STRING_TO_JSVAL(JS_NewStringCopyZ(*js_cx,logtxt_fname))
,NULL,NULL,JSPROP_ENUMERATE|JSPROP_READONLY);
JS_DefineProperty(*js_cx, *js_glob, "recipient_address"
,STRING_TO_JSVAL(JS_NewStringCopyZ(*js_cx,rcpt_addr))
,NULL,NULL,JSPROP_ENUMERATE|JSPROP_READONLY);
JS_DefineProperty(*js_cx, *js_glob, "recipient_list_filename"
,STRING_TO_JSVAL(JS_NewStringCopyZ(*js_cx,rcptlst_fname))
,NULL,NULL,JSPROP_ENUMERATE|JSPROP_READONLY);
JS_DefineProperty(*js_cx, *js_glob, "processing_error_filename"
,STRING_TO_JSVAL(JS_NewStringCopyZ(*js_cx,proc_err_fname))
,NULL,NULL,JSPROP_ENUMERATE|JSPROP_READONLY);
JS_DefineProperty(*js_cx, *js_glob, "sender_name"
,STRING_TO_JSVAL(JS_NewStringCopyZ(*js_cx,sender))
,NULL,NULL,JSPROP_ENUMERATE|JSPROP_READONLY);
JS_DefineProperty(*js_cx, *js_glob, "sender_address"
,STRING_TO_JSVAL(JS_NewStringCopyZ(*js_cx,sender_addr))
,NULL,NULL,JSPROP_ENUMERATE|JSPROP_READONLY);
JS_DefineProperty(*js_cx, *js_glob, "reverse_path"
,STRING_TO_JSVAL(JS_NewStringCopyZ(*js_cx,reverse_path))
,NULL,NULL,JSPROP_ENUMERATE|JSPROP_READONLY);
JS_DefineProperty(*js_cx, *js_glob, "hello_name"
,STRING_TO_JSVAL(JS_NewStringCopyZ(*js_cx,hello_name))
,NULL,NULL,JSPROP_ENUMERATE|JSPROP_READONLY);
}
if((js_scope=JS_NewObject(*js_cx, NULL, NULL, *js_glob))==NULL)
break;
/* Convert command-line to argv/argc */
argv=JS_NewArrayObject(*js_cx, 0, NULL);
JS_DefineProperty(*js_cx, js_scope, "argv", OBJECT_TO_JSVAL(argv)
,NULL,NULL,JSPROP_READONLY|JSPROP_ENUMERATE);
p=cmdline;
FIND_WHITESPACE(p);
SKIP_WHITESPACE(p);
for(argc=0;*p;argc++) {
SAFECOPY(arg,p);
truncstr(arg," \t");
val=STRING_TO_JSVAL(JS_NewStringCopyZ(*js_cx,arg));
if(!JS_SetElement(*js_cx, argv, argc, &val))
break;
FIND_WHITESPACE(p);
SKIP_WHITESPACE(p);
}
JS_DefineProperty(*js_cx, js_scope, "argc", INT_TO_JSVAL(argc)
,NULL,NULL,JSPROP_READONLY|JSPROP_ENUMERATE);
lprintf(LOG_DEBUG,"%04d %s Evaluating: %s"
,sock, log_prefix, mailproc->eval);
js_script=JS_CompileScript(*js_cx, js_scope, mailproc->eval, strlen(mailproc->eval), NULL, 1);
} else {
lprintf(LOG_DEBUG,"%04d %s Executing: %s"
if((js_script=JS_CompileFile(*js_cx, js_scope, path)) != NULL)
js_PrepareToExecute(*js_cx, js_scope, path, /* startup_dir: */NULL, js_scope);
/* ToDo: Set operational callback */
success=JS_ExecuteScript(*js_cx, js_scope, js_script, &rval);
JS_GetProperty(*js_cx, js_scope, "exit_code", &rval);
if(rval!=JSVAL_VOID && JSVAL_IS_NUMBER(rval))
JS_ValueToInt32(*js_cx,rval,result);
js_EvalOnExit(*js_cx, js_scope, &js_callback);
JS_ReportPendingException(*js_cx);
} while(0);
JS_ENDREQUEST(*js_cx);
return(success);
}
void js_cleanup(JSRuntime* js_runtime, JSContext* js_cx, JSObject** js_glob)
if(js_cx!=NULL) {
JS_BEGINREQUEST(js_cx);
JS_RemoveObjectRoot(js_cx, js_glob);
JS_ENDREQUEST(js_cx);
}
if(js_runtime!=NULL)
jsrt_Release(js_runtime);
}
static char* get_header_field(char* buf, char* name, size_t maxlen)
{
size_t len;
if(buf[0]<=' ') /* folded header */
return NULL;
if((p=strchr(buf,':'))==NULL)
return NULL;
len = p-buf;
if(len >= maxlen)
len = maxlen-1;
truncsp(name);
p++; /* skip colon */
SKIP_WHITESPACE(p);
return p;
}
static int parse_header_field(char* buf, smbmsg_t* msg, ushort* type)
{
char* p;
char* tp;
char field[128];
int len;
ushort nettype;
if(buf[0]<=' ' && *type!=UNKNOWN) { /* folded header, append to previous */
p=buf;
truncsp(p);
if(*type==RFC822HEADER || *type==SMTPRECEIVED)
smb_hfield_append_str(msg,*type,"\r\n");
else { /* Unfold other common header field types (e.g. Subject, From, To) */
smb_hfield_append_str(msg,*type," ");
SKIP_WHITESPACE(p);
}
return smb_hfield_append_str(msg, *type, p);
}
if((p=strchr(buf,':'))==NULL)
return smb_hfield_str(msg, *type=RFC822HEADER, buf);
len=(ulong)p-(ulong)buf;
if(len>sizeof(field)-1)
len=sizeof(field)-1;
sprintf(field,"%.*s",len,buf);
truncsp(field);
p++; /* skip colon */
SKIP_WHITESPACE(p);
truncsp(p);
if(!stricmp(field, "TO"))
return smb_hfield_str(msg, *type=RFC822TO, p);
if(!stricmp(field, "REPLY-TO")) {
smb_hfield_str(msg, *type=RFC822REPLYTO, p);
if((tp=strrchr(p,'<'))!=NULL) {
tp++;
truncstr(tp,">");
p=tp;
}
nettype=NET_INTERNET;
smb_hfield(msg, REPLYTONETTYPE, sizeof(nettype), &nettype);
return smb_hfield_str(msg, *type=REPLYTONETADDR, p);
}
if(!stricmp(field, "FROM"))
return smb_hfield_str(msg, *type=RFC822FROM, p);
if(!stricmp(field, "ORGANIZATION"))
return smb_hfield_str(msg, *type=SENDERORG, p);
if(!stricmp(field, "DATE")) {
msg->hdr.when_written=rfc822date(p);
*type=UNKNOWN;
return SMB_SUCCESS;
}
if(!stricmp(field, "MESSAGE-ID"))
return smb_hfield_str(msg, *type=RFC822MSGID, p);
if(!stricmp(field, "IN-REPLY-TO"))
return smb_hfield_str(msg, *type=RFC822REPLYID, p);
if(!stricmp(field, "CC"))
return smb_hfield_str(msg, *type=SMB_CARBONCOPY, p);
if(!stricmp(field, "RECEIVED"))
return smb_hfield_str(msg, *type=SMTPRECEIVED, p);
if(!stricmp(field, "RETURN-PATH")) {
*type=UNKNOWN;
return SMB_SUCCESS; /* Ignore existing "Return-Path" header fields */
}
/* Fall-through */
return smb_hfield_str(msg, *type=RFC822HEADER, buf);
}
static int chk_received_hdr(SOCKET socket,const char* prot,const char *buf,IN_ADDR *dnsbl_result, char *dnsbl, char *dnsbl_ip)
{
char host_name[128];
char *fromstr;
char ip[16];
char *p;
char *p2;
if(fromstr==NULL)
return(0);
strlwr(fromstr);
do {
p=strstr(fromstr,"from ");
if(p==NULL)
break;
p+=4;
SKIP_WHITESPACE(p);
if(*p==0)
break;
p2=host_name;
for(;*p && !isspace((unsigned char)*p) && p2<host_name+126;p++) {
*p2++=*p;
}
*p2=0;
p=strtok_r(fromstr,"[",&last);
if(p==NULL)
break;
p=strtok_r(NULL,"]",&last);
if(p==NULL)
break;
if(strnicmp("IPv6:", p, 5)) {
p+=5;
SKIP_WHITESPACE(p);
memset(&ai, 0, sizeof(ai));
ai.ai_flags = AI_NUMERICHOST|AI_NUMERICSERV|AI_PASSIVE;
if(getaddrinfo(p, NULL, &ai, &res)!=0)
break;
freeaddrinfo(res);
} else {
freeaddrinfo(res);
}
else {
strncpy(ip,p,16);
ip[15]=0;
addr.in.sin_family=AF_INET;
addr.in.sin_addr.s_addr=inet_addr(ip);
lprintf(LOG_DEBUG,"%04d %s DNSBL checking received header address %s [%s]",socket,prot,host_name,ip);
if((dnsbl_result->s_addr=dns_blacklisted(socket,prot,&addr,host_name,dnsbl,dnsbl_ip))!=0)
lprintf(LOG_NOTICE,"%04d %s BLACKLISTED SERVER on %s: %s [%s] = %s"
,socket, prot, dnsbl, host_name, ip, inet_ntoa(*dnsbl_result));
} while(0);
free(fromstr);
return(dnsbl_result->s_addr);
}
static void strip_char(char* str, char ch)
{
char* src;
char* p;
char* tmp = strdup(str);
if(tmp == NULL)
return;
p=tmp;
for(src = str; *src; src++) {
if(*src != ch)
*(p++) = *src;
}
*p=0;
strcpy(str, tmp);
free(tmp);
}
static void parse_mail_address(char* p
,char* name, size_t name_len
,char* addr, size_t addr_len)
{
char* tp;
char tmp[128];
SKIP_WHITESPACE(p);
/* Get the address */
if((tp=strrchr(p,'<'))!=NULL)
tp++;
else
tp=p;
SKIP_WHITESPACE(tp);
truncstr(addr,">( ");
SAFECOPY(tmp,p);
p=tmp;
/* Get the "name" (if possible) */
if((tp=strchr(p,'"'))!=NULL) { /* name in quotes? */
p=tp+1;
tp=strrchr(p,'"');
} else if((tp=strchr(p,'('))!=NULL) { /* name in parenthesis? */
p=tp+1;
} else if(*p=='<') { /* address in brackets? */
p++;
} else /* name, then address in brackets */
tp=strchr(p,'<');
if(tp) *tp=0;
truncsp(name);
}
/* Decode quoted-printable content-transfer-encoded text */
/* Ignores (strips) unsupported ctrl chars and non-ASCII chars */
/* Does not enforce 76 char line length limit */
static char* qp_decode(char* buf)
{
uchar* p=(uchar*)buf;
uchar* dest=p;
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
for(;;p++) {
if(*p==0) {
*dest++='\r';
*dest++='\n';
break;
}
if(*p==' ' || (*p>='!' && *p<='~' && *p!='=') || *p=='\t')
*dest++=*p;
else if(*p=='=') {
p++;
if(*p==0) /* soft link break */
break;
if(isxdigit(*p) && isxdigit(*(p+1))) {
char hex[3];
hex[0]=*p;
hex[1]=*(p+1);
hex[2]=0;
/* ToDo: what about encoded NULs and the like? */
*dest++=(uchar)strtoul(hex,NULL,16);
p++;
} else { /* bad encoding */
*dest++='=';
*dest++=*p;
}
}
}
*dest=0;
return buf;
}
static BOOL checktag(scfg_t *scfg, char *tag, uint usernum)
{
char fname[MAX_PATH+1];
if(tag==NULL)
return(FALSE);
SAFEPRINTF2(fname,"%suser/%04d.smtpblock",scfg->data_dir,usernum);
return(findstr(tag, fname));
}
static BOOL smtp_splittag(char *in, char **name, char **tag)
{
char *last;
if(in==NULL)
return(FALSE);
*name=strtok_r(in, "#", &last);
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
if(*name) {
*tag=strtok_r(NULL, "", &last);
return(TRUE);
}
return(FALSE);
}
static uint smtp_matchuser(scfg_t *scfg, char *str, BOOL aliases, BOOL datdupe)
{
char *user=strdup(str);
char *name;
char *tag=NULL;
uint usernum=0;
if(!user)
return(0);
if(!smtp_splittag(user, &name, &tag))
goto end;
if(datdupe)
usernum=userdatdupe(scfg, 0, U_NAME, LEN_NAME, name, /* del */FALSE, /* next */FALSE, NULL, NULL);
else
usernum=matchuser(scfg, name, aliases);
if(!usernum)
goto end;
if(checktag(scfg, tag, usernum))
usernum=UINT_MAX;
end:
free(user);
return(usernum);
}
#define WITH_ESMTP (1<<0)
#define WITH_AUTH (1<<1)
#define WITH_TLS (1<<2)
char *with_clauses[] = {
"SMTP", // No WITH_*
"ESMTP", // WITH_ESMTP
"SMTP", // WITH_AUTH
"ESMTPA", // WITH_ESMTP | WITH_AUTH
"SMTP", // WITH_TLS
"ESMTPS", // WITH_ESMTP | WITH_TLS
"SMTP", // WITH_TLS | WITH_AUTH
"ESMTPSA" // WITH_TLS | WITH_AUTH | WITH_ESMTP
};
static void smtp_thread(void* arg)
{
int i,j;
char path[MAX_PATH+1];
char value[INI_MAX_VALUE_LEN];
str_list_t sec_list;
char* section;
char buf[1024],*p,*tp,*cp;
char hdrfield[512];
char alias_buf[128];
char reverse_path[128];
char date[64];
char qwkid[32];
char rcpt_to[128];
char rcpt_name[128];
char rcpt_addr[128];

rswindell
committed
char sender[128];
char sender_ext[128];

rswindell
committed
char sender_addr[128];
char user_name[128];
char user_pass[128];
char relay_list[MAX_PATH+1];
char domain_list[MAX_PATH+1];
char spam_bait[MAX_PATH+1];
char spam_block[MAX_PATH+1];
char spam_block_exemptions[MAX_PATH+1];
BOOL spam_block_exempt=FALSE;
char host_ip[INET6_ADDRSTRLEN];
char server_ip[INET6_ADDRSTRLEN];

rswindell
committed
char* telegram_buf;
char* msgbuf;
char challenge[256];
char response[128];
char secret[64];
char md5_data[384];
uchar digest[MD5_DIGEST_SIZE];
char dest_host[128];
char* errmsg;
ushort dest_port;
ushort hfield_type;
ushort agent;
ulong hdr_lines=0;
ulong hdr_len=0;
ulong badcmds=0;

rswindell
committed
BOOL telegram=FALSE;
BOOL forward=FALSE;
BOOL no_forward=FALSE;
BOOL auth_login;
BOOL routed=FALSE;
BOOL dnsbl_recvhdr;
BOOL msg_handled;
uint subnum=INVALID_SUB;
char msgtxt_fname[MAX_PATH+1];
char newtxt_fname[MAX_PATH+1];
char logtxt_fname[MAX_PATH+1];
char rcptlst_fname[MAX_PATH+1];
ushort rcpt_count=0;
FILE* proc_out;
char proc_err_fname[MAX_PATH+1];
char session_id[MAX_PATH+1];
FILE* spy=NULL;
SOCKET socket;
int smb_error;
smbmsg_t msg;
smbmsg_t newmsg;
user_t user;
user_t relay_user;

rswindell
committed
node_t node;
client_t client;
smtp_t smtp=*(smtp_t*)arg;
IN_ADDR dnsbl_result;
int mailproc_match;
JSRuntime* js_runtime=NULL;
JSContext* js_cx=NULL;
JSObject* js_glob=NULL;
struct mailproc* mailproc;
int session = -1;
BOOL nodelay=TRUE;
ulong nb = 0;
unsigned with_val;
int level;
int cstat;
char *estr;
enum {
SMTP_STATE_INITIAL
,SMTP_STATE_HELO
,SMTP_STATE_DATA_HEADER
,SMTP_STATE_DATA_BODY
} state = SMTP_STATE_INITIAL;
enum {
SMTP_CMD_NONE
,SMTP_CMD_MAIL
,SMTP_CMD_SEND
,SMTP_CMD_SOML
,SMTP_CMD_SAML
} cmd = SMTP_CMD_NONE;
enum {
ENCODING_NONE
,ENCODING_BASE64
,ENCODING_QUOTED_PRINTABLE
} content_encoding = ENCODING_NONE;
SetThreadName("sbbs/smtp");
thread_up(TRUE /* setuid */);
free(arg);
socket=smtp.socket;
client.protocol = smtp.tls_port ? "SMTPS" : "SMTP";
lprintf(LOG_DEBUG,"%04d %s Session thread started", socket, client.protocol);
if(startup->inbound_sound[0] && !(startup->options&MAIL_OPT_MUTE))
PlaySound(startup->inbound_sound, NULL, SND_ASYNC|SND_FILENAME);
addr_len=sizeof(server_addr);
if(smtp.tls_port) {
if (get_ssl_cert(&scfg, &estr, &level) == -1) {
if (estr) {
lprintf(level, "%04d %s !%s", socket, client.protocol, estr);
free_crypt_attrstr(estr);
mail_close_socket(&socket, &session);
thread_down();
return;
}
if ((cstat = cryptCreateSession(&session, CRYPT_UNUSED, CRYPT_SESSION_SSL_SERVER)) != CRYPT_OK) {
GCES(cstat, client.protocol, socket, CRYPT_UNUSED, "creating session");
mail_close_socket(&socket, &session);
thread_down();
return;
}
if ((cstat = cryptSetAttribute(session, CRYPT_SESSINFO_SSL_OPTIONS, CRYPT_SSLOPTION_DISABLE_CERTVERIFY)) != CRYPT_OK) {
GCES(cstat, client.protocol, socket, CRYPT_UNUSED, "disabling certificate verification");
mail_close_socket(&socket, &session);
thread_down();
return;
}
if ((cstat = cryptSetAttribute(session, CRYPT_SESSINFO_PRIVATEKEY, scfg.tls_certificate)) != CRYPT_OK) {
GCES(cstat, client.protocol, socket, CRYPT_UNUSED, "setting private key");
mail_close_socket(&socket, &session);
thread_down();
return;
}
nodelay = TRUE;
setsockopt(socket,IPPROTO_TCP,TCP_NODELAY,(char*)&nodelay,sizeof(nodelay));
nb=0;
ioctlsocket(socket,FIONBIO,&nb);
if ((cstat = cryptSetAttribute(session, CRYPT_SESSINFO_NETWORKSOCKET, socket)) != CRYPT_OK) {
GCES(cstat, client.protocol, socket, CRYPT_UNUSED, "setting network socket");
mail_close_socket(&socket, &session);
thread_down();
return;
}
if ((cstat = cryptSetAttribute(session, CRYPT_SESSINFO_ACTIVE, 1)) != CRYPT_OK) {
GCES(cstat, client.protocol, socket, CRYPT_UNUSED, "setting session active");
mail_close_socket(&socket, &session);
thread_down();
return;
}
if (startup->max_inactivity) {
if ((cstat = cryptSetAttribute(session, CRYPT_OPTION_NET_READTIMEOUT, startup->max_inactivity)) != CRYPT_OK) {
GCES(cstat, client.protocol, socket, CRYPT_UNUSED, "setting read timeout");
mail_close_socket(&socket, &session);
thread_down();
return;
}
}
}
lprintf(LOG_CRIT,"%04d %s !ERROR %d (%d) getting address/port"
,socket, client.protocol, i, ERROR_VALUE);
sockprintf(socket,client.protocol,session,sys_error);
mail_close_socket(&socket, &session);
if((mailproc_to_match=malloc(sizeof(BOOL)*mailproc_count))==NULL) {
lprintf(LOG_CRIT,"%04d %s !ERROR allocating memory for mailproc_to_match", socket, client.protocol);
sockprintf(socket,client.protocol,session,sys_error);
mail_close_socket(&socket, &session);
thread_down();
return;
}
memset(mailproc_to_match,FALSE,sizeof(BOOL)*mailproc_count);
memset(&smb,0,sizeof(smb));

rswindell
committed
memset(&msg,0,sizeof(msg));

rswindell
committed
memset(&user,0,sizeof(user));
memset(&relay_user,0,sizeof(relay_user));
lprintf(LOG_INFO,"%04d %s Connection accepted on port %u from: %s port %u"
,socket, client.protocol, inet_addrport(&server_addr), host_ip, inet_addrport(&smtp.client_addr));
if(getnameinfo(&smtp.client_addr.addr, smtp.client_addr_len, host_name, sizeof(host_name), NULL, 0, (startup->options&MAIL_OPT_NO_HOST_LOOKUP)?NI_NUMERICHOST:0)!=0)
SAFECOPY(host_name, "<no name>");
if(!(startup->options&MAIL_OPT_NO_HOST_LOOKUP))
lprintf(LOG_INFO,"%04d %s Hostname: %s", socket, client.protocol, host_name);
protected_uint32_adjust(&active_clients, 1);
update_clients();
SAFECOPY(hello_name,host_name);
SAFEPRINTF(spam_bait,"%sspambait.cfg",scfg.ctrl_dir);
SAFEPRINTF(spam_block,"%sspamblock.cfg",scfg.ctrl_dir);
SAFEPRINTF(spam_block_exemptions,"%sspamblock_exempt.cfg",scfg.ctrl_dir);
inet_addrtop(&server_addr,server_ip,sizeof(server_ip));
if(strcmp(server_ip, host_ip)==0) {
/* local connection */
dnsbl_result.s_addr=0;
} else {
ulong banned = loginBanned(&scfg, startup->login_attempt_list, socket, host_name, startup->login_attempt, &attempted);
lprintf(LOG_NOTICE, "%04d !TEMPORARY BAN of %s (%lu login attempts, last: %s) - remaining: %s"
,socket, host_ip, attempted.count-attempted.dupes, attempted.user, seconds_to_str(banned, ban_duration));
mail_close_socket(&socket, &session);
thread_down();
protected_uint32_adjust(&active_clients, -1);
update_clients();
free(mailproc_to_match);
return;
}
spam_block_exempt = findstr(host_ip,spam_block_exemptions) || findstr(host_name,spam_block_exemptions);
if(trashcan(&scfg,host_ip,"ip")
|| (findstr(host_ip,spam_block) && !spam_block_exempt)) {
lprintf(LOG_NOTICE,"%04d %s !CLIENT IP ADDRESS BLOCKED: %s (%lu total)"
,socket, client.protocol, host_ip, ++stats.sessions_refused);
sockprintf(socket,client.protocol,session,"550 CLIENT IP ADDRESS BLOCKED: %s", host_ip);
mail_close_socket(&socket, &session);
thread_down();
protected_uint32_adjust(&active_clients, -1);
update_clients();
return;
}
if(trashcan(&scfg,host_name,"host")
|| (findstr(host_name,spam_block) && !spam_block_exempt)) {
lprintf(LOG_NOTICE,"%04d %s !CLIENT HOSTNAME BLOCKED: %s (%lu total)"
,socket, client.protocol, host_name, ++stats.sessions_refused);
sockprintf(socket,client.protocol,session,"550 CLIENT HOSTNAME BLOCKED: %s", host_name);
mail_close_socket(&socket, &session);
thread_down();
protected_uint32_adjust(&active_clients, -1);
update_clients();
/* SPAM Filters (mail-abuse.org) */
dnsbl_result.s_addr = dns_blacklisted(socket,client.protocol,&smtp.client_addr,host_name,dnsbl,dnsbl_ip);
if(dnsbl_result.s_addr) {
lprintf(LOG_NOTICE,"%04d %s BLACKLISTED SERVER on %s: %s [%s] = %s"
,socket, client.protocol, dnsbl, host_name, dnsbl_ip, inet_ntoa(dnsbl_result));
if(startup->options&MAIL_OPT_DNSBL_REFUSE) {
SAFEPRINTF2(str,"Listed on %s as %s", dnsbl, inet_ntoa(dnsbl_result));
spamlog(&scfg, (char*)client.protocol, "SESSION REFUSED", str, host_name, dnsbl_ip, NULL, NULL);
sockprintf(socket,client.protocol,session
,"550 Mail from %s refused due to listing at %s"
,dnsbl_ip, dnsbl);
mail_close_socket(&socket, &session);
lprintf(LOG_NOTICE,"%04d %s !REFUSED SESSION from blacklisted server (%lu total)"
,socket, client.protocol, ++stats.sessions_refused);
thread_down();
protected_uint32_adjust(&active_clients, -1);
update_clients();
return;
}
}
SAFEPRINTF(smb.file,"%smail",scfg.data_dir);
if(smb_islocked(&smb)) {
lprintf(LOG_WARNING,"%04d %s !MAIL BASE LOCKED: %s"
,socket, client.protocol, smb.last_error);
sockprintf(socket,client.protocol,session,sys_unavail);
mail_close_socket(&socket, &session);
thread_down();
protected_uint32_adjust(&active_clients, -1);
update_clients();
return;
}
SAFEPRINTF(spam.file,"%sspam",scfg.data_dir);
spam.retry_time=scfg.smb_retry_time;
spam.subnum=INVALID_SUB;
srand((unsigned int)(time(NULL) ^ (time_t)GetCurrentThreadId())); /* seed random number generator */
rand(); /* throw-away first result */
SAFEPRINTF4(session_id,"%x%x%x%lx",getpid(),socket,rand(),(long)clock());
lprintf(LOG_DEBUG,"%04d %s Session ID=%s", socket, client.protocol, session_id);
SAFEPRINTF3(msgtxt_fname,"%sSBBS_%s.%s.msg", scfg.temp_dir, client.protocol, session_id);
SAFEPRINTF3(newtxt_fname,"%sSBBS_%s.%s.new", scfg.temp_dir, client.protocol, session_id);
SAFEPRINTF3(logtxt_fname,"%sSBBS_%s.%s.log", scfg.temp_dir, client.protocol, session_id);