vendor/bundle/ruby/2.7.0/gems/dnsruby-1.61.5/lib/dnsruby/resource/TSIG.rb
# Checks TSIG signatures across sessions of multiple DNS envelopes.
# This method is called each time a new envelope comes in. The envelope
# is checked - if a TSIG is present, them the stream so far is verified,
# and the response#tsigstate set to :Verified. If a TSIG is not present,
# and does not need to be present, then the message is added to the digest
# stream and the response#tsigstate is set to :Intermediate.
# If there is an error with the TSIG verification, then the response#tsigstate
# is set to :Failed.
# Like verify, this method will only be called by the Dnsruby::SingleResolver
# class. Client code need not call this method directly.
Checks TSIG signatures across sessions of multiple DNS envelopes.
This method is called each time a new envelope comes in. The envelope
is checked - if a TSIG is present, them the stream so far is verified,
and the response#tsigstate set to :Verified. If a TSIG is not present,
and does not need to be present, then the message is added to the digest
stream and the response#tsigstate is set to :Intermediate.
If there is an error with the TSIG verification, then the response#tsigstate
is set to :Failed.
Like verify, this method will only be called by the Dnsruby::SingleResolver
class. Client code need not call this method directly.
Checks TSIG signatures across sessions of multiple DNS envelopes . This method is called each time a new envelope comes in . The envelope is checked - if a TSIG is present them the stream so far is verified and the response#tsigstate set to : Verified . If a TSIG is not present and does not need to be present then the message is added to the digest stream and the response#tsigstate is set to : Intermediate . If there is an error with the TSIG verification then the response#tsigstate is set to : Failed . Like verify this method will only be called by the Dnsruby :: SingleResolver class . Client code need not call this method directly .
def verify_envelope(response, response_bytes)
        *   Prior Digest (running)
        *   DNS Messages (any unsigned messages since the last TSIG)
        *   TSIG Timers (current message)
        This allows the client to rapidly detect when the session has been
        altered; at which point it can close the connection and retry.  If a
        client TSIG verification fails, the client MUST close the connection.
        If the client does not receive TSIG records frequently enough (as
        specified above) it SHOULD assume the connection has been hijacked
        and it SHOULD close the connection.  The client SHOULD treat this the
        same way as they would any other interrupted transfer (although the
        exact behavior is not specified).
         Each time a new envelope comes in, this method is called on the QUERY TSIG RR.
         It will set the response tsigstate to :Verified :Intermediate or :Failed
         as appropriate.
         Keep digest going of messages as they come in (and mark them intermediate)
         When TSIG comes in, work out what key should be and check. If OK, mark
         verified. Can reset digest then.
        if (!@buf)
          @num_envelopes = 0
          @last_signed = 0
        end
        @num_envelopes += 1
        if (!response.tsig)
          if ((@num_envelopes > 1) && (@num_envelopes - @last_signed < 100))
            Dnsruby.log.debug("Receiving intermediate envelope in TSIG TCP session")
            response.tsigstate = :Intermediate
            response.tsigerror = RCode.NOERROR
            @buf = @buf + response_bytes
            return
          else
            response.tsigstate = :Failed
            Dnsruby.log.error("Expecting signed packet")
            return false
          end
        end
        @last_signed = @num_envelopes
         We have a TSIG - process it!
        tsig = response.tsig
        if (@num_envelopes == 1)
          Dnsruby.log.debug("First response in TSIG TCP session - verifying normally")
           Process it as a standard answer
          ok = verify(@query, response, response_bytes)
          if (ok)
            mac_bytes = MessageEncoder.new {|m|
              m.put_pack('n', tsig.mac_size)
              m.put_bytes(tsig.mac)
            }.to_s
            @buf = mac_bytes
          end
          return ok
        end
        Dnsruby.log.debug("Processing TSIG on TSIG TCP session")
        if (!verify_common(response))
          return false
        end
         Now add the current message data - remember to frig the arcount
        response_bytes = Header.decrement_arcount_encoded(response_bytes)
        @buf += response_bytes[0, response.tsigstart]
         Let's add the timers
        timers_data = MessageEncoder.new { |msg|
          time_high = (tsig.time_signed >> 32)
          time_low = (tsig.time_signed & 0xFFFFFFFF)
          msg.put_pack('nN', time_high, time_low)
          msg.put_pack('n', tsig.fudge)
        }.to_s
        @buf += timers_data
        mac = calculate_mac(tsig.algorithm, @buf)
        if (mac != tsig.mac)
          Dnsruby.log.error("TSIG Verify error on TSIG TCP session")
          response.tsigstate = :Failed
          return false
        end
        mac_bytes = MessageEncoder.new {|m|
          m.put_pack('n', mac.length)
          m.put_bytes(mac)
        }.to_s
        @buf=mac_bytes
        response.tsigstate = :Verified
        response.tsigerror = RCode.NOERROR
        return true
      end
