Esempio n. 1
0
static void MailResult(const ExecConfig *config, char *file)
{
    int sd, count = 0, anomaly = false;
    char prev_file[CF_BUFSIZE], vbuff[CF_BUFSIZE];
    struct hostent *hp;
    struct sockaddr_in raddr;
    struct servent *server;
    struct stat statbuf;
#if defined __linux__ || defined __NetBSD__ || defined __FreeBSD__ || defined __OpenBSD__
    time_t now = time(NULL);
#endif
    FILE *fp;

    CfOut(cf_verbose, "", "Mail result...\n");

    if (cfstat(file, &statbuf) == -1)
    {
        return;
    }

    snprintf(prev_file, CF_BUFSIZE - 1, "%s/outputs/previous", CFWORKDIR);
    MapName(prev_file);

    if (statbuf.st_size == 0)
    {
        unlink(file);
        CfDebug("Nothing to report in %s\n", file);
        return;
    }

    if (CompareResult(file, prev_file) == 0)
    {
        CfOut(cf_verbose, "", "Previous output is the same as current so do not mail it\n");
        return;
    }

    if ((strlen(config->mail_server) == 0) || (strlen(config->mail_to_address) == 0))
    {
        /* Syslog should have done this */
        CfOut(cf_verbose, "", "Empty mail server or address - skipping");
        return;
    }

    if (config->mail_max_lines == 0)
    {
        CfDebug("Not mailing: EmailMaxLines was zero\n");
        return;
    }

    CfDebug("Mailing results of (%s) to (%s)\n", file, config->mail_to_address);

/* Check first for anomalies - for subject header */

    if ((fp = fopen(file, "r")) == NULL)
    {
        CfOut(cf_inform, "fopen", "!! Couldn't open file %s", file);
        return;
    }

    while (!feof(fp))
    {
        vbuff[0] = '\0';
        if (fgets(vbuff, CF_BUFSIZE, fp) == NULL)
        {
            break;
        }

        if (strstr(vbuff, "entropy"))
        {
            anomaly = true;
            break;
        }
    }

    fclose(fp);

    if ((fp = fopen(file, "r")) == NULL)
    {
        CfOut(cf_inform, "fopen", "Couldn't open file %s", file);
        return;
    }

    CfDebug("Looking up hostname %s\n\n", config->mail_server);

    if ((hp = gethostbyname(config->mail_server)) == NULL)
    {
        printf("Unknown host: %s\n", config->mail_server);
        printf("Make sure that fully qualified names can be looked up at your site.\n");
        fclose(fp);
        return;
    }

    if ((server = getservbyname("smtp", "tcp")) == NULL)
    {
        CfOut(cf_inform, "getservbyname", "Unable to lookup smtp service");
        fclose(fp);
        return;
    }

    memset(&raddr, 0, sizeof(raddr));

    raddr.sin_port = (unsigned int) server->s_port;
    raddr.sin_addr.s_addr = ((struct in_addr *) (hp->h_addr))->s_addr;
    raddr.sin_family = AF_INET;

    CfDebug("Connecting...\n");

    if ((sd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
    {
        CfOut(cf_inform, "socket", "Couldn't open a socket");
        fclose(fp);
        return;
    }

    if (connect(sd, (void *) &raddr, sizeof(raddr)) == -1)
    {
        CfOut(cf_inform, "connect", "Couldn't connect to host %s\n", config->mail_server);
        fclose(fp);
        cf_closesocket(sd);
        return;
    }

/* read greeting */

    if (!Dialogue(sd, NULL))
    {
        goto mail_err;
    }

    sprintf(vbuff, "HELO %s\r\n", config->fq_name);
    CfDebug("%s", vbuff);

    if (!Dialogue(sd, vbuff))
    {
        goto mail_err;
    }

    if (strlen(config->mail_from_address) == 0)
    {
        sprintf(vbuff, "MAIL FROM: <cfengine@%s>\r\n", config->fq_name);
        CfDebug("%s", vbuff);
    }
    else
    {
        sprintf(vbuff, "MAIL FROM: <%s>\r\n", config->mail_from_address);
        CfDebug("%s", vbuff);
    }

    if (!Dialogue(sd, vbuff))
    {
        goto mail_err;
    }

    sprintf(vbuff, "RCPT TO: <%s>\r\n", config->mail_to_address);
    CfDebug("%s", vbuff);

    if (!Dialogue(sd, vbuff))
    {
        goto mail_err;
    }

    if (!Dialogue(sd, "DATA\r\n"))
    {
        goto mail_err;
    }

    if (anomaly)
    {
        sprintf(vbuff, "Subject: %s **!! [%s/%s]\r\n", MailSubject(), config->fq_name, config->ip_address);
        CfDebug("%s", vbuff);
    }
    else
    {
        sprintf(vbuff, "Subject: %s [%s/%s]\r\n", MailSubject(), config->fq_name, config->ip_address);
        CfDebug("%s", vbuff);
    }

    send(sd, vbuff, strlen(vbuff), 0);

#if defined __linux__ || defined __NetBSD__ || defined __FreeBSD__ || defined __OpenBSD__
    strftime(vbuff, CF_BUFSIZE, "Date: %a, %d %b %Y %H:%M:%S %z\r\n", localtime(&now));
    send(sd, vbuff, strlen(vbuff), 0);
#endif

    if (strlen(config->mail_from_address) == 0)
    {
        sprintf(vbuff, "From: cfengine@%s\r\n", config->fq_name);
        CfDebug("%s", vbuff);
    }
    else
    {
        sprintf(vbuff, "From: %s\r\n", config->mail_from_address);
        CfDebug("%s", vbuff);
    }

    send(sd, vbuff, strlen(vbuff), 0);

    sprintf(vbuff, "To: %s\r\n\r\n", config->mail_to_address);
    CfDebug("%s", vbuff);
    send(sd, vbuff, strlen(vbuff), 0);

    while (!feof(fp))
    {
        vbuff[0] = '\0';
        if (fgets(vbuff, CF_BUFSIZE, fp) == NULL)
        {
            break;
        }

        CfDebug("%s", vbuff);

        if (strlen(vbuff) > 0)
        {
            vbuff[strlen(vbuff) - 1] = '\r';
            strcat(vbuff, "\n");
            count++;
            send(sd, vbuff, strlen(vbuff), 0);
        }

        if ((config->mail_max_lines != INF_LINES) && (count > config->mail_max_lines))
        {
            sprintf(vbuff, "\r\n[Mail truncated by cfengine. File is at %s on %s]\r\n", file, config->fq_name);
            send(sd, vbuff, strlen(vbuff), 0);
            break;
        }
    }

    if (!Dialogue(sd, ".\r\n"))
    {
        CfDebug("mail_err\n");
        goto mail_err;
    }

    Dialogue(sd, "QUIT\r\n");
    CfDebug("Done sending mail\n");
    fclose(fp);
    cf_closesocket(sd);
    return;

  mail_err:

    fclose(fp);
    cf_closesocket(sd);
    CfOut(cf_log, "", "Cannot mail to %s.", config->mail_to_address);
}
Esempio n. 2
0
void MailResult(char *file,char *to)

{ int sd, sent, count = 0, anomaly = false;
  char domain[256], prev_file[CF_BUFSIZE];
  struct hostent *hp;
  struct sockaddr_in raddr;
  struct servent *server;
  struct stat statbuf;
  time_t now = time(NULL);
  FILE *fp;

if ((strlen(VMAILSERVER) == 0) || (strlen(to) == 0))
   {
   /* Syslog should have done this */
   return;
   }
  
if (stat(file,&statbuf) == -1)
   {
   exit(0);
   }

snprintf(prev_file,CF_BUFSIZE-1,"%s/outputs/previous",CFWORKDIR);

if (statbuf.st_size == 0)
   {
   unlink(file);
   Debug("Nothing to report in %s\n",file);
   return;
   }

if (CompareResult(file,prev_file) == 0 ) 
   {
   Verbose("Previous output is the same as current so do not mail it\n");
   return;
   }

if (MAXLINES == 0)
   {
   Debug("Not mailing: EmailMaxLines was zero\n");
   return;
   }
 
Debug("Mailing results of (%s) to (%s)\n",file,to);
 
if (strlen(to) == 0)
   {
   return;
   }

/* Check first for anomalies - for subject header */
 
if ((fp=fopen(file,"r")) == NULL)
   {
   snprintf(VBUFF,CF_BUFSIZE-1,"Couldn't open file %s",file);
   CfLog(cfinform,VBUFF,"fopen");
   return;
   }

 while (!feof(fp))
    {
    VBUFF[0] = '\0';
    fgets(VBUFF,CF_BUFSIZE,fp);
    if (strstr(VBUFF,"entropy"))
       {
       anomaly = true;
       break;
       }
    }
 
fclose(fp);
 
if ((fp=fopen(file,"r")) == NULL)
   {
   snprintf(VBUFF,CF_BUFSIZE-1,"Couldn't open file %s",file);
   CfLog(cfinform,VBUFF,"fopen");
   return;
   }
 
Debug("Looking up hostname %s\n\n",VMAILSERVER);

if ((hp = gethostbyname(VMAILSERVER)) == NULL)
   {
   printf("Unknown host: %s\n", VMAILSERVER);
   printf("Make sure that fully qualified names can be looked up at your site!\n");
   printf("i.e. www.gnu.org, not just www. If you use NIS or /etc/hosts\n");
   printf("make sure that the full form is registered too as an alias!\n");
   fclose(fp);
   return;
   }

if ((server = getservbyname("smtp","tcp")) == NULL)
   {
   CfLog(cfinform,"Unable to lookup smtp service","getservbyname");
   fclose(fp);
   return;
   }

memset(&raddr,0,sizeof(raddr));

raddr.sin_port = (unsigned int) server->s_port;
raddr.sin_addr.s_addr = ((struct in_addr *)(hp->h_addr))->s_addr;
raddr.sin_family = AF_INET;  

Debug("Connecting...\n");

if ((sd = socket(AF_INET,SOCK_STREAM,0)) == -1)
   {
   CfLog(cfinform,"Couldn't open a socket","socket");
   fclose(fp);
   return;
   }
   
if (connect(sd,(void *) &raddr,sizeof(raddr)) == -1)
   {
   snprintf(OUTPUT,CF_BUFSIZE*2,"Couldn't connect to host %s\n",VMAILSERVER);
   CfLog(cfinform,OUTPUT,"connect");
   fclose(fp);
   close(sd);
   return;
   }

/* read greeting */
 
if (!Dialogue(sd,NULL))
   {
   goto mail_err;
   }
 
sprintf(VBUFF,"HELO %s\r\n",VFQNAME); 
Debug("%s",VBUFF);

if (!Dialogue(sd,VBUFF))
   {
   goto mail_err;
   }

 if (strlen(MAILFROM) == 0)
    {
    sprintf(VBUFF,"MAIL FROM: <cfengine@%s>\r\n",VFQNAME);
    Debug("%s",VBUFF);
    }
 else
    {
    sprintf(VBUFF,"MAIL FROM: <%s>\r\n",MAILFROM);
    Debug("%s",VBUFF);    
    }

if (!Dialogue(sd,VBUFF))
   {
   goto mail_err;
   }
 
sprintf(VBUFF,"RCPT TO: <%s>\r\n",to);
Debug("%s",VBUFF);

if (!Dialogue(sd,VBUFF))
    {
    goto mail_err;
    }

if (!Dialogue(sd,"DATA\r\n"))
    {
    goto mail_err;
    }

if (anomaly)
   {
   sprintf(VBUFF,"Subject: **!! (%s/%s)\r\n",VFQNAME,VIPADDRESS);
   Debug("%s",VBUFF);
   }
else
   {
   sprintf(VBUFF,"Subject: (%s/%s)\r\n",VFQNAME,VIPADDRESS);
   Debug("%s",VBUFF);
   }
 
sent=send(sd,VBUFF,strlen(VBUFF),0);

#if defined LINUX || defined NETBSD || defined FREEBSD || defined OPENBSD
strftime(VBUFF,CF_BUFSIZE,"Date: %a, %d %b %Y %H:%M:%S %z\r\n",localtime(&now));
sent=send(sd,VBUFF,strlen(VBUFF),0);
#endif

 if (strlen(MAILFROM) == 0)
    {
    sprintf(VBUFF,"From: cfengine@%s\r\n",VFQNAME);
    Debug("%s",VBUFF);
    }
 else
    {
    sprintf(VBUFF,"From: %s\r\n",MAILFROM);
    Debug("%s",VBUFF);    
    }
 
sent=send(sd,VBUFF,strlen(VBUFF),0);

sprintf(VBUFF,"To: %s\r\n\r\n",to); 
Debug("%s",VBUFF);
sent=send(sd,VBUFF,strlen(VBUFF),0);

while(!feof(fp))
   {
   VBUFF[0] = '\0';
   fgets(VBUFF,CF_BUFSIZE,fp);
   Debug("%s",VBUFF);
   
   if (strlen(VBUFF) > 0)
      {
      VBUFF[strlen(VBUFF)-1] = '\r';
      strcat(VBUFF, "\n");
      count++;
      sent=send(sd,VBUFF,strlen(VBUFF),0);
      }
   
   if ((MAXLINES != INF_LINES) && (count > MAXLINES))
      {
      sprintf(VBUFF,"\r\n[Mail truncated by cfengine. File is at %s on %s]\r\n",file,VFQNAME);
      sent=send(sd,VBUFF,strlen(VBUFF),0);
      break;
      }
   } 

if (!Dialogue(sd,".\r\n"))
   {
   Debug("mail_err\n");
   goto mail_err;
   }
 
Dialogue(sd,"QUIT\r\n");
Debug("Done sending mail\n");
fclose(fp);
close(sd);
return;
 
mail_err: 

fclose(fp);
close(sd); 
sprintf(VBUFF, "Cannot mail to %s.", to);
CfLog(cflogonly,VBUFF,"");
}
Esempio n. 3
0
static void MailResult(const ExecConfig *config, const char *file)
{
#if defined __linux__ || defined __NetBSD__ || defined __FreeBSD__ || defined __OpenBSD__
    time_t now = time(NULL);
#endif
    Log(LOG_LEVEL_VERBOSE, "Mail result...");

    {
        struct stat statbuf;
        if (stat(file, &statbuf) == -1)
        {
            return;
        }

        if (statbuf.st_size == 0)
        {
            unlink(file);
            Log(LOG_LEVEL_DEBUG, "Nothing to report in file '%s'", file);
            return;
        }
    }

    {
        char prev_file[CF_BUFSIZE];
        snprintf(prev_file, CF_BUFSIZE - 1, "%s/outputs/previous", CFWORKDIR);
        MapName(prev_file);

        if (CompareResult(file, prev_file) == 0)
        {
            Log(LOG_LEVEL_VERBOSE, "Previous output is the same as current so do not mail it");
            return;
        }
    }

    if ((strlen(config->mail_server) == 0) || (strlen(config->mail_to_address) == 0))
    {
        /* Syslog should have done this */
        Log(LOG_LEVEL_VERBOSE, "Empty mail server or address - skipping");
        return;
    }

    if (config->mail_max_lines == 0)
    {
        Log(LOG_LEVEL_DEBUG, "Not mailing: EmailMaxLines was zero");
        return;
    }

    Log(LOG_LEVEL_DEBUG, "Mailing results of '%s' to '%s'", file, config->mail_to_address);

/* Check first for anomalies - for subject header */

    FILE *fp = fopen(file, "r");
    if (!fp)
    {
        Log(LOG_LEVEL_INFO, "Couldn't open file '%s'. (fopen: %s)", file, GetErrorStr());
        return;
    }

    bool anomaly = false;
    char vbuff[CF_BUFSIZE];

    while (!feof(fp))
    {
        vbuff[0] = '\0';
        if (fgets(vbuff, sizeof(vbuff), fp) == NULL)
        {
            break;
        }

        if (strstr(vbuff, "entropy"))
        {
            anomaly = true;
            break;
        }
    }

    fclose(fp);

    if ((fp = fopen(file, "r")) == NULL)
    {
        Log(LOG_LEVEL_INFO, "Couldn't open file '%s'. (fopen: %s)", file, GetErrorStr());
        return;
    }

    struct hostent *hp = gethostbyname(config->mail_server);
    if (!hp)
    {
        Log(LOG_LEVEL_ERR, "While mailing agent output, unknown host '%s'. Make sure that fully qualified names can be looked up at your site.",
            config->mail_server);
        fclose(fp);
        return;
    }

    struct servent *server = getservbyname("smtp", "tcp");
    if (!server)
    {
        Log(LOG_LEVEL_INFO, "Unable to lookup smtp service. (getservbyname: %s)", GetErrorStr());
        fclose(fp);
        return;
    }

    struct sockaddr_in raddr;
    memset(&raddr, 0, sizeof(raddr));

    raddr.sin_port = (unsigned int) server->s_port;
    raddr.sin_addr.s_addr = ((struct in_addr *) (hp->h_addr))->s_addr;
    raddr.sin_family = AF_INET;

    Log(LOG_LEVEL_DEBUG, "Connecting...");

    int sd = socket(AF_INET, SOCK_STREAM, 0);
    if (sd == -1)
    {
        Log(LOG_LEVEL_INFO, "Couldn't open a socket. (socket: %s)", GetErrorStr());
        fclose(fp);
        return;
    }

    if (connect(sd, (void *) &raddr, sizeof(raddr)) == -1)
    {
        Log(LOG_LEVEL_INFO, "Couldn't connect to host '%s'. (connect: %s)",
            config->mail_server, GetErrorStr());
        fclose(fp);
        cf_closesocket(sd);
        return;
    }

/* read greeting */

    if (!Dialogue(sd, NULL))
    {
        goto mail_err;
    }

    sprintf(vbuff, "HELO %s\r\n", config->fq_name);
    Log(LOG_LEVEL_DEBUG, "%s", vbuff);

    if (!Dialogue(sd, vbuff))
    {
        goto mail_err;
    }

    if (strlen(config->mail_from_address) == 0)
    {
        sprintf(vbuff, "MAIL FROM: <cfengine@%s>\r\n", config->fq_name);
        Log(LOG_LEVEL_DEBUG, "%s", vbuff);
    }
    else
    {
        sprintf(vbuff, "MAIL FROM: <%s>\r\n", config->mail_from_address);
        Log(LOG_LEVEL_DEBUG, "%s", vbuff);
    }

    if (!Dialogue(sd, vbuff))
    {
        goto mail_err;
    }

    sprintf(vbuff, "RCPT TO: <%s>\r\n", config->mail_to_address);
    Log(LOG_LEVEL_DEBUG, "%s", vbuff);

    if (!Dialogue(sd, vbuff))
    {
        goto mail_err;
    }

    if (!Dialogue(sd, "DATA\r\n"))
    {
        goto mail_err;
    }

    char mailsubject_anomaly_prefix[8];
    if (anomaly)
    {
        strcpy(mailsubject_anomaly_prefix, "**!! ");
    }
    else
    {
        mailsubject_anomaly_prefix[0] = '\0';
    }

    if (SafeStringLength(config->mail_subject) == 0)
    {
        snprintf(vbuff, sizeof(vbuff), "Subject: %s[%s/%s]\r\n", mailsubject_anomaly_prefix, config->fq_name, config->ip_address);
        Log(LOG_LEVEL_DEBUG, "%s", vbuff);
    }
    else
    {
        snprintf(vbuff, sizeof(vbuff), "Subject: %s%s\r\n", mailsubject_anomaly_prefix, config->mail_subject);
        Log(LOG_LEVEL_DEBUG, "%s", vbuff);
    }

    send(sd, vbuff, strlen(vbuff), 0);

    /* send X-CFEngine SMTP header if mailsubject set */
    if (SafeStringLength(config->mail_subject) > 0)
    {
        unsigned char digest[EVP_MAX_MD_SIZE + 1];
        char buffer[EVP_MAX_MD_SIZE * 4];

        char *existing_policy_server = ReadPolicyServerFile(GetWorkDir());

        HashPubKey(PUBKEY, digest, CF_DEFAULT_DIGEST);

        snprintf(vbuff, sizeof(vbuff), "X-CFEngine: vfqhost=\"%s\";ip-addresses=\"%s\";policyhub=\"%s\";pkhash=\"%s\"\r\n",
                 VFQNAME, config->ip_addresses, existing_policy_server,
                 HashPrintSafe(CF_DEFAULT_DIGEST, true, digest, buffer));

        send(sd, vbuff, strlen(vbuff), 0);
        free(existing_policy_server);
    }

#if defined __linux__ || defined __NetBSD__ || defined __FreeBSD__ || defined __OpenBSD__
    strftime(vbuff, CF_BUFSIZE, "Date: %a, %d %b %Y %H:%M:%S %z\r\n", localtime(&now));
    send(sd, vbuff, strlen(vbuff), 0);
#endif

    if (strlen(config->mail_from_address) == 0)
    {
        sprintf(vbuff, "From: cfengine@%s\r\n", config->fq_name);
        Log(LOG_LEVEL_DEBUG, "%s", vbuff);
    }
    else
    {
        sprintf(vbuff, "From: %s\r\n", config->mail_from_address);
        Log(LOG_LEVEL_DEBUG, "%s", vbuff);
    }

    send(sd, vbuff, strlen(vbuff), 0);

    sprintf(vbuff, "To: %s\r\n\r\n", config->mail_to_address);
    Log(LOG_LEVEL_DEBUG, "%s", vbuff);
    send(sd, vbuff, strlen(vbuff), 0);

    int count = 0;
    while (!feof(fp))
    {
        vbuff[0] = '\0';
        if (fgets(vbuff, sizeof(vbuff), fp) == NULL)
        {
            break;
        }

        Log(LOG_LEVEL_DEBUG, "%s", vbuff);

        if (strlen(vbuff) > 0)
        {
            vbuff[strlen(vbuff) - 1] = '\r';
            strcat(vbuff, "\n");
            count++;
            send(sd, vbuff, strlen(vbuff), 0);
        }

        if ((config->mail_max_lines != INF_LINES) && (count > config->mail_max_lines))
        {
            sprintf(vbuff, "\r\n[Mail truncated by cfengine. File is at %s on %s]\r\n", file, config->fq_name);
            send(sd, vbuff, strlen(vbuff), 0);
            break;
        }
    }

    if (!Dialogue(sd, ".\r\n"))
    {
        Log(LOG_LEVEL_DEBUG, "mail_err\n");
        goto mail_err;
    }

    Dialogue(sd, "QUIT\r\n");
    Log(LOG_LEVEL_DEBUG, "Done sending mail");
    fclose(fp);
    cf_closesocket(sd);
    return;

  mail_err:

    fclose(fp);
    cf_closesocket(sd);
    Log(LOG_LEVEL_INFO, "Cannot mail to %s.", config->mail_to_address);
}
Esempio n. 4
0
int main(int argc, char *argv[])
{
    if (CompareResult(argv[1], argv[2]) != 0) exit(1);
    return 0;
}