~ubuntu-branches/ubuntu/hardy/exim4/hardy-proposed

« back to all changes in this revision

Viewing changes to src/transport.c

  • Committer: Bazaar Package Importer
  • Author(s): Marc Haber
  • Date: 2005-07-02 06:08:34 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20050702060834-qk17pd52kb9nt3bj
Tags: 4.52-1
* new upstream version 4.51. (mh)
  * adapt 70_remove_exim-users_references
  * remove 37_gnutlsparams
  * adapt 36_pcre
  * adapt 31_eximmanpage
* fix package priorities to have them in sync with override again. (mh)
* Fix error in nb (Norwegian) translation.
  Thanks to Helge Hafting. (mh). Closes: #315775
* Standards-Version: 3.6.2, no changes needed. (mh)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* $Cambridge: exim/exim-src/src/transport.c,v 1.12 2005/06/27 14:29:44 ph10 Exp $ */
 
2
 
1
3
/*************************************************
2
4
*     Exim - an Internet mail transport agent    *
3
5
*************************************************/
4
6
 
5
 
/* Copyright (c) University of Cambridge 1995 - 2004 */
 
7
/* Copyright (c) University of Cambridge 1995 - 2005 */
6
8
/* See the file NOTICE for conditions of use and distribution. */
7
9
 
8
10
/* General functions concerned with transportation, and generic options for all
197
199
transport_write_block(int fd, uschar *block, int len)
198
200
{
199
201
int i, rc, save_errno;
 
202
int local_timeout = transport_write_timeout;
 
203
 
 
204
/* This loop is for handling incomplete writes and other retries. In most
 
205
normal cases, it is only ever executed once. */
200
206
 
201
207
for (i = 0; i < 100; i++)
202
208
  {
203
209
  DEBUG(D_transport)
204
210
    debug_printf("writing data block fd=%d size=%d timeout=%d\n",
205
 
      fd, len, transport_write_timeout);
206
 
  if (transport_write_timeout > 0) alarm(transport_write_timeout);
207
 
 
208
 
  #ifdef SUPPORT_TLS
209
 
  if (tls_active == fd) rc = tls_write(block, len); else
210
 
  #endif
211
 
 
212
 
  rc = write(fd, block, len);
213
 
  save_errno = errno;
214
 
 
215
 
  /* Cancel the alarm and deal with a timeout */
216
 
 
217
 
  if (transport_write_timeout > 0)
218
 
    {
219
 
    alarm(0);
 
211
      fd, len, local_timeout);
 
212
 
 
213
  /* This code makes use of alarm() in order to implement the timeout. This
 
214
  isn't a very tidy way of doing things. Using non-blocking I/O with select()
 
215
  provides a neater approach. However, I don't know how to do this when TLS is
 
216
  in use. */
 
217
 
 
218
  if (transport_write_timeout <= 0)   /* No timeout wanted */
 
219
    {
 
220
    #ifdef SUPPORT_TLS
 
221
    if (tls_active == fd) rc = tls_write(block, len); else
 
222
    #endif
 
223
    rc = write(fd, block, len);
 
224
    save_errno = errno;
 
225
    }
 
226
 
 
227
  /* Timeout wanted. */
 
228
 
 
229
  else
 
230
    {
 
231
    alarm(local_timeout);
 
232
    #ifdef SUPPORT_TLS
 
233
    if (tls_active == fd) rc = tls_write(block, len); else
 
234
    #endif
 
235
    rc = write(fd, block, len);
 
236
    save_errno = errno;
 
237
    local_timeout = alarm(0);
220
238
    if (sigalrm_seen)
221
239
      {
222
240
      errno = ETIMEDOUT;
228
246
 
229
247
  if (rc == len) { transport_count += len; return TRUE; }
230
248
 
231
 
  /* A non-negative return code is an incomplete write. Try again. */
 
249
  /* A non-negative return code is an incomplete write. Try again for the rest
 
250
  of the block. If we have exactly hit the timeout, give up. */
232
251
 
233
252
  if (rc >= 0)
234
253
    {
236
255
    block += rc;
237
256
    transport_count += rc;
238
257
    DEBUG(D_transport) debug_printf("write incomplete (%d)\n", rc);
239
 
    continue;
 
258
    goto CHECK_TIMEOUT;   /* A few lines below */
240
259
    }
241
260
 
242
261
  /* A negative return code with an EINTR error is another form of
246
265
    {
247
266
    DEBUG(D_transport)
248
267
      debug_printf("write interrupted before anything written\n");
249
 
    continue;
 
268
    goto CHECK_TIMEOUT;   /* A few lines below */
250
269
    }
251
270
 
252
271
  /* A response of EAGAIN from write() is likely only in the case of writing
257
276
    DEBUG(D_transport)
258
277
      debug_printf("write temporarily locked out, waiting 1 sec\n");
259
278
    sleep(1);
 
279
 
 
280
    /* Before continuing to try another write, check that we haven't run out of
 
281
    time. */
 
282
 
 
283
    CHECK_TIMEOUT:
 
284
    if (transport_write_timeout > 0 && local_timeout <= 0)
 
285
      {
 
286
      errno = ETIMEDOUT;
 
287
      return FALSE;
 
288
      }
260
289
    continue;
261
290
    }
262
291
 
795
824
  same alias might share some of them) but we want to output them in the
