Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Improved code to discover the IP address of the peer. Record the IP address of the peer in a Received: header line of all input emails. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA3-256: |
9979edbdef54f547ffd2f41882691a4c |
User & Date: | drh 2018-07-13 18:20:54.845 |
Context
2018-07-13
| ||
18:40 | Attempts to obtain the IPv6 address of the peer do not seem to work. Fallback to getting the IPv4 address until we figure this out. ... (check-in: cf94d5a0 user: drh tags: trunk) | |
18:20 | Improved code to discover the IP address of the peer. Record the IP address of the peer in a Received: header line of all input emails. ... (check-in: 9979edbd user: drh tags: trunk) | |
16:26 | When logging transaction errors on the error log, try to include information about where the transaction started. ... (check-in: 43336f67 user: drh tags: trunk) | |
Changes
Changes to src/cgi.c.
︙ | ︙ | |||
1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 | *zInput = 0; zInput++; while( fossil_isspace(*zInput) ){ zInput++; } } if( zLeftOver ){ *zLeftOver = zInput; } return zResult; } /* ** This routine handles a single HTTP request which is coming in on ** g.httpIn and which replies on g.httpOut ** ** The HTTP request is read from g.httpIn and is used to initialize ** entries in the cgi_parameter() hash, as if those entries were ** environment variables. A call to cgi_init() completes ** the setup. Once all the setup is finished, this procedure returns ** and subsequent code handles the actual generation of the webpage. */ void cgi_handle_http_request(const char *zIpAddr){ char *z, *zToken; int i; | > > > > > > > > > > > > > > > > > > > < < | 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 | *zInput = 0; zInput++; while( fossil_isspace(*zInput) ){ zInput++; } } if( zLeftOver ){ *zLeftOver = zInput; } return zResult; } /* ** Determine the IP address on the other side of a connection. ** Return a pointer to a string. Or return 0 if unable. ** ** The string is held in a static buffer that is overwritten on ** each call. */ char *cgi_remote_ip(int fd){ static char zIp[100]; struct sockaddr_in6 addr; socklen_t sz = sizeof(addr); if( getpeername(fd, &addr, &sz) ) return 0; zIp[0] = 0; if( inet_ntop(AF_INET6, &addr, zIp, sizeof(zIp))==0 ){ return 0; } return zIp; } /* ** This routine handles a single HTTP request which is coming in on ** g.httpIn and which replies on g.httpOut ** ** The HTTP request is read from g.httpIn and is used to initialize ** entries in the cgi_parameter() hash, as if those entries were ** environment variables. A call to cgi_init() completes ** the setup. Once all the setup is finished, this procedure returns ** and subsequent code handles the actual generation of the webpage. */ void cgi_handle_http_request(const char *zIpAddr){ char *z, *zToken; int i; char zLine[2000]; /* A single line of input. */ g.fullHttpReply = 1; if( fgets(zLine, sizeof(zLine),g.httpIn)==0 ){ malformed_request("missing HTTP header"); } blob_append(&g.httpHeader, zLine, -1); cgi_trace(zLine); |
︙ | ︙ | |||
1418 1419 1420 1421 1422 1423 1424 | } cgi_setenv("REQUEST_URI", zToken); cgi_setenv("SCRIPT_NAME", ""); for(i=0; zToken[i] && zToken[i]!='?'; i++){} if( zToken[i] ) zToken[i++] = 0; cgi_setenv("PATH_INFO", zToken); cgi_setenv("QUERY_STRING", &zToken[i]); | | | < < < | 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 | } cgi_setenv("REQUEST_URI", zToken); cgi_setenv("SCRIPT_NAME", ""); for(i=0; zToken[i] && zToken[i]!='?'; i++){} if( zToken[i] ) zToken[i++] = 0; cgi_setenv("PATH_INFO", zToken); cgi_setenv("QUERY_STRING", &zToken[i]); if( zIpAddr==0 ){ zIpAddr = cgi_remote_ip(fileno(g.httpIn)); } if( zIpAddr ){ cgi_setenv("REMOTE_ADDR", zIpAddr); g.zIpAddr = mprintf("%s", zIpAddr); } /* Get all the optional fields that follow the first line. |
︙ | ︙ |
Changes to src/smtp.c.
︙ | ︙ | |||
735 736 737 738 739 740 741 742 743 744 745 746 747 748 | #if LOCAL_INTERFACE /* ** State information for the server */ struct SmtpServer { sqlite3_int64 idTranscript; /* Transcript ID number */ sqlite3_int64 idMsg; /* Message ID number */ char *zEhlo; /* Client domain on the EHLO line */ char *zFrom; /* MAIL FROM: argument */ int nTo; /* Number of RCPT TO: lines seen */ struct SmtpTo { char *z; /* Address in each RCPT TO line */ int okRemote; /* zTo can be in another domain */ } *aTo; | > | 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 | #if LOCAL_INTERFACE /* ** State information for the server */ struct SmtpServer { sqlite3_int64 idTranscript; /* Transcript ID number */ sqlite3_int64 idMsg; /* Message ID number */ const char *zIpAddr; /* Remote IP address */ char *zEhlo; /* Client domain on the EHLO line */ char *zFrom; /* MAIL FROM: argument */ int nTo; /* Number of RCPT TO: lines seen */ struct SmtpTo { char *z; /* Address in each RCPT TO line */ int okRemote; /* zTo can be in another domain */ } *aTo; |
︙ | ︙ | |||
853 854 855 856 857 858 859 860 861 862 863 864 865 866 | } if( (p->srvrFlags & SMTPSRV_STDERR)!=0 ){ fprintf(stderr, "C: %s", aBuf); } } return rc; } /* ** Capture the incoming email data into the p->msg blob. Dequote ** lines of "..\r\n" into just ".\r\n". */ static void smtp_server_capture_data(SmtpServer *p, char *z, int n){ int nLine = 0; | > > > > > > > > | 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 | } if( (p->srvrFlags & SMTPSRV_STDERR)!=0 ){ fprintf(stderr, "C: %s", aBuf); } } return rc; } /* ** RFC-5321 requires certain content be prepended to an email header ** as that email is received. */ static void smtp_server_prepend_header_lines(SmtpServer *p){ blob_appendf(&p->msg, "Received: from %s by Fossil-smtp\r\n", p->zIpAddr); } /* ** Capture the incoming email data into the p->msg blob. Dequote ** lines of "..\r\n" into just ".\r\n". */ static void smtp_server_capture_data(SmtpServer *p, char *z, int n){ int nLine = 0; |
︙ | ︙ | |||
1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 | ** ** Options: ** ** --dryrun Do not record any emails in the database ** ** --trace Print a transcript of the conversation on stderr ** for debugging and analysis */ void smtp_server(void){ char *zDbName; const char *zDomain; SmtpServer x; char z[5000]; smtp_server_init(&x); zDomain = find_option("domain",0,1); if( zDomain==0 ) zDomain = ""; x.srvrFlags = SMTPSRV_LOG; if( find_option("trace",0,0)!=0 ) x.srvrFlags |= SMTPSRV_STDERR; if( find_option("dryrun",0,0)!=0 ) x.srvrFlags |= SMTPSRV_DRYRUN; verify_all_options(); if( g.argc!=3 ) usage("DBNAME"); zDbName = g.argv[2]; zDbName = enter_chroot_jail(zDbName, 0); db_open_repository(zDbName); add_content_sql_commands(g.db); smtp_server_send(&x, "220 %s ESMTP https://fossil-scm.org/ %s\r\n", | > > > > > > > > > > > > > | 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 | ** ** Options: ** ** --dryrun Do not record any emails in the database ** ** --trace Print a transcript of the conversation on stderr ** for debugging and analysis ** ** --ipaddr ADDR The SMTP connection originates at ADDR. Or if ADDR ** is the name of an environment variable, the address ** is ready from that environment variable. */ void smtp_server(void){ char *zDbName; const char *zDomain; SmtpServer x; char z[5000]; smtp_server_init(&x); zDomain = find_option("domain",0,1); if( zDomain==0 ) zDomain = ""; x.srvrFlags = SMTPSRV_LOG; if( find_option("trace",0,0)!=0 ) x.srvrFlags |= SMTPSRV_STDERR; if( find_option("dryrun",0,0)!=0 ) x.srvrFlags |= SMTPSRV_DRYRUN; x.zIpAddr = find_option("ipaddr",0,1); if( x.zIpAddr ){ const char *zNew = fossil_getenv(x.zIpAddr); if( zNew && zNew[0] ) x.zIpAddr = zNew; } if( x.zIpAddr==0 ){ x.zIpAddr = cgi_remote_ip(0); if( x.zIpAddr==0 ) x.zIpAddr = "?.?.?.?"; } verify_all_options(); if( g.argc!=3 ) usage("DBNAME"); zDbName = g.argv[2]; zDbName = enter_chroot_jail(zDbName, 0); db_open_repository(zDbName); add_content_sql_commands(g.db); smtp_server_send(&x, "220 %s ESMTP https://fossil-scm.org/ %s\r\n", |
︙ | ︙ | |||
1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 | }else if( strncmp(z, "DATA", 4)==0 && fossil_isspace(z[4]) ){ if( x.zFrom==0 || x.nTo==0 ){ smtp_server_send(&x, "500 missing RCPT TO\r\n"); continue; } smtp_server_send(&x, "354 ready\r\n"); smtp_server_capture_data(&x, z, sizeof(z)); smtp_server_send(&x, "250 ok\r\n"); }else if( strncmp(z, "QUIT", 4)==0 && fossil_isspace(z[4]) ){ smtp_server_send(&x, "221 closing connection\r\n"); smtp_server_route_incoming(&x, 1); break; | > | 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 | }else if( strncmp(z, "DATA", 4)==0 && fossil_isspace(z[4]) ){ if( x.zFrom==0 || x.nTo==0 ){ smtp_server_send(&x, "500 missing RCPT TO\r\n"); continue; } smtp_server_send(&x, "354 ready\r\n"); smtp_server_prepend_header_lines(&x); smtp_server_capture_data(&x, z, sizeof(z)); smtp_server_send(&x, "250 ok\r\n"); }else if( strncmp(z, "QUIT", 4)==0 && fossil_isspace(z[4]) ){ smtp_server_send(&x, "221 closing connection\r\n"); smtp_server_route_incoming(&x, 1); break; |
︙ | ︙ |