/[anubis]/anubis/src/tunnel.c
ViewVC logotype

Diff of /anubis/src/tunnel.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.10 by gray, Mon Feb 17 20:54:04 2003 UTC revision 1.11 by gray, Wed Feb 26 16:59:15 2003 UTC
# Line 32  Line 32 
32  static int  transfer_command(void *, void *, char *);  static int  transfer_command(void *, void *, char *);
33  static void process_command(void *, void *, char *, int);  static void process_command(void *, void *, char *, int);
34  static void transfer_header(void *, void *, struct list *list);  static void transfer_header(void *, void *, struct list *list);
 static void process_header_line(char *);  
35  static void transfer_body(void *, void *);  static void transfer_body(void *, void *);
 static void add_remailer_commands(void *);  
 static void transform_body(void *sd_server);  
36  static void process_data(void *sd_client, void *sd_server);  static void process_data(void *sd_client, void *sd_server);
37    
38    
 /* Auxiliary list handling functions */  
 /* These belong to the future list.c */  
 typedef int (*list_iterator_t)(struct list *list, void *data);  
   
 void  
 list_iterate(struct list *p, list_iterator_t itr, void *data)  
 {  
         while (p) {  
                 struct list *q = p->next;  
                 itr(p, data);  
                 p = q;  
         };  
 }  
   
 void  
 list_append(struct list **a, struct list *b)  
 {  
         if (!*a)  
                 *a = b;  
         else {  
                 struct list *p;  
                   
                 for (p = *a; p->next; p = p->next)  
                         ;  
                 p->next = b;  
         }  
 }  
   
   
39  /* Collect and send headers */  /* Collect and send headers */
40    
41  /* Headers spanning multiple lines are wrapped into a single line, preserving  /* Headers spanning multiple lines are wrapped into a single line, preserving
# Line 99  get_boundary(char *line) Line 67  get_boundary(char *line)
67  }  }
68    
69  static void  static void
70    add_header(struct list *list, char *line)
71    {
72            ASSOC *asc = header_assoc(line);
73            list_append(list, asc);
74            if (asc->key && strcasecmp(asc->key, "subject") == 0) {
75                    char *p = strstr(asc->value, BEGIN_TRIGGER);
76    
77                    if (p) {
78                            asc = xmalloc(sizeof(*asc));
79                            
80                            *p = 0;
81                            p += sizeof(BEGIN_TRIGGER) - 1;
82                            asc->key = strdup(X_ANUBIS_RULE_HEADER);
83                            asc->value = strdup(p);
84                            list_append(list, asc);
85                    }
86            }
87    }
88    
89    static void
90  collect_headers(void *sd_client, struct list **listp)  collect_headers(void *sd_client, struct list **listp)
91  {  {
         struct list *tail;  
92          char buf[LINEBUFFER+1];          char buf[LINEBUFFER+1];
93            char *line = NULL;
94    
95          *listp = tail = NULL;          *listp = list_create();
96          while (recvline(SERVER, sd_client, buf, LINEBUFFER)) {          while (recvline(SERVER, sd_client, buf, LINEBUFFER)) {
                 if (strncmp(buf, CRLF, 2) == 0)  
                         break;  
97                  remcrlf(buf);                  remcrlf(buf);
98                  if (isspace(buf[0])) {                  if (isspace(buf[0])) {
99                          if (!tail)                          if (!line)
100                                  /* Something wrong, assume we've got no                                  /* Something wrong, assume we've got no
101                                     headers */                                     headers */
102                                  break;                                  break;
103                          tail->line = xrealloc(tail->line,                          line = xrealloc(line,
104                                                strlen(tail->line) +                                          strlen(line) + strlen(buf) + 2);
105                                                strlen(buf) + 2);                          strcat(line, "\n");
106                          strcat(tail->line, "\n");                          strcat(line, buf);
                         strcat(tail->line, buf);  