796
825
  opposite order. This is a bit tedious, but there shouldn't be very many
797
826
  of them. We just walk the list twice, reversing the pointers each time,
798
 
  but on the second time, write out the items. */
 
827
  but on the second time, write out the items.
 
828
 
 
829
  Headers added to an address by a router are guaranteed to end with a newline.
 
830
  */
799
831
 
800
832
  if (addr != NULL)
801
833
    {
822
854
  /* If a string containing additional headers exists, expand it and write
823
855
  out the result. This is done last so that if it (deliberately or accidentally)
824
856
  isn't in header format, it won't mess up any other headers. An empty string
825
 
  or a forced expansion failure are noops. */
 
857
  or a forced expansion failure are noops. An added header string from a
 
858
  transport may not end with a newline; add one if it does not. */
826
859
 
827
860
  if (add_headers != NULL)
828
861
    {
844
877
        if (s[len-1] != '\n' && !write_chunk(fd, US"\n", 1, use_crlf))
845
878
          return FALSE;
846
879
        DEBUG(D_transport)
847
 
          debug_printf("added header line(s):\n%s---\n", s);
 
880
          {
 
881
          debug_printf("added header line(s):\n%s", s);
 
882
          if (s[len-1] != '\n') debug_printf("\n");
 
883
          debug_printf("---\n");
 
884
          }
848
885
        }
849
886
      }
850
887
    }
901
938
}
902
939
 
903
940
 
 
941
#ifdef EXPERIMENTAL_DOMAINKEYS
 
942
 
 
943
/**********************************************************************************
 
944
*    External interface to write the message, while signing it with domainkeys    *
 
945
**********************************************************************************/
 
946
 
 
947
/* This function is a wrapper around transport_write_message(). It is only called
 
948
   from the smtp transport if
 
949
   (1) Domainkeys support is compiled in.
 
950
   (2) The dk_private_key option on the smtp transport is set.
 
951
   The function sets up a replacement fd into a -K file, then calls the normal
 
952
   function. This way, the exact bits that exim would have put "on the wire" will
 
953
   end up in the file (except for TLS encapsulation, which is the very
 
954
   very last thing). When we are done signing the file, send the
 
955
   signed message down the original fd (or TLS fd).
 
956
 
 
957
Arguments:     as for internal_transport_write_message() above, with additional
 
958
               arguments:
 
959
               uschar *dk_private_key         The private key to use (filename or plain data)
 
960
               uschar *dk_domain              Override domain (normally NULL)
 
961
               uschar *dk_selector            The selector to use.
 
962
               uschar *dk_canon               The canonalization scheme to use, "simple" or "nofws"
 
963
               uschar *dk_headers             Colon-separated header list to include in the signing
 
964
                                              process.
 
965
               uschar *dk_strict              What to do if signing fails: 1/true  => throw error
 
966
                                                                           0/false => send anyway
 
967
 
 
968
Returns:       TRUE on success; FALSE (with errno) for any failure
 
969
*/
 
