2019-08-29 15:41:59 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								package   sign 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								import   ( 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 "fmt" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 "io" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 "os" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 "path/filepath" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 "time" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 "github.com/coredns/coredns/plugin/file" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 "github.com/coredns/coredns/plugin/file/tree" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 clog   "github.com/coredns/coredns/plugin/pkg/log" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 "github.com/miekg/dns" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								var   log   =   clog . NewWithPlugin ( "sign" ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Signer holds the data needed to sign a zone file. 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								type   Signer   struct   { 
  
						 
					
						
							
								
									
										
										
										
											2020-01-12 13:56:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 keys          [ ] Pair 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 origin        string 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 dbfile        string 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 directory     string 
  
						 
					
						
							
								
									
										
										
										
											2021-02-10 16:56:03 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 modTime       time . Time 
  
						 
					
						
							
								
									
										
										
										
											2020-01-12 13:56:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 jitterIncep   time . Duration 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 jitterExpir   time . Duration 
  
						 
					
						
							
								
									
										
										
										
											2019-08-29 15:41:59 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 signedfile   string 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 stop         chan   struct { } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Sign signs a zone file according to the parameters in s. 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func   ( s   * Signer )   Sign ( now   time . Time )   ( * file . Zone ,   error )   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 rd ,   err   :=   os . Open ( s . dbfile ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 if   err   !=   nil   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 return   nil ,   err 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 z ,   err   :=   Parse ( rd ,   s . origin ,   s . dbfile ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 if   err   !=   nil   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 return   nil ,   err 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-02-10 16:56:03 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 // s.dbfile is a parseable zone file, track the mtime 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 if   fi ,   err   :=   os . Stat ( s . dbfile ) ;   err   ==   nil   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 s . modTime   =   fi . ModTime ( ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-12-06 19:54:31 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 mttl   :=   z . Apex . SOA . Minttl 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 ttl   :=   z . Apex . SOA . Header ( ) . Ttl 
  
						 
					
						
							
								
									
										
										
										
											2020-01-12 13:56:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 inception ,   expiration   :=   lifetime ( now ,   s . jitterIncep ,   s . jitterExpir ) 
  
						 
					
						
							
								
									
										
										
										
											2019-08-29 15:41:59 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									 z . Apex . SOA . Serial   =   uint32 ( now . Unix ( ) ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 for   _ ,   pair   :=   range   s . keys   { 
  
						 
					
						
							
								
									
										
										
										
											2019-12-06 19:54:31 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										 pair . Public . Header ( ) . Ttl   =   ttl   // set TTL on key so it matches the RRSIG. 
  
						 
					
						
							
								
									
										
										
										
											2019-08-29 15:41:59 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										 z . Insert ( pair . Public ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 z . Insert ( pair . Public . ToDS ( dns . SHA1 ) . ToCDS ( ) ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 z . Insert ( pair . Public . ToDS ( dns . SHA256 ) . ToCDS ( ) ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 z . Insert ( pair . Public . ToCDNSKEY ( ) ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-12-06 19:54:31 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 names   :=   names ( s . origin ,   z ) 
  
						 
					
						
							
								
									
										
										
										
											2019-08-29 15:41:59 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									 ln   :=   len ( names ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 for   _ ,   pair   :=   range   s . keys   { 
  
						 
					
						
							
								
									
										
										
										
											2019-12-06 19:54:31 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										 rrsig ,   err   :=   pair . signRRs ( [ ] dns . RR { z . Apex . SOA } ,   s . origin ,   ttl ,   inception ,   expiration ) 
  
						 
					
						
							
								
									
										
										
										
											2019-08-29 15:41:59 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										 if   err   !=   nil   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 return   nil ,   err 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 z . Insert ( rrsig ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 // NS apex may not be set if RR's have been discarded because the origin doesn't match. 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 if   len ( z . Apex . NS )   >   0   { 
  
						 
					
						
							
								
									
										
										
										
											2019-12-06 19:54:31 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											 rrsig ,   err   =   pair . signRRs ( z . Apex . NS ,   s . origin ,   ttl ,   inception ,   expiration ) 
  
						 
					
						
							
								
									
										
										
										
											2019-08-29 15:41:59 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											 if   err   !=   nil   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												 return   nil ,   err 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 z . Insert ( rrsig ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 // We are walking the tree in the same direction, so names[] can be used here to indicated the next element. 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 i   :=   1 
  
						 
					
						
							
								
									
										
										
										
											2019-12-06 19:54:31 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 err   =   z . AuthWalk ( func ( e   * tree . Elem ,   zrrs   map [ uint16 ] [ ] dns . RR ,   auth   bool )   error   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 if   ! auth   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 return   nil 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 if   e . Name ( )   ==   s . origin   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 nsec   :=   NSEC ( e . Name ( ) ,   names [ ( ln + i ) % ln ] ,   mttl ,   append ( e . Types ( ) ,   dns . TypeNS ,   dns . TypeSOA ,   dns . TypeRRSIG ,   dns . TypeNSEC ) ) 
  
						 
					
						
							
								
									
										
										
										
											2019-08-29 15:41:59 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											 z . Insert ( nsec ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 }   else   { 
  
						 
					
						
							
								
									
										
										
										
											2019-12-06 19:54:31 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											 nsec   :=   NSEC ( e . Name ( ) ,   names [ ( ln + i ) % ln ] ,   mttl ,   append ( e . Types ( ) ,   dns . TypeRRSIG ,   dns . TypeNSEC ) ) 
  
						 
					
						
							
								
									
										
										
										
											2019-08-29 15:41:59 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											 z . Insert ( nsec ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 for   t ,   rrs   :=   range   zrrs   { 
  
						 
					
						
							
								
									
										
										
										
											2019-12-06 19:54:31 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											 // RRSIGs are not signed and NS records are not signed because we are never authoratiative for them. 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 // The zone's apex nameservers records are not kept in this tree and are signed separately. 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 if   t   ==   dns . TypeRRSIG   ||   t   ==   dns . TypeNS   { 
  
						 
					
						
							
								
									
										
										
										
											2019-08-29 15:41:59 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												 continue 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 for   _ ,   pair   :=   range   s . keys   { 
  
						 
					
						
							
								
									
										
										
										
											2019-12-06 19:54:31 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												 rrsig ,   err   :=   pair . signRRs ( rrs ,   s . origin ,   rrs [ 0 ] . Header ( ) . Ttl ,   inception ,   expiration ) 
  
						 
					
						
							
								
									
										
										
										
											2019-08-29 15:41:59 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												 if   err   !=   nil   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													 return   err 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												 e . Insert ( rrsig ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 i ++ 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 return   nil 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 } ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 return   z ,   err 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// resign checks if the signed zone exists, or needs resigning. 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func   ( s   * Signer )   resign ( )   error   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 signedfile   :=   filepath . Join ( s . directory ,   s . signedfile ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 rd ,   err   :=   os . Open ( signedfile ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 if   err   !=   nil   &&   os . IsNotExist ( err )   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 return   err 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 } 
  
						 
					
						
							
								
									
										
										
										
											2021-02-10 16:56:03 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 // if modtime of the input zone file has changed, we will also resign. 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 if   fi ,   err   :=   os . Stat ( s . dbfile ) ;   err   ==   nil   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 if   ! s . modTime . IsZero ( )   &&   fi . ModTime ( )   !=   s . modTime   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 return   fmt . Errorf ( "zone's modification time %s; differs from last seen modification time: %s" ,   fi . ModTime ( ) . Format ( timeFmt ) ,   s . modTime . Format ( timeFmt ) ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 } 
  
						 
					
						
							
								
									
										
										
										
											2019-08-29 15:41:59 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 now   :=   time . Now ( ) . UTC ( ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 return   resign ( rd ,   now ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// resign will scan rd and check the signature on the SOA record. We will resign on the basis 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// of 2 conditions: 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// * either the inception is more than 6 days ago, or 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// * we only have 1 week left on the signature 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// All SOA signatures will be checked. If the SOA isn't found in the first 100 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// records, we will resign the zone. 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func   resign ( rd   io . Reader ,   now   time . Time )   ( why   error )   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 zp   :=   dns . NewZoneParser ( rd ,   "." ,   "resign" ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 zp . SetIncludeAllowed ( true ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 i   :=   0 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 for   rr ,   ok   :=   zp . Next ( ) ;   ok ;   rr ,   ok   =   zp . Next ( )   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 if   err   :=   zp . Err ( ) ;   err   !=   nil   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 return   err 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 switch   x   :=   rr . ( type )   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 case   * dns . RRSIG : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 if   x . TypeCovered   !=   dns . TypeSOA   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												 continue 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 incep ,   _   :=   time . Parse ( "20060102150405" ,   dns . TimeToString ( x . Inception ) ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 // If too long ago, resign. 
  
						 
					
						
							
								
									
										
										
										
											2020-01-12 13:56:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											 if   now . Sub ( incep )   >=   0   &&   now . Sub ( incep )   >   durationResignDays   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												 return   fmt . Errorf ( "inception %q was more than: %s ago from %s: %s" ,   incep . Format ( timeFmt ) ,   durationResignDays ,   now . Format ( timeFmt ) ,   now . Sub ( incep ) ) 
  
						 
					
						
							
								
									
										
										
										
											2019-08-29 15:41:59 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 // Inception hasn't even start yet. 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 if   now . Sub ( incep )   <   0   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												 return   fmt . Errorf ( "inception %q date is in the future: %s" ,   incep . Format ( timeFmt ) ,   now . Sub ( incep ) ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 expire ,   _   :=   time . Parse ( "20060102150405" ,   dns . TimeToString ( x . Expiration ) ) 
  
						 
					
						
							
								
									
										
										
										
											2020-01-12 13:56:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											 if   expire . Sub ( now )   <   durationExpireDays   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												 return   fmt . Errorf ( "expiration %q is less than: %s away from %s: %s" ,   expire . Format ( timeFmt ) ,   durationExpireDays ,   now . Format ( timeFmt ) ,   expire . Sub ( now ) ) 
  
						 
					
						
							
								
									
										
										
										
											2019-08-29 15:41:59 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 i ++ 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 if   i   >   100   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 // 100 is a random number. A SOA record should be the first in the zonefile, but RFC 1035 doesn't actually mandate this. So it could 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 // be 3rd or even later. The number 100 looks crazy high enough that it will catch all weird zones, but not high enough to keep the CPU 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 // busy with parsing all the time. 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 return   fmt . Errorf ( "no SOA RRSIG found in first 100 records" ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 return   nil 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func   signAndLog ( s   * Signer ,   why   error )   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 now   :=   time . Now ( ) . UTC ( ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 z ,   err   :=   s . Sign ( now ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 log . Infof ( "Signing %q because %s" ,   s . origin ,   why ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 if   err   !=   nil   { 
  
						 
					
						
							
								
									
										
										
										
											2020-01-12 13:56:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										 log . Warningf ( "Error signing %q with key tags %q in %s: %s, next: %s" ,   s . origin ,   keyTag ( s . keys ) ,   time . Since ( now ) ,   err ,   now . Add ( durationRefreshHours ) . Format ( timeFmt ) ) 
  
						 
					
						
							
								
									
										
										
										
											2019-08-29 15:41:59 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										 return 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 if   err   :=   s . write ( z ) ;   err   !=   nil   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 log . Warningf ( "Error signing %q: failed to move zone file into place: %s" ,   s . origin ,   err ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 return 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 } 
  
						 
					
						
							
								
									
										
										
										
											2020-01-12 13:56:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 log . Infof ( "Successfully signed zone %q in %q with key tags %q and %d SOA serial, elapsed %f, next: %s" ,   s . origin ,   filepath . Join ( s . directory ,   s . signedfile ) ,   keyTag ( s . keys ) ,   z . Apex . SOA . Serial ,   time . Since ( now ) . Seconds ( ) ,   now . Add ( durationRefreshHours ) . Format ( timeFmt ) ) 
  
						 
					
						
							
								
									
										
										
										
											2019-08-29 15:41:59 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								} 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// refresh checks every val if some zones need to be resigned. 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func   ( s   * Signer )   refresh ( val   time . Duration )   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 tick   :=   time . NewTicker ( val ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 defer   tick . Stop ( ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 for   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 select   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 case   <- s . stop : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 return 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 case   <- tick . C : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 why   :=   s . resign ( ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 if   why   ==   nil   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												 continue 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 signAndLog ( s ,   why ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-01-12 13:56:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func   lifetime ( now   time . Time ,   jitterInception ,   jitterExpiration   time . Duration )   ( uint32 ,   uint32 )   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 incep   :=   uint32 ( now . Add ( durationSignatureInceptionHours ) . Add ( jitterInception ) . Unix ( ) ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 expir   :=   uint32 ( now . Add ( durationSignatureExpireDays ) . Add ( jitterExpiration ) . Unix ( ) ) 
  
						 
					
						
							
								
									
										
										
										
											2019-08-29 15:41:59 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									 return   incep ,   expir 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}