107                  } else {                  } else {
108                          if (!(topt & (T_BOUNDARY|T_ENTIRE_BODY)) && tail)                          if (line) {
109                              get_boundary(tail->line);                                  if (!(topt & (T_BOUNDARY|T_ENTIRE_BODY)))
110                          tail = new_element(tail, listp, buf);                                          get_boundary(line);
111                                    add_header(*listp, line);
112                                    line = NULL;
113                            }
114                            if (buf[0] == 0)
115                                    break;
116                            line = strdup(buf);
117                  }                  }
118          }          }
119  }  }
120    
121  static void  static void
122  write_header_line (void *sd_server, char *line)  write_header_line(void *sd_server, char *line)
123  {  {
124          char *p;          char *p;
125    
# Line 138  write_header_line (void *sd_server, char Line 130  write_header_line (void *sd_server, char
130          } while (p = strtok(NULL, "\n"));          } while (p = strtok(NULL, "\n"));
131  }  }
132                                                    
133  void  static void
134  send_header (void *sd_server, struct list **plist)  write_assoc(void *sd_server, ASSOC *entry)
135  {  {
136          struct list *p;          if (entry->key) {
137          p = *plist;                  if (strcmp(entry->key, X_ANUBIS_RULE_HEADER) == 0)
138          while (p) {                          return;
139                  struct list *q = p->next;                  swrite(CLIENT, sd_server, entry->key);
140                  write_header_line(sd_server, p->line);                  swrite(CLIENT, sd_server, ":");
                 free(p->line);  
                 free(p);  
                 p = q;  
141          }          }
142          *plist = NULL;          write_header_line(sd_server, entry->value);
143    }
144                            
145    void
146    send_header(void *sd_server, struct list *list)
147    {
148            ASSOC *p;
149    
150            for (p = list_first(list); p; p = list_next(list))
151                    write_assoc(sd_server, p);
152    }
153    
154    void
155    send_string_list(void *sd_server, struct list *list)
156    {
157            char *p;
158    
159            for (p = list_first(list); p; p = list_next(list))
160                    write_header_line(sd_server, p);
161  }  }
162    
163    
# Line 177  collect_body(void *sd_client, char **ret Line 184  collect_body(void *sd_client, char **ret
184          char buf[LINEBUFFER+1];          char buf[LINEBUFFER+1];
185          struct obstack stk;          struct obstack stk;
186          int state = 0;          int state = 0;
         struct list *tail = NULL;  
187          int len;          int len;
188    
189          if (topt & T_BOUNDARY)          if (topt & T_BOUNDARY) {
190                  len = strlen(message.boundary);                  len = strlen(message.boundary);
191                            message.mime_hdr = list_create();
192            }
193                            
194          obstack_init (&stk);          obstack_init (&stk);
195          while (state != ST_DONE          while (state != ST_DONE
196                 && (nread = recvline(SERVER, sd_client, buf, LINEBUFFER))) {                 && (nread = recvline(SERVER, sd_client, buf, LINEBUFFER))) {
# Line 202  collect_body(void *sd_client, char **ret Line 210  collect_body(void *sd_client, char **ret
210                                  if (buf[0] == 0)                                  if (buf[0] == 0)
211                                          state = ST_BODY;                                          state = ST_BODY;
212                                  else                                  else
213                                          tail = new_element(tail,                                          list_append(message.mime_hdr,
214                                                             &message.mime_hdr,                                                      strdup(buf));
                                                            buf);  
215                                  break;                                  break;
216    
217                          case ST_BODY:                          case ST_BODY:
# Line 233  send_body(void *sd_server) Line 240  send_body(void *sd_server)
240          if (topt & T_BOUNDARY) {          if (topt & T_BOUNDARY) {
241                  swrite(CLIENT, sd_server, message.boundary);                  swrite(CLIENT, sd_server, message.boundary);
242                  swrite(CLIENT, sd_server, CRLF);                  swrite(CLIENT, sd_server, CRLF);
243                  send_header(sd_server, &message.mime_hdr);                  send_string_list(sd_server, message.mime_hdr);
244                  swrite(CLIENT, sd_server, CRLF);                  swrite(CLIENT, sd_server, CRLF);
245          }          }
246    
# Line 321  smtp_session(void *sd_client, void *sd_s Line 328  smtp_session(void *sd_client, void *sd_s
328  *********************/  *********************/
329    
330  static void  static void
331    save_command(char *line)
332    {
333            int i;
334            ASSOC *asc = xmalloc(sizeof(*asc));
335    
336            for (i = 0; line[i] && isspace(line[i]); i++)
337                    ;
338    
339            asc->key = xmalloc(i + 1);
340            memcpy(asc->key, line, i);
341            asc->key[i] = 0;
342            for (; line[i] && isspace(line[i]); i++)
343                    ;
344            if (line[i])
345                    asc->value = strdup(&line[i]);
346            else
347                    asc->value = NULL;
348            list_append(message.commands, asc);
349    }
350    
351    static void
352  process_command(void *sd_client, void *sd_server, char *command, int size)  process_command(void *sd_client, void *sd_server, char *command, int size)
353  {  {
354          char buf[LINEBUFFER+1];          char buf[LINEBUFFER+1];
355          safe_strcpy(buf, command); /* make a back-up */          safe_strcpy(buf, command); /* make a back-up */
356          change_to_lower(buf);          save_command(buf);
357    
358          rcfile_process_cond("RULE", COMMAND, command);          change_to_lower(buf);
359                    
360          if (strncmp(buf, "starttls", 8) == 0) {          if (strncmp(buf, "starttls", 8) == 0) {
361    
# Line 566  transfer_command(void *sd_client, void * Line 594  transfer_command(void *sd_client, void *
594                  if (strncmp(buf, "quit", 4) == 0)                  if (strncmp(buf, "quit", 4) == 0)
595                          return 0; /* The QUIT command */                          return 0; /* The QUIT command */
596                  else if (strncmp(buf, "rset", 4) == 0) {                  else if (strncmp(buf, "rset", 4) == 0) {
597                            destroy_assoc_list(&message.commands);
598                            destroy_assoc_list(&message.header);
599                            destroy_string_list(&message.mime_hdr);
600                          xfree(message.body);                          xfree(message.body);
601                          xfree(message.boundary);                          xfree(message.boundary);
                         destroy_list(&message.addlist);  
                         destroy_list(&message.remlist);  
                         destroy_list(&message.modlist);  
                         mopt = 0;  
602                          topt &= ~T_BOUNDARY;                          topt &= ~T_BOUNDARY;
603                          topt &= ~T_ERROR;                          topt &= ~T_ERROR;
                         if (topt & T_SUPERCLIENT)  
                                 rcfile_process_section(CF_CLIENT, "ALL", NULL);  
604                  }                  }
605                  else if (strncmp(buf, "data", 4) == 0) {                  else if (strncmp(buf, "data", 4) == 0) {
606                          process_data(sd_client, sd_server);                          process_data(sd_client, sd_server);
607                          xfree(message.body);                          xfree(message.body);
608                          xfree(message.boundary);                          xfree(message.boundary);
                         mopt = 0;  
609                          topt &= ~T_BOUNDARY;                          topt &= ~T_BOUNDARY;
610                          topt &= ~T_ERROR;                          topt &= ~T_ERROR;
                         if (topt & T_SUPERCLIENT)  
                                 rcfile_process_section(CF_CLIENT, "ALL", NULL);  
611                  }                  }
612          }          }
613          return 1; /* OK */          return 1; /* OK */
# Line 594  transfer_command(void *sd_client, void * Line 616  transfer_command(void *sd_client, void *
616  void  void
617  process_data(void *sd_client, void *sd_server)  process_data(void *sd_client, void *sd_server)
618  {  {
         struct list *message_hdr;  
619          char buf[LINEBUFFER+1];          char buf[LINEBUFFER+1];
620    
621          alarm(1800);          alarm(1800);
622    
623          collect_headers(sd_client, &message_hdr);          collect_headers(sd_client, &message.header);
624          collect_body(sd_client, &message.body);          collect_body(sd_client, &message.body);
625    
626          transfer_header(sd_client, sd_server, message_hdr);          rcfile_process_section(CF_CLIENT, "RULE", NULL, &message);
627          transform_body(sd_server);          
628            transfer_header(sd_client, sd_server, message.header);
629          transfer_body(sd_client, sd_server);          transfer_body(sd_client, sd_server);
630    
631          recvline(CLIENT, sd_server, buf, LINEBUFFER);          recvline(CLIENT, sd_server, buf, LINEBUFFER);
# Line 614  process_data(void *sd_client, void *sd_s Line 636  process_data(void *sd_client, void *sd_s
636          alarm(0);          alarm(0);
637  }  }
638                    
 /*****************  
   MESSAGE HEADER  
 ******************/  
   
 struct header_data {  
         void *sd_client;  
         void *sd_server;  
         struct list *header;  
 };  
   
 struct closure {  
         RC_REGEX *regex;  
         char *modify;  
         struct list *head, *tail;  
 };  
   
 int  
 action_remove2(struct list *p, void *data)  
 {  
         struct closure *clos = data;  
         int rc, stat;  
         char **rv = NULL;  
           
         stat = anubis_regex_match(clos->regex, p->line, &rc, &rv);  
         free_pptr(rv);  
         if (stat) {  
                 free(p->line);  
                 free(p);  
         } else {  
                 p->next = NULL;  
                 if (clos->head == NULL)  
                         clos->head = p;  
                 if (clos->tail)  
                         clos->tail->next = p;  
                 clos->tail = p;  
         }  
         return 0;  
 }  
   
 int  
 action_remove(struct list *p, void *data)  
 {  
         struct header_data *hp = data;  
         struct closure clos;  
   
         clos.regex = anubis_regex_compile(p->line, 0);  
         clos.head = clos.tail = NULL;  
         list_iterate(hp->header, action_remove2, &clos);  
         hp->header = clos.head;  
         anubis_regex_free(clos.regex);  
         free(p->line);  
         free(p);  
         return 0;  
 }  
   
 int  
 action_mod2(struct list *p, void *data)  
 {  
         struct closure *clos = data;  
         int rc, stat;  
         char **rv = NULL;  
           
         stat = anubis_regex_match(clos->regex, p->line, &rc, &rv);  
         if (stat) {  
                 free(p->line);  
                 p->line = substitute(clos->modify, rv);  
                 if (!p->line)  
                         p->line = strdup(clos->modify);  
                 free_pptr(rv);  
         }  
         return 0;  
 }  
   
 int  
 action_mod(struct list *p, void *data)  
 {  
         struct header_data *hp = data;  
         struct closure clos;  
   
         clos.regex = anubis_regex_compile(p->line, 0);  
         clos.head = clos.tail = NULL;  
         clos.modify = p->modify;  
         list_iterate(hp->header, action_mod2, &clos);  
         anubis_regex_free(clos.regex);  
         free(p->line);  
         free(p);  
         return 0;  
 }  
   
 int  
 action_free(struct list *p, void *data)  
 {  
         free(p->line);  
         free(p);  
         return 0;  
 }  
   
639  static void  static void
640  transfer_header(void *sd_client, void *sd_server, struct list *header_buf)  transfer_header(void *sd_client, void *sd_server, struct list *header_buf)
641  {  {
642          struct list *p;          send_header(sd_server, header_buf);
         struct header_data hd;  
           
         hd.sd_server = sd_server;  
         hd.sd_client = sd_client;  
         hd.header = header_buf;  
   
         for (p = hd.header; p; p = p->next)  
                 process_header_line(p->line);  
           
 #ifdef WITH_GUILE  
         guile_process_list(&header_buf, &message.body);  
 #endif /* WITH_GUILE */  
           
         list_iterate(message.remlist, action_remove, &hd);  
         message.remlist = NULL;  
   
         list_append(&hd.header, message.addlist);  
         message.addlist = NULL;  
           
         list_iterate(message.modlist, action_mod, &hd);  
         message.modlist = NULL;  
           
 #ifdef WITH_GUILE  
         guile_postprocess_list(&hd.header, &message.body);  
 #endif /* WITH_GUILE */  
   
         send_header(sd_server, &hd.header);  
643          swrite(CLIENT, sd_server, CRLF);          swrite(CLIENT, sd_server, CRLF);
           
         list_iterate(hd.header, action_free, NULL);  
644  }  }
645    
 static void  
 process_header_line(char *header_line)  
 {  
         char *p = 0;  
         char backup[LINEBUFFER+1];  
   
         /*  
            The Trigger.  
         */  
   
         p = strstr(header_line, BEGIN_TRIGGER);  
         if (p) {  
                 safe_strcpy(backup, p);  
                 *p = '\0';  
                 p = backup;  
                 p += sizeof(BEGIN_TRIGGER) - 1;  
         } else  
                 p = header_line;  
   
         rcfile_process_cond("RULE", HEADER, p);  
         return;  
 }  
646    
647  /***************  /***************
648    MESSAGE BODY    MESSAGE BODY
649  ****************/  ****************/
650    
   
   
651  static void  static void
652  raw_transfer(void *sd_client, void *sd_server)  raw_transfer(void *sd_client, void *sd_server)
653  {  {
# Line 794  transfer_body(void *sd_client, void *sd_ Line 666  transfer_body(void *sd_client, void *sd_
666  {  {
667          if (topt & T_BOUNDARY) {          if (topt & T_BOUNDARY) {
668                  send_body(sd_server);                  send_body(sd_server);
 #ifdef HAVE_GPG  
                 if ((mopt & M_GPG_ENCRYPT) || (mopt & M_GPG_SIGN))  
                         swrite(CLIENT, sd_server, CRLF);  
 #endif /* HAVE_GPG */  
669                                    
670                  /* Transfer everything else */                  /* Transfer everything else */
671                  raw_transfer(sd_client, sd_server);                  raw_transfer(sd_client, sd_server);
# Line 806  transfer_body(void *sd_client, void *sd_ Line 674  transfer_body(void *sd_client, void *sd_
674          swrite(CLIENT, sd_server, "."CRLF);          swrite(CLIENT, sd_server, "."CRLF);
675  }  }
676    
677    void
678  static void  message_add_header(MESSAGE *msg, char *hdr)
 add_remailer_commands(void *sd_server)  
679  {  {
680          char buf[1024];          list_append(msg->header, header_assoc(hdr));
681    }
682    
683          if (!(mopt & M_RMGPG)) {  void
684                  if (mopt & M_RMRRT) {  message_remove_headers(MESSAGE *msg, char *arg)
685                          sprintf(buf, "::"CRLF"Anon-To: %s"CRLF, rm.rrt);  {
686                          swrite(CLIENT, sd_server, buf);          ASSOC *asc;
687                  }          RC_REGEX *regex = anubis_regex_compile(arg, 0);
688                  else if (mopt & M_RMPOST) {          
689                          sprintf(buf, "::"CRLF"Anon-Post-To: %s"CRLF, rm.post);          for (asc = list_first(msg->header); asc;
690                          swrite(CLIENT, sd_server, buf);               asc = list_next(msg->header)) {
691                  }                  char **rv;
692                  if ((mopt & M_RMLT) || (mopt & M_RMRLT)) {                  int rc;
693                          sprintf(buf, "Latent-Time: +%s%s"CRLF,                  char *h = assoc_to_header(asc);
694                          rm.latent_time, (mopt & M_RMRLT) ? "r" : "");                  
695                          swrite(CLIENT, sd_server, buf);                  if (anubis_regex_match(regex, h, &rc, &rv)) {
696                  }                          list_remove_current(msg->header);
697                  swrite(CLIENT, sd_server, CRLF);                          assoc_free(asc);
698                  if (mopt & M_RMHEADER) {                  }
699                          remcrlf(rm.header);                  free(h);
700                          swrite(CLIENT, sd_server, "##"CRLF);                  if (rc)
701                          swrite(CLIENT, sd_server, rm.header);                          free_pptr(rv);
                         swrite(CLIENT, sd_server, CRLF);  
                 }  
702          }          }
703  #ifdef HAVE_GPG          anubis_regex_free(regex);
         else  
                 swrite(CLIENT, sd_server, "::"CRLF"Encrypted: PGP"CRLF CRLF);  
 #endif /* HAVE_GPG */  
   
         return;  
704  }  }
705    
706  static void  void
707  transform_body(void *sd_server)  message_modify_headers(MESSAGE *msg, char *arg, char *modify)
708  {  {
709          check_all_files(session.client);          ASSOC *asc;
710          if (!(topt & T_ERROR) && (mopt & M_EXTBODYPROC)) {          RC_REGEX *regex = anubis_regex_compile(arg, 0);
711                  int rs = 0;          
712                  char *extbuf = 0;          for (asc = list_first(msg->header); asc;
713                  extbuf = external_program(&rs, message.exteditor, message.body, 0, 0);               asc = list_next(msg->header)) {
714                  if (rs != -1 && extbuf) {                  char **rv;
715                          xfree(message.body);                  int rc;
716                          message.body = extbuf;                  char *h = assoc_to_header(asc);
717                    
718                    if (anubis_regex_match(regex, h, &rc, &rv)) {
719                            free(asc->value);
720                            asc->value = substitute(modify, rv);
721                            if (!asc->value)
722                                    asc->value = strdup(modify);
723                  }                  }
724                    free(h);
725                    free_pptr(rv);
726          }          }
727            anubis_regex_free(regex);
728    }
729    
730  #ifdef HAVE_GPG  void
731          if (!(topt & T_ERROR) && ((mopt & M_GPG_ENCRYPT)  message_external_proc(MESSAGE *msg, char *name)
732                                    || (mopt & M_GPG_SIGN) || (mopt & M_RMGPG)))  {
733                  check_gpg();          int rc = 0;
734  #endif /* HAVE_GPG */          char *extbuf = 0;
735            extbuf = external_program(&rc, name, message.body, 0, 0);
736          if (!(topt & T_ERROR)) {          if (rc != -1 && extbuf) {
737                  if (mopt & M_RM)                  xfree(message.body);
738                          add_remailer_commands(sd_server);                  message.body = extbuf;
739          }          }
         topt &= ~T_ERROR;  
         return;  
740  }  }
741    
742  /* EOF */  /* EOF */

Legend:
Removed from v.1.10  
changed lines
  Added in v.1.11

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26