970
 
 
971
BOOL
 
972
dk_transport_write_message(address_item *addr, int fd, int options,
 
973
  int size_limit, uschar *add_headers, uschar *remove_headers,
 
974
  uschar *check_string, uschar *escape_string, rewrite_rule *rewrite_rules,
 
975
  int rewrite_existflags, uschar *dk_private_key, uschar *dk_domain,
 
976
  uschar *dk_selector, uschar *dk_canon, uschar *dk_headers, uschar *dk_strict)
 
977
{
 
978
  int dk_fd;
 
979
  int save_errno = 0;
 
980
  BOOL rc;
 
981
  uschar dk_spool_name[256];
 
982
  char sbuf[2048];
 
983
  int sread = 0;
 
984
  int wwritten = 0;
 
985
  uschar *dk_signature = NULL;
 
986
 
 
987
  snprintf(CS dk_spool_name, 256, "%s/input/%s/%s-K",
 
988
          spool_directory, message_subdir, message_id);
 
989
  dk_fd = Uopen(dk_spool_name, O_RDWR|O_CREAT|O_EXCL, SPOOL_MODE);
 
990
  if (dk_fd < 0)
 
991
    {
 
992
    /* Can't create spool file. Ugh. */
 
993
    rc = FALSE;
 
994
    save_errno = errno;
 
995
    goto CLEANUP;
 
996
    }
 
997
 
 
998
  /* Call original function */
 
999
  rc = transport_write_message(addr, dk_fd, options,
 
1000
    size_limit, add_headers, remove_headers,
 
1001
    check_string, escape_string, rewrite_rules,
 
1002
    rewrite_existflags);
 
1003
 
 
1004
  /* Save error state. We must clean up before returning. */
 
1005
  if (!rc)
 
1006
    {
 
1007
    save_errno = errno;
 
1008
    goto CLEANUP;
 
1009
    }
 
1010
 
 
1011
  /* Rewind file and feed it to the goats^W DK lib */
 
1012
  lseek(dk_fd, 0, SEEK_SET);
 
1013
  dk_signature = dk_exim_sign(dk_fd,
 
1014
                              dk_private_key,
 
1015
                              dk_domain,
 
1016
                              dk_selector,
 
1017
                              dk_canon);
 
1018
 
 
1019
  if (dk_signature != NULL)
 
1020
    {
 
1021
    /* Send the signature first */
 
1022
    int siglen = Ustrlen(dk_signature);
 
1023
    while(siglen > 0)
 
1024
      {
 
1025
      #ifdef SUPPORT_TLS
 
1026
      if (tls_active == fd) wwritten = tls_write(dk_signature, siglen); else
 
1027
      #endif
 
1028
      wwritten = write(fd,dk_signature,siglen);
 
1029
      if (wwritten == -1)
 
1030
        {
 
1031
        /* error, bail out */
 
1032
        save_errno = errno;
 
1033
        rc = FALSE;
 
1034
        goto CLEANUP;
 
1035
        }
 
1036
      siglen -= wwritten;
 
1037
      dk_signature += wwritten;
 
1038
      }
 
1039
    }
 
1040
  else if (dk_strict != NULL)
 
1041
    {
 
1042
    uschar *dk_strict_result = expand_string(dk_strict);
 
1043
    if (dk_strict_result != NULL)
 
1044
      {
 
1045
      if ( (strcmpic(dk_strict,US"1") == 0) ||
 
1046
           (strcmpic(dk_strict,US"true") == 0) )
 
1047
        {
 
1048
        save_errno = errno;
 
1049
        rc = FALSE;
 
1050
        goto CLEANUP;
 
1051
        }
 
1052
      }
 
1053
    }
 
1054
 
 
1055
  /* Rewind file and send it down the original fd. */
 
1056
  lseek(dk_fd, 0, SEEK_SET);
 
1057
 
 
1058
  while((sread = read(dk_fd,sbuf,2048)) > 0)
 
1059
    {
 
1060
    char *p = sbuf;
 
1061
    /* write the chunk */
 
1062
    DK_WRITE:
 
1063
    #ifdef SUPPORT_TLS
 
1064
    if (tls_active == fd) wwritten = tls_write(US p, sread); else
 
1065
    #endif
 
1066
    wwritten = write(fd,p,sread);
 
1067
    if (wwritten == -1)
 
1068
      {
 
1069
      /* error, bail out */
 
1070
      save_errno = errno;
 
1071
      rc = FALSE;
 
1072
      goto CLEANUP;
 
1073
      }
 
1074
    if (wwritten < sread)
 
1075
      {
 
1076
      /* short write, try again */
 
1077
      p += wwritten;
 
1078
      sread -= wwritten;
 
1079
      goto DK_WRITE;
 
1080
      }
 
1081
    }
 
1082
 
 
1083
  if (sread == -1)
 
1084
    {
 
1085
    save_errno = errno;
 
1086
    rc = FALSE;
 
1087
    goto CLEANUP;
 
1088
    }
 
1089
 
 
1090
 
 
1091
  CLEANUP:
 
1092
  /* unlink -K file */
 
1093
  (void)close(dk_fd);
 
1094
  Uunlink(dk_spool_name);
 
1095
  errno = save_errno;
 
1096
  return rc;
 
1097
}
 
