示例#1
0
/* OS_Sendmail v0.1: 2005/03/18
 */
int OS_Sendmail(MailConfig *mail, struct tm *p)
{
    int socket,i=0;
    char *msg;
    char snd_msg[128];
    char additional_to[512];

    MailNode *mailmsg;

    additional_to[0] = '\0';
    
    /* If there is no sms message, we attempt to get from the
     * email list.
     */
    mailmsg = OS_PopLastMail();

    if(mailmsg == NULL)
    {
        merror("%s: No email to be sent. Inconsistent state.",ARGV0);
    }
    

    /* Connecting to the smtp server */	
    socket = OS_ConnectTCP(SMTP_DEFAULT_PORT, mail->smtpserver);
    if(socket < 0)
    {
        return(socket);
    }


    /* Receiving the banner */
    msg = OS_RecvTCP(socket, OS_SIZE_1024);
    if((msg == NULL)||(!OS_Match(VALIDBANNER, msg)))
    {
        merror(BANNER_ERROR);
        if(msg)
            free(msg);
        close(socket);
        return(OS_INVALID);	
    }
    MAIL_DEBUG("DEBUG: Received banner: '%s' %s", msg, "");
    free(msg);



    /* Sending HELO message */
    OS_SendTCP(socket,HELOMSG);
    msg = OS_RecvTCP(socket, OS_SIZE_1024);
    if((msg == NULL)||(!OS_Match(VALIDMAIL, msg)))
    {
        if(msg)
        {
            /* Ugly fix warning :) */
            /* In some cases (with virus scans in the middle)
             * we may get two banners. Check for that in here.
             */
            if(OS_Match(VALIDBANNER, msg))
            {
                free(msg);

                /* Try again */
                msg = OS_RecvTCP(socket, OS_SIZE_1024);
                if((msg == NULL)||(!OS_Match(VALIDMAIL, msg)))
                {
                    merror("%s:%s",HELO_ERROR,msg!= NULL?msg:"null");
                    if(msg)
                        free(msg);
                    close(socket);
                    return(OS_INVALID);    
                }
            }
            else
            {
                merror("%s:%s",HELO_ERROR,msg);
                free(msg);
                close(socket);
                return(OS_INVALID);
            }
        }
        else
        {
            merror("%s:%s",HELO_ERROR,"null");
            close(socket);
            return(OS_INVALID);
        }
    }

    MAIL_DEBUG("DEBUG: Sent '%s', received: '%s'", HELOMSG, msg);
    free(msg);	


    /* Building "Mail from" msg */
    memset(snd_msg,'\0',128);
    snprintf(snd_msg,127, MAILFROM, mail->from);
    OS_SendTCP(socket, snd_msg);
    msg = OS_RecvTCP(socket, OS_SIZE_1024);
    if((msg == NULL)||(!OS_Match(VALIDMAIL, msg)))
    {
        merror(FROM_ERROR);
        if(msg)
            free(msg);
        close(socket);
        return(OS_INVALID);	
    }
    MAIL_DEBUG("DEBUG: Sent '%s', received: '%s'", snd_msg, msg);
    free(msg);	


    /* Building "RCPT TO" msg */
    while(1)
    {
        if(mail->to[i] == NULL)
        {
            if(i == 0)
            {
                merror(INTERNAL_ERROR);
                close(socket);
                return(OS_INVALID);
            }
            break;
        }
        memset(snd_msg,'\0',128);
        snprintf(snd_msg,127,RCPTTO, mail->to[i++]);
        OS_SendTCP(socket,snd_msg);
        msg = OS_RecvTCP(socket, OS_SIZE_1024);
        if((msg == NULL)||(!OS_Match(VALIDMAIL, msg)))
        {
            merror(TO_ERROR, mail->to[i -1]);
            if(msg)
                free(msg);
            close(socket);
            return(OS_INVALID);	
        }
        MAIL_DEBUG("DEBUG: Sent '%s', received: '%s'", snd_msg, msg);
        free(msg);
    }


    /* Additional RCPT to */
    if(mail->gran_to)
    {
        i = 0;
        while(mail->gran_to[i] != NULL)
        {
            if(mail->gran_set[i] != FULL_FORMAT)
            {
                i++;
                continue;
            }

            memset(snd_msg,'\0',128);
            snprintf(snd_msg,127,RCPTTO, mail->gran_to[i]);
            OS_SendTCP(socket,snd_msg);
            msg = OS_RecvTCP(socket, OS_SIZE_1024);
            if((msg == NULL)||(!OS_Match(VALIDMAIL, msg)))
            {
                merror(TO_ERROR, mail->gran_to[i]);
                if(msg)
                    free(msg);

                i++;
                continue;    
            }
            
            MAIL_DEBUG("DEBUG: Sent '%s', received: '%s'", snd_msg, msg);
            free(msg);
            i++;
            continue;
        }
    }


    /* Sending the "DATA" msg */
    OS_SendTCP(socket,DATAMSG);
    msg = OS_RecvTCP(socket, OS_SIZE_1024);
    if((msg == NULL)||(!OS_Match(VALIDDATA, msg)))
    {
        merror(DATA_ERROR);
        if(msg)
            free(msg);
        close(socket);
        return(OS_INVALID);	
    }
    MAIL_DEBUG("DEBUG: Sent '%s', received: '%s'", DATAMSG, msg);
    free(msg);


    /* Building "From" and "To" in the e-mail header */
    memset(snd_msg,'\0',128);
    snprintf(snd_msg,127, TO, mail->to[0]);
    OS_SendTCP(socket, snd_msg);

    memset(snd_msg,'\0',128);
    snprintf(snd_msg,127, FROM, mail->from);
    OS_SendTCP(socket, snd_msg);


    /* Adding CCs */
    if(mail->to[1])
    {
        i = 1;
        while(1)
        {
            if(mail->to[i] == NULL)
            {
                break;
            }
            
            memset(snd_msg,'\0',128);
            snprintf(snd_msg,127, TO, mail->to[i]);
            OS_SendTCP(socket,snd_msg);

            i++;
        }
    }


    /* More CCs - from granular options */
    if(mail->gran_to)
    {
        i = 0;
        while(mail->gran_to[i] != NULL)
        {
            if(mail->gran_set[i] != FULL_FORMAT)
            {
                i++;
                continue;
            }

            memset(snd_msg,'\0',128);
            snprintf(snd_msg,127, TO, mail->gran_to[i]);
            OS_SendTCP(socket, snd_msg);
            i++;
            continue;
        }
    }


    /* Sending date */
    memset(snd_msg,'\0',128);


    /* Solaris doesn't have the "%z", so we set the timezone to 0. */
    #ifdef SOLARIS
    strftime(snd_msg, 127, "Date: %a, %d %b %Y %T -0000\r\n",p);
    #else
    strftime(snd_msg, 127, "Date: %a, %d %b %Y %T %z\r\n",p);
    #endif
                            
    OS_SendTCP(socket,snd_msg);


    /* Sending subject */
    memset(snd_msg,'\0',128);


    /* Checking if global subject is available */
    if((_g_subject_level != 0) && (_g_subject[0] != '\0'))
    {
        snprintf(snd_msg, 127, SUBJECT, _g_subject);	

        /* Clearing global values */
        _g_subject[0] = '\0';
        _g_subject_level = 0;
    }
    else
    {
        snprintf(snd_msg, 127, SUBJECT, mailmsg->mail->subject);
    }
    OS_SendTCP(socket,snd_msg);



    /* Sending body */

    /* Sending multiple emails together if we have to */
    do
    {
        OS_SendTCP(socket, mailmsg->mail->body);
        mailmsg = OS_PopLastMail();
    }while(mailmsg);


    /* Sending end of data \r\n.\r\n */
    OS_SendTCP(socket,ENDDATA);	
    msg = OS_RecvTCP(socket, OS_SIZE_1024);
    if(mail->strict_checking && ((msg == NULL)||(!OS_Match(VALIDMAIL, msg))))
    {
        merror(END_DATA_ERROR);
        if(msg)
            free(msg);
        close(socket);
        return(OS_INVALID);	
    }
    /* Checking msg in here, since it may be null */
    if(msg)
        free(msg);


    /* quitting and closing socket */
    OS_SendTCP(socket,QUITMSG);
    msg = OS_RecvTCP(socket, OS_SIZE_1024);

    if(msg)
        free(msg);

    memset(snd_msg,'\0',128);	


    /* Returning 0 (success) */
    close(socket);

    return(0);
}
示例#2
0
/* OS_Run: Read the queue and send the appropriate alerts.
 * not supposed to return..
 */
