File: message.rb

package info (click to toggle)
ruby-ntlm 0.6.3-2
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, forky, sid, trixie
  • size: 408 kB
  • sloc: ruby: 2,663; makefile: 6
file content (129 lines) | stat: -rw-r--r-- 3,095 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
module Net
module NTLM

  SSP_SIGN = "NTLMSSP\0"

  FLAGS = {
      :UNICODE              => 0x00000001,
      :OEM                  => 0x00000002,
      :REQUEST_TARGET       => 0x00000004,
      :MBZ9                 => 0x00000008,
      :SIGN                 => 0x00000010,
      :SEAL                 => 0x00000020,
      :NEG_DATAGRAM         => 0x00000040,
      :NETWARE              => 0x00000100,
      :NTLM                 => 0x00000200,
      :NEG_NT_ONLY          => 0x00000400,
      :MBZ7                 => 0x00000800,
      :DOMAIN_SUPPLIED      => 0x00001000,
      :WORKSTATION_SUPPLIED => 0x00002000,
      :LOCAL_CALL           => 0x00004000,
      :ALWAYS_SIGN          => 0x00008000,
      :TARGET_TYPE_DOMAIN   => 0x00010000,
      :NTLM2_KEY            => 0x00080000,
      :TARGET_INFO          => 0x00800000,
      :KEY128               => 0x20000000,
      :KEY_EXCHANGE         => 0x40000000,
      :KEY56                => 0x80000000
  }.freeze

  FLAG_KEYS = FLAGS.keys.sort{|a, b| FLAGS[a] <=> FLAGS[b] }

  DEFAULT_FLAGS = {
      :TYPE1 => FLAGS[:UNICODE] | FLAGS[:OEM] | FLAGS[:REQUEST_TARGET] | FLAGS[:NTLM] | FLAGS[:ALWAYS_SIGN] | FLAGS[:NTLM2_KEY],
      :TYPE2 => FLAGS[:UNICODE],
      :TYPE3 => FLAGS[:UNICODE] | FLAGS[:REQUEST_TARGET] | FLAGS[:NTLM] | FLAGS[:ALWAYS_SIGN] | FLAGS[:NTLM2_KEY]
  }


  # @private false
  class Message < FieldSet
    class << Message
      def parse(str)
        m = Type0.new
        m.parse(str)
        case m.type
        when 1
          t = Type1.new.parse(str)
        when 2
          t = Type2.new.parse(str)
        when 3
          t = Type3.new.parse(str)
        else
          raise ArgumentError, "unknown type: #{m.type}"
        end
        t
      end

      def decode64(str)
        parse(Base64.decode64(str))
      end
    end

    # @return [self]
    def parse(str)
      super

      while has_disabled_fields? && serialize.size < str.size
        # enable the next disabled field
        self.class.names.find { |name| !self[name].active && enable(name) }
        super
      end

      self
    end

    def has_flag?(flag)
      (self[:flag].value & FLAGS[flag]) == FLAGS[flag]
    end

    def set_flag(flag)
      self[:flag].value  |= FLAGS[flag]
    end

    def dump_flags
      FLAG_KEYS.each{ |k| print(k, "=", has_flag?(k), "\n") }
    end

    def serialize
      deflag
      super + security_buffers.map{|n, f| f.value}.join
    end

    def encode64
      Base64.encode64(serialize).gsub(/\n/, '')
    end

    def decode64(str)
      parse(Base64.decode64(str))
    end

    alias head_size size

    def data_size
      security_buffers.inject(0){|sum, a| sum += a[1].data_size}
    end

    def size
      head_size + data_size
    end


    def security_buffers
      @alist.find_all{|n, f| f.instance_of?(SecurityBuffer)}
    end

    def deflag
      security_buffers.inject(head_size){|cur, a|
        a[1].offset = cur
        cur += a[1].data_size
      }
    end

    def data_edge
      security_buffers.map{ |n, f| f.active ? f.offset : size}.min
    end

  end
end
end