def header7bit(s):
	"""QP_CORRUPT headers."""
	#return mimify.mime_encode_header(s + ' ')[:-1]
	# XXX due to mime_encode_header bug
	import re
	p = re.compile('=\n([^ \t])');
	return p.sub(r'\1', mimify.mime_encode_header(s + ' ')[:-1])
    if (i in form.inputkeys) and form.field[i][0].content:
      request_file.write('%s = %s\n' % (i,form.field[i][0].content))

request_file.close()
os.chmod(request_filename,0444)

##############################################################################
# Send a nice e-mail with random ID to user to initiate mail dialogue
##############################################################################

if caCertReqMailAdr and emailAddress:

  import smtplib, mimify

  if commonName:
    to_addr = '%s <%s>' % (mimify.mime_encode_header(commonName),emailAddress)
  else:
    to_addr = '%s' % (emailAddress)

  mail_msg = """From: %s
To: %s
Subject: %s

Someone (maybe you) has sent a certificate request
to our certificate authority.

Please answer this e-mail with the same subject
if this was really you and the data below is correct.

If someone abused your name / e-mail address simply
forget about this message and delete it. %s
      newcertpathname = os.path.join(ca.new_certs_dir,certfilename)
      cert = openssl.cert.X509CertificateClass(newcertpathname)

      if openssl.db.GetEntrybySerial(ca.database,cert.serial):

	certpathname = os.path.join(ca.certs,certfilename)

        if not os.path.isfile(certpathname):

          import mimify

          issuername = charset.asn12iso(cert.issuer.get('CN',''))
	  issueremail = cert.issuer.get('Email','root@localhost')
          subjectname = charset.asn12iso(cert.subject.get('CN',''))
	  subjectemail = cert.subject.get('Email','')
          from_addr = mimify.mime_encode_header('%s <%s>' % (issuername,issueremail))
	  if subjectemail:
	    to_name,to_email = subjectname,subjectemail
          else:
	    to_name,to_email = issuername,issueremail
          to_addr = mimify.mime_encode_header('%s <%s>' % (to_name,to_email))

	  # Mailbody
	  mail_msg = newcert_mailtext % (
	               from_addr,
		       to_addr,
		       cert.serial,
		       strftime('%Y-%m-%d %H:%M',gmtime(cert.notBefore_secs)),
		       strftime('%Y-%m-%d %H:%M',gmtime(cert.notAfter_secs)),
		       ca.nsBaseUrl,nsGetCertUrl,ca_name,certtype,cert.serial,
		       cert.asciiprint(),
def sendmail ( to_addrs, subj, msg, 
               from_addr = Configuration.FromAddress,
               **extended ):
    """**
    <p>The general-purpose sendmail function, which is called
    by the STML &lt;:sendmail:&gt; tag, or directly by Python code.</p>
    <p><tt>to_addrs</tt> should be a list or tuple of email address
    strings. <tt>subj</tt> must be a string, although it may be empty.
    <tt>msg</tt> is a string containing the body of the message; it can
    be empty. <tt>from_addr</tt> is a single mail address string; it 
    defaults to the value of the <tt>FromAddress</tt> variable in 
    <tt>templating.conf</tt>.</p>
    <p>This function returns nothing on success, and raises a
    <code>MailError</code> on any mail failure.</p>
    <p>
    The From: and To: headers are always built from supplied parameters.
    Cc: and Bcc: headers in the supplied mail text are not touched
    and not used.
    </p>
    <p>
    The sendmail function adds a correct Date: header, ensures that
    the From: header is set and generates a Message-Id: header if
    necessary. If the raw parameter is true, these headers are
    not touched.
    </p>

    <p>
    The extended parameter accepts the following parameters:
    </p>
    <dl>
     <dt>to_name='name'</dt>
     <dd>A name that may be used in the To: header
         directly. It's merged with to_addrs if the there is only one value for
         to_addrs. If there are multiple to_addrs, it is used
         literally and may then contain an address too.</dd>
     <dt>from_name</dt>
     <dd>A name that is merged with from_addr in the From: header.</dd>
     <dt>envelope_sender</dt>
     <dd>The sender address that is used in the SMTP dialogue. This
         address gets possible bounces.</dd>
     <dt>charset='charset-name'</dt>
     <dd>The character set that is used for encoding of headers
         and the message body. At the moment only <tt>iso-8859-1</tt>
         and <tt>us-ascii</tt> are supported because of limitations
         in the rfc822 module. The default is us-ascii</dd>
     <dt>encoding='encoding-type'</dt>
     <dd>The encoding type that is used for encoding of headers
         and the message body.<br />
         Possible values are <tt>base64</tt>, <tt>7bit</tt>,
         <tt>8bit</tt> and <tt>quoted-printable</tt><br />
         When 7bit is used, the MIME headers (Mime-Version,
         Content-Encoding and Content-Type are not set (and deleted
         if present in the msg).<br />
         The default value is 7bit.</dd>
     <dt>raw=True</dt>
     <dd>If this parameter is set to true the contents of the message
         is not altered in any way. The message is given in the parameter
         <tt>msg</tt>. In this case the envelope_sender
         has to be set, the receivers are taken from to_addrs as
         usual</dd>
    </dl>
    """

    # force SkunkWeb administrator to change the default envelope sender
    if from_addr == 'root@localhost':
        WARN("MailServices: FromAddress not changed, use a deliverable address!")
        raise MailError, "FromAddress not changed, use a deliverable address!"
    

    # if they supplied only a string as to_addrs (i.e. one address),
    # make it a list
    if type(to_addrs) == type(''):
        to_addrs = [to_addrs]
    rnum = len(to_addrs)       # number of receivers

    # do defined address checks, raise exception in case of problems
    address_check(_addresscheck_level, to_addrs)

    # check if the message is to be sent 'as is'
    if extended.has_key('raw') and extended['raw']:
        if not extended.has_key('envelope_sender'):
           WARN("MailServices: envelope_sender not set, but 'raw' send requested")
           raise MailError, "envelope_sender not set, but 'raw' send requested"
        dispatch_to_send_method(to_addrs, msg, extended['envelope_sender'])
        return

    # charset setting
    if extended.has_key('charset'):
        charset = string.lower(extended['charset'])
        if charset not in valid_charsets:
           WARN("MailServices: invalid character set parameter given: %s" \
	         % (extended['charset']))
           raise MailError, "invalid character set parameter given"
    else:
        charset = 'us-ascii'

    # check envelope sender
    if extended.has_key('envelope_sender'):
        envelope_sender = extended['envelope_sender']
    else:
        envelope_sender = from_addr

    mailfile = StringIO(msg)
    mail = mimetools.Message(mailfile)

    # insert subject
    if not subj or subj == '':
        subj = 'no subject'
    # work around limitation in mimify
    mail['Subject'] = mimify.mime_encode_header(subj + ' <')[:-2]

    # insert from header
    if extended.has_key('from_name'):
        fromheader = extended['from_name'] + ' <' + from_addr + '>'
        fromheader = mimify.mime_encode_header(fromheader)
    else:
        fromheader = from_addr
    mail['From'] = fromheader

    # insert to header
    if extended.has_key('to_name'):
        toheader = extended['to_name']
        if rnum == 1:
            if len(filter(lambda x: x in ['<','>'], list(toheader))) != 0:
                WARN("MailServices: angle bracket in to_name when using single recipient")
                raise MailError, "angle bracket in to_name when using single recipient"
            toheader = toheader + ' <' + to_addrs[0] + '>'
        mail['To'] = mimify.mime_encode_header(toheader)
    else:    
        if rnum == 1:
            mail['To'] = to_addrs[0]
        else:
            mail['To'] = "recipient list not shown: ;"

    # required Date: header
    lt=time.time()
    mail['Date']=arpa(lt)

    # not necessary but useful - Message-Id
    utcdate = time.strftime('%Y%m%d%H%M%S', time.gmtime(lt))
    pid = os.getpid()
    idhost = socket.getfqdn()
    randint = random.randrange(100000)
    mail['Message-Id'] = \
             '<%s.%s.%s.skunkweb@%s>' % (utcdate, pid, randint, idhost)

    # character set
    if extended.has_key('charset'):
        charset = string.lower(extended['charset'])
        if charset not in ['us-ascii', 'iso-8859-1']:
            WARN("MailServices: charset %s is not supported" % (charset))
            raise MailError, "charset %s is not supported" % (charset)
    else:
        charset = 'us-ascii'

    # encoding
    if extended.has_key('encoding'):
        encoding = string.lower(extended['encoding'])
        if encoding not in ['7bit', '8bit', 'base64', 'quoted-printable']:
            WARN("MailServices: encoding %s is not supported" % (encoding))
            raise MailError, "encoding %s is not supported" % (encoding)
    else:
        encoding = '7bit'

    # check the presence of 8bit data
    if len(filter(lambda x: ord(x) > 127, list(msg))) > 0:
        eightbitdata = True
    else:
        eightbitdata = False

    if encoding == '7bit':
        # check for correctness
        if charset != 'us-ascii':
            WARN("MailServices: 7bit encoding but charset is not us-ascii")
            raise MailError, "7bit encoding but charset is not us-ascii"
        if eightbitdata:
            WARN("MailServices: 7bit encoding but 8bit data present")
            raise MailError, "7bit encoding but 8bit data present"
        # delete present MIME headers if 7bit encoding is used
        if mail.has_key('Content-Transfer-Encoding'):
            del mail['Content-Transfer-Encoding']
        if mail.has_key('Mime-Version'):
            del mail['Mime-Version']
        if mail.has_key('Content-Type'):
            del mail['Content-Type']
    else:                                     # not 7bit
        mail['Content-Transfer-Encoding'] = encoding
        mail['Mime-Version'] = '1.0'
        mail['Content-Type'] = 'text/plain; charset=%s' % (charset)
        headers = mail.__str__() + '\n'
        mail.rewindbody()
        body = mailfile.read()
        mailfile.close()
        mailfile=StringIO(body)
        newmfile = StringIO()
        # only encode body - mimetools doesn't check this
        mimetools.encode(mailfile, newmfile, encoding)
        mailfile = StringIO(headers + newmfile.getvalue())
        newmfile.close()
        mail = mimetools.Message(mailfile)

    mail.rewindbody()
    messagetext = mail.__str__() + '\n' + mailfile.read()
    mailfile.close()
    # now send
    dispatch_to_send_method(to_addrs, messagetext, envelope_sender)
did not match the attributes

  commonName   = %s
  emailAddress = %s

given in your certificate request. Your certificate request will
be processed anyway. But if you intend to use the requested
certificate for signing e-mails you might want to adjust the from
address in your mail clients preferences / options menu to avoid
trouble with other mail users reporting invalid signatures.

If you have further questions simply reply to this e-mail.
""" % (
  mime_encode_header(
    charset.t612iso(
      cacert.subject.get('CN','CA administrator'))
    ),
    ca_from_addr,
  certreq_mail_attr,
  caChallengeId,
  from_addr,
  certreq_name_attr,certreq_mail_attr
)

  try:
    smtpconn=smtplib.SMTP(MailRelay)
    try:
      try:
        smtpconn.set_debuglevel(0)
        smtpconn.sendmail(ca_from_addr,certreq_mail_attr,mail_msg)
      finally:
Beispiel #6
0
def sendmail(to_addrs,
             subj,
             msg,
             from_addr=Configuration.FromAddress,
             **extended):
    """**
    <p>The general-purpose sendmail function, which is called
    by the STML &lt;:sendmail:&gt; tag, or directly by Python code.</p>
    <p><tt>to_addrs</tt> should be a list or tuple of email address
    strings. <tt>subj</tt> must be a string, although it may be empty.
    <tt>msg</tt> is a string containing the body of the message; it can
    be empty. <tt>from_addr</tt> is a single mail address string; it 
    defaults to the value of the <tt>FromAddress</tt> variable in 
    <tt>templating.conf</tt>.</p>
    <p>This function returns nothing on success, and raises a
    <code>MailError</code> on any mail failure.</p>
    <p>
    The From: and To: headers are always built from supplied parameters.
    Cc: and Bcc: headers in the supplied mail text are not touched
    and not used.
    </p>
    <p>
    The sendmail function adds a correct Date: header, ensures that
    the From: header is set and generates a Message-Id: header if
    necessary. If the raw parameter is true, these headers are
    not touched.
    </p>

    <p>
    The extended parameter accepts the following parameters:
    </p>
    <dl>
     <dt>to_name='name'</dt>
     <dd>A name that may be used in the To: header
         directly. It's merged with to_addrs if the there is only one value for
         to_addrs. If there are multiple to_addrs, it is used
         literally and may then contain an address too.</dd>
     <dt>from_name</dt>
     <dd>A name that is merged with from_addr in the From: header.</dd>
     <dt>envelope_sender</dt>
     <dd>The sender address that is used in the SMTP dialogue. This
         address gets possible bounces.</dd>
     <dt>charset='charset-name'</dt>
     <dd>The character set that is used for encoding of headers
         and the message body. At the moment only <tt>iso-8859-1</tt>
         and <tt>us-ascii</tt> are supported because of limitations
         in the rfc822 module. The default is us-ascii</dd>
     <dt>encoding='encoding-type'</dt>
     <dd>The encoding type that is used for encoding of headers
         and the message body.<br />
         Possible values are <tt>base64</tt>, <tt>7bit</tt>,
         <tt>8bit</tt> and <tt>quoted-printable</tt><br />
         When 7bit is used, the MIME headers (Mime-Version,
         Content-Encoding and Content-Type are not set (and deleted
         if present in the msg).<br />
         The default value is 7bit.</dd>
     <dt>raw=True</dt>
     <dd>If this parameter is set to true the contents of the message
         is not altered in any way. The message is given in the parameter
         <tt>msg</tt>. In this case the envelope_sender
         has to be set, the receivers are taken from to_addrs as
         usual</dd>
    </dl>
    """

    # force SkunkWeb administrator to change the default envelope sender
    if from_addr == 'root@localhost':
        WARN(
            "MailServices: FromAddress not changed, use a deliverable address!"
        )
        raise MailError, "FromAddress not changed, use a deliverable address!"

    # if they supplied only a string as to_addrs (i.e. one address),
    # make it a list
    if type(to_addrs) == type(''):
        to_addrs = [to_addrs]
    rnum = len(to_addrs)  # number of receivers

    # do defined address checks, raise exception in case of problems
    address_check(_addresscheck_level, to_addrs)

    # check if the message is to be sent 'as is'
    if extended.has_key('raw') and extended['raw']:
        if not extended.has_key('envelope_sender'):
            WARN(
                "MailServices: envelope_sender not set, but 'raw' send requested"
            )
            raise MailError, "envelope_sender not set, but 'raw' send requested"
        dispatch_to_send_method(to_addrs, msg, extended['envelope_sender'])
        return

    # charset setting
    if extended.has_key('charset'):
        charset = string.lower(extended['charset'])
        if charset not in valid_charsets:
            WARN("MailServices: invalid character set parameter given: %s" \
           % (extended['charset']))
            raise MailError, "invalid character set parameter given"
    else:
        charset = 'us-ascii'

    # check envelope sender
    if extended.has_key('envelope_sender'):
        envelope_sender = extended['envelope_sender']
    else:
        envelope_sender = from_addr

    mailfile = StringIO(msg)
    mail = mimetools.Message(mailfile)

    # insert subject
    if not subj or subj == '':
        subj = 'no subject'
    # work around limitation in mimify
    mail['Subject'] = mimify.mime_encode_header(subj + ' <')[:-2]

    # insert from header
    if extended.has_key('from_name'):
        fromheader = extended['from_name'] + ' <' + from_addr + '>'
        fromheader = mimify.mime_encode_header(fromheader)
    else:
        fromheader = from_addr
    mail['From'] = fromheader

    # insert to header
    if extended.has_key('to_name'):
        toheader = extended['to_name']
        if rnum == 1:
            if len(filter(lambda x: x in ['<', '>'], list(toheader))) != 0:
                WARN(
                    "MailServices: angle bracket in to_name when using single recipient"
                )
                raise MailError, "angle bracket in to_name when using single recipient"
            toheader = toheader + ' <' + to_addrs[0] + '>'
        mail['To'] = mimify.mime_encode_header(toheader)
    else:
        if rnum == 1:
            mail['To'] = to_addrs[0]
        else:
            mail['To'] = "recipient list not shown: ;"

    # required Date: header
    lt = time.time()
    mail['Date'] = arpa(lt)

    # not necessary but useful - Message-Id
    utcdate = time.strftime('%Y%m%d%H%M%S', time.gmtime(lt))
    pid = os.getpid()
    idhost = socket.getfqdn()
    randint = random.randrange(100000)
    mail['Message-Id'] = \
             '<%s.%s.%s.skunkweb@%s>' % (utcdate, pid, randint, idhost)

    # character set
    if extended.has_key('charset'):
        charset = string.lower(extended['charset'])
        if charset not in ['us-ascii', 'iso-8859-1']:
            WARN("MailServices: charset %s is not supported" % (charset))
            raise MailError, "charset %s is not supported" % (charset)
    else:
        charset = 'us-ascii'

    # encoding
    if extended.has_key('encoding'):
        encoding = string.lower(extended['encoding'])
        if encoding not in ['7bit', '8bit', 'base64', 'quoted-printable']:
            WARN("MailServices: encoding %s is not supported" % (encoding))
            raise MailError, "encoding %s is not supported" % (encoding)
    else:
        encoding = '7bit'

    # check the presence of 8bit data
    if len(filter(lambda x: ord(x) > 127, list(msg))) > 0:
        eightbitdata = True
    else:
        eightbitdata = False

    if encoding == '7bit':
        # check for correctness
        if charset != 'us-ascii':
            WARN("MailServices: 7bit encoding but charset is not us-ascii")
            raise MailError, "7bit encoding but charset is not us-ascii"
        if eightbitdata:
            WARN("MailServices: 7bit encoding but 8bit data present")
            raise MailError, "7bit encoding but 8bit data present"
        # delete present MIME headers if 7bit encoding is used
        if mail.has_key('Content-Transfer-Encoding'):
            del mail['Content-Transfer-Encoding']
        if mail.has_key('Mime-Version'):
            del mail['Mime-Version']
        if mail.has_key('Content-Type'):
            del mail['Content-Type']
    else:  # not 7bit
        mail['Content-Transfer-Encoding'] = encoding
        mail['Mime-Version'] = '1.0'
        mail['Content-Type'] = 'text/plain; charset=%s' % (charset)
        headers = mail.__str__() + '\n'
        mail.rewindbody()
        body = mailfile.read()
        mailfile.close()
        mailfile = StringIO(body)
        newmfile = StringIO()
        # only encode body - mimetools doesn't check this
        mimetools.encode(mailfile, newmfile, encoding)
        mailfile = StringIO(headers + newmfile.getvalue())
        newmfile.close()
        mail = mimetools.Message(mailfile)

    mail.rewindbody()
    messagetext = mail.__str__() + '\n' + mailfile.read()
    mailfile.close()
    # now send
    dispatch_to_send_method(to_addrs, messagetext, envelope_sender)