1098
#endif
904
1099
 
905
1100
 
906
1101
/*************************************************
931
1126
int pfd[2];
932
1127
pid_t filter_pid, write_pid;
933
1128
 
 
1129
transport_filter_timed_out = FALSE;
 
1130
 
934
1131
/* If there is no filter command set up, call the internal function that does
935
1132
the actual work, passing it the incoming fd, and return its result. */
936
1133
 
967
1164
yield = FALSE;
968
1165
write_pid = (pid_t)(-1);
969
1166
 
970
 
fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC);
 
1167
(void)fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC);
971
1168
filter_pid = child_open(transport_filter_argv, NULL, 077, &fd_write, &fd_read,
972
1169
  FALSE);
973
 
fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) & ~FD_CLOEXEC);
 
1170
(void)fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) & ~FD_CLOEXEC);
974
1171
if (filter_pid < 0) goto TIDY_UP;      /* errno set */
975
1172
 
976
1173
DEBUG(D_transport)
985
1182
if ((write_pid = fork()) == 0)
986
1183
  {
987
1184
  BOOL rc;
988
 
  close(fd_read);
989
 
  close(pfd[pipe_read]);
 
1185
  (void)close(fd_read);
 
1186
  (void)close(pfd[pipe_read]);
990
1187
  nl_check_length = nl_escape_length = 0;
991
1188
  rc = internal_transport_write_message(addr, fd_write,
992
1189
    (options & ~(topt_use_crlf | topt_end_dot)),
993
1190
    size_limit, add_headers, remove_headers, NULL, NULL,
994
1191
    rewrite_rules, rewrite_existflags);
995
1192
  save_errno = errno;
996
 
  write(pfd[pipe_write], (void *)&rc, sizeof(BOOL));
997
 
  write(pfd[pipe_write], (void *)&save_errno, sizeof(int));
998
 
  write(pfd[pipe_write], (void *)&(addr->more_errno), sizeof(int));
 
1193
  (void)write(pfd[pipe_write], (void *)&rc, sizeof(BOOL));
 
1194
  (void)write(pfd[pipe_write], (void *)&save_errno, sizeof(int));
 
1195
  (void)write(pfd[pipe_write], (void *)&(addr->more_errno), sizeof(int));
999
1196
  _exit(0);
1000
1197
  }