static void OS_Run(MailConfig *mail)
{
    MailMsg *msg;
    MailMsg *s_msg = NULL;
    MailMsg *msg_sms = NULL;

    time_t tm;
    struct tm *p;

    int i = 0;
    int mailtosend = 0;
    int childcount = 0;
    int thishour = 0;

    int n_errs = 0;

    file_queue *fileq;


    /* Getting currently time before starting */
    tm = time(NULL);
    p = localtime(&tm);
    thishour = p->tm_hour;


    /* Init file queue */
    i = 0;
    i |= CRALERT_MAIL_SET;
    os_calloc(1, sizeof(file_queue), fileq);
    Init_FileQueue(fileq, p, i);


    /* Creating the list */
    OS_CreateMailList(MAIL_LIST_SIZE);


    /* Setting default timeout */
    mail_timeout = DEFAULT_TIMEOUT;


    /* Clearing global vars */
    _g_subject_level = 0;
    memset(_g_subject, '\0', SUBJECT_SIZE +2);


    while(1)
    {
        tm = time(NULL);
        p = localtime(&tm);


        /* SMS messages are sent without delay */
        if(msg_sms)
        {
            pid_t pid;

            pid = fork();

            if(pid < 0)
            {
                merror("%s: Fork failed. cause: %d - %s", ARGV0, errno, strerror(errno));
                merror(FORK_ERROR, ARGV0);
                sleep(30);
                continue;
            }
            else if (pid == 0)
            {
                if(OS_Sendsms(mail, p, msg_sms) < 0)
                    merror(SNDMAIL_ERROR, ARGV0, mail->smtpserver);

                exit(0);
            }


            /* Freeing sms structure */
            FreeMailMsg(msg_sms);
            msg_sms = NULL;


            /* Increasing child count */
            childcount++;
        }


        /* If mail_timeout == NEXTMAIL_TIMEOUT, we will try to get
         * more messages, before sending anything
         */
        if((mail_timeout == NEXTMAIL_TIMEOUT) && (p->tm_hour == thishour))
        {
            /* getting more messages */
        }


        /* Hour changed. Send all supressed mails */
        else if(((mailtosend < mail->maxperhour) && (mailtosend != 0))||
                ((p->tm_hour != thishour) && (childcount < MAXCHILDPROCESS)))
        {
            MailNode *mailmsg;
            pid_t pid;

            /* Checking if we have anything to sent */
            mailmsg = OS_CheckLastMail();
            if(mailmsg == NULL)
            {
                /* dont fork in here */
                goto snd_check_hour;
            }

            pid = fork();
            if(pid < 0)
            {
                merror("%s: Fork failed. cause: %d - %s", ARGV0, errno, strerror(errno));
                merror(FORK_ERROR, ARGV0);
                sleep(30);
                continue;
            }
            else if (pid == 0)
            {
                if(OS_Sendmail(mail, p) < 0)
                    merror(SNDMAIL_ERROR,ARGV0,mail->smtpserver);

                exit(0);
            }

            /* Cleaning the memory */
            mailmsg = OS_PopLastMail();
            do
            {
                FreeMail(mailmsg);
                mailmsg = OS_PopLastMail();
            }while(mailmsg);


            /* Increasing child count */
            childcount++;


            /* Clearing global vars */
            _g_subject[0] = '\0';
            _g_subject[SUBJECT_SIZE -1] = '\0';
            _g_subject_level = 0;


            /* Cleaning up set values */
            if(mail->gran_to)
            {
                i = 0;
                while(mail->gran_to[i] != NULL)
                {
                    if(s_msg && mail->gran_set[i] == DONOTGROUP)
                    {
                        mail->gran_set[i] = FULL_FORMAT;
                    }
                    else
                    {
                        mail->gran_set[i] = 0;
                    }
                    i++;
                }
            }

            snd_check_hour:
            /* If we sent everything */
            if(p->tm_hour != thishour)
            {
                thishour = p->tm_hour;

                mailtosend = 0;
            }
        }

        /* Saved message for the do_not_group option.
         */
        if(s_msg)
        {
            /* We need to set the remaining do no group to
             * full format.
             */
            if(mail->gran_to)
            {
                i = 0;
                while(mail->gran_to[i] != NULL)
                {
                    if(mail->gran_set[i] == DONOTGROUP)
                    {
                        mail->gran_set[i] = FULL_FORMAT;
                    }
                    i++;
                }
            }

            OS_AddMailtoList(s_msg);

            s_msg = NULL;
            mailtosend++;
            continue;
        }


        /* Receive message from queue */
        if((msg = OS_RecvMailQ(fileq, p, mail, &msg_sms)) != NULL)
        {
            /* If the e-mail priority is do_not_group, we first will
             * flush all previous entries and then send it.
             * We use s_msg to hold the pointer to the message
             * while we flush it.
             */
            if(mail->priority == DONOTGROUP)
            {
                s_msg = msg;
            }
            else
            {
                OS_AddMailtoList(msg);
            }


            /* Change timeout to see if any new message is coming shortly */
            if(mail->groupping)
            {
                /* If priority is set, send email now */
                if(mail->priority)
                {
                    mail_timeout = DEFAULT_TIMEOUT;

                    /* If do_not_group is set, we do not increase the
                     * list count in here.
                     */
                    if(mail->priority != DONOTGROUP)
                    {
                        mailtosend++;
                    }
                }
                else
                {
                    /* 5 seconds only */
                    mail_timeout = NEXTMAIL_TIMEOUT;
                }
            }
            else
            {
                /* Send message by itself */
                mailtosend++;
            }
        }
        else
        {
            if(mail_timeout == NEXTMAIL_TIMEOUT)
            {
                mailtosend++;

                /* Default timeout */
                mail_timeout = DEFAULT_TIMEOUT;
            }
        }


        /* Waiting for the childs .. */
        while (childcount)
        {
            int wp;
            int p_status;
            wp = waitpid((pid_t) -1, &p_status, WNOHANG);
            if (wp < 0)
            {
                merror(WAITPID_ERROR, ARGV0);
                n_errs++;
            }

            /* if = 0, we still need to wait for the child process */
            else if (wp == 0)
                break;
            else
            {
                if(p_status != 0)
                {
                    merror(CHLDWAIT_ERROR,ARGV0,p_status);
                    merror(SNDMAIL_ERROR,ARGV0,mail->smtpserver);
                    n_errs++;
                }
                childcount--;
            }

            /* Too many errors */
            if(n_errs > 6)
            {
                merror(TOOMANY_WAIT_ERROR,ARGV0);
                merror(SNDMAIL_ERROR,ARGV0,mail->smtpserver);
                exit(1);
            }
        }

    }
}