1919 DMARCPrefix = regexp .MustCompile (`^v\s*=\s*DMARC1` ) // Matches v=DMARC1 with whitespace (RFC7489).
2020 SPFPrefix = regexp .MustCompile (`^v=(?i)spf1` )
2121
22- // knownDkimSelectors is a list of known DKIM selectors.
23- knownDkimSelectors = []string {
22+ // knownDKIMSelectors is a list of known DKIM selectors.
23+ knownDKIMSelectors = []string {
2424 "x" , // Generic
2525 "google" , // Google
2626 "selector1" , // Microsoft
@@ -94,7 +94,7 @@ func (s *Scanner) getDNSAnswers(domain string, recordType uint16) ([]dns.RR, err
9494 }
9595
9696 if in .Rcode != dns .RcodeSuccess {
97- // disregard NXDOMAIN errors
97+ // Disregard NXDOMAIN errors.
9898 if in .Rcode == dns .RcodeNameError {
9999 return nil , nil
100100 }
@@ -140,7 +140,11 @@ func (s *Scanner) getTypeBIMI(domain string) (string, error) {
140140// getTypeDKIM queries the DNS server for DKIM records of a domain.
141141// It returns a string (DKIM record) and an error if any occurred.
142142func (s * Scanner ) getTypeDKIM (domain string ) (string , error ) {
143- selectors := append (s .dkimSelectors , knownDkimSelectors ... )
143+ selectors := append (s .dkimSelectors , knownDKIMSelectors ... )
144+
145+ // Some Microsoft domains (e.g. "onmicrosoft.com") use dynamic selectors.
146+ dashedDomain := strings .ReplaceAll (strings .ToLower (domain ), "." , "-" )
147+ selectors = append (selectors , "selector1-" + dashedDomain , "selector2-" + dashedDomain )
144148
145149 for _ , selector := range selectors {
146150 records , err := s .getDNSRecords (selector + "._domainkey." + domain , dns .TypeTXT )
@@ -150,7 +154,7 @@ func (s *Scanner) getTypeDKIM(domain string) (string, error) {
150154
151155 for index , record := range records {
152156 if strings .HasPrefix (record , DKIMPrefix ) {
153- // TXT records can be split across multiple strings, so we need to join them
157+ // TXT records can be split across multiple strings, we need to join them.
154158 return strings .Join (records [index :], "" ), nil
155159 }
156160 }
@@ -173,7 +177,7 @@ func (s *Scanner) getTypeDMARC(domain string) (string, error) {
173177
174178 for index , record := range records {
175179 if DMARCPrefix .MatchString (record ) {
176- // TXT records can be split across multiple strings, so we need to join them
180+ // TXT records can be split across multiple strings, we need to join them.
177181 return strings .Join (records [index :], "" ), nil
178182 }
179183 }
0 commit comments