1 2 3The README file M. Rose 4 Dover Beach Consulting, Inc. 5 February 2002 6 7 8 The personal.tcl Mailbot 9 10 11Abstract 12 13 The personal.tcl mailbot implements a highly-specialized filter for 14 personal messages. It MUST not be used by people who receive mailing 15 list traffic in their personal mailboxes. 16 17Table of Contents 18 19 1. SYNOPSIS . . . . . . . . . . . . . . . . . . . . . . . . . . 2 20 1.1 Requirements . . . . . . . . . . . . . . . . . . . . . . . . 2 21 1.2 Copyrights . . . . . . . . . . . . . . . . . . . . . . . . . 2 22 2. PHILOSOPHY . . . . . . . . . . . . . . . . . . . . . . . . . 3 23 2.1 Guest Lists . . . . . . . . . . . . . . . . . . . . . . . . 4 24 3. BEHAVIOR . . . . . . . . . . . . . . . . . . . . . . . . . . 5 25 3.1 Arguments . . . . . . . . . . . . . . . . . . . . . . . . . 5 26 3.2 Actions . . . . . . . . . . . . . . . . . . . . . . . . . . 6 27 3.3 The Configuration File . . . . . . . . . . . . . . . . . . . 7 28 3.3.1 Configuration Options . . . . . . . . . . . . . . . . . . . 7 29 3.3.2 Configurable Procedures . . . . . . . . . . . . . . . . . . 10 30 References . . . . . . . . . . . . . . . . . . . . . . . . . 12 31 Author's Address . . . . . . . . . . . . . . . . . . . . . . 12 32 A. Impersonal Mail . . . . . . . . . . . . . . . . . . . . . . 13 33 A.1 Configuration Options . . . . . . . . . . . . . . . . . . . 14 34 A.1.1 foldersDirectory . . . . . . . . . . . . . . . . . . . . . . 14 35 A.1.2 foldersFile . . . . . . . . . . . . . . . . . . . . . . . . 14 36 A.1.3 announceMailboxes . . . . . . . . . . . . . . . . . . . . . 14 37 A.1.4 mappingFile . . . . . . . . . . . . . . . . . . . . . . . . 14 38 A.2 Configurable Procedures . . . . . . . . . . . . . . . . . . 15 39 A.2.1 impersonalMail . . . . . . . . . . . . . . . . . . . . . . . 15 40 A.2.2 processFolder . . . . . . . . . . . . . . . . . . . . . . . 16 41 B. An Example configFile . . . . . . . . . . . . . . . . . . . 17 42 C. Acknowledgements . . . . . . . . . . . . . . . . . . . . . . 18 43 44 45 46 47 48 49 50 51 52 53 54 55Rose [Page 1] 56 57README The personal.tcl Mailbot February 2002 58 59 601. SYNOPSIS 61 62 Create a configuration file (Section 3.3) and add this line to your 63 ".forward" file: 64 65 "| LIB/mbot-1.1/personal.tcl -config FILE -user USER" 66 67 where "LIB" is where the Tcl library lives, "FILE" is the name of 68 your configuration file, and "USER" is your username. 69 701.1 Requirements 71 72 This package requires: 73 74 o Tcl version 8.3 [1] or later 75 76 o tcl lib [2] 77 78 o TclX version 8.0 [3] or later 79 80 811.2 Copyrights 82 83 (c) 1999-2002 Marshall T. Rose 84 85 Hold harmless the author, and any lawful use is allowed. 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111Rose [Page 2] 112 113README The personal.tcl Mailbot February 2002 114 115 1162. PHILOSOPHY 117 118 The mailbot's philosophy is simple: 119 120 o The mailbot receives all of your incoming personal mail. 121 122 o You ALWAYS copy yourself on every message you send, so that the 123 mailbot receives all of your outgoing personal mail. 124 125 o The mailbot performs six tasks, all optional: 126 127 * makes audit copies of your incoming and outgoing mail; 128 129 * performs duplicate supression; 130 131 * performs originator supression by rejecting messages from 132 people who aren't your friends or on a guest list; 133 134 * performs content supression by rejecting messages that contain 135 attachments with extensions on your prohibited list; 136 137 * sends a textual synopsis to your PDA; and, 138 139 * sends a copy to your remote mailbox. 140 141 Do NOT use the personal.tcl mailbot if you receive mailing list 142 traffic in your personal mailbox. When sending mail to a mailing 143 list, either: 144 145 o use a "From" address that the personal.tcl mailbot will process as 146 "impersonal" mail, (e.g., "hewes+ietf.general@example.com"); or, 147 148 o set the "Reply-To" for the message to the mailing list. 149 150 Consult Appendix A for information on how "impersonal" mail is 151 identified and processed. 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167Rose [Page 3] 168 169README The personal.tcl Mailbot February 2002 170 171 1722.1 Guest Lists 173 174 Guest lists are an effective mechanism for cutting back on excessive 175 mail. 176 177 o when the mailbot receives a message from you, it adds any 178 recipients it finds to a permanent-guest list; 179 180 o when the mailbot receives a message from someone on a guest list, 181 it adds any recipients it finds to a temporary-guest list; but, 182 183 o when the mailbot receives a message from someone not on any guest 184 list, they get a rejection notice. 185 186 Note that in order to promote someone to the permanent-guest list, 187 you must send them a message (with a copy to yourself). In most 188 cases, simply replying to the original message accomplishes this. Of 189 course, if you don't want to promote someone to the permanent-guest 190 list, simply remove that address (or your address) from the list of 191 recipients in your reply. 192 193 Here are the fine points: 194 195 o rejection notices contain a passphrase that may be used at most 196 once to bypass the guest list mechanism (notices also contain the 197 original message to minimize type-in by the uninvited); 198 199 o a flip-flop is used to avoid mail loops; and, 200 201 o messages originated by an administrative address (e.g., 202 "Postmaster") bypass the guest list mechanism (unless the message 203 refers to a previously-rejected message, in which case it is 204 supressed). 205 206 The rejection notice should be written carefully to minimize an 207 extreme negative reaction on the part of the uninvited. Of course, 208 by allowing a passphrase, this provides something of a CQ test for 209 the uninvited -- if someone can't pass the test... 210 211 212 213 214 215 216 217 218 219 220 221 222 223Rose [Page 4] 224 225README The personal.tcl Mailbot February 2002 226 227 2283. BEHAVIOR 229 2303.1 Arguments 231 232 The mailbot supports the following command line arguments: 233 234 -config configFile: specifies the name of the configuration file 235 to use; 236 237 -debug boolean: enables debug output; 238 239 -file messageFile: specifies the name of the file containing the 240 message; 241 242 -originator orginatorAddress: specifies the email-address of the 243 originator of the message; and, 244 245 -user userName: specifies the user-identity of the recipient. 246 247 Note that if "-user" is given, then the working directory is set to 248 userName's home directory before configFile is sourced, and the umask 249 is set defensively. 250 251 The default values are: 252 253 personal.tcl -config .personal-config.tcl \ 254 -debug 0 \ 255 -file - \ 256 -originator "derived from message" 257 258 Given the default values, only "-user" need be specified. The reason 259 is that if a message is being delivered to multiple local recipients, 260 and if any of the ".forward" files are identical in content, then 261 sendmail may not deliver the message to all of the local recipients. 262 263 A few other (sendmail related) tips: 264 265 o If sendmail is configured with smrsh, you'll need to symlink 266 personal.tcl into the /usr/libexec/sm.bin/ directory. 267 268 o Make sure that tclsh8.0 is in the path specified on the third-line 269 of personal.tcl. 270 271 o You should chmod your ".forward" file to 0600. 272 273 274 275 276 277 278 279Rose [Page 5] 280 281README The personal.tcl Mailbot February 2002 282 283 2843.2 Actions 285 286 The mailbot begins by parsing its arguments, sourcing configFile, and 287 then examining the incoming message: 288 289 1. If auditInFile (Section 3.3.1.3) is set, a copy of the message is 290 saved (Section 3.3.2.4) there. 291 292 2. If the message contains a previously-encountered "Message-ID", 293 processing terminates. 294 295 3. If the message's originator can not be determined, a copy of the 296 message is saved (Section 3.3.2.4) in the defaultMaildrop 297 (Section 3.3.1.2) and processing terminates. 298 299 4. The originator's email-address is examined: 300 301 1. If the originator appears to be an automated administrative 302 process (Section 3.3.2.1), and if a previously rejected 303 email-address is found in the message, processing terminates. 304 305 2. Otherwise, if the originator isn't the user (Section 306 3.3.2.3), or a friend (Section 3.3.2.2), or a permanent- 307 access guest, or a temporary-access guest, and if noticeFile 308 (Section 3.3.1.10) is set, then the message is rejected. 309 310 3. Otherwise, each recipient email-address in the message's 311 header is added to a guest list. (If the originator is the 312 user (Section 3.3.2.3), the permanent-guest list is used 313 instead of the temporary-guest list.) 314 315 5. If the originator is the the user (Section 3.3.2.3), then: 316 317 1. If auditOutFile (Section 3.3.1.4) is set, saved (Section 318 3.3.2.4) there. 319 320 2. Regardless, processing terminates. 321 322 6. If pdaMailboxes (Section 3.3.1.11) is set, and if any plaintext 323 is contained in the message, then the plaintext is sent to those 324 email-addresses. 325 326 7. If remoteMailboxes (Section 3.3.1.12) is set, and if the message 327 is successful resent to those email-addresses, then processing 328 terminates. 329 330 8. A copy of the message is saved (Section 3.3.2.4) in the 331 defaultMaildrop (Section 3.3.1.2) and processing terminates. 332 333 334 335Rose [Page 6] 336 337README The personal.tcl Mailbot February 2002 338 339 3403.3 The Configuration File 341 342 There are two kinds of information that may be defined in configFile: 343 configuration options (Section 3.3.1) and configurable procedures 344 (Section 3.3.2). 345 346 Here's a simple example of a configFile for a user named "example": 347 348 set options(dataDirectory) .personal 349 set options(defaultMaildrop) /var/mail/example 350 set options(logFile) [file join .personal personal.log] 351 set options(noticeFile) [file join .personal notice.txt] 352 353 3543.3.1 Configuration Options 355 356 configFile must define dataDirectory (Section 3.3.1.1) and 357 defaultMaildrop (Section 3.3.1.2). All other configuration options 358 are optional. 359 3603.3.1.1 dataDirectory 361 362 The directory where the mailbot keeps its databases. The 363 subdirectories are: 364 365 badaddrs: the directory of rejected email-addresses 366 367 inaddrs: the directory of originator email-addresses 368 369 msgids: the directory of Message-IDs 370 371 outaddrs: the permanent-guest list 372 373 phrases: the directory of at-most-once passphrases 374 375 tmpaddrs: the temporary-guest list 376 377 If you want to remove someone from a guest list, simply go to that 378 directory and delete the corresponding file. 379 3803.3.1.2 defaultMaildrop 381 382 The filename where messages are saved (Section 3.3.2.4) for later 383 viewing by your user agent. 384 3853.3.1.3 auditInFile 386 387 The filename where messages are saved (Section 3.3.2.4) for audit 388 389 390 391Rose [Page 7] 392 393README The personal.tcl Mailbot February 2002 394 395 396 purposes. 397 3983.3.1.4 auditOutFile 399 400 The filename where your outgoing messages are saved (Section 3.3.2.4) 401 for audit purposes. 402 4033.3.1.5 dropNames 404 405 A list of filename extensions for attachments that automatically 406 cause the message to be rejected. 407 4083.3.1.6 friendlyDomains 409 410 A list used by friendP (Section 3.3.2.2) giving the domain names 411 where your friends live. 412 4133.3.1.7 friendlyfire 414 415 If present and true, then someone sending a message both to you and 416 someone you've previously sent mail to, is considered a friend. 417 4183.3.1.8 logFile 419 420 The filename where the mailbot logs (Section 3.3.2.8) its actions. 421 4223.3.1.9 myMailbox 423 424 Your preferred email-address with commentary text, e.g., 425 426 Arlington Hewes <hewes@example.com> 427 428 4293.3.1.10 noticeFile 430 431 The filename containing the textual notice sent when a message is 432 rejected. Note that all occurrances of "%passPhrase%" within this 433 file are replaced with an at-most-once passphrase allowing the 434 originator to bypass the mailbot's filtering. Similarly, any 435 occurrences of "%subject%" are replaced by the "Subject" of the 436 incoming message. 437 4383.3.1.11 pdaMailboxes 439 440 The email-addresses where a textual synopsis of the incoming message 441 is sent. 442 443 444 445 446 447Rose [Page 8] 448 449README The personal.tcl Mailbot February 2002 450 451 4523.3.1.12 remoteMailboxes 453 454 The email-addresses where a copy of the incoming message is resent. 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503Rose [Page 9] 504 505README The personal.tcl Mailbot February 2002 506 507 5083.3.2 Configurable Procedures 509 510 All of these procedures are defined in personal.tcl. You may 511 override any of them in configFile. 512 5133.3.2.1 adminP 514 515 proc adminP {local domain} 516 517 Returns "1" if the email-address is an automated administrative 518 process. 519 5203.3.2.2 friendP 521 522 proc friendP {local domain} 523 524 Returns "1" if the email-address is from a friendly domain (Section 525 3.3.1.6) or sub-domain. 526 5273.3.2.3 ownerP 528 529 proc ownerP {local domain} 530 531 Returns "1" if the email-address refers to the user (as determined by 532 looking at myMailbox (Section 3.3.1.9), pdaMailboxes (Section 533 3.3.1.11), and remoteMailboxes (Section 3.3.1.12). 534 5353.3.2.4 saveMessage 536 537 proc saveMessage {inF {outF ""}} 538 539 Saves a copy of the message contained in the file inF. If the 540 destination file, outF, isn't specified, it defaults to the 541 defaultMaildrop (Section 3.3.1.2). 542 5433.3.2.5 findPhrase 544 545 proc findPhrase {subject} 546 547 Returns "1" if a previously-allocated passphrase is present in the 548 subject. If so, the passphrase is forgotten. 549 5503.3.2.6 makePhrase 551 552 proc makePhrase {} 553 554 Returns an at-most-once passphrase for use with a rejection notice. 555 556 557 558 559Rose [Page 10] 560 561README The personal.tcl Mailbot February 2002 562 563 5643.3.2.7 pruneDir 565 566 proc pruneDir {dir type} 567 568 Removes old entries from one of the mailbot's databases (Section 569 3.3.1.1). The second parameter is one of "addr", "msgid", or 570 "phrase". 571 5723.3.2.8 tclLog 573 574 proc tclLog {message} 575 576 Writes a message to the logFile (Section 3.3.1.8). 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615Rose [Page 11] 616 617README The personal.tcl Mailbot February 2002 618 619 620References 621 622 [1] <http://sourceforge.net/projects/tcl/> 623 624 [2] <http://sourceforge.net/projects/tcllib/> 625 626 [3] <http://sourceforge.net/projects/tclx/> 627 628 629Author's Address 630 631 Marshall T. Rose 632 Dover Beach Consulting, Inc. 633 POB 255268 634 Sacramento, CA 95865-5268 635 US 636 637 Phone: +1 916 483 8878 638 Fax: +1 916 483 8848 639 EMail: mrose@dbc.mtview.ca.us 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671Rose [Page 12] 672 673README The personal.tcl Mailbot February 2002 674 675 676Appendix A. Impersonal Mail 677 678 If impersonalMail (Appendix A.2.1) returns a non-empty string then 679 the message is processed differently than the algorithm given in 680 Section 3.2. Specifically: 681 682 1. If the message contains a previously-encountered "Message-ID", 683 processing terminates. 684 685 2. If the message's originator can not be determined, processing 686 terminates. 687 688 3. The value returned by impersonalMail (Appendix A.2.1) is the 689 folder's name and is broken into one or more components seperated 690 by dots ("."). If there aren't at least two components, or if 691 any of the components are empty (e.g., the folder is named 692 "sys..announce"), then the message is bounced. 693 694 4. If mappingFile (Appendix A.1.4) exists, that file is examined to 695 see if an entry is present for the folder. If so, the message is 696 processed according to the value present, one of: 697 698 "ignore": the message is silently ignored; 699 700 "bounce": the message is noisily bounced; or, 701 702 otherwise: the message is resent to the address. 703 704 Regardless, if an entry was present for the folder, then 705 processing terminates. 706 707 5. The message is saved (Section 3.3.2.4) in a file whose name is 708 constructed by replacing each dot (".") in the folder name with a 709 directory seperator (e.g., if the folder is named "sys.announce", 710 then the file is called "announce" underneath the directory "sys" 711 underneath the directory identified by foldersDirectory (Appendix 712 A.1.1). 713 714 6. Finally, the file identified by foldersFile (Appendix A.1.2) is 715 updated as necessary. 716 717 718 719 720 721 722 723 724 725 726 727Rose [Page 13] 728 729README The personal.tcl Mailbot February 2002 730 731 732A.1 Configuration Options 733 734 If "impersonal" mail is received, then foldersFile (Appendix A.1.2) 735 and foldersDirectory (Appendix A.1.1) must exist. 736 737A.1.1 foldersDirectory 738 739 The directory where the mailbot keeps private folders. 740 741A.1.2 foldersFile 742 743 This file contains one line for each private folder. 744 745A.1.3 announceMailboxes 746 747 The email-addresses where an announcement is sent when a new private 748 folder is created. 749 750A.1.4 mappingFile 751 752 The file consulted by the mailbot to determine how to process 753 "impersonal" messages. Each line of the file consists of a folder 754 name and value, seperated by a colon (":"). There are three reserved 755 values: "bounce", "ignore", and "store". 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783Rose [Page 14] 784 785README The personal.tcl Mailbot February 2002 786 787 788A.2 Configurable Procedures 789 790 All of these procedures are defined in personal.tcl. You may 791 override any of them in configFile. 792 793A.2.1 impersonalMail 794 795 proc impersonalMail {} 796 797 If the message is deemed "impersonal", return the name of a 798 corresponding private folder; otherwise, return the empty-string. 799 800 Many mail systems have a mechanism of passing additional information 801 when performing final delivery using a program. With modern versions 802 of sendmail, for example, if mail is sent to a local user named 803 "user+detail", then, in the absense of an alias for either 804 "user+detail" or "user+*", then the message is delivered to "user". 805 The trick is to get sendmail to pass the "detail" part to the 806 mailbot. 807 808 At present, sendmail passes this information only if procmail is your 809 local mailer. Here's how I do it: 810 811 *** _alias.c Tue Dec 29 10:42:25 1998 812 --- alias.c Sat Sep 18 21:51:35 1999 813 *************** 814 *** 813,818 **** 815 --- 813,821 ---- 816 define('z', user->q_home, e); 817 define('u', user->q_user, e); 818 define('h', user->q_host, e); 819 + 820 + setuserenv("SUFFIX", user->q_host); 821 + 822 if (ForwardPath == NULL) 823 ForwardPath = newstr("\201z/.forward"); 824 825 This makes available an environment variable called "SUFFIX" which 826 has the "details" part. The drawback in this approach is that this 827 information is lost if the message is re-queued for delivery (what's 828 really needed is an addition to the .forward syntax to allow macros 829 such as $h to be passed). 830 831 832 833 834 835 836 837 838 839Rose [Page 15] 840 841README The personal.tcl Mailbot February 2002 842 843 844 The corresponding impersonalMail procedure is defined as: 845 846 proc impersonalMail {} { 847 global env 848 849 return $env(SUFFIX) 850 } 851 852 853A.2.2 processFolder 854 855 proc processFolder {folderName mimeT} { return $string } 856 857 If an entry for the folder exists in the mappingFile (Appendix 858 A.1.4), and if the value for that entry is "process", then this 859 procedure is invoked to return a string indicating what action to 860 take (cf., Appendix A). 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895Rose [Page 16] 896 897README The personal.tcl Mailbot February 2002 898 899 900Appendix B. An Example configFile 901 902 Here is the ".forward" file for the user "hewes": 903 904 "|/usr/pkg/lib/mbot-1.1/personal.tcl 905 -config .personal/config.tcl -user hewes" 906 907 (Of course, it's all on one line.) 908 909 Here is the user's ".personal/config.tcl" file: 910 911 array set options [list \ 912 dataDirectory .personal \ 913 defaultMaildrop /var/mail/hewes \ 914 auditInFile [file join .personal INCOMING] \ 915 auditOutFile [file join .personal OUTGOING] \ 916 friendlyDomains [list tcp.int example.com] \ 917 logFile [file join .personal personal.log] \ 918 myMailbox "Arlington Hewes <hewes@example.com>" \ 919 pdaMailboxes hewes.pager@example.com \ 920 noticeFile [file join .personal notice.txt] \ 921 foldersDirectory [file join .personal folders] \ 922 foldersFile [file join .personal .mailboxlist] \ 923 announceMailboxes hewes+sys.announce@example.com \ 924 mappingFile [file join .personal mapping] \ 925 friendlyFire 1 \ 926 dropNames [list *.bat *.exe *.src *.pif *.wav *.vbs] \ 927 ] 928 929 proc impersonalMail {} { 930 global env 931 932 return $env(SUFFIX) 933 } 934 935 Note that because remoteMailboxes (Section 3.3.1.12) isn't defined, 936 personal messages are ultimately stored in the user's defaultMaildrop 937 (Section 3.3.1.2). 938 939 940 941 942 943 944 945 946 947 948 949 950 951Rose [Page 17] 952 953README The personal.tcl Mailbot February 2002 954 955 956Appendix C. Acknowledgements 957 958 The original version of this mailbot was written by the author in 959 1994, implemented using the safe-tcl package (Borenstein and Rose, 960 circa 1993). 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007Rose [Page 18] 1008 1009