From durwin at mgtsciences.com Wed Oct 19 18:25:32 2011 From: durwin at mgtsciences.com (durwin at mgtsciences.com) Date: Wed, 19 Oct 2011 16:25:32 -0600 Subject: [Pymilter] Where do I find details of the class variables? Message-ID: Sorry if this shows twice. I first sent it from my personal address then realized I registered with business. === I have the milter-template working. I want to access the 'Received:' headers and search them for the IP address of the server it came from. I see a whole lot of lines with 'self.' but I can't find where to get details about each of those. What variables are available to me? Can anyone direct me to the documentation I need? Regards, Durwin This email message and any attachments are for the sole use of the intended recipient(s) and may contain proprietary and/or confidential information which may be privileged or otherwise protected from disclosure. Any unauthorized review, use, disclosure or distribution is prohibited. If you are not the intended recipient(s), please contact the sender by reply email and destroy the original message and any copies of the message as well as any attachments to the original message. -------------- next part -------------- An HTML attachment was scrubbed... URL: From stuart at bmsi.com Wed Oct 19 19:05:15 2011 From: stuart at bmsi.com (Stuart D. Gathman) Date: Wed, 19 Oct 2011 19:05:15 -0400 (EDT) Subject: [Pymilter] Where do I find details of the class variables? In-Reply-To: References: Message-ID: On Wed, 19 Oct 2011, durwin at mgtsciences.com wrote: > I have the milter-template working. I want to access the 'Received:' > headers and search them for the IP address of the server it came from. Short answer: You don't need to do that. Long answer: If you did need to search the Received headers, the header call back is called for each header field and provides the field name and value for each header in turn (as it is received by sendmail/postfix). However, your milter is called in real time as the message is received, and the connect ip is provided in the connect callback - so there is usually no need to search received headers. I generally save this to self.connectip. (milter-template.py saves it to self.IP). Advanced answer: If you are running "behind" another (trusted) MX, and you want the ip that connected to *that* MX, then the first Received header encountered by the header callback has the information. You could generalize this, and make self.connectip a list, which gets the the current connect ip as the first member, and appends addition ips from received headers in order. So *if* self.connectip[0] is trusted, then the IP that connected to it is self.connectip[1]. (I would post sample code, but don't know how to parse the Received header right off the bat.) > I see a whole lot of lines with 'self.' but I can't find > where to get details about each of those. What variables are available to > me? Short answer: None Long answer: In python, you create instance variables by just assigning them. There are no public instance variables in Milter.Base except ones you create. There are public methods, and callbacks. The callbacks provide information in the arguments (for example the helo callback provides the helo name used), and additional information can gotten from methods like getsymval(). Vaporware answer: I have thought about providing a plugin framework on top of Milter.Base, which would include standard information gathering plugins. This is not much of a win for a single purpose milter (such as you are probably writing), but would help organize bloated, overgrown, all singing, all dancing multi-purpose milters such as bms.py milter (in the milter package). > Can anyone direct me to the documentation I need? http://spidey2.bmsi.com/pymilter/ (on the left side navbar on pymilter page) -- Stuart D. Gathman Business Management Systems Inc. Phone: 703 591-0911 Fax: 703 591-6154 "Confutatis maledictis, flammis acribus addictis" - background song for a Microsoft sponsored "Where do you want to go from here?" commercial. From durwin at mgtsciences.com Thu Oct 20 11:33:06 2011 From: durwin at mgtsciences.com (durwin at mgtsciences.com) Date: Thu, 20 Oct 2011 09:33:06 -0600 Subject: [Pymilter] Where do I find details of the class variables? In-Reply-To: References: Message-ID: Durwin F. De La Rue Management Sciences, Inc. 6022 Constitution Ave. NE Albuquerque, NM 87110 Phone (505) 255-8611 "Stuart D. Gathman" wrote on 10/19/2011 05:05:15 PM: > "Stuart D. Gathman" > 10/19/2011 05:05 PM > > To > > durwin at mgtsciences.com > > cc > > pymilter at bmsi.com > > Subject > > Re: [Pymilter] Where do I find details of the class variables? > > On Wed, 19 Oct 2011, durwin at mgtsciences.com wrote: > > > I have the milter-template working. I want to access the 'Received:' > > headers and search them for the IP address of the server it came from. > > Short answer: You don't need to do that. > > Long answer: If you did need to search the Received headers, the header call > back is called for each header field and provides the field name and > value for each header in turn (as it is received by sendmail/postfix). > > However, your milter is called in real time as the message is received, > and the connect ip is provided in the connect callback - so there is usually > no need to search received headers. I generally save this to self.connectip. > (milter-template.py saves it to self.IP). > > Advanced answer: If you are running "behind" another (trusted) MX, > and you want > the ip that connected to *that* MX, then the first Received header encountered > by the header callback has the information. You could generalize this, > and make self.connectip a list, which gets the the current connect ip as the > first member, and appends addition ips from received headers in order. > So *if* self.connectip[0] is trusted, then the IP that connected to it > is self.connectip[1]. (I would post sample code, but don't know how to > parse the Received header right off the bat.) I am beginning to understand what is occurring. Does milter-template.py pass the email through unmodified? As I see it, it copies the email into a string buffer (as it gets each piece) and in the end returns the string buffer as the email? It never modifies the email directly? It does look like the from is being modified in 'envfrom'. When 'header' is called with each header field, I would just look for 'Received:' in 'name' and parse the 'hval' string for what I want? Since the string buffer is created in envfrom, is it the first callback (after the init and connect)? What is 'envfrom' and 'envrcpt'? Aren't the from and recipient fields sent to header are well? Where is 'log' writing to? maillog? Would 'log ' be a good place to put debug information? What does background do? > > > I see a whole lot of lines with 'self.' but I can't find > > where to get details about each of those. What variables are available to > > me? > > Short answer: None > > Long answer: In python, you create instance variables by just assigning them. > There are no public instance variables in Milter.Base except ones you create. > There are public methods, and callbacks. The callbacks provide > information in the arguments (for example the helo callback provides > the helo name used), and additional information can gotten from > methods like getsymval(). > > Vaporware answer: I have thought about providing a plugin framework > on top of Milter.Base, which would include standard information gathering > plugins. This is not much of a win for a single purpose milter (such > as you are probably writing), but would help organize bloated, overgrown, > all singing, all dancing multi-purpose milters such as bms.py milter > (in the milter package). > > > Can anyone direct me to the documentation I need? > > http://spidey2.bmsi.com/pymilter/ > > (on the left side navbar on pymilter page) > > -- > Stuart D. Gathman > Business Management Systems Inc. Phone: 703 591-0911 Fax: 703 591-6154 > "Confutatis maledictis, flammis acribus addictis" - background song for > a Microsoft sponsored "Where do you want to go from here?" commercial. Thank you for your time. Durwin This email message and any attachments are for the sole use of the intended recipient(s) and may contain proprietary and/or confidential information which may be privileged or otherwise protected from disclosure. Any unauthorized review, use, disclosure or distribution is prohibited. If you are not the intended recipient(s), please contact the sender by reply email and destroy the original message and any copies of the message as well as any attachments to the original message. -------------- next part -------------- An HTML attachment was scrubbed... URL: From stuart at bmsi.com Thu Oct 20 14:38:46 2011 From: stuart at bmsi.com (Stuart D. Gathman) Date: Thu, 20 Oct 2011 14:38:46 -0400 (EDT) Subject: [Pymilter] Where do I find details of the class variables? In-Reply-To: References: Message-ID: On Thu, 20 Oct 2011, durwin at mgtsciences.com wrote: > I am beginning to understand what is occurring. Does milter-template.py > pass the email through unmodified? As I see it, it copies the email into a > string buffer (as it gets each piece) and in the end returns the string > buffer as the email? It never modifies the email directly? It does look > like the from is being modified in 'envfrom'. It parses the string buffer into an email.message object - but then throws it away. It is just an example of how to collect the email message, since that it a FAQ. > When 'header' is called with each header field, I would just look for > 'Received:' in 'name' and parse the 'hval' string for what I want? Yes. Name would just be "Received". > Since the string buffer is created in envfrom, is it the first callback > (after the init and connect)? It is the first callback for each message. There can be multiple messages on a connection. > What is 'envfrom' and 'envrcpt'? Aren't the from and recipient fields sent > to header are well? NO NO NO! The envfrom is supposed to be copied to the Return-Path header field but your MTA, but otherwise there is no relation. The envrcpt is what is actually used to deliver the email, NOT the "To" header field (which is basically just commentary and can be any garbage). The envfrom is where any DSNs are sent. The envfrom can be efficiently validated using the SPF protocol (you can use pyspf to implement), and if validated is the actual source of the email (as opposed to header From which can be any garbage). Think of header fields as letter head, and envfrom/envrcpt as the actually address and return address on the envelope. > Where is 'log' writing to? maillog? Would 'log ' be a good place to put > debug information? Milter.Base.log does nothing. Milter.Milter.log sends log to stdout. milter-template.myMilter.log sends log to a background process, which then prints it to stdout (to illustrate how to use multiprocessing with pymilter). In the milter package, bms.py and spfmilter.py send the log to the logging module, which is configured by default for stdout and syslog.mail respectively. > What does background do? Threads can't usually harness multiple CPUs in python due to the GIL. Also, user defined signal handling is problematic when using libmilter (as pymilter does). So the multiprocessing module is the easy way to do parallel processing in pure python, and works well with pymilter. -- Stuart D. Gathman Business Management Systems Inc. Phone: 703 591-0911 Fax: 703 591-6154 "Confutatis maledictis, flammis acribus addictis" - background song for a Microsoft sponsored "Where do you want to go from here?" commercial. From durwin at mgtsciences.com Thu Oct 20 14:54:27 2011 From: durwin at mgtsciences.com (durwin at mgtsciences.com) Date: Thu, 20 Oct 2011 12:54:27 -0600 Subject: [Pymilter] Where do I find details of the class variables? In-Reply-To: References: Message-ID: "Stuart D. Gathman" wrote on 10/20/2011 12:38:46 PM: > > I am beginning to understand what is occurring. Does milter-template.py > > pass the email through unmodified? As I see it, it copies the email into a > > string buffer (as it gets each piece) and in the end returns the string > > buffer as the email? It never modifies the email directly? It does look > > like the from is being modified in 'envfrom'. > > It parses the string buffer into an email.message object - but then > throws it away. It is just an example of how to collect the email message, > since that it a FAQ. So to actually modify the email I would alter the buffer passed in? What about adding a header? How is that accomplished? Thank you, Durwin This email message and any attachments are for the sole use of the intended recipient(s) and may contain proprietary and/or confidential information which may be privileged or otherwise protected from disclosure. Any unauthorized review, use, disclosure or distribution is prohibited. If you are not the intended recipient(s), please contact the sender by reply email and destroy the original message and any copies of the message as well as any attachments to the original message. -------------- next part -------------- An HTML attachment was scrubbed... URL: From durwin at mgtsciences.com Thu Oct 20 15:11:15 2011 From: durwin at mgtsciences.com (durwin at mgtsciences.com) Date: Thu, 20 Oct 2011 13:11:15 -0600 Subject: [Pymilter] Where do I find details of the class variables? In-Reply-To: References: Message-ID: > durwin at mgtsciences.com > Sent by: pymilter-bounces at bmsi.com > > 10/20/2011 12:54 PM > > To > > "Stuart D. Gathman" > > cc > > pymilter at bmsi.com > > Subject > > Re: [Pymilter] Where do I find details of the class variables? > > "Stuart D. Gathman" wrote on 10/20/2011 12:38:46 PM: > > > > > I am beginning to understand what is occurring. Does milter-template.py > > > pass the email through unmodified? As I see it, it copies the > email into a > > > string buffer (as it gets each piece) and in the end returns the string > > > buffer as the email? It never modifies the email directly? It does look > > > like the from is being modified in 'envfrom'. > > > > It parses the string buffer into an email.message object - but then > > throws it away. It is just an example of how to collect the email message, > > since that it a FAQ. > > So to actually modify the email I would alter the buffer passed in? > > What about adding a header? How is that accomplished? You can forget the last message. I started looking at sample.py and it filled in the holes. That and the link to spidey2 you sent earlier. Thank you again, Durwin This email message and any attachments are for the sole use of the intended recipient(s) and may contain proprietary and/or confidential information which may be privileged or otherwise protected from disclosure. Any unauthorized review, use, disclosure or distribution is prohibited. If you are not the intended recipient(s), please contact the sender by reply email and destroy the original message and any copies of the message as well as any attachments to the original message. -------------- next part -------------- An HTML attachment was scrubbed... URL: From stuart at bmsi.com Thu Oct 20 15:26:46 2011 From: stuart at bmsi.com (Stuart D. Gathman) Date: Thu, 20 Oct 2011 15:26:46 -0400 (EDT) Subject: [Pymilter] Where do I find details of the class variables? In-Reply-To: References: Message-ID: On Thu, 20 Oct 2011, durwin at mgtsciences.com wrote: > So to actually modify the email I would alter the buffer passed in? You isolate the body (the part after the headers), and call self.replacebody() with the modified body. To modify headers, use self.addheader() and self.chgheader(). > What about adding a header? How is that accomplished? Use self.addheader(). -- Stuart D. Gathman Business Management Systems Inc. Phone: 703 591-0911 Fax: 703 591-6154 "Confutatis maledictis, flammis acribus addictis" - background song for a Microsoft sponsored "Where do you want to go from here?" commercial. From pieter at insync.za.net Mon Oct 24 20:46:06 2011 From: pieter at insync.za.net (Pieter De Wit) Date: Tue, 25 Oct 2011 13:46:06 +1300 (NZDT) Subject: [Pymilter] Bypass of authenticated users Message-ID: Hi List, How do I get pyspfmilter to bypass authenticated users? Thanks, Pieter De Wit From stuart at bmsi.com Mon Oct 24 21:08:00 2011 From: stuart at bmsi.com (Stuart D. Gathman) Date: Mon, 24 Oct 2011 21:08:00 -0400 (EDT) Subject: [Pymilter] Bypass of authenticated users In-Reply-To: References: Message-ID: On Tue, 25 Oct 2011, Pieter De Wit wrote: > How do I get pyspfmilter to bypass authenticated users? Try this: Index: spfmilter.py =================================================================== RCS file: /cvsroot/pymilter/milter/spfmilter.py,v retrieving revision 1.11 diff -u -r1.11 spfmilter.py --- spfmilter.py 14 Sep 2009 14:24:11 -0000 1.11 +++ spfmilter.py 25 Oct 2011 01:06:28 -0000 @@ -126,6 +126,42 @@ t = parse_addr(f) if len(t) == 2: t[1] = t[1].lower() self.canon_from = '@'.join(t) + + # Check SMTP AUTH, also available: + # auth_authen authenticated user + # auth_author (ESMTP AUTH= param) + # auth_ssf (connection security, 0 = unencrypted) + # auth_type (authentication method, CRAM-MD5, DIGEST-MD5, PLAIN, etc) + # cipher_bits SSL encryption strength + # cert_subject SSL cert subject + # verify SSL cert verified + + self.user = self.getsymval('{auth_authen}') + if self.user: + # Very simple SMTP AUTH policy by default: + # any successful authentication is considered INTERNAL + # Detailed authorization policy is configured in the access file below. + self.internal_connection = True + self.log( + "SMTP AUTH:",self.user, self.getsymval('{auth_type}'), + "sslbits =",self.getsymval('{cipher_bits}'), + "ssf =",self.getsymval('{auth_ssf}'), "INTERNAL" + ) + # Restrict SMTP AUTH users to authorized domains + if self.internal_connection: + p = SPFPolicy('%s@%s'%(self.user,domain)) + policy = p.getPolicy('smtp-auth:') + p.close() + if policy: + if policy != 'OK': + self.log("REJECT: unauthorized user",self.user, + "at",self.connectip,"sending MAIL FROM",self.canon_from) + self.setreply('550','5.7.1', + 'SMTP user %s is not authorized to use MAIL FROM %s.' % + (self.user,self.canon_from) + ) + return Milter.REJECT + if not (self.internal_connection or self.trusted_relay) and self.connectip: rc = self.check_spf() if rc != Milter.CONTINUE: return rc -- Stuart D. Gathman Business Management Systems Inc. Phone: 703 591-0911 Fax: 703 591-6154 "Confutatis maledictis, flammis acribus addictis" - background song for a Microsoft sponsored "Where do you want to go from here?" commercial.