@ -76,30 +76,35 @@ func (st ServerType) buildTLSApp( 
			
		
	
		
		
			
				
							} 		}  
			
		
	
		
		
			
				
						} 	}  
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
						// a catch-all automation policy is used as a "default" for all subjects that
  
			
		
	
		
		
			
				
						// don't have custom configuration explicitly associated with them; this
  
			
		
	
		
		
			
				
						// is only to add if the global settings or defaults are non-empty
  
			
		
	
		
		
			
				
						catchAllAP ,  err  :=  newBaseAutomationPolicy ( options ,  warnings ,  false ) 	catchAllAP ,  err  :=  newBaseAutomationPolicy ( options ,  warnings ,  false )  
			
		
	
		
		
			
				
						if  err  !=  nil  { 	if  err  !=  nil  {  
			
		
	
		
		
			
				
							return  nil ,  warnings ,  err 		return  nil ,  warnings ,  err  
			
		
	
		
		
			
				
						} 	}  
			
		
	
		
		
			
				
						if  catchAllAP  !=  nil  {  
			
		
	
		
		
			
				
							if  tlsApp . Automation  ==  nil  {  
			
		
	
		
		
			
				
								tlsApp . Automation  =  new ( caddytls . AutomationConfig )  
			
		
	
		
		
			
				
							}  
			
		
	
		
		
			
				
							tlsApp . Automation . Policies  =  append ( tlsApp . Automation . Policies ,  catchAllAP )  
			
		
	
		
		
			
				
						}  
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
						for  _ ,  p  :=  range  pairings  { 	for  _ ,  p  :=  range  pairings  {  
			
		
	
		
		
			
				
							for  _ ,  sblock  :=  range  p . serverBlocks  { 		for  _ ,  sblock  :=  range  p . serverBlocks  {  
			
		
	
		
		
			
				
								// get values that populate an automation policy for this block
 			// get values that populate an automation policy for this block
  
			
		
	
		
		
			
				
					
								var  ap  * caddytls . AutomationPolicy 			ap ,  err  :=  newBaseAutomationPolicy ( options ,  warnings ,  true )  
			
				
				
			
		
	
		
		
	
		
		
			
				
								if  err  !=  nil  {  
			
		
	
		
		
			
				
									return  nil ,  warnings ,  err  
			
		
	
		
		
			
				
								}  
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
								sblockHosts  :=  sblock . hostsFromKeys ( false ) 			sblockHosts  :=  sblock . hostsFromKeys ( false )  
			
		
	
		
		
			
				
					
								if  len ( sblockHosts )  ==  0  { 			if  len ( sblockHosts )  ==  0  &&  catchAllAP  !=  nil  {  
			
				
				
			
		
	
		
		
	
		
		
			
				
									ap  =  catchAllAP 				ap  =  catchAllAP  
			
		
	
		
		
			
				
								} 			}  
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
								// on-demand tls
 			// on-demand tls
  
			
		
	
		
		
			
				
								if  _ ,  ok  :=  sblock . pile [ "tls.on_demand" ] ;  ok  { 			if  _ ,  ok  :=  sblock . pile [ "tls.on_demand" ] ;  ok  {  
			
		
	
		
		
			
				
									if  ap  ==  nil  {  
			
		
	
		
		
			
				
										var  err  error  
			
		
	
		
		
			
				
										ap ,  err  =  newBaseAutomationPolicy ( options ,  warnings ,  true )  
			
		
	
		
		
			
				
										if  err  !=  nil  {  
			
		
	
		
		
			
				
											return  nil ,  warnings ,  err  
			
		
	
		
		
			
				
										}  
			
		
	
		
		
			
				
									}  
			
		
	
		
		
			
				
									ap . OnDemand  =  true 				ap . OnDemand  =  true  
			
		
	
		
		
			
				
								} 			}  
			
		
	
		
		
			
				
					
 
			
		
	
	
		
		
			
				
					
						
						
						
							
								 
						
					 
					@ -107,13 +112,6 @@ func (st ServerType) buildTLSApp( 
			
		
	
		
		
			
				
								if  issuerVals ,  ok  :=  sblock . pile [ "tls.cert_issuer" ] ;  ok  { 			if  issuerVals ,  ok  :=  sblock . pile [ "tls.cert_issuer" ] ;  ok  {  
			
		
	
		
		
			
				
									for  _ ,  issuerVal  :=  range  issuerVals  { 				for  _ ,  issuerVal  :=  range  issuerVals  {  
			
		
	
		
		
			
				
										issuer  :=  issuerVal . Value . ( certmagic . Issuer ) 					issuer  :=  issuerVal . Value . ( certmagic . Issuer )  
			
		
	
		
		
			
				
										if  ap  ==  nil  {  
			
		
	
		
		
			
				
											var  err  error  
			
		
	
		
		
			
				
											ap ,  err  =  newBaseAutomationPolicy ( options ,  warnings ,  true )  
			
		
	
		
		
			
				
											if  err  !=  nil  {  
			
		
	
		
		
			
				
												return  nil ,  warnings ,  err  
			
		
	
		
		
			
				
											}  
			
		
	
		
		
			
				
										}  
			
		
	
		
		
			
				
										if  ap  ==  catchAllAP  &&  ! reflect . DeepEqual ( ap . Issuer ,  issuer )  { 					if  ap  ==  catchAllAP  &&  ! reflect . DeepEqual ( ap . Issuer ,  issuer )  {  
			
		
	
		
		
			
				
											return  nil ,  warnings ,  fmt . Errorf ( "automation policy from site block is also default/catch-all policy because of key without hostname, and the two are in conflict: %#v != %#v" ,  ap . Issuer ,  issuer ) 						return  nil ,  warnings ,  fmt . Errorf ( "automation policy from site block is also default/catch-all policy because of key without hostname, and the two are in conflict: %#v != %#v" ,  ap . Issuer ,  issuer )  
			
		
	
		
		
			
				
										} 					}  
			
		
	
	
		
		
			
				
					
						
						
						
							
								 
						
					 
					@ -123,15 +121,6 @@ func (st ServerType) buildTLSApp( 
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
								// custom bind host
 			// custom bind host
  
			
		
	
		
		
			
				
								for  _ ,  cfgVal  :=  range  sblock . pile [ "bind" ]  { 			for  _ ,  cfgVal  :=  range  sblock . pile [ "bind" ]  {  
			
		
	
		
		
			
				
									// either an existing issuer is already configured (and thus, ap is not
  
			
		
	
		
		
			
				
									// nil), or we need to configure an issuer, so we need ap to be non-nil
  
			
		
	
		
		
			
				
									if  ap  ==  nil  {  
			
		
	
		
		
			
				
										ap ,  err  =  newBaseAutomationPolicy ( options ,  warnings ,  true )  
			
		
	
		
		
			
				
										if  err  !=  nil  {  
			
		
	
		
		
			
				
											return  nil ,  warnings ,  err  
			
		
	
		
		
			
				
										}  
			
		
	
		
		
			
				
									}  
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
									// if an issuer was already configured and it is NOT an ACME
 				// if an issuer was already configured and it is NOT an ACME
  
			
		
	
		
		
			
				
									// issuer, skip, since we intend to adjust only ACME issuers
 				// issuer, skip, since we intend to adjust only ACME issuers
  
			
		
	
		
		
			
				
									var  acmeIssuer  * caddytls . ACMEIssuer 				var  acmeIssuer  * caddytls . ACMEIssuer  
			
		
	
	
		
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
					@ -164,13 +153,6 @@ func (st ServerType) buildTLSApp( 
			
		
	
		
		
			
				
									ap . Issuer  =  acmeIssuer  // we'll encode it later
 				ap . Issuer  =  acmeIssuer  // we'll encode it later
  
			
		
	
		
		
			
				
								} 			}  
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
								if  ap  !=  nil  {  
			
		
	
		
		
			
				
									if  ap . Issuer  !=  nil  {  
			
		
	
		
		
			
				
										// encode issuer now that it's all set up
  
			
		
	
		
		
			
				
										issuerName  :=  ap . Issuer . ( caddy . Module ) . CaddyModule ( ) . ID . Name ( )  
			
		
	
		
		
			
				
										ap . IssuerRaw  =  caddyconfig . JSONModuleObject ( ap . Issuer ,  "module" ,  issuerName ,  & warnings )  
			
		
	
		
		
			
				
									}  
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
								// first make sure this block is allowed to create an automation policy;
 			// first make sure this block is allowed to create an automation policy;
  
			
		
	
		
		
			
				
								// doing so is forbidden if it has a key with no host (i.e. ":443")
 			// doing so is forbidden if it has a key with no host (i.e. ":443")
  
			
		
	
		
		
			
				
								// and if there is a different server block that also has a key with no
 			// and if there is a different server block that also has a key with no
  
			
		
	
	
		
		
			
				
					
						
						
						
							
								 
						
					 
					@ -196,13 +178,9 @@ func (st ServerType) buildTLSApp( 
			
		
	
		
		
			
				
									} 				}  
			
		
	
		
		
			
				
								} 			}  
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
					
									// associate our new automation policy with this server block's hosts,
 			// associate our new automation policy with this server block's hosts
  
			
				
				
			
		
	
		
		
			
				
									// unless, of course, the server block has a key with no hosts, in which
  
			
		
	
		
		
			
				
									// case its automation policy becomes or blends with the default/global
  
			
		
	
		
		
			
				
									// automation policy because, of necessity, it applies to all hostnames
  
			
		
	
		
		
			
				
									// (i.e. it has no Subjects filter) -- in that case, we'll append it last
  
			
		
	
		
		
			
				
									if  ap  !=  catchAllAP  {  
			
		
	
		
		
	
		
		
			
				
								ap . Subjects  =  sblockHosts 			ap . Subjects  =  sblockHosts  
			
		
	
		
		
			
				
								sort . Strings ( ap . Subjects )  // solely for deterministic test results
  
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
								// if a combination of public and internal names were given
 			// if a combination of public and internal names were given
  
			
		
	
		
		
			
				
								// for this same server block and no issuer was specified, we
 			// for this same server block and no issuer was specified, we
  
			
		
	
	
		
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
					@ -244,8 +222,6 @@ func (st ServerType) buildTLSApp( 
			
		
	
		
		
			
				
								if  ap2  !=  nil  { 			if  ap2  !=  nil  {  
			
		
	
		
		
			
				
									tlsApp . Automation . Policies  =  append ( tlsApp . Automation . Policies ,  ap2 ) 				tlsApp . Automation . Policies  =  append ( tlsApp . Automation . Policies ,  ap2 )  
			
		
	
		
		
			
				
								} 			}  
			
		
	
		
		
			
				
									}  
			
		
	
		
		
			
				
								}  
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
								// certificate loaders
 			// certificate loaders
  
			
		
	
		
		
			
				
								if  clVals ,  ok  :=  sblock . pile [ "tls.cert_loader" ] ;  ok  { 			if  clVals ,  ok  :=  sblock . pile [ "tls.cert_loader" ] ;  ok  {  
			
		
	
	
		
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
					@ -319,23 +295,17 @@ func (st ServerType) buildTLSApp( 
			
		
	
		
		
			
				
							tlsApp . Automation . Policies  =  append ( tlsApp . Automation . Policies ,  internalAP ) 		tlsApp . Automation . Policies  =  append ( tlsApp . Automation . Policies ,  internalAP )  
			
		
	
		
		
			
				
						} 	}  
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
					
						// if there is a global/catch-all automation policy, ensure it goes last
 	// finalize and verify policies; do cleanup
  
			
				
				
			
		
	
		
		
			
				
					
						if  catchAllAP  !=  nil  { 	if  tlsApp . Automation  !=  nil  {  
			
				
				
			
		
	
		
		
			
				
					
							// first, encode its issuer, if there is one
 		// encode any issuer values we created, so they will be rendered in the output
  
			
				
				
			
		
	
		
		
			
				
					
							if  catchAllAP . Issuer  !=  nil  { 		for  _ ,  ap  :=  range  tlsApp . Automation . Policies  {  
			
				
				
			
		
	
		
		
			
				
					
								issuerName  :=  catchAllAP . Issuer . ( caddy . Module ) . CaddyModule ( ) . ID . Name ( ) 			if  ap . Issuer  !=  nil  &&  ap . IssuerRaw  ==  nil  {  
			
				
				
			
		
	
		
		
			
				
					
								catchAllAP . IssuerRaw  =  caddyconfig . JSONModuleObject ( catchAllAP . Issuer ,  "module" ,  issuerName ,  & warnings ) 				// encode issuer now that it's all set up
  
			
				
				
			
		
	
		
		
			
				
					
							} 				issuerName  :=  ap . Issuer . ( caddy . Module ) . CaddyModule ( ) . ID . Name ( )  
			
				
				
			
		
	
		
		
			
				
					
					
				ap . IssuerRaw  =  caddyconfig . JSONModuleObject ( ap . Issuer ,  "module" ,  issuerName ,  & warnings )  
			
				
				
			
		
	
		
		
			
				
							// then append it to the end of the policies list
  
			
		
	
		
		
			
				
							if  tlsApp . Automation  ==  nil  {  
			
		
	
		
		
			
				
								tlsApp . Automation  =  new ( caddytls . AutomationConfig )  
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
								} 			}  
			
		
	
		
		
			
				
							tlsApp . Automation . Policies  =  append ( tlsApp . Automation . Policies ,  catchAllAP )  
			
		
	
		
		
			
				
							} 		}  
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
						// do a little verification & cleanup
  
			
		
	
		
		
			
				
						if  tlsApp . Automation  !=  nil  {  
			
		
	
		
		
			
				
							// consolidate automation policies that are the exact same
 		// consolidate automation policies that are the exact same
  
			
		
	
		
		
			
				
							tlsApp . Automation . Policies  =  consolidateAutomationPolicies ( tlsApp . Automation . Policies ) 		tlsApp . Automation . Policies  =  consolidateAutomationPolicies ( tlsApp . Automation . Policies )  
			
		
	
		
		
			
				
					
 
			
		
	
	
		
		
			
				
					
						
						
						
							
								 
						
					 
					@ -351,6 +321,14 @@ func (st ServerType) buildTLSApp( 
			
		
	
		
		
			
				
									automationHostSet [ s ]  =  struct { } { } 				automationHostSet [ s ]  =  struct { } { }  
			
		
	
		
		
			
				
								} 			}  
			
		
	
		
		
			
				
							} 		}  
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
							// if nothing remains, remove any excess values to clean up the resulting config
  
			
		
	
		
		
			
				
							if  len ( tlsApp . Automation . Policies )  ==  0  {  
			
		
	
		
		
			
				
								tlsApp . Automation . Policies  =  nil  
			
		
	
		
		
			
				
							}  
			
		
	
		
		
			
				
							if  reflect . DeepEqual ( tlsApp . Automation ,  new ( caddytls . AutomationConfig ) )  {  
			
		
	
		
		
			
				
								tlsApp . Automation  =  nil  
			
		
	
		
		
			
				
							}  
			
		
	
		
		
			
				
						} 	}  
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
						return  tlsApp ,  warnings ,  nil 	return  tlsApp ,  warnings ,  nil  
			
		
	
	
		
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
					@ -448,12 +426,30 @@ func disambiguateACMEIssuer(acmeIssuer *caddytls.ACMEIssuer) certmagic.Issuer { 
			
		
	
		
		
			
				
					// consolidateAutomationPolicies combines automation policies that are the same,
 // consolidateAutomationPolicies combines automation policies that are the same,
  
			
		
	
		
		
			
				
					// for a cleaner overall output.
 // for a cleaner overall output.
  
			
		
	
		
		
			
				
					func  consolidateAutomationPolicies ( aps  [ ] * caddytls . AutomationPolicy )  [ ] * caddytls . AutomationPolicy  { func  consolidateAutomationPolicies ( aps  [ ] * caddytls . AutomationPolicy )  [ ] * caddytls . AutomationPolicy  {  
			
		
	
		
		
			
				
						// sort from most specific to least specific; we depend on this ordering
  
			
		
	
		
		
			
				
						sort . SliceStable ( aps ,  func ( i ,  j  int )  bool  {  
			
		
	
		
		
			
				
							if  automationPolicyIsSubset ( aps [ i ] ,  aps [ j ] )  {  
			
		
	
		
		
			
				
								return  true  
			
		
	
		
		
			
				
							}  
			
		
	
		
		
			
				
							if  automationPolicyIsSubset ( aps [ j ] ,  aps [ i ] )  {  
			
		
	
		
		
			
				
								return  false  
			
		
	
		
		
			
				
							}  
			
		
	
		
		
			
				
							return  len ( aps [ i ] . Subjects )  >  len ( aps [ j ] . Subjects )  
			
		
	
		
		
			
				
						} )  
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
						// remove any empty policies (except subjects, of course)
  
			
		
	
		
		
			
				
						emptyAP  :=  new ( caddytls . AutomationPolicy )  
			
		
	
		
		
			
				
						for  i  :=  0 ;  i  <  len ( aps ) ;  i ++  { 	for  i  :=  0 ;  i  <  len ( aps ) ;  i ++  {  
			
		
	
		
		
			
				
					
							for  j  :=  0 ;  j  <  len ( aps ) ;  j ++  { 		emptyAP . Subjects  =  aps [ i ] . Subjects  
			
				
				
			
		
	
		
		
			
				
					
								if  j  ==  i  { 		if  reflect . DeepEqual ( aps [ i ] ,  emptyAP )  {  
			
				
				
			
		
	
		
		
			
				
					
									continue 			aps  =  append ( aps [ : i ] ,  aps [ i + 1 : ] ... )  
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
								i --  
			
		
	
		
		
			
				
							}  
			
		
	
		
		
			
				
						} 	}  
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
						// remove or combine duplicate policies
  
			
		
	
		
		
			
				
						for  i  :=  0 ;  i  <  len ( aps ) ;  i ++  {  
			
		
	
		
		
			
				
							for  j  :=  i  +  1 ;  j  <  len ( aps ) ;  j ++  {  
			
		
	
		
		
			
				
								// if they're exactly equal in every way, just keep one of them
 			// if they're exactly equal in every way, just keep one of them
  
			
		
	
		
		
			
				
								if  reflect . DeepEqual ( aps [ i ] ,  aps [ j ] )  { 			if  reflect . DeepEqual ( aps [ i ] ,  aps [ j ] )  {  
			
		
	
		
		
			
				
									aps  =  append ( aps [ : j ] ,  aps [ j + 1 : ] ... ) 				aps  =  append ( aps [ : j ] ,  aps [ j + 1 : ] ... )  
			
		
	
	
		
		
			
				
					
						
						
						
							
								 
						
					 
					@ -473,10 +469,17 @@ func consolidateAutomationPolicies(aps []*caddytls.AutomationPolicy) []*caddytls 
			
		
	
		
		
			
				
									aps [ i ] . KeyType  ==  aps [ j ] . KeyType  && 				aps [ i ] . KeyType  ==  aps [ j ] . KeyType  &&  
			
		
	
		
		
			
				
									aps [ i ] . OnDemand  ==  aps [ j ] . OnDemand  && 				aps [ i ] . OnDemand  ==  aps [ j ] . OnDemand  &&  
			
		
	
		
		
			
				
									aps [ i ] . RenewalWindowRatio  ==  aps [ j ] . RenewalWindowRatio  { 				aps [ i ] . RenewalWindowRatio  ==  aps [ j ] . RenewalWindowRatio  {  
			
		
	
		
		
			
				
					
									if  len ( aps [ i ] . Subjects )  ==  0  &&  len ( aps [ j ] . Subjects )  >  0  { 				if  len ( aps [ i ] . Subjects )  >  0  &&  len ( aps [ j ] . Subjects )  ==  0  {  
			
				
				
			
		
	
		
		
			
				
					
										aps  =  append ( aps [ : j ] ,  aps [ j + 1 : ] ... ) 					// later policy (at j) has no subjects ("catch-all"), so we can
  
			
				
				
			
		
	
		
		
			
				
					
									}  else  if  len ( aps [ i ] . Subjects )  >  0  &&  len ( aps [ j ] . Subjects )  ==  0  { 					// remove the identical-but-more-specific policy that comes first
  
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
										// AS LONG AS it is not shadowed by another policy before it; e.g.
  
			
		
	
		
		
			
				
										// if policy i is for example.com, policy i+1 is '*.com', and policy
  
			
		
	
		
		
			
				
										// j is catch-all, we cannot remove policy i because that would
  
			
		
	
		
		
			
				
										// cause example.com to be served by the less specific policy for
  
			
		
	
		
		
			
				
										// '*.com', which might be different (yes we've seen this happen)
  
			
		
	
		
		
			
				
										if  automationPolicyShadows ( i ,  aps )  >=  j  {  
			
		
	
		
		
			
				
											aps  =  append ( aps [ : i ] ,  aps [ i + 1 : ] ... ) 						aps  =  append ( aps [ : i ] ,  aps [ i + 1 : ] ... )  
			
		
	
		
		
			
				
										}  
			
		
	
		
		
			
				
									}  else  { 				}  else  {  
			
		
	
		
		
			
				
										// avoid repeated subjects
 					// avoid repeated subjects
  
			
		
	
		
		
			
				
										for  _ ,  subj  :=  range  aps [ j ] . Subjects  { 					for  _ ,  subj  :=  range  aps [ j ] . Subjects  {  
			
		
	
	
		
		
			
				
					
						
						
						
							
								 
						
					 
					@ -486,16 +489,48 @@ func consolidateAutomationPolicies(aps []*caddytls.AutomationPolicy) []*caddytls 
			
		
	
		
		
			
				
										} 					}  
			
		
	
		
		
			
				
										aps  =  append ( aps [ : j ] ,  aps [ j + 1 : ] ... ) 					aps  =  append ( aps [ : j ] ,  aps [ j + 1 : ] ... )  
			
		
	
		
		
			
				
									} 				}  
			
		
	
		
		
			
				
									i --  
			
		
	
		
		
			
				
									break  
			
		
	
		
		
			
				
								} 			}  
			
		
	
		
		
			
				
							} 		}  
			
		
	
		
		
			
				
						} 	}  
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
						// ensure any catch-all policies go last
  
			
		
	
		
		
			
				
						sort . SliceStable ( aps ,  func ( i ,  j  int )  bool  {  
			
		
	
		
		
			
				
							return  len ( aps [ i ] . Subjects )  >  len ( aps [ j ] . Subjects )  
			
		
	
		
		
			
				
						} )  
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
						return  aps 	return  aps  
			
		
	
		
		
			
				
					} }  
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
					// automationPolicyIsSubset returns true if a's subjects are a subset
  
			
		
	
		
		
			
				
					// of b's subjects.
  
			
		
	
		
		
			
				
					func  automationPolicyIsSubset ( a ,  b  * caddytls . AutomationPolicy )  bool  {  
			
		
	
		
		
			
				
						if  len ( b . Subjects )  ==  0  {  
			
		
	
		
		
			
				
							return  true  
			
		
	
		
		
			
				
						}  
			
		
	
		
		
			
				
						if  len ( a . Subjects )  ==  0  {  
			
		
	
		
		
			
				
							return  false  
			
		
	
		
		
			
				
						}  
			
		
	
		
		
			
				
						for  _ ,  aSubj  :=  range  a . Subjects  {  
			
		
	
		
		
			
				
							var  inSuperset  bool  
			
		
	
		
		
			
				
							for  _ ,  bSubj  :=  range  b . Subjects  {  
			
		
	
		
		
			
				
								if  certmagic . MatchWildcard ( aSubj ,  bSubj )  {  
			
		
	
		
		
			
				
									inSuperset  =  true  
			
		
	
		
		
			
				
									break  
			
		
	
		
		
			
				
								}  
			
		
	
		
		
			
				
							}  
			
		
	
		
		
			
				
							if  ! inSuperset  {  
			
		
	
		
		
			
				
								return  false  
			
		
	
		
		
			
				
							}  
			
		
	
		
		
			
				
						}  
			
		
	
		
		
			
				
						return  true  
			
		
	
		
		
			
				
					}  
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
					// automationPolicyShadows returns the index of a policy that aps[i] shadows;
  
			
		
	
		
		
			
				
					// in other words, for all policies after position i, if that policy covers
  
			
		
	
		
		
			
				
					// the same subjects but is less specific, that policy's position is returned,
  
			
		
	
		
		
			
				
					// or -1 if no shadowing is found. For example, if policy i is for
  
			
		
	
		
		
			
				
					// "foo.example.com" and policy i+2 is for "*.example.com", then i+2 will be
  
			
		
	
		
		
			
				
					// returned, since that policy is shadowed by i, which is in front.
  
			
		
	
		
		
			
				
					func  automationPolicyShadows ( i  int ,  aps  [ ] * caddytls . AutomationPolicy )  int  {  
			
		
	
		
		
			
				
						for  j  :=  i  +  1 ;  j  <  len ( aps ) ;  j ++  {  
			
		
	
		
		
			
				
							if  automationPolicyIsSubset ( aps [ i ] ,  aps [ j ] )  {  
			
		
	
		
		
			
				
								return  j  
			
		
	
		
		
			
				
							}  
			
		
	
		
		
			
				
						}  
			
		
	
		
		
			
				
						return  - 1  
			
		
	
		
		
			
				
					}