2008-09-05 17:35:58 +04:00
#
# ***** BEGIN LICENSE BLOCK *****
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
#
# The contents of this file are subject to the Mozilla Public License Version
# 1.1 (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
# http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
# for the specific language governing rights and limitations under the
# License.
#
# The Original Code is mozilla.org code.
#
# The Initial Developer of the Original Code is
# Mozilla Foundation.
# Portions created by the Initial Developer are Copyright (C) 2008
# the Initial Developer. All Rights Reserved.
#
# Contributor(s):
# Honza Bambas <honzab@firemni.cz>
#
# Alternatively, the contents of this file may be used under the terms of
# either the GNU General Public License Version 2 or later (the "GPL"), or
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
# in which case the provisions of the GPL or the LGPL are applicable instead
# of those above. If you wish to allow use of your version of this file only
# under the terms of either the GPL or the LGPL, and not to allow others to
# use your version of this file under the terms of the MPL, indicate your
# decision by deleting the provisions above and replace them with the notice
# and other provisions required by the GPL or the LGPL. If you do not delete
# the provisions above, a recipient may use your version of this file under
# the terms of any one of the MPL, the GPL or the LGPL.
#
# ***** END LICENSE BLOCK *****
import automation
import os
import re
2008-10-21 19:50:38 +04:00
import shutil
2008-09-05 17:35:58 +04:00
import sys
2008-12-05 19:52:25 +03:00
#expand DIST_BIN = __XPC_BIN_PATH__
2008-09-05 17:35:58 +04:00
#expand BIN_SUFFIX = __BIN_SUFFIX__
2009-01-19 00:44:43 +03:00
#expand PROFILE_DIR = __PROFILE_DIR__
2008-09-05 17:35:58 +04:00
#expand CERTS_SRC_DIR = __CERTS_SRC_DIR__
dbFiles = [
re . compile ( " ^cert[0-9]+ \ .db$ " ) ,
re . compile ( " ^key[0-9]+ \ .db$ " ) ,
re . compile ( " ^secmod \ .db$ " )
]
def unlinkDbFiles ( path ) :
for root , dirs , files in os . walk ( path ) :
for name in files :
for dbFile in dbFiles :
if dbFile . match ( name ) and os . path . exists ( os . path . join ( root , name ) ) :
os . unlink ( os . path . join ( root , name ) )
2008-10-21 19:50:38 +04:00
def dbFilesExist ( path ) :
for root , dirs , files in os . walk ( path ) :
for name in files :
for dbFile in dbFiles :
if dbFile . match ( name ) and os . path . exists ( os . path . join ( root , name ) ) :
return True
return False
2008-09-05 17:35:58 +04:00
def runUtil ( util , args , inputdata = None ) :
2009-01-12 22:23:28 +03:00
if inputdata :
proc = automation . Process ( [ util ] + args , env = automation . environment ( ) , stdin = automation . PIPE )
proc . communicate ( inputdata )
return proc . returncode
return automation . Process ( [ util ] + args , env = automation . environment ( ) ) . wait ( )
2008-09-05 17:35:58 +04:00
def createRandomFile ( randomFile ) :
import random
file = open ( randomFile , " wb " ) ;
for count in xrange ( 0 , 2048 ) :
file . write ( chr ( random . randint ( 0 , 255 ) ) )
file . close ( )
2009-01-19 00:44:43 +03:00
def createCertificateAuthority ( profileDir , srcDir ) :
2008-09-05 17:35:58 +04:00
certutil = DIST_BIN + " /certutil " + BIN_SUFFIX
pk12util = DIST_BIN + " /pk12util " + BIN_SUFFIX
2009-01-19 00:44:43 +03:00
tempDbDir = os . path . join ( profileDir , " .temp " )
2008-09-05 17:35:58 +04:00
if not os . path . exists ( tempDbDir ) :
os . mkdir ( tempDbDir )
pwfilePath = os . path . join ( tempDbDir , " .crtdbpw " )
rndfilePath = os . path . join ( tempDbDir , " .rndfile " )
pgoCAModulePathSrc = os . path . join ( srcDir , " pgoca.p12 " )
pgoCAPathSrc = os . path . join ( srcDir , " pgoca.ca " )
pwfile = open ( pwfilePath , " w " )
pwfile . write ( " \n " )
pwfile . close ( )
unlinkDbFiles ( tempDbDir )
# Create temporary certification database for CA generation
status = runUtil ( certutil , [ " -N " , " -d " , tempDbDir , " -f " , pwfilePath ] )
if status != 0 :
return status
createRandomFile ( rndfilePath ) ;
status = runUtil ( certutil , [ " -S " , " -d " , tempDbDir , " -s " , " CN=Temporary Certificate Authority, O=Mozilla Testing, OU=Profile Guided Optimization " , " -t " , " C,, " , " -x " , " -m " , " 1 " , " -v " , " 120 " , " -n " , " pgo temporary ca " , " -2 " , " -f " , pwfilePath , " -z " , rndfilePath ] , " Y \n 0 \n N \n " )
if status != 0 :
return status
status = runUtil ( certutil , [ " -L " , " -d " , tempDbDir , " -n " , " pgo temporary ca " , " -a " , " -o " , pgoCAPathSrc , " -f " , pwfilePath ] )
if status != 0 :
return status
status = runUtil ( pk12util , [ " -o " , pgoCAModulePathSrc , " -n " , " pgo temporary ca " , " -d " , tempDbDir , " -w " , pwfilePath , " -k " , pwfilePath ] )
if status != 0 :
return status
unlinkDbFiles ( tempDbDir )
os . unlink ( pwfilePath )
os . unlink ( rndfilePath )
os . rmdir ( tempDbDir )
return 0
2009-01-19 00:44:43 +03:00
def createSSLServerCertificate ( profileDir , srcDir ) :
2008-09-05 17:35:58 +04:00
certutil = DIST_BIN + " /certutil " + BIN_SUFFIX
pk12util = DIST_BIN + " /pk12util " + BIN_SUFFIX
2009-01-19 00:44:43 +03:00
pwfilePath = os . path . join ( profileDir , " .crtdbpw " )
rndfilePath = os . path . join ( profileDir , " .rndfile " )
pgoCAPath = os . path . join ( srcDir , " pgoca.p12 " )
2008-09-05 17:35:58 +04:00
pwfile = open ( pwfilePath , " w " )
pwfile . write ( " \n " )
pwfile . close ( )
2008-10-21 19:50:38 +04:00
if not dbFilesExist ( srcDir ) :
2009-01-19 00:44:43 +03:00
# Make sure all DB files from src are really deleted
2008-10-21 19:50:38 +04:00
unlinkDbFiles ( srcDir )
# Create certification database for ssltunnel
status = runUtil ( certutil , [ " -N " , " -d " , srcDir , " -f " , pwfilePath ] )
if status != 0 :
return status
status = runUtil ( pk12util , [ " -i " , pgoCAPath , " -w " , pwfilePath , " -d " , srcDir , " -k " , pwfilePath ] )
if status != 0 :
return status
2008-09-05 17:35:58 +04:00
# Generate automatic certificate
2009-01-19 00:44:43 +03:00
locations = automation . readLocations ( os . path . join ( profileDir , " server-locations.txt " ) )
2008-09-05 17:35:58 +04:00
locations . pop ( 0 )
locationsParam = " "
firstLocation = " "
for loc in locations :
if loc . scheme == " https " and " nocert " not in loc . options :
customCertOption = False
customCertRE = re . compile ( " ^cert=(?: \ w+) " )
for option in loc . options :
match = customCertRE . match ( option )
if match :
customCertOption = True
break
if not customCertOption :
if len ( locationsParam ) > 0 :
locationsParam + = " , "
locationsParam + = loc . host
if firstLocation == " " :
firstLocation = loc . host
if firstLocation == " " :
print " Nothing to generate, no automatic secure hosts specified "
else :
createRandomFile ( rndfilePath ) ;
2008-10-21 19:50:38 +04:00
runUtil ( certutil , [ " -D " , " -n " , " pgo server certificate " , " -d " , srcDir , " -z " , rndfilePath , " -f " , pwfilePath ] )
# Ignore the result, the certificate may not be present when new database is being built
status = runUtil ( certutil , [ " -S " , " -s " , " CN= %s " % firstLocation , " -t " , " Pu,, " , " -c " , " pgo temporary ca " , " -m " , " 2 " , " -8 " , locationsParam , " -v " , " 12 " , " -n " , " pgo server certificate " , " -d " , srcDir , " -z " , rndfilePath , " -f " , pwfilePath ] )
2008-09-05 17:35:58 +04:00
if status != 0 :
return status
os . unlink ( pwfilePath )
os . unlink ( rndfilePath )
return 0
if len ( sys . argv ) == 1 :
print " Specify --gen-server or --gen-ca "
sys . exit ( 1 )
if sys . argv [ 1 ] == " --gen-server " :
2009-01-19 00:44:43 +03:00
certificateStatus = createSSLServerCertificate ( PROFILE_DIR , CERTS_SRC_DIR )
2008-09-05 17:35:58 +04:00
if certificateStatus != 0 :
print " ERROR FAIL: SSL Server Certificate generation "
sys . exit ( certificateStatus )
if sys . argv [ 1 ] == " --gen-ca " :
2009-01-19 00:44:43 +03:00
certificateStatus = createCertificateAuthority ( PROFILE_DIR , CERTS_SRC_DIR )
2008-09-05 17:35:58 +04:00
if certificateStatus != 0 :
print " ERROR FAIL: Certificate Authority generation "
else :
print " \n \n "
print " =================================================== "
print " IMPORTANT: "
print " To use this new certificate authority in tests "
print " run ' make ' at testing/mochitest "
print " =================================================== "
sys . exit ( certificateStatus )
print " Invalid option specified "
sys . exit ( 1 )