Loading ...
Sorry, an error occurred while loading the content.
 

external postfix content filter poc doesn't work

Expand Messages
  • Gökhan Alkan
    I try to develop poc code for postfix content filtering. All i need is read the 10025/tcp and send all data which i can read to 10026/tcp. Below is my poc
    Message 1 of 7 , Apr 23, 2014
      I try to develop poc code for postfix content filtering. All i need is read the 10025/tcp and send all data which i can read to 10026/tcp. Below is my poc code. But i try to send email it doesn't work and postfix show me "451 4.3.0 Error: queue file write error".

      
      #include <stdio.h>
      #include <string.h>
      #include <stdlib.h>
      #include <sys/socket.h>
      #include <arpa/inet.h>
      #include <netinet/in.h>
      #include <unistd.h>
      #include <time.h>
      #include <errno.h>
      #include <fcntl.h>
      
      
      #define PORT 10025
      #define REMOTE_PORT 10026
      #define REMOTE_IP "0.0.0.0"
      
      
      int main(int argc, const char **argv)
      {
      
              int addr_len, result, yes = 1;
              int server_sock = 0, client_sock = 0, sock_fd = 0;
              char buff[1025];
      
              struct sockaddr_in serv_addr, client_addr, remote_addr;
      
      
              if ((server_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
                      perror("socket");
                      exit(EXIT_FAILURE);
              }
      
              if (setsockopt(server_sock, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) { 
                      perror("setsockopt"); 
                      exit(1); 
              }  
      
              memset(buff, 0x0, sizeof(buff));
              memset(&serv_addr, 0x0, sizeof(serv_addr));
              memset(&client_addr, 0x0, sizeof(client_addr));
              memset(&remote_addr, 0x0, sizeof(remote_addr));
      
              serv_addr.sin_family = AF_INET;
              serv_addr.sin_port = htons(PORT);
              serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
      
              remote_addr.sin_family = AF_INET;
              remote_addr.sin_port = htons(REMOTE_PORT); 
      
      
              if ((bind(server_sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr))) < 0) {
                      perror("bind");
                      exit(EXIT_FAILURE);
              }
      
              if (listen(server_sock, 8) < 0) {
                      perror("listen");
                      exit(EXIT_FAILURE);     
              }       
      
              fcntl(server_sock, F_SETFL, O_NONBLOCK);
              fcntl(client_sock, F_SETFL, O_NONBLOCK); 
      
              addr_len = sizeof(client_addr);
              client_sock = accept(server_sock, (struct sockaddr *)&client_addr, &addr_len);
              sock_fd = socket(AF_INET, SOCK_STREAM, 0);      
      
              while(1) {
                      result = recv(client_sock, buff, sizeof(buff),0 );
                      inet_pton(AF_INET, REMOTE_IP, &remote_addr.sin_addr);
                      connect(sock_fd, (struct sockaddr *)&remote_addr, sizeof(remote_addr));
                      send(sock_fd, buff, (sizeof(buff)-1), 0);
              }
      
      
              shutdown(client_sock, SHUT_RDWR);
      
              close(server_sock);
              close(client_sock);
              close(sock_fd);
      
              return 0;
      }

      And here is my postfix master.cf configuration.

      smtp inet n - n - 20 smtpd -o smtpd_proxy_filter=0.0.0.0:10025 -o smtpd_client_connection_count_limit=10

      0.0.0.0:10026 inet n - n - - smtpd -o smtpd_authorized_xforward_hosts=127.0.0.0/8 -o smtpd_client_restrictions= -o smtpd_helo_restrictions= -o smtpd_sender_restrictions= -o smtpd_recipient_restrictions=permit_mynetworks,reject -o smtpd_data_restrictions= -o mynetworks=127.0.0.0/8 -o receive_override_options=no_unknown_recipient_checks

    • Wietse Venema
      ... I recommend that you use netcat. Wietse ... What if fcntl() reports an error? ... client_sock is still zero here. What if fcntl() reports an error? ...
      Message 2 of 7 , Apr 23, 2014
        G?khan Alkan:
        > I try to develop poc code for postfix content filtering. All i need is read
        > the 10025/tcp and send all data which i can read to 10026/tcp. Below is my
        > poc code. But i try to send email it doesn't work and postfix show me "451
        > 4.3.0 Error: queue file write error".

        I recommend that you use netcat.

        Wietse

        > fcntl(server_sock, F_SETFL, O_NONBLOCK);

        What if fcntl() reports an error?

        > fcntl(client_sock, F_SETFL, O_NONBLOCK);

        client_sock is still zero here.

        What if fcntl() reports an error?

        > client_sock = accept(server_sock, (struct sockaddr
        > *)&client_addr, &addr_len);

        What if accept() reports an error? It will always return -1 because
        server_sock is non-blocking. Thus, client_sock will always be -1.

        > sock_fd = socket(AF_INET, SOCK_STREAM, 0);

        What if socket() reports an error?

        > while(1) {
        > result = recv(client_sock, buff, sizeof(buff),0 );

        What if recv() reports an error? At this point, client_sock is
        -1 because accept() reported an error. See above.

        > inet_pton(AF_INET, REMOTE_IP, &remote_addr.sin_addr);
        > connect(sock_fd, (struct sockaddr *)&remote_addr,
        > sizeof(remote_addr));

        What if connect() reports an error?

        > send(sock_fd, buff, (sizeof(buff)-1), 0);

        What if send() reports an error?

        > }

        The above program loops forever in while(1).

        > shutdown(client_sock, SHUT_RDWR);

        What if shutdown() reports an error? At this point client_sock is -1
        because accept() reported an error. See above.

        > close(server_sock);
        > close(client_sock);
        > close(sock_fd);

        Wietse
      • Gökhan Alkan
        Hi all, Thank you for your reply. - You recommened me that use netcat. But what for ? (debugging, sending test email vs vs ...) Can you explain a bit more
        Message 3 of 7 , Apr 23, 2014
          Hi all,

          Thank you for your reply.

          - You recommened me that use netcat. But what for ?  (debugging, sending test email vs vs ...) Can you explain a bit more please ? 

          - As you said i added the code error handling. But when i run this poc code and try to send email postfix again says me "451 4.3.0 Error: queue file write error" and wait rcpt to : xxx@.... All i need is send mail through 10025/tcp and send it through 10026/tcp. So i can see smtp traffic before-queue postfix method.

          Actually i have explored example code but i havent seen. So i don't know how i can debug and fix this. I try to develop program running before-queue postfix method.

          Best regards.


          New code is below

          #include <stdio.h>
          #include <string.h>
          #include <stdlib.h>
          #include <sys/socket.h>
          #include <arpa/inet.h>
          #include <netinet/in.h>
          #include <unistd.h>
          #include <time.h>
          #include <errno.h>
          #include <fcntl.h>

          #define PORT 10025
          #define REMOTE_PORT 10026
          #define REMOTE_IP "0.0.0.0"
          #define TRUE 1

          void exitsys(const char *msg);

          int main(int argc, const char **argv)
          {
                  int addr_len, result, yes = 1;
                  int server_sock = 0, client_sock = 0, sock_fd = 0;
                  char buff[1025];
                  struct sockaddr_in server_addr, client_addr, remote_addr;
                  fd_set read_fds;
                  struct timeval timeout;

                  timeout.tv_sec = 1;     // seconds
                  timeout.tv_usec = 0;

                  if ((server_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
                          exitsys("socket");

                  if (setsockopt(server_sock, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1)
                          exitsys("setsockopt");


                  memset(buff, 0x0, sizeof(buff));
                  memset(&server_addr, 0x0, sizeof(server_addr));
                  memset(&client_addr, 0x0, sizeof(client_addr));
                  memset(&remote_addr, 0x0, sizeof(remote_addr));

                  server_addr.sin_family = AF_INET;
                  server_addr.sin_port = htons(PORT);
                  server_addr.sin_addr.s_addr = htonl(INADDR_ANY);

                  remote_addr.sin_family = AF_INET;
                  remote_addr.sin_port = htons(REMOTE_PORT); 


                  if ((bind(server_sock, (struct sockaddr*)&server_addr, sizeof(server_addr))) < 0) 
                          exitsys("bind");

                  if (fcntl(server_sock, F_SETFL, O_NONBLOCK) < 0)
                          exitsys("fcntl");
                  
                  if (listen(server_sock, 8) < 0) 
                          exitsys("listen");

                 while (TRUE) {
                          if ( (select(server_sock, NULL, NULL, NULL, &timeout)) > 0) {
                                  addr_len = sizeof(client_addr);

                                  if ( (client_sock = accept(server_sock, (struct sockaddr *)&client_addr, &addr_len)) < 0 )
                                          exitsys("accept-1");

                                  if ( ( sock_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0 )
                                          exitsys("socket");      

                                  inet_pton(AF_INET, REMOTE_IP, &remote_addr.sin_addr);
                                  connect(sock_fd, (struct sockaddr *)&remote_addr, sizeof(remote_addr));

                                  if ( fcntl(client_sock, F_SETFL, O_NONBLOCK) < 0)
                                          exitsys("fcntl");


                                  while (TRUE) {
                                          if ( (select(client_sock, NULL, NULL, NULL, &timeout)) > 0 ) {

                                                  result = recv(client_sock, buff, sizeof(buff), 0);
                                                  if (result > 0)
                                                          send(sock_fd, buff, (sizeof(buff)-1), 0);
                                                  else
                                                          printf("YOK\n");
                                          }
                                  }
                                  shutdown(client_sock, SHUT_RDWR);

                                  close(server_sock);
                                  close(client_sock);
                                  close(sock_fd);
                          }
                  }

                  return 0;
          }


          void exitsys(const char *msg)
          {
                  perror(msg);
                  exit(EXIT_FAILURE);
          }




          On Wed, Apr 23, 2014 at 4:59 PM, Wietse Venema <wietse@...> wrote:
          G?khan Alkan:
          > I try to develop poc code for postfix content filtering. All i need is read
          > the 10025/tcp and send all data which i can read to 10026/tcp. Below is my
          > poc code. But i try to send email it doesn't work and postfix show me "451
          > 4.3.0 Error: queue file write error".

          I recommend that you use netcat.

                  Wietse

          >         fcntl(server_sock, F_SETFL, O_NONBLOCK);

          What if fcntl() reports an error?

          >         fcntl(client_sock, F_SETFL, O_NONBLOCK);

          client_sock is still zero here.

          What if fcntl() reports an error?

          >         client_sock = accept(server_sock, (struct sockaddr
          > *)&client_addr, &addr_len);

          What if accept() reports an error?  It will always return -1 because
          server_sock is non-blocking. Thus, client_sock will always be -1.

          >         sock_fd = socket(AF_INET, SOCK_STREAM, 0);

          What if socket() reports an error?

          >         while(1) {
          >                 result = recv(client_sock, buff, sizeof(buff),0 );

          What if recv() reports an error? At this point, client_sock is
          -1 because accept() reported an error. See above.

          >                 inet_pton(AF_INET, REMOTE_IP, &remote_addr.sin_addr);
          >                 connect(sock_fd, (struct sockaddr *)&remote_addr,
          > sizeof(remote_addr));

          What if connect() reports an error?

          >                 send(sock_fd, buff, (sizeof(buff)-1), 0);

          What if send() reports an error?

          >         }

          The above program loops forever in while(1).

          >         shutdown(client_sock, SHUT_RDWR);

          What if shutdown() reports an error? At this point client_sock is -1
          because accept() reported an error. See above.

          >         close(server_sock);
          >         close(client_sock);
          >         close(sock_fd);

                  Wietse



          --
          ----------------------
          Gökhan ALKAN

        • Wietse Venema
          ... Your program copies only in one direction. SMTP requires that you copy data in both directions between the client that connects to port 10025/tcp, and the
          Message 4 of 7 , Apr 23, 2014
            G?khan Alkan:
            > Hi all,
            >
            > Thank you for your reply.

            Your program copies only in one direction. SMTP requires that you
            copy data in both directions between the client that connects to
            port 10025/tcp, and the server that listens on port 10026/tcp.

            Look in with a search engine for smtpprox. It speaks SMTP and does
            exactly what you need. You can add code to it as needed.

            smtpprox is written in Perl. I expect that similar code has been
            written in Python and so on. Don't try to do this in C.

            Wietse
          • Gökhan Alkan
            Hi all, Thank you for your reply again. I assume that receive data from 10025/tcp and send to 10026 is enough for this purpose. But i think, i am wrong this
            Message 5 of 7 , Apr 23, 2014
              Hi all,

              Thank you for your reply again.

              I assume that receive data from 10025/tcp and send to 10026 is enough for this purpose. But i think, i am wrong this subject. I should send data both client which connect to 10025 and other side which i will connect to 10026.

              I will explore this project named smtpprox. But you said to me dont try to do this in C. Why you said this? As you said it can be developed using pyhton perl or any other script language. But what about performance problem? Especially server which is under heavy email traffic 

              Best regards



              On Thursday, April 24, 2014, Wietse Venema <wietse@...> wrote:
              G?khan Alkan:
              > Hi all,
              >
              > Thank you for your reply.

              Your program copies only in one direction.  SMTP requires that you
              copy data in both directions between the client that connects to
              port 10025/tcp, and the server that listens on port 10026/tcp.

              Look in with a search engine for smtpprox. It speaks SMTP and does
              exactly what you need. You can add code to it as needed.

              smtpprox is written in Perl. I expect that similar code has been
              written in Python and so on. Don't try to do this in C.

                      Wietse


              --
              ----------------------
              Gökhan ALKAN


            • Wietse Venema
              ... My advice, as an experienced programmer, is that you should not write mission-critical code in C. The performance difference is irrelevant because the
              Message 6 of 7 , Apr 23, 2014
                G?khan Alkan:
                > Hi all,
                >
                > Thank you for your reply again.
                >
                > I assume that receive data from 10025/tcp and send to 10026 is enough for
                > this purpose. But i think, i am wrong this subject. I should send data both
                > client which connect to 10025 and other side which i will connect to 10026.
                >
                > I will explore this project named smtpprox. But you said to me dont try to
                > do this in C. Why you said this? As you said it can be developed using
                > pyhton perl or any other script language. But what about performance
                > problem? Especially server which is under heavy email traffic

                My advice, as an experienced programmer, is that you should not
                write mission-critical code in C. The performance difference is
                irrelevant because the scripts work, and your code does not work.

                If you ask me again why, then I will no longer be polite.

                Wietse
              • Gökhan Alkan
                Hi Thanks for your replies. Best regards ... -- ... Gökhan ALKAN Hi Thanks for your replies.  Best regards On Thursday, April 24, 2014, Wietse Venema
                Message 7 of 7 , Apr 23, 2014
                  Hi

                  Thanks for your replies. 

                  Best regards

                  On Thursday, April 24, 2014, Wietse Venema <wietse@...> wrote:
                  G?khan Alkan:
                  > Hi all,
                  >
                  > Thank you for your reply again.
                  >
                  > I assume that receive data from 10025/tcp and send to 10026 is enough for
                  > this purpose. But i think, i am wrong this subject. I should send data both
                  > client which connect to 10025 and other side which i will connect to 10026.
                  >
                  > I will explore this project named smtpprox. But you said to me dont try to
                  > do this in C. Why you said this? As you said it can be developed using
                  > pyhton perl or any other script language. But what about performance
                  > problem? Especially server which is under heavy email traffic

                  My advice, as an experienced programmer, is that you should not
                  write mission-critical code in C. The performance difference is
                  irrelevant because the scripts work, and your code does not work.

                  If you ask me again why, then I will no longer be polite.

                          Wietse


                  --
                  ----------------------
                  Gökhan ALKAN


                Your message has been successfully submitted and would be delivered to recipients shortly.