/* Los servidores de correo (SMPT), actualmente requieren establecer una conexión para autentificar al usuario antes de enviar el correo. Según el servidor la seguridad se puede obtener vía SSL o TSL. En este ejemplo se usa TSL a través del utilitario openssl. Una vez que la conexión es segura, y debido a que las claves o password pueden usar casi cualquier caracter, para autenticarse, la cuenta y la clave deben enviarse codificadas en base64. Una vez que se acepta la autenticación, se procede a enviar el correo usando los comandos del protocolo SMTP. */ #include #include #include #include #include #define LINE_SIZE 200 int main(void) { pid_t pid; int pfdToChild[2]; int pfdFromChild[2]; int i, status; char smtp[LINE_SIZE]; int port; char auth[LINE_SIZE]; char rcpt_to[LINE_SIZE]; FILE * toChild, *fromChild; char line[LINE_SIZE]; printf("Ingrese el servidor smtp a utilizar:"); scanf("%s",smtp); printf("Ingrese el puerto donde éste escucha:"); scanf("%i",&port); printf("Ingrese, en base64, la cuenta y password desde donde enviará el correo:"); scanf("%s",auth); printf("Ingrese la cuenta a donde enviará el correo:"); scanf("%s",rcpt_to); printf("SMTP: %s\n",smtp); printf("Port: %i\n",port); printf("AUTH: %s\n",auth); printf("RCPT TO: %s\n",rcpt_to); /* * Create a pipe. */ if (pipe(pfdToChild) < 0) { perror("pipe"); exit(1); } if (pipe(pfdFromChild) < 0) { perror("pipe"); exit(1); } /* * Create a child process. */ if ((pid = fork()) < 0) { perror("fork"); exit(1); } /* * The child process executes "openssl" to create a secure conection. */ if (pid == 0) { /* * Attach standard input to the end of the pipe where parent writes. */ dup2(pfdToChild[0], 0); /* parent process -> openssl */ close(pfdToChild[1]); /* * Attach standard output to the end of the pipe where parent reads. */ dup2(pfdFromChild[1],1); /* openssl -> parent */ dup2(pfdFromChild[1],2); /* it's important, the error/success codes of each smtp command go to standard error */ close(pfdFromChild[0]); sprintf(line,"%s:%i",smtp,port); /* variable arguments of openssl */ execl("/usr/bin/openssl", "openssl", "s_client", "-connect", line, "-crlf", "-starttls","smtp", NULL); perror("exec"); _exit(127); } /* This is the parent */ close(pfdToChild[0]); close(pfdFromChild[1]); toChild = fdopen(pfdToChild[1], "w"); fromChild = fdopen(pfdFromChild[0], "r"); /* * Write our mail message to the pipe. */ /* wait for the end of the key exchange mechanism */ while (strncmp(fgets(line, sizeof(line), fromChild),"250 ",4)!=0); fprintf(toChild,"AUTH PLAIN %s\n", auth); fflush(toChild); fgets(line, sizeof(line), fromChild); printf("\tAGV AUTH\t%s\n", line); fprintf(toChild,"mail from: %s\n",""); fflush(toChild); fgets(line, sizeof(line), fromChild); printf("\tAGV mail from\t%s\n", line); fprintf(toChild,"rcpt to: %s\n",rcpt_to); /*it must be recpt to with lowercase! */ fflush(toChild); fgets(line, sizeof(line), fromChild); printf("\tAGV rcpt to\t%s\n", line); fprintf(toChild,"data\n"); fflush(toChild); fgets(line, sizeof(line), fromChild); printf("\tAGV data\t%s\n", line); fprintf(toChild, "From:\"Sansanito\" \n\ To: \"Amigos\" \nSubject: Correo de prueba\n\n\ Este es un correo de prueba enviado una cuenta gmail de Agustin y usando dos pipes.\n.\ Quede' mal despues de la clase de hoy en que muchas cosas no funcionaron, partiendo por la \ red. Con este correo ahora todo funciona. Agustin\n.\n"); fflush(toChild); fgets(line, sizeof(line), fromChild); printf("\tAGV\t%s\n", line); fprintf(toChild,"quit\n"); fflush(toChild); fgets(line, sizeof(line), fromChild); printf("\tAGV quit\t%s\n", line); /* * Close the pipe and wait for the child * to exit. */ fclose(toChild); fclose(fromChild); waitpid(pid, &status, 0); /* * Exit with a status of 0, indicating that * everything went fine. */ exit(0); }