def verify_envelope ( response , response_bytes ) if ( ! @buf ) @num_envelopes = 0 @last_signed = 0 end @num_envelopes += 1 if ( ! response . tsig ) if ( ( @num_envelopes > 1 ) && ( @num_envelopes - @last_signed < 100 ) ) Dnsruby . log . debug ( "Receiving intermediate envelope in TSIG TCP session" ) response . tsigstate = :Intermediate response . tsigerror = RCode . NOERROR @buf = @buf + response_bytes return else response . tsigstate = :Failed Dnsruby . log . error ( "Expecting signed packet" ) return false end end @last_signed = @num_envelopes tsig = response . tsig if ( @num_envelopes == 1 ) Dnsruby . log . debug ( "First response in TSIG TCP session - verifying normally" ) ok = verify ( @query , response , response_bytes ) if ( ok ) mac_bytes = MessageEncoder . new { | m | m . put_pack ( 'n' , tsig . mac_size ) m . put_bytes ( tsig . mac ) } . to_s @buf = mac_bytes end return ok end Dnsruby . log . debug ( "Processing TSIG on TSIG TCP session" ) if ( ! verify_common ( response ) ) return false end response_bytes = Header . decrement_arcount_encoded ( response_bytes ) @buf += response_bytes [ 0 , response . tsigstart ] timers_data = MessageEncoder . new { | msg | time_high = ( tsig . time_signed >> 32 ) time_low = ( tsig . time_signed & 0xFFFFFFFF ) msg . put_pack ( 'nN' , time_high , time_low ) msg . put_pack ( 'n' , tsig . fudge ) } . to_s @buf += timers_data mac = calculate_mac ( tsig . algorithm , @buf ) if ( mac != tsig . mac ) Dnsruby . log . error ( "TSIG Verify error on TSIG TCP session" ) response . tsigstate = :Failed return false end mac_bytes = MessageEncoder . new { | m | m . put_pack ( 'n' , mac . length ) m . put_bytes ( mac ) } . to_s @buf = mac_bytes response . tsigstate = :Verified response . tsigerror = RCode . NOERROR return true end
Checks TSIG signatures across sessions of multiple DNS envelopes.
Checks TSIG signatures across sessions of multiple DNS envelopes .
# RFC2845 Section 4.4 # ----- # A DNS TCP session can include multiple DNS envelopes.  This is, for # example, commonly used by zone transfer.  Using TSIG on such a # connection can protect the connection from hijacking and provide data # integrity.  The TSIG MUST be included on the first and last DNS # envelopes.  It can be optionally placed on any intermediary # envelopes.  It is expensive to include it on every envelopes, but it # MUST be placed on at least every 100'th envelope.  The first envelope # is processed as a standard answer, and subsequent messages have the # following digest components: #  # *   Prior Digest (running) # *   DNS Messages (any unsigned messages since the last TSIG) # *   TSIG Timers (current message) #  # This allows the client to rapidly detect when the session has been # altered; at which point it can close the connection and retry.  If a # client TSIG verification fails, the client MUST close the connection. # If the client does not receive TSIG records frequently enough (as # specified above) it SHOULD assume the connection has been hijacked # and it SHOULD close the connection.  The client SHOULD treat this the # same way as they would any other interrupted transfer (although the # exact behavior is not specified). # ----- #  #  Each time a new envelope comes in, this method is called on the QUERY TSIG RR. #  It will set the response tsigstate to :Verified :Intermediate or :Failed #  as appropriate. #  Keep digest going of messages as they come in (and mark them intermediate) #  When TSIG comes in, work out what key should be and check. If OK, mark #  verified. Can reset digest then. #  We have a TSIG - process it! #  Process it as a standard answer #  Now add the current message data - remember to frig the arcount #  Let's add the timers
response
<not_specific>
response_bytes
<not_specific>