def _validateArgs(): if args.defaultCert: if (args.domainId, args.passFile, args.out) != (None, None, "self-signed-cert"): fail( "If you specify --default-cert, cannot also specify --domain-id, --pass-file or --out=csr." ) args.domainId = "DefaultDomain" else: if None in (args.domainId, args.passFile): fail( "Must specify --default-cert or both --domain-id and --pass-file." ) if not re.match("^[A-Za-z]{1}[A-Za-z0-9_-]{0,31}$", args.domainId): fail( "Invalid domain name: '%s'. Permitted characters: [A-Za-z0-9_-]. " "Must start with a letter, max length 32." % args.domainId) if not os.path.exists(args.passFile): fail("Password file does not exist: %s" % args.passFile) minPassphraseLength = 4 with open(args.passFile, 'r') as f: content = f.read() contentNoLFCR = content.rstrip('\r\n') if (len(contentNoLFCR) < minPassphraseLength): fail("Passphase provided is too short. Length is %d, expected >= %d." % \ (len(contentNoLFCR), minPassphraseLength))
def _generatePrivateKey(): pemFilename = os.path.join(generatedCertsPath, "%s-key.pem" % args.domainId) try: print("Generating private key...") opensslCmd = "openssl genrsa -out %s -des -passout file:%s 2048" % ( pemFilename, args.passFile) runOpenSslCmd(opensslCmd) except IOError as e: fail("Failed to generate Private Key: %s" % os.strerror(e.errno)) return pemFilename
def _validateMetricsArgs(): if args.metrics: if args.metricsDbPassFile is not None and not os.path.isfile( args.metricsDbPassFile): fail("Metrics database password file does not exist: %s" % args.metricsDbPassFile) if args.metricsDbUrl.find( "${") == -1 and args.metricsDbUrl[:5] != "jdbc:": fail( "Invalid metrics database URL '%s': must be a selector or start with 'jdbc:'" % args.metricsDbUrl) else: args.metricsDbUrl = "" args.metricsDbUsername = "" args.metricsDbPassFile = None
def _validateServerAndDbArgs(): if args.analyticsPort < 0 or args.analyticsPort > 65535: fail("Invalid Analytics port - must be in range 0-65535: %s" % args.analyticsPort) if args.defaultUser: args.analyticsUsername = "******" args.analyticsPassFile = None else: if args.analyticsPassFile is None: fail("Must specify ONE of --default-user or --analytics-pass-file.") if not os.path.isfile(args.analyticsPassFile): fail("Analytics password file does not exist: %s" % args.analyticsPassFile) if args.metricsDbPassFile is not None and not os.path.isfile(args.metricsDbPassFile): fail("Metrics database password file does not exist: %s" % args.metricsDbPassFile) if args.metricsDbUrl.find("${") == -1 and args.metricsDbUrl[:5] != "jdbc:": fail("Invalid metrics database URL '%s': must be a selector or start with 'jdbc:'" % args.metricsDbUrl)
def _setup(): # Create directory to hold generated key and csr/cert generatedCertsDir = os.path.join(os.path.dirname(__file__), "certs", args.domainId) if os.path.exists(generatedCertsDir): if args.force: print("Removing existing output directory: %s" % generatedCertsDir) shutil.rmtree(generatedCertsDir) else: fail( "Output directory already exists for this domain-id: %s\nUse --force to overwrite." % generatedCertsDir) os.makedirs(generatedCertsDir) # Create temporary passphrase file if default cert being generated if args.defaultCert: args.passFile = os.path.join(generatedCertsDir, "default-pass-file.txt") with open(args.passFile, 'w') as f: f.write("changeme") # Instantiate openssl conf file from template openSslTemplate = os.path.join(os.path.dirname(__file__), "utils", "openssl-template.cnf") opensslCnfFile = os.path.join(generatedCertsDir, "openssl.cnf") shutil.copyfile(openSslTemplate, opensslCnfFile) with open(opensslCnfFile) as f: s = f.read() s = re.sub(r"basedir = \?", "basedir = %s" % generatedCertsDir, s) s = re.sub("domaincert.pem", "%s-cert.pem" % args.domainId, s) s = re.sub("domainkey", "%s-key" % args.domainId, s) with open(opensslCnfFile, 'w') as f: f.write(s) os.environ["OPENSSL_CONF"] = opensslCnfFile # Create openssl helper files with open(os.path.join(generatedCertsDir, "index.txt"), 'w') as _: pass with open(os.path.join(generatedCertsDir, "serial"), 'w') as serialFile: firstserial = hex(int(round(time.time() * 1000)))[2:] if len(firstserial) % 2 != 0: firstserial = "0%s" % firstserial serialFile.write(firstserial) return (opensslCnfFile, generatedCertsDir)
def _generateCSR(privateKeyFile): print("Generating CSR...") domainInfo = _getDomainInfo() csrFile = os.path.join(generatedCertsPath, "%s.csr" % args.domainId) params = { "signAlg": args.signAlg, "privateKeyFile": privateKeyFile, "csrFile": csrFile, "domainInfo": domainInfo, "opensslCnf": opensslCnf, "passFile": args.passFile } opensslCmd = ( 'openssl req -%(signAlg)s -new -key "%(privateKeyFile)s" -out "%(csrFile)s" -subj "%(domainInfo)s" ' '-reqexts domain_extensions -config "%(opensslCnf)s" -passin file:"%(passFile)s"' % params) try: runOpenSslCmd(opensslCmd) except IOError as e: fail("Failed to generate CSR: %s" % os.strerror(e.errno)) return csrFile
def _validateReportArgs(): if args.emailReports: if len(args.emailTo) == 0 or None in (args.emailFrom, args.smtpHost, args.smtpUsername, args.smtpPassFile): fail("If report emails are enabled, must specify --email-to, --email-from, " "--smtp-host, --smtp-username, --smtp-pass-file.") for address in args.emailTo: if EMAIL_PATTERN.match(address) is None: fail("Invalid --email-to address: %s" % address) if EMAIL_PATTERN.match(args.emailFrom) is None: fail("Invalid --email-from address: %s" % args.emailFrom) if args.smtpPort < 0 or args.smtpPort > 65535: fail("Invalid SMTP port - must be in range 0-65535: %s" % args.smtpPort) if not os.path.isfile(args.smtpPassFile): fail("SMTP password file does not exist: %s" % args.smtpPassFile) else: args.emailTo = [] args.emailFrom = "" args.smtpHost = "" args.smtpPort = 25 args.smtpUsername = "" args.smtpPassFile = None
def _validateArgs(): if not os.path.isfile(args.installer): fail("Installer does not exist: %s" % args.installer) if (args.baseOS, args.parentImage).count(None) != 1: fail("Must specify one of --os or --parent-image.") if not isValidImageName(args.outImage): fail("Invalid name for output image: %s" % args.outImage) if args.parentImage is not None: if not isValidImageName(args.parentImage): fail("Invalid name for parent image: %s" % args.parentImage) if not imageExists(args.parentImage): print( "WARN: Parent image '%s' does not exist locally, Docker will try to pull " "it from remote repository.\n" % args.parentImage) else: args.parentImage = OS_IMAGE[args.baseOS]
def _generateCert(csrFile): print("Generating self-signed domain cert...") certFile = os.path.join(generatedCertsPath, "%s-cert.pem" % args.domainId) startDate = _getStartDate() params = { "startDate": startDate, "signAlg": args.signAlg, "csrFile": csrFile, "certFile": certFile, "opensslCnf": opensslCnf, "passFile": args.passFile } # Specify -extfile to get a v3 certificate. Need a v3 certificate for SSL to work. # Do not specify -extensions section as we want to copy extensions from the CSR via # "copy_extensions = copyall" in openssl.cnf. opensslCmd = ( 'openssl ca -startdate %(startDate)s -md %(signAlg)s -in "%(csrFile)s" -out "%(certFile)s" ' '-extfile "%(opensslCnf)s" -batch -notext -passin file:"%(passFile)s" -selfsign' % params) try: runOpenSslCmd(opensslCmd) except IOError as e: fail("Failed to generate certificate: %s" % os.strerror(e.errno)) return certFile
def _validateSecurityArgs(): if args.defaultCert: if (args.domainCert, args.domainKey, args.domainKeyPassFile) != (None, None, None): fail( "If you specify --default-cert, cannot also specify --domain-cert, " "--domain-key or --domain-key-pass-file.") args.domainCert = "certs/DefaultDomain/DefaultDomain-cert.pem" args.domainKey = "certs/DefaultDomain/DefaultDomain-key.pem" if not os.path.isfile(args.domainCert): fail( "Default domain cert does not exist. Run ./gen_domain_cert.py --default-cert" ) if not os.path.isfile(args.domainKey): fail( "Default domain private key file does not exist. Run ./gen_domain_cert.py --default-cert" ) else: if None in (args.domainCert, args.domainKey, args.domainKeyPassFile): fail( "Must specify --default-cert or all of (--domain-cert, --domain-key, " "--domain-key-pass-file).") if not os.path.isfile(args.domainCert): fail("Domain cert file does not exist: %s" % args.domainCert) if not os.path.isfile(args.domainKey): fail("Domain private key file does not exist: %s" % args.domainKey) if not os.path.isfile(args.domainKeyPassFile): fail("Domain key passphrase file does not exist: %s" % args.domainKeyPassFile)
def _validateGeneralArgs(): if not args.parentImage: fail("Must specify name of parent Docker image.") if not isValidImageName(args.parentImage): fail("Invalid name for parent Docker image: %s" % args.parentImage) if not imageExists(args.parentImage): print( "WARN: Parent image '%s' does not exist locally, Docker will try to pull " "it from remote repository.\n" % args.parentImage) if not isValidImageName(args.outImage): fail("Invalid name for output Docker image: %s" % args.outImage) if args.fed is not None and not os.path.isfile(args.fed): fail("FED file does not exist: %s" % args.fed) if args.fedPassFile is not None: if not os.path.isfile(args.fedPassFile): fail("FED passphrase file does not exist: %s" % args.fedPassFile) if args.fed is None: fail( "If you specify a FED passphrase you must also specify a FED file." ) if args.license is not None and not os.path.isfile(args.license): fail("License file does not exist: %s" % args.license) if args.mergeDir is not None: if not os.path.isdir(args.mergeDir): fail("Specified merge directory is not a directory: %s" % args.mergeDir) if not args.mergeDir.endswith( "apigateway") and not args.mergeDir.endswith("apigateway/"): fail("Merge directory must be called 'apigateway'.") if args.anmPassFile is not None and not os.path.isfile(args.anmPassFile): fail("API Gateway Manager password file does not exist: %s" % args.anmPassFile) adminUsersFilePresent = (args.mergeDir is not None and os.path.isfile( os.path.join(args.mergeDir, "conf", "adminUsers.json"))) if (args.defaultUser, args.anmPassFile is not None, adminUsersFilePresent).count(True) != 1: fail( "Must specify ONE of --anm-pass-file, --default-user, or --merge-dir " "containing file apigateway/conf/adminUsers.json.")
def _validateSecurityArgs(): if args.defaultCert: if (args.domainCert, args.domainKey, args.domainKeyPassFile) != (None, None, None): fail("If you specify --default-cert, cannot also specify --domain-cert, " "--domain-key or --domain-key-pass-file.") args.domainCert = "certs/DefaultDomain/DefaultDomain-cert.pem" args.domainKey = "certs/DefaultDomain/DefaultDomain-key.pem" if not os.path.isfile(args.domainCert): fail("Default domain cert does not exist. Run ./gen_domain_cert.py --default-cert") if not os.path.isfile(args.domainKey): fail("Default domain private key file does not exist. Run ./gen_domain_cert.py --default-cert") if args.groupId == "DefaultDomain": fail("Group ID and domain ID cannot be the same; both are set to 'DefaultDomain'") else: if None in (args.domainCert, args.domainKey, args.domainKeyPassFile): fail("Must specify --default-cert or all of (--domain-cert, --domain-key, " "--domain-key-pass-file).") if not os.path.isfile(args.domainCert): fail("Domain cert file does not exist: %s" % args.domainCert) if not os.path.isfile(args.domainKey): fail("Domain private key file does not exist: %s" % args.domainKey) if not os.path.isfile(args.domainKeyPassFile): fail("Domain key passphrase file does not exist: %s" % args.domainKeyPassFile) result = runOpenSslCmd('openssl x509 -in "%s" -subject -noout -nameopt multiline' % args.domainCert) domainId = re.search(r"commonName *= *(.*)", result, re.MULTILINE).group(1).strip() if args.groupId == domainId: fail("Group ID and domain ID cannot be the same; both are set to '%s'" % domainId)
def _validateGeneralArgs(): if not os.path.isfile(args.license): fail("License file does not exist: %s" % args.license) if not re.match("^[A-Za-z]{1}[A-Za-z0-9_-]{0,31}$", args.groupId): fail("Invalid group ID: '%s'. Permitted characters: [A-Za-z0-9_-]. " "Must start with a letter, max length 32." % args.groupId) if (args.apiManager, args.factoryFed, args.fed, args.pol) == (False, False, None, None): fail("Must specify API Manager, FED, POL or factory FED.") if args.apiManager: if (args.factoryFed, args.fed, args.pol, args.env, args.fedPassFile) != (False, None, None, None, None): fail("API Manager cannot be specified in combination with FED, POL, ENV or FED passphrase.") if args.factoryFed: if (args.fed, args.pol, args.env, args.fedPassFile) != (None, None, None, None): fail("Factory FED cannot be specified in combination with FED, POL, ENV or FED passphrase.") if args.fed is not None: if not os.path.isfile(args.fed): fail("FED file does not exist: %s" % args.fed) if (args.pol, args.env) != (None, None): fail("Either POL and ENV combination or FED is permitted (POL+ENV=FED).") if args.pol is not None: if not os.path.isfile(args.pol): fail("POL file does not exist: %s" % args.pol) if args.env is None: fail("ENV file must be provided together with POL.") if args.env is not None: if not os.path.isfile(args.env): fail("ENV file does not exist: %s" % args.env) if args.pol is None: fail("POL file must be provided together with ENV.") if args.fedPassFile is not None: if not os.path.isfile(args.fedPassFile): fail("FED passphrase file does not exist: %s" % args.fedPassFile) if (args.fed, args.pol) == (None, None): fail("If you specify a FED passphrase you must also specify a FED or POL file.") if args.mergeDir is not None: if not os.path.isdir(args.mergeDir): fail("Specified merge directory is not a directory: %s" % args.mergeDir) if not args.mergeDir.endswith("apigateway") and not args.mergeDir.endswith("apigateway/"): fail("Merge directory must be called 'apigateway'.") if args.outImage is None: args.outImage = "api-gateway-" + args.groupId.lower() if not isValidImageName(args.outImage): fail("Invalid name for output Docker image: %s" % args.outImage) if not args.parentImage: fail("Must specify name of parent Docker image.") if not isValidImageName(args.parentImage): fail("Invalid name for parent Docker image: %s" % args.parentImage) if not imageExists(args.parentImage): print("WARN: Parent image '%s' does not exist locally, Docker will try to pull " "it from remote repository.\n" % args.parentImage)
def _validateGeneralArgs(): if not os.path.isfile(args.license): fail("License file does not exist: %s" % args.license) if not os.path.isfile(args.installer): fail("Installer does not exist: %s" % args.installer) if (args.baseOS, args.parentImage).count(None) != 1: fail("Must specify one of --os or --parent-image.") if not isValidImageName(args.outImage): fail("Invalid name for output image: %s" % args.outImage) if args.parentImage is not None: if not isValidImageName(args.parentImage): fail("Invalid name for parent image: %s" % args.parentImage) if not imageExists(args.parentImage): print("WARN: Parent image '%s' does not exist locally, Docker will try to pull " "it from remote repository.\n" % args.parentImage) else: args.parentImage = OS_IMAGE[args.baseOS] if args.fed is not None and not os.path.isfile(args.fed): fail("FED file does not exist: %s" % args.fed) if args.fedPassFile is not None: if not os.path.isfile(args.fedPassFile): fail("FED passphrase file does not exist: %s" % args.fedPassFile) if args.fed is None: fail("If you specify a FED passphrase you must also specify a FED file.") if args.mergeDir is not None: if not os.path.isdir(args.mergeDir): fail("Specified merge directory is not a directory: %s" % args.mergeDir) if not args.mergeDir.endswith("analytics") and not args.mergeDir.endswith("analytics/"): fail("Merge directory must be called 'analytics'.")