
<cc        y   @   s  d  Z  d d l m Z d d l Z d d l Z d d l Z d d l Z d d l Z d d l Z d d l	 Z	 d d l
 Z
 d d l Z d d l Z d d l Z d d l Z d d l Z d d l m Z d d l m Z d d l m Z m Z y d d l m Z Wn' e k
 r%d Z e e j   Z n Xd d	 l m Z d d
 l m Z d d l m Z d d l  m! Z! d d l" m# Z# y" d d l$ Z$ e$ j% Z& e$ j' Z( Wn; e k
 rd d l% Z% d d l) Z) e% j* Z& e) j* Z( n Xy e+ e, f Wn e- k
 rd Z+ d Z, n Xy& d d l. Z/ d d l0 m1 Z1 e+ Z2 Wn e k
 rCe, Z2 n Xy d d l3 Z3 e+ Z4 Wn e k
 rse, Z4 n Xd Z5 d Z6 d Z7 d Z8 d Z9 e e d Z: e j; d e j<  Z= e j; d e j<  Z> d   Z? d   Z@ d e+ d  ZA d   ZB d   ZC d   ZD e j; d   ZE e j; d! e j<  ZF d"   ZG e j; d#  ZH d$ d%  ZI d&   ZJ d e, d'  ZL d(   ZM e, d)  ZN d ZO d ZP g  ZQ xA eO D]9 ZR x0 eP D]( ZS eQ jT eS eR  eQ jT eR eS  qWqW[S [R d@   ZU dA   ZV e jW dB  ZX dC   ZY e+ dD  ZZ e+ dE  Z[ e+ dF  Z\ e j; dG e j<  Z] e, dH  Z^ dI   Z_ e, dJ  Z` dK   Za dL eb f dM     YZc d e, d d dN  Zd d e, d d dO  Ze i d dP 6d dQ 6d dR 6ddS 6ddT 6ddV 6ddW 6ddY 6ddZ 6dd[ 6dd\ 6Zf d]   Zg d e+ d^  Zh d e, d_  Zi d`   Zj da   Zk db   Zl dc   Zm dd   Zn d d de  Zo d ap df   Zq d dg  Zr dh   Zs di   Zt dj   Zu dk   Zv d dl  Zw d dm  Zx dn   Zy do   Zz dp   Z{ dq dr ds dt du dv dw dx dy dz d{ d| d} d~ d d d d d d d d d d d d d d d d d d d d d d d d d d d d d d d d d d d d d d d d d d d d d d d d d d d d d d d d d d d d d d d d d d d d d d d d d d d d d d d d d d d d d d d d d d d d d d d d d d d d d d d d d d d gy Z| e j; d j} e|  e j<  Z~ e j; d  Z e j; d e j<  Z d   Z d   Z i  a d   Z d   Z d   Z d   Z e, d  Z i  Z d a d   Z d   Z d   Z d   Z d   Z d   Z d   Z d   Z d S(	  s   Miscellaneous essential routines.

This includes actual message transmission routines, address checking and
message and address munging, a handy-dandy routine to map a function on all
the mailing lists, and whatever else doesn't belong elsewhere.

i(   t   nested_scopesN(   t   HeaderParseError(   t   UnicodeType(   t
   whitespacet   digits(   t   ascii_letterst   abcdefghijklmnopqrstuvwxyz(   t   mm_cfg(   t   Errors(   t   Site(   t   SafeDict(   t   syslogi   i    (   t   DNSExceptiont    u    s   s   
t   .t   _s   %\(([_a-z]\w*?)\)s?s%   (\${2})|\$([_a-z]\w*)|\${([_a-z]\w*)}c         C   s   t  t j t j d |    d k rn t j j d t j j d t j j d d    } t d d |  |  t	 St
 j |   } x= d D]5 } t j j | d |  } t j j |  r t Sq Wt	 S(   s'   Return true iff list `listname' exists.R   i    t   HTTP_FORWARDED_FORt   HTTP_X_FORWARDED_FORt   REMOTE_ADDRs   unidentified origint   mischiefs(   Hostile listname: listname=%s: remote=%ss   .pcks	   .pck.lasts   .dbs   .db.lastt   config(   s   .pcks	   .pck.lasts   .dbs   .db.last(   t   lent   ret   subR   t   ACCEPTABLE_LISTNAME_CHARACTERSt   ost   environt   getR   t   FalseR	   t   get_listpatht   patht   joint   existst   True(   t   listnamet   remotet   basepatht   extt   dbfile(    (    s,   /export/web/mailman/mailman/Mailman/Utils.pyt   list_existsg   s    
$c           C   s
   t  j   S(   s8   Return the names of all lists in default list directory.(   R	   t   get_listnames(    (    (    s,   /export/web/mailman/mailman/Mailman/Utils.pyt
   list_names   s    iF   c         C   sz  d } t  j d |   } xW| D]O} g  } t } x | j t  D] } | s` | j |  qA n  | r | d t k r t }	 n t }	 | r |	 r | d j   d | | d <n | j |  |	 } qA Wx| D]}  x|  rUt |   | k r |  } d }  nJ| }
 x* |
 d k r0|  |
 t k r0|
 d 8}
 qW|
 } x* | d k rc|  | t k rc| d 8} q:W| d k r| } x0 | t |   k  r|  | t k r| d 7} qyW| }
 x0 |
 t |   k  r|  |
 t k r|
 d 7}
 qW|
 d 8}
 n  |  | d  d } |
 d 7}
 x0 |
 t |   k  r=|  |
 t k r=|
 d 7}
 qW|  |
 }  | | 7} q W| d 7} q W| d 7} q W| d  S(	   s  Wrap and fill the text to the specified column.

    Wrapping is always in effect, although if it is not possible to wrap a
    line (because some word is longer than `column' characters) the line is
    broken at the next available whitespace boundary.  Paragraphs are also
    always filled, unless honor_leading_ws is true and the line begins with
    whitespace.  This is the algorithm that the Python FAQ wizard uses, and
    seems like a good compromise.

    R   s   

i    it    i   s   
i(	   R   t   splitR   t   NLt   appendR   R!   t   rstripR   (   t   textt   columnt   honor_leading_wst   wrappedt   parast   parat   linest   fillprevt   linet   fillthist   bolt   eol(    (    s,   /export/web/mailman/mailman/Mailman/Utils.pyt   wrap   sX    	
		%%
%
c         C   s"   d } d } | j  |  j |   S(   Ns   
 .
s   
.
(   R   R+   (   R/   t   JOINERt   SEP(    (    s,   /export/web/mailman/mailman/Mailman/Utils.pyt   QuotePeriods   s    c         C   sn   d  } d  } |  j   }  |  j d  } | d k  r= |  d  f S|  |  } |  | d } | j d  } | | f S(   Nt   @i   R   (   t   Nonet   lowert   findR+   (   t   emailt   usert   domaint   at_signt   rest(    (    s,   /export/web/mailman/mailman/Mailman/Utils.pyt
   ParseEmail   s    

c         C   s=   |  j  d  } | d k r |  S|  |  d |  | d j   S(   s3   returns the address with the domain part lowercasedR?   ii   (   RB   RA   (   t   addrt   atind(    (    s,   /export/web/mailman/mailman/Mailman/Utils.pyt   LCDomain   s    s"   [][()<>|:;^,\\"\000-\037\177-\377]s	   [-a-z0-9]c         C   s8  t  |  t  s t  |  t  rF t |   d k r9 d }  qF |  d }  n  |  sb |  j d  d k rn t j  n  t j |   r t j	 |   n  t
 |   \ } } | s t j |   n  t |  d k  r t j |   n  x] | D]U } t |  d k s!| d d k s!t t j d |   d k r t j	 |   q q Wd S(   s0   Verify that an email address isn't grossly evil.i    R   iR*   i   t   -N(   t
   isinstancet   listt   tupleR   t   countR   t   MMBadEmailErrort	   _badcharst   searcht   MMHostileAddressRH   t   _valid_domainR   (   t   sRD   t   domain_partst   p(    (    s,   /export/web/mailman/mailman/Mailman/Utils.pyt   ValidateEmail   s     	@s   [^\x21-\x7e]t	   PATH_INFOc         C   sZ  t  j j |   } | rVt  j j d t  j j d t  j j d d    } t j |  r t j |  d } t d d t   |  n  g  | j d  D] } | r | ^ q } t j	 d k r t j	 } n= t
   } | r t g  | D] } t |  ^ q  } n d	 } | rRt | d  | k rRt d
 d | d |  | d |  d | d <n  | Sd  S(   NR   R   R   s   unidentified origini    t   errors;   Warning: Possible malformed path attack domain=%s remote=%st   /i   R   s(   Hostile listname: listname=%s: remote=%ss   ...(   R   R   R   t   CRNLpatRS   R+   R   t
   get_domainR   t   MAX_LISTNAME_LENGTHR)   t   maxR   R@   (   t   envarR   R#   RX   t   piecest   longestt	   lst_namest   x(    (    s,   /export/web/mailman/mailman/Mailman/Utils.pyt   GetPathPieces  s2    
(	(c           C   s   t  j j d  S(   Nt   REQUEST_METHOD(   R   R   R   (    (    (    s,   /export/web/mailman/mailman/Mailman/Utils.pyt   GetRequestMethod:  s    c         C   s&  | d k r< t j t   } | d d k r< | d } q< n  t j j d  } | d k r t j j d d  t j j d d  } n  t j |  d } | r| j |  r| t	 |  } | j
 d  } | d	 k r | j d d	 |  } n | j d  } d
 | |  } n
 | |  } | t j S(   s   target - scriptname only, nothing extra
    web_page_url - the list's configvar of the same name
    absolute - a flag which if set, generates an absolute url
    iR\   t   REQUEST_URIt   SCRIPT_NAMER   RZ   i   t   ?i    s   ../N(   R@   R   t   DEFAULT_URL_PATTERNR^   R   R   R   t   urlparset
   startswithR   RB   RP   t   CGIEXT(   t   targett   web_page_urlt   absolutet   fullpatht   baseurlt   iRP   R   (    (    s,   /export/web/mailman/mailman/Mailman/Utils.pyt	   ScriptURL?  s$    
c         C   s   |  j    }  t |   \ } } |  g } | r} | d } xC t |  d k ry | j d | t j |  f  | d } q: Wn  | S(   s  returns a sorted list of addresses that could possibly match
    a given name.

    For Example, given scott@pobox.com, return ['scott@pobox.com'],
    given scott@blackbox.pobox.com return ['scott@blackbox.pobox.com',
                                           'scott@pobox.com']i   i   s   %s@%s(   RA   RH   R   R-   t   DOTR   (   t   nameRD   RE   t   res(    (    s,   /export/web/mailman/mailman/Mailman/Utils.pyt   GetPossibleMatchingAddrs\  s    	
 c         C   sO   i  } | r0 x< |  D] } t  | | j   <q Wn x |  D] } t  | | <q7 W| S(   s<   Return a dict keyed by the entries in the list passed to it.(   R!   RA   (   t   Lt   foldcaset   dRu   (    (    s,   /export/web/mailman/mailman/Mailman/Utils.pyt	   List2Dictp  s    t   at   eRu   t   ot   ut   bt   cR}   t   ft   gt   ht   kt   mt   nRX   t   rRV   t   tt   vt   wRe   t   zc         C   sJ   g  } x0 t  |  d |  k  r8 | j t j t   q	 Wt j |  |   S(   Ni   (   R   R-   t   randomt   choicet
   _syllablest   EMPTYSTRINGR   (   t   lengtht   syls(    (    s,   /export/web/mailman/mailman/Mailman/Utils.pyt   UserFriendly_MakeRandomPassword  s    c         C   sG  d } g  } d  } zx | |  k  r y t j |  |  } Wn t t f k
 r | d  k r y t j d t j  } Wq t k
 r } | j t j	 k r   n  t
 d d  t |   SXn  t j | |  |  } n X| j |  | t |  7} q Wt j t j |   } | j d d  |   SWd  | d  k	 rBt j |  n  Xd  S(   Ni    s   /dev/urandomR[   s+   urandom not available, passwords not secures   
R   (   R@   R   t   urandomt   AttributeErrort   NotImplementedErrort   opent   O_RDONLYt   OSErrort   errnot   ENOENTR   R   t   readR-   R   t   base64t   encodestringR   R   t   replacet   close(   R   t	   bytesreadt   bytest   fdt   newbytesR   RV   (    (    s,   /export/web/mailman/mailman/Mailman/Utils.pyt   Secure_MakeRandomPassword  s0    c         C   s   t  j r t |   St |   S(   N(   R   t   USER_FRIENDLY_PASSWORDSR   R   (   R   (    (    s,   /export/web/mailman/mailman/Mailman/Utils.pyt   MakeRandomPassword  s    	
c          C   sR   t  t j   d  }  t  t j   d  } d   } d t t | |  | f   S(   Ni4   c         S   sV   d |  k o d k  n r) |  d 7}  n  d |  k o@ d k  n rR |  d 7}  n  |  S(   Ni    i   iA   i4   iG   (    (   R   (    (    s,   /export/web/mailman/mailman/Mailman/Utils.pyt   mkletter  s
    s   %c%c(   t   intR   RO   t   map(   t   chr1t   chr2R   (    (    s,   /export/web/mailman/mailman/Mailman/Utils.pyt   GetRandomSeed  s    	c         C   sy   | r t  j } n	 t  j } t j d  } z: t | d  } | j t |   j   d  | j	   Wd  t j |  Xd  S(   Ni   R   s   
(
   R   t   SITE_PW_FILEt   LISTCREATOR_PW_FILER   t   umaskR   t   writet   sha_newt	   hexdigestR   (   t   pwt	   siteadmint   filenamet   omaskt   fp(    (    s,   /export/web/mailman/mailman/Mailman/Utils.pyt   set_global_password  s    	c         C   sx   |  r t  j } n	 t  j } y* t |  } | j   d  } | j   Wn, t k
 rs } | j t j k ro   n  d  SX| S(   Ni(
   R   R   R   R   R   R   t   IOErrorR   R   R@   (   R   R   R   t	   challengeR   (    (    s,   /export/web/mailman/mailman/Mailman/Utils.pyt   get_global_password  s    	 c         C   s2   t  |  } | d  k r d  S| t |   j   k S(   N(   R   R@   R   R   (   t   responseR   R   (    (    s,   /export/web/mailman/mailman/Mailman/Utils.pyt   check_global_password  s    s   &amp;((?:#[0-9]+|[a-z]+);)c         C   s   t  |  t  s t  |  t  rF t |   d k r9 d }  qF |  d }  n  t j r t  |  t  r x- t j D] } |  j | t j |  }  qh Wq n  | r t	 j
 |  d t St j d t	 j
 |  d t  Sd  S(   Ni    R   it   quotes   &\1(   RM   RN   RO   R   R   t   BROKEN_BROWSER_WORKAROUNDt   strt   BROKEN_BROWSER_REPLACEMENTSR   t   cgit   escapeR!   t   _ampreR   (   RV   t   doubleescapeR   (    (    s,   /export/web/mailman/mailman/Mailman/Utils.pyt   websafe  s    		#c         C   sa   |  j  d d  } t |  d k rW y | d t | d  f SWqW t k
 rS qW Xn  |  d f S(   Nt   :i   i   i    iw   (   R+   R   R   t
   ValueError(   RV   t   parts(    (    s,   /export/web/mailman/mailman/Mailman/Utils.pyt	   nntpsplit  s    c         C   s*   | r |  j  d d  S|  j  d d  Sd S(   s   Make email address unrecognizable to web spiders, but invertable.

    When for_text option is set (not default), make a sentence fragment
    instead of a token.R?   s    at s   --at--N(   R   (   RI   t   for_text(    (    s,   /export/web/mailman/mailman/Mailman/Utils.pyt   ObscureEmail  s    c         C   s   |  j  d d  S(   s!   Invert ObscureEmail() conversion.s   --at--R?   (   R   (   RI   (    (    s,   /export/web/mailman/mailman/Mailman/Utils.pyt   UnobscureEmail  s    t	   OuterExitc           B   s   e  Z RS(    (   t   __name__t
   __module__(    (    (    s,   /export/web/mailman/mailman/Mailman/Utils.pyR   "  s   c         C   s  g  } | d  k	 r" | j |  n  | d  k	 rA | j | j  n  | j t j  g  } | d  k	 r | j | j    | j t j j t j	 | j
   n  | j t j j t j	 d   | j t j	  d  } y x | D]y } xp | D]h } t j j | | |   }	 y t |	  } t  Wq t k
 rN}
 |
 j t j k rE  n  d  } q Xq Wq WWn t k
 rkn X| d  k ry+ t j j t j	 d |   }	 t |	  } Wqt k
 r}
 |
 j t j k r  n  t t j d |    qXn  | j   } | j   | } | d  k	 ry^ t |  } y | j |  } Wn8 t k
 rmt | t |  d  } | j |  } n XWqt t f k
 r}
 t d d |	 |
  qXn  | r| |	 f St |  |	 f S(   Nt   sitet   ens   No template file foundR   R[   s   broken template: %s
%s(   R@   R-   t   preferred_languageR   t   DEFAULT_SERVER_LANGUAGERs   R   R   R   t   TEMPLATE_DIRt	   host_nameR   R   R   R   R   R   R   R
   t   interpolatet   UnicodeErrort   unicodet
   GetCharSett	   TypeErrorR   R   R;   (   t   templatefilet   dictt   rawt   langt   mlistt	   languagest
   searchdirsR   t   dirR   R   t   templateR/   t   sdictt	   utemplate(    (    s,   /export/web/mailman/mailman/Mailman/Utils.pyt   findtext%  sf    4%
  

c         C   s   t  |  | | | |  d S(   Ni    (   R   (   R   R   R   R   R   (    (    s,   /export/web/mailman/mailman/Mailman/Utils.pyt   maketext  s    t   confirmt   helpt   infot   listst   optionsi   t   passwordt   removei   t   sett	   subscribet   unsubscribet   whoc         C   s  d } g  } xc t  j j |   D]O } | d k r5 Pn  | j   rN | d 7} n  | t j k ra t S| j |  q Wt j	 |  } t
 j | j   j    r t S| d  } t |  j d d   } | j |  x | D] } | j   s q n  g  | j   D] } | j   ^ q } t
 j | d d  \ }	 }
 |	 d  k rM|
 d  k rMq n  |	 t | d  k on|
 k n r | d d k r| d d k rq n  t Sq Wt S(   Ni    s   -- i   i   t   subjectR   R   i   t   ont   off(   NN(   R   R   (   RC   t	   Iteratorst   body_line_iteratort   stripR   t   DEFAULT_MAIL_COMMANDS_MAX_LINESR   R-   R,   R   t	   ADMINDATAt   has_keyRA   R!   R   R   R+   R@   R   (   t   msgt   linecntR5   R7   t   bodytextt	   bodylinesR   t   wordt   wordst   minargst   maxargs(    (    s,   /export/web/mailman/mailman/Mailman/Utils.pyt   is_administrivia  s8    
%& c         C   s{   |  } t  j j d  r( t  j d } n? t  j j d  rg t  j j d  rg t  j d t  j d } n  | rw t |  S| S(   s  Return the full virtual path this CGI script was invoked with.

    Newer web servers seems to supply this info in the REQUEST_URI
    environment variable -- which isn't part of the CGI/1.1 spec.
    Thus, if REQUEST_URI isn't available, we concatenate SCRIPT_NAME
    and PATH_INFO, both of which are part of CGI/1.1.

    Optional argument `fallback' (default `None') is returned if both of
    the above methods fail.

    The url will be cgi escaped to prevent cross-site scripting attacks,
    unless `escape' is set to 0.
    Ri   Rj   RZ   (   R   R   R   R   (   t   fallbackR   t   url(    (    s,   /export/web/mailman/mailman/Mailman/Utils.pyt   GetRequestURI  s    $
c         C   s   x |  r | r |   n  y t  j d t  j  \ } } Wn6 t k
 rp } | j t j k rb   n  |  j   Pn X| d k r y |  | =Wq t k
 r q Xn  | r Pq q Wd  S(   Nii    (   R   t   waitpidt   WNOHANGR   R   t   ECHILDt   cleart   KeyError(   t   kidst   funct   oncet   pidt   statusR   (    (    s,   /export/web/mailman/mailman/Mailman/Utils.pyt   reap  s"    	

c         C   s   t  j |  d S(   Ni    (   R   t   LC_DESCRIPTIONS(   R   (    (    s,   /export/web/mailman/mailman/Mailman/Utils.pyt   GetLanguageDescr  s    c         C   s   t  j |  d S(   Ni   (   R   R  (   R   (    (    s,   /export/web/mailman/mailman/Mailman/Utils.pyR     s    c         C   s   t  j |  d S(   Ni   (   R   R  (   R   (    (    s,   /export/web/mailman/mailman/Mailman/Utils.pyt   GetDirection	  s    c         C   s   t  j j |   S(   N(   R   R  R   (   R   (    (    s,   /export/web/mailman/mailman/Mailman/Utils.pyt
   IsLanguage  s    c          C   s   t  j j d t  j j d   }  t  j j d  } | rd |  j d |  rd |  t |  d  }  n  t j r |  r t |  j    St j	 r t
 j
 t j	  d p t j } | j   Sd  S(   Nt	   HTTP_HOSTt   SERVER_NAMEt   SERVER_PORTR   i   (   R   R   R   t   endswithR   R   t   VIRTUAL_HOST_OVERVIEWR   RA   t   DEFAULT_URLRm   t   DEFAULT_URL_HOST(   t   hostt   portt   hostname(    (    s,   /export/web/mailman/mailman/Mailman/Utils.pyR^     s    !		c         C   s[   |  d  k r* t j j t   t    }  n  | d  k rG d t j |  f Sd t j | |  f S(   Ns   %s@%ss   %s-%s@%s(   R@   R   t   VIRTUAL_HOSTSR   R^   t   MAILMAN_SITE_LIST(   R%  t   extra(    (    s,   /export/web/mailman/mailman/Mailman/Utils.pyt   get_site_email"  s
    c         C   s<   d t  t j   t j   |  j   |  j f } t  d 7a  | S(   Ns   <mailman.%d.%d.%d.%s@%s>i   (   t   _serialt   timeR   t   getpidt   internal_nameR   (   R   t   msgid(    (    s,   /export/web/mailman/mailman/Mailman/Utils.pyt   unique_message_id3  s
    
c         C   s4   |  d  k r t j   d  }  n  t j |  d d  S(   Ni   i    i   i(   i    (   i    i    i    i    i    (   i(   R@   R+  t	   localtimet   mktime(   t   date(    (    s,   /export/web/mailman/mailman/Mailman/Utils.pyt   midnight>  s    c         C   s   |  j  d d  j  d d  }  t j |   } xq t d t |  d  D]W } | | d r | | d d t k r d | | d	 | | <qF d | | | | <qF Wt j |  S(
   s$   Convert from %-strings to $-strings.t   $s   $$s   %%t   %i   i   i    s   ${t   }(   R   t   creR+   t   rangeR   t
   IDENTCHARSR   R   (   RV   R   Ru   (    (    s,   /export/web/mailman/mailman/Mailman/Utils.pyt	   to_dollarM  s    &c         C   s   |  j  d d  j  d d  }  t j |   } x t d t |  d  D]v } | | d
 k	 ri d | | <qF | | d d
 k	 r d | | d d | | d <qF d | | d	 d | | d	 <qF Wt j t d
 |   S(   s$   Convert from $-strings to %-strings.R5  s   %%s   $$R4  i   i   s   %(s   )si   N(	   R   t   dreR+   R8  R   R@   R   R   t   filter(   RV   R   Ru   (    (    s,   /export/web/mailman/mailman/Mailman/Utils.pyt
   to_percentY  s    !"c         C   s_   i  } xR t  d g  t j |   D]! \ } } } | p= | p= d ^ q  D] } t | | <qG W| S(   s?   Return the set (dictionary) of identifiers found in a $-string.N(   R<  R@   R;  t   findallR!   (   RV   R}   R   R   R   Rx   (    (    s,   /export/web/mailman/mailman/Mailman/Utils.pyt   dollar_identifiersg  s    Gc         C   s.   i  } x! t  j |   D] } t | | <q W| S(   s?   Return the set (dictionary) of identifiers found in a %-string.(   R7  R>  R!   (   RV   R}   Rx   (    (    s,   /export/web/mailman/mailman/Mailman/Utils.pyt   percent_identifierso  s    c            sD  g   t  j d |   }  f d   }   f d   } x t r0 j | | j d    | se Pn  | j d  } | j d  r y | t | d   Wq-t k
 r  j | d | d   q-Xq9 t j	 j
 | d	  } | j d  r| j d  r| t | d d
 !  q9  j | |   q9 Wt j   } | S(   Ns   &(?P<ref>[^;]+);c            s     j  t |    d  S(   N(   R-   t   unichr(   Ru   (   t   newparts(    s,   /export/web/mailman/mailman/Mailman/Utils.pyt   appchr}  s    c            sY   t  |  t  r |  S  d  k r( d } n! t    } | d k rI d } n  t |  | d  S(   Ns
   iso-8859-1s   us-asciiR   (   RM   R   R@   R   (   RV   t   charset(   R   (    s,   /export/web/mailman/mailman/Mailman/Utils.pyt	   tounicode  s    		i    t   #i   t   &t   ;Rk   i(   R   R+   R!   R-   t   popRn   R   R   t   htmlentitydefst
   entitydefsR   R  R   R   (   RV   R   R   RC  RE  t   refR   t   newstr(    (   R   RB  s,   /export/web/mailman/mailman/Mailman/Utils.pyt   canonstrz  s(    	"c         C   s   |  d  k r d }  n  | d  k r* d } n t |  } y3 t |  t  rU |  j |  St |  |  } |  SWn t k
 r t |   SXd  S(   Nu    s   us-ascii(   R@   R   RM   R   t   encodeR   R   t   uquote(   RV   R   RD  R   (    (    s,   /export/web/mailman/mailman/Mailman/Utils.pyt
   uncanonstr  s    		c         C   sc   g  } xG |  D]? } t  |  } | d k r? | j d |  q | j |  q Wt t j |   S(   Ni   s   &#%3d;(   t   ordR-   R   R   R   (   RV   R   R   R   (    (    s,   /export/web/mailman/mailman/Mailman/Utils.pyRP    s    c         C   s   yS t  j j t  j j |    } | j   } t j | j    } | j | d  SWn- t	 t
 t t f k
 r t j |  j    SXd  S(   NR   (   RC   t   Headert   make_headert   decode_headert   __unicode__t   UEMPTYSTRINGR   t
   splitlinesRO  t   LookupErrorR   R   R   R   (   RV   t   csetR   t   ustrR7   (    (    s,   /export/web/mailman/mailman/Mailman/Utils.pyt   oneline  s    c         C   s  t  |  t  s |  Sd } d } t } t } t } x| t |   k  r|  | } | r | t k ro | d 7} n# | t k r | d 7} n
 | | 7} t } nG| r | t k rt } qn)| d k r | r t } n| d k r| rt } | | 7} t } n | d k r&| r&t } | | 7} n t j d |  r| r| t k rW| d 7} q}| t k rp| d 7} q}| | 7} qnb | d	 k r| r| | 7} t } n< | t k r| d 7} n# | t k r| d 7} n
 | | 7} | d
 7} q4 W| S(   NR   i    s   \ns   \rRF  t   [t   ]s   \ss   \i   (	   RM   R   R   R   R,   t   CRR!   R   RS   (   t   patternt
   newpatternRu   t   inclasst	   skiptoeolt   copynextR   (    (    s,   /export/web/mailman/mailman/Mailman/Utils.pyt   strip_verbose_pattern  sZ    

		
	
	
s   <i?frames2   <link(?! rel="SHORTCUT ICON" href="<mm-favicon>">)s   <metas   <objects   <scripts
   @keyframess   \bj(?:ava)?script\bs   \bvbs(?:cript)?\bs   \bdomactivate\bs   \bdomattrmodified\bs   \bdomcharacterdatamodified\bs   \bdomfocus(?:in|out)\bs   \bdommenuitem(?:in)?active\bs   \bdommousescroll\bs$   \bdomnodeinserted(?:intodocument)?\bs#   \bdomnoderemoved(?:fromdocument)?\bs   \bdomsubtreemodified\bs   \bfscommand\bs   \bonabort\bs   \bon(?:de)?activate\bs   \bon(?:after|before)print\bs   \bon(?:after|before)update\bs+   \b(?:on)?animation(?:end|iteration|start)\bs8   \bonbefore(?:(?:de)?activate|copy|cut|editfocus|paste)\bs   \bonbeforeunload\bs   \bonbegin\bs
   \bonblur\bs   \bonbounce\bs   \bonbroadcast\bs   \boncanplay(?:through)?\bs   \bon(?:cell)?change\bs   \boncheckboxstatechange\bs   \bon(?:dbl)?click\bs   \bonclose\bs   \boncommand(?:update)?\bs   \boncomposition(?:end|start)\bs   \boncontextmenu\bs   \boncontrolselect\bs
   \boncopy\bs	   \boncut\bs   \bondataavailable\bs!   \bondataset(?:changed|complete)\bs5   \bondrag(?:drop|end|enter|exit|gesture|leave|over)?\bs   \bondragstart\bs
   \bondrop\bs   \bondurationchange\bs   \bonemptied\bs   \bonend(?:ed)?\bs   \bonerror(?:update)?\bs   \bonfilterchange\bs   \bonfinish\bs   \bonfocus(?:in|out)?\bs   \bonhashchange\bs
   \bonhelp\bs   \boninput\bs   \bonkey(?:up|down|press)\bs   \bonlayoutcomplete\bs   \bon(?:un)?load\bs   \bonloaded(?:meta)?data\bs   \bonloadstart\bs   \bonlosecapture\bs   \bonmedia(?:complete|error)\bs   \bonmessage\bs6   \bonmouse(?:down|enter|leave|move|out|over|up|wheel)\bs   \bonmove(?:end|start)?\bs   \bon(?:off|on)line\bs
   \bonopen\bs   \bonoutofsync\bs   \bonoverflow(?:changed)?\bs   \bonpage(?:hide|show)\bs   \bonpaint\bs   \bonpaste\bs   \bonpause\bs   \bonplay(?:ing)?\bs   \bonpopstate\bs*   \bonpopup(?:hidden|hiding|showing|shown)\bs   \bonprogress\bs   \bonpropertychange\bs   \bonradiostatechange\bs   \bonratechange\bs   \bonreadystatechange\bs   \bonrepeat\bs   \bonreset\bs   \bonresize(?:end|start)?\bs   \bonresume\bs   \bonreverse\bs'   \bonrow(?:delete|enter|exit|inserted)\bs#   \bonrows(?:delete|enter|inserted)\bs   \bonscroll\bs   \bonsearch\bs   \bonseek(?:ed|ing)?\bs   \bonselect(?:start)?\bs   \bonselectionchange\bs
   \bonshow\bs   \bonstart\bs   \bonstalled\bs
   \bonstop\bs   \bonstorage\bs   \bonsubmit\bs   \bonsuspend\bs   \bonsync(?:from|to)preference\bs   \bonsyncrestored\bs
   \bontext\bs   \bontime(?:error|update)\bs   \bontoggle\bs$   \bontouch(?:cancel|end|move|start)\bs   \bontrackchange\bs   \b(?:on)?transitionend\bs   \bonunderflow\bs   \bonurlflip\bs   \bonvolumechange\bs   \bonwaiting\bs   \bonwheel\bs   \bseeksegmenttime\bs   \bsvgabort\bs   \bsvgerror\bs   \bsvgload\bs   \bsvgresize\bs   \bsvgscroll\bs   \bsvgunload\bs   \bsvgzoom\bt   |s   [ -	--]s,   (&#[0-9]+;?)|(&#x[0-9a-f]+;?)|(%[0-9a-f]{2})c         C   s   |  j    j   j d  } yG | j d  s< | j d  rR t | d d  } n t | d  } Wn t k
 rv d SX| d k  r t |  Sd Sd	 S(
   s=   Translate &#... and %xx encodings into the encoded character.s   &#;Re   R5  i   i   i
   R   i   N(   t   groupRA   R   Rn   R   R   t   chr(   t   mot   matcht   val(    (    s,   /export/web/mailman/mailman/Mailman/Utils.pyt
   _translate  s    
c         C   s3   t  j t j d t j t |     r+ t St Sd S(   sW  Check HTML string for various tags, script language names and
    'onxxx' actions that can be used in XSS attacks.
    Currently, this a very simple minded test.  It just looks for
    patterns without analyzing context.  Thus, it potentially flags lots
    of benign stuff.
    Returns True if anything suspicious found, False otherwise.
    R   N(   t   _badhtmlRS   t   _filtercharsR   t   _encodedcharsRl  R!   R   (   t   html(    (    s,   /export/web/mailman/mailman/Mailman/Utils.pyt   suspiciousHTML  s    	c         C   s:  t  r
 d S|  s d Sy t j |   } Wn* t j k
 rS } t d d |  |  d SXx | j   D] } | j   sa | j d  sa | j d  r qa n  t j	 d d | j    } | s qa n  | j
   j d  } | d	 j d
  r	t } | d	 d g | d } n t } | j   d j |  } | t  | <qa Wd S(   s\   This loads and parses the data from the url argument into s_dict for
    use by get_org_dom.NR[   s#   Unable to retrieve data from %s: %sR*   s   //s    .*R   R   i    t   !i   (   t   s_dictt   urllib2t   urlopent   URLErrorR   t	   readlinesR   Rn   R   R   RA   R+   R!   R   t   reverseR   (   R  R}   R   R7   R   t   excR   (    (    s,   /export/web/mailman/mailman/Mailman/Utils.pyt   get_suffixes  s2    
+
c         C   s4   |  t  | d t |     } | j   d j |  S(   sJ   A helper to get a domain name consisting of the first l+1 labels
    in d.i   R   (   t   minR   Rx  R   (   R}   t   lt   dom(    (    s,   /export/web/mailman/mailman/Mailman/Utils.pyt   _get_dom  s    
c         C   s  t  s t t j  n  g  } |  j   j d  } | j   x t  j   D] } | j d  } t |  t |  k rH x t	 t |  d  D]. } | | | | k r | | d k r Pq q W| t |  d | d k s | d d k r | j
 |  q qH qH W| st | d  Sd } xk | D]c } t  | rSt | t | j d   d  St | j d   | k r#t | j d   } q#q#Wt | |  S(   sq   Given a domain name, this returns the corresponding Organizational
    Domain which may be the same as the input.R   i   t   *ii    (   Rs  Rz  R   t$   DMARC_ORGANIZATIONAL_DOMAIN_DATA_URLRA   R+   Rx  t   keysR   R8  R-   R~  (   RE   t   hitsR}   R   t   ksRu   R|  (    (    s,   /export/web/mailman/mailman/Mailman/Utils.pyt   get_org_dom  s,    
$.
 c         C   s   t  s t d d |  j  t S| j   } | j d  } | d k  rH t S| | d } t |  | d |  } | d k r| | St |  } | | k r t |  | d | d t } | d k r | Sn  t S(   NR[   s@   DNS lookup for dmarc_moderation_action for list %s not availableR?   i   s   _dmarc.t   continuet   org(	   t   dns_resolverR   t	   real_nameR   RA   t   rfindt   _DMARCProhibitedR  R!   (   R   RC   RF   t   f_domRe   t   o_dom(    (    s,   /export/web/mailman/mailman/Mailman/Utils.pyt   IsDMARCProhibited  s&    
c      
   C   s  yO t  j j   } t t j  | _ t t j  | _ | j	 | t  j
 j  } Wnz t  j j t  j j f k
 ru d St  j j k
 r t d d | |  t St k
 r } t d d | | | j  t SXi  } i  } t | d g  }	 x | j j D] }
 |
 j j   j   } |
 j t  j
 j k rE|
 j d j j   | | <n  |
 j t  j
 j k r`q n  | j | g   j d j |
 j d j    q Wt! |	  } t |  } x~ | r(| j" d  } | | k r| | | k rqn  | j | |  | j# | |  |	 j# | |  |	 j$ |  qqWt% |	  d k rNt d d	 |  n  x|	 D]} | | k rmqUn  t& d
   | |  } t% |  d k rd St% |  d k rt d d | t% |   t' Sx:| D]2} t( j) d | t( j*  } | r| r| j+ d  j   } n9 t( j) d | t( j*  } | r| j+ d  j   } n q| d k ryt d d |  j, | | | |  t S|  j- r| d k rt d d |  j, | | | |  t S|  j. r|  j- r|  j/ d k r| d k rt d d |  j, | | | |  t SqWqUWt' S(   NR  R[   s2   DNSException: No Nameservers available for %s (%s)s:   DNSException: Unable to query DMARC policy for %s (%s). %sR   i    R   i   sY   multiple DMARC entries in results for %s,
                   processing each to be strictc         S   s   |  j  d  S(   Ns	   v=DMARC1;(   Rn   (   R   (    (    s,   /export/web/mailman/mailman/Mailman/Utils.pyt   <lambda>`  R   sf   RRset of TXT records for %s has %d v=DMARC1 entries;
                       ignoring them per RFC 7849s   \bsp=(\w*)\bs   \bp=(\w*)\bt   rejectt   vettes6   %s: DMARC lookup for %s (%s) found p=reject in %s = %st
   quarantines:   %s: DMARC lookup for %s (%s) found p=quarantine in %s = %si   t   nones4   %s: DMARC lookup for %s (%s) found p=none in %s = %s(   i   i   (0   t   dnst   resolvert   Resolvert   floatR   t   DMARC_RESOLVER_TIMEOUTt   timeoutt   DMARC_RESOLVER_LIFETIMEt   lifetimet   queryt	   rdatatypet   TXTt   NXDOMAINt   NoAnswert   NoNameserversR   R!   R   t   __doc__R   R   t   answerRx   t   to_textRA   t   rdtypet   CNAMEt   itemsRp   t
   setdefaultR-   R   t   stringsRN   RI  t   addt   discardR   R<  R   R   RS   t
   IGNORECASERg  R  t"   dmarc_quarantine_moderation_actiont   dmarc_none_moderation_actiont   dmarc_moderation_action(   R   RC   t   dmarc_domainR  R  t   txt_recsR   t   results_by_namet   cnamest
   want_namest   txt_recRx   t   expandst   seent   itemt   dmarcst   entryRi  t   policy(    (    s,   /export/web/mailman/mailman/Mailman/Utils.pyR  #  s    
	
				c         C   sv  |  j  d k r t S| j   } t j   } t j | g   j | t |  j   t	 t
 t |   } | j   x0 | D]( } t | | | k  rx t | | =qx qx Wt d 7a t t j k rDd a x~ t j   D]m } t	 t
 t |   } | j   x0 | D]( } t | | | k  r t | | =q q Wt | s t | =q q Wn  |  j |  sWt St
 t j | g    |  j  k S(   s;  For lists that request it, we keep track of recent posts by address.
A message from an address to a list, if the list requests it, is remembered
for a specified time whether or not the address is a list member, and if the
address is a member and the member is over the threshold for the list, that
fact is returned.i    i   (   t   member_verbosity_thresholdR   RA   R+  t   recentMemberPostingsR  R-   R  t   member_verbosity_intervalR8  R   Rx  t   clean_countR   t   VERBOSE_CLEAN_LIMITR  t   isMemberR   (   R   RC   t   nowRe   Ru   RI   (    (    s,   /export/web/mailman/mailman/Mailman/Utils.pyt   IsVerboseMember  s4    	



c         C   s   | s
 g  Sy |  j  d d  \ } } Wn t k
 r: g  SX| j   } t j d d |  j   } | j d  } g  } x$ | D] } | j | j d   q~ WxE | D]= } | | k r g  | D]  } | | k r | d | ^ q Sq Wg  S(   sU  The arguments are an email address and a string representing a
    list of lists in a form like 'a,b,c;1,2' representing [['a', 'b',
    'c'],['1', '2']].  The inner lists are domains which are
    equivalent in some sense.  The return is an empty list or a list
    of email addresses equivalent to the first argument.
    For example, given

    email = 'user@me.com'
    domains_list = '''domain1, domain2; mac.com, me.com, icloud.com;
                   domaina, domainb
                   '''

    check_eq_domains(email, domains_list) will return
    ['user@mac.com', 'user@icloud.com']
    R?   i   s   \sR   RH  t   ,(   t   rsplitR   RA   R   R   R+   R-   (   RC   t   domains_listt   localRE   t   domainsR}   Re   (    (    s,   /export/web/mailman/mailman/Mailman/Utils.pyt   check_eq_domains  s     /c         C   s   y} |  j  d  d  d k r9 t t |  j  d  d   S|  j  d  d  j   d k rx t t |  j  d  d d   Sd SWn t k
 r d SXd  S(   Ni   RF  R   i   u   �(   Rg  RA  R   RA   R   (   Ri  (    (    s,   /export/web/mailman/mailman/Mailman/Utils.pyt   _invert_xml  s     c         C   sW   t  |  t  rO |  j | d  } t j d t |  } t j d t |  } | S|  Sd S(   sk  This converts a string s, encoded in cset to a unicode with translation
    of XML character references and textual \uxxxx escapes.  It is more or less
    the inverse of unicode.decode(cset, errors='xmlcharrefreplace').  It is
    similar to canonstr above except for replacing invalid refs with the
    unicode replace character and recognizing \u escapes.
    R   u   &(#[0-9]+);u   (?i)\\(u[a-f0-9]{4})N(   RM   R   t   decodeR   R   R  (   RV   RZ  t   us(    (    s,   /export/web/mailman/mailman/Mailman/Utils.pyt   xml_to_unicode  s    c         C   sA  t  s
 t St r{ y. t |  d d d d } t j |  j } Wn t k
 rR t SXd j d j	 | j
 d  d    } nM |  j
 d  } t |  d k r t Sd	 j | d
 | d | d | d  } t j j   } y | j | t j j  } Wn t k
 rt SX| st S| j j   } t j d | t j  r=t St S(   Nt   encodings   us-asciit   errorsR   s   {0}.zen.spamhaus.orgR   ii   s    {0}.{1}.{2}.{3}.zen.spamhaus.orgi   i   i   i    s   127\.0\.0\.[2-7]$(   R  R   t   have_ipaddressR   t	   ipaddresst
   ip_addresst   reverse_pointerR   t   formatR   R+   R   R  R  R  R  R  t   AR   t   rrsetR  R   RS   t	   MULTILINER!   (   t   ipt   uipt   ptrt   lookupR   R  t   ansR/   (    (    s,   /export/web/mailman/mailman/Mailman/Utils.pyt	   banned_ip  s6    (c         C   s   t  s
 t S|  j   }  t |   \ } } d | } t j j   } y | j | t j j	  } Wn t
 k
 rq t SX| s| t S| j j   } t j d | t j  r t j d | t j  s t Sn  t S(   Ns   %s.dbl.spamhaus.orgs   127\.0\.1\.\d{1,3}$s   127\.0\.1\.255$(   R  R   RA   RH   R  R  R  R  R  R  R   R  R  R   RS   R  R!   (   RC   RD   RE   R  R  R  R/   (    (    s,   /export/web/mailman/mailman/Mailman/Utils.pyt   banned_domain  s"    
c         C   sx   | | k r d } n  | | } t  j t |   } | | d } |  j d d d } t |  | | d t |  f S(   sg   Returns a CAPTCHA question, the HTML for the answer box, and
    the data to be put into the CSRF tokenR   i    t   captcha_answert   sizei   RL   (   R   t	   randrangeR   t	   FormatBoxR   R   (   R   R   t   captchast   idxt   questiont   box_html(    (    s,   /export/web/mailman/mailman/Mailman/Utils.pyt   captcha_display1  s    	
c         C   s   y% |  j  d  \ } }  t |   }  Wn t k
 r9 t SX| | k rJ t S| | } |  t t |   k rp t S| |  d d } t j | |  S(   NRL   i   R4  (   R+   R   R   R   R8  R   R   Rj  (   R  t   given_answerR  R   t   correct_answer_pattern(    (    s,   /export/web/mailman/mailman/Mailman/Utils.pyt   captcha_verify>  s    
(   R   R   Ru   R   R   (   R   R   R}   R   R   R   R   R   R   RX   R   RV   R   R   R   Re   R   (   i   i   (   i    i    (   i    i    (   i    i    (   i    i    (   i   i   (   i    i    (   i   i   (   i    i   (   i    i   (   i    i   (   R  t
   __future__R    R   t   sysR   R   R+  R   R   R   Rt  Rm   RJ  t   email.HeaderRC   t   email.Iteratorst   email.ErrorsR   t   typesR   t   stringR   R   R   t   ImportErrort   _lowert   uppert   MailmanR   R   R	   t   Mailman.SafeDictR
   t   Mailman.Logging.SyslogR   t   hashlibt   md5t   md5_newt   sha1R   t   shat   newR!   R   t	   NameErrort   dns.resolverR  t   dns.exceptionR   R  R  R  R   RW  R_  R,   Rw   R9  t   compileR  R7  R;  R'   R)   R;   R>   RH   RK   RR   RU   RY   R]   Rf   Rh   R@   Rv   Rz   R~   t   _vowelst   _consonantsR   R   R   R-   R   R   t   MEMBER_PASSWORD_LENGTHR   R   R   R   R   R   R   R   R   R   t	   ExceptionR   R   R   R   R	  R  R  R  R   R  R  R^   R)  R*  R/  R3  R:  R=  R?  R@  RN  RQ  RP  R\  Re  t	   _badwordsR   Rm  Rn  Ro  Rl  Rq  Rs  Rz  R~  R  R  R  R  R  R  R  R  R  R  R  R  R  (    (    (    s,   /export/web/mailman/mailman/Mailman/Utils.pyt   <module>   s&  		




		K					"		 		!		
	o
	'										/			@							 	l	*	"					