1001
1198
save_errno = errno;
1002
1199
 
1003
1200
/* Parent process: close our copy of the writing subprocess' pipes. */
1004
1201
 
1005
 
close(pfd[pipe_write]);
1006
 
close(fd_write);
 
1202
(void)close(pfd[pipe_write]);
 
1203
(void)close(fd_write);
1007
1204
fd_write = -1;
1008
1205
 
1009
1206
/* Writing process creation failed */
1043
1240
  if (sigalrm_seen)
1044
1241
    {
1045
1242
    errno = ETIMEDOUT;
 
1243
    transport_filter_timed_out = TRUE;
1046
1244
    goto TIDY_UP;
1047
1245
    }
1048
1246
 
1072
1270
TIDY_UP:
1073
1271
save_errno = errno;
1074
1272
 
1075
 
close(fd_read);
1076
 
if (fd_write > 0) close(fd_write);
 
1273
(void)close(fd_read);
 
1274
if (fd_write > 0) (void)close(fd_write);
1077
1275
 
1078
1276
if (!yield)
1079
1277
  {
1093
1291
  }
1094
1292
 
1095
1293
/* Wait for the writing process to complete. If it ends successfully,
1096
 
read the results from its pipe. */
 
1294
read the results from its pipe, provided we haven't already had a filter
 
1295
process failure. */
1097
1296
 
1098
1297
DEBUG(D_transport) debug_printf("waiting for writing process\n");
1099
1298
if (write_pid > 0)
1100
1299
  {
1101
 
  if ((rc = child_close(write_pid, 30)) == 0)
 
1300
  rc = child_close(write_pid, 30);
 
1301
  if (yield)
1102
1302
    {
1103
 
    BOOL ok;
1104
 
    read(pfd[pipe_read], (void *)&ok, sizeof(BOOL));
1105
 
    if (!ok)
1106
 
      {
1107
 
      read(pfd[pipe_read], (void *)&save_errno, sizeof(int));
1108
 
      read(pfd[pipe_read], (void *)&(addr->more_errno), sizeof(int));
 
1303
    if (rc == 0)
 
1304
      {
 
1305
      BOOL ok;
 
1306
      (void)read(pfd[pipe_read], (void *)&ok, sizeof(BOOL));
 
1307
      if (!ok)
 
1308
        {
 
1309
        (void)read(pfd[pipe_read], (void *)&save_errno, sizeof(int));
 
1310
        (void)read(pfd[pipe_read], (void *)&(addr->more_errno), sizeof(int));
 
1311
        yield = FALSE;
 
1312
        }
 
1313
      }
 
1314
    else
 
1315
      {
1109
1316
      yield = FALSE;
 
1317
      save_errno = ERRNO_FILTER_FAIL;
 
1318
      addr->more_errno = rc;
 
1319
      DEBUG(D_transport) debug_printf("writing process returned %d\n", rc);
1110
1320
      }
1111
1321
    }
1112
 
  else if (yield)
1113
 
    {
1114
 
    yield = FALSE;
1115
 
    save_errno = ERRNO_FILTER_FAIL;
1116
 
    addr->more_errno = rc;
1117
 
    DEBUG(D_transport) debug_printf("writing process returned %d\n", rc);
1118
 
    }
1119
1322
  }
1120
 
close(pfd[pipe_read]);
 
1323
(void)close(pfd[pipe_read]);
1121
1324
 
1122
1325
/* If there have been no problems we can now add the terminating "." if this is
1123
1326
SMTP output, turning off escaping beforehand. If the last character from the
1581
1784
 
1582
1785
  if (socket_fd != 0)
1583
1786
    {
1584
 
    dup2(socket_fd, 0);
1585
 
    close(socket_fd);
 
1787
    (void)dup2(socket_fd, 0);
 
1788
    (void)close(socket_fd);
1586
1789
    }
1587
1790
 
1588
1791
  DEBUG(D_exec) debug_print_argv(argv);