This file is indexed.

/usr/lib/ruby/vendor_ruby/merb-core/dispatch/session/store_container.rb is in ruby-merb-core 1.1.3+dfsg-2.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
module Merb
  
  class SessionStoreContainer < SessionContainer
    
    class_inheritable_accessor :store
    # :api: private
    attr_accessor  :_fingerprint
    
    # Determines how many times to try generating a unique session key before we give up
    GENERATE_MAX_TRIES = 100

    # The class attribute :store holds a reference to an object that implements 
    # the following interface:
    #
    # - retrieve_session(session_id) # returns a Hash
    # - store_session(session_id, data) # expects data to be Hash
    # - delete_session(session_id)
    #
    # You can use session store classes directly by assigning to :store in your
    # config/init.rb after_app_loads step, for example:
    #
    #   Merb::BootLoader.after_app_loads do
    #     SessionStoreContainer.store = MemorySession.new
    #   end
    #
    # Or you can inherit from SessionStoreContainer to create a SessionContainer
    # that delegates to aggregated store.
    #
    #   class MemorySession < SessionStoreContainer
    #     self.session_store_type = :memory
    #   end
    #
    #   class MemoryContainer
    #   
    #     def self.retrieve_session(session_id)
    #       ...
    #     end
    #   
    #     def self.store_session(session_id, data)
    #       ...
    #     end
    #   
    #     def self.delete_session(session_id)
    #       ...
    #     end
    #   
    #   end    
    # When used directly, report as :store store
    self.session_store_type = :store
    
    class << self
      
      # Generates a new session ID and creates a new session.
      # 
      # ==== Returns
      # SessionStoreContainer:: The new session.
      # 
      # :api: private
      def generate
        
        # make sure we generate a unique session uuid
        sid = nil
        GENERATE_MAX_TRIES.times do |i|
          sid = Merb::SessionMixin.rand_uuid
          data = store.retrieve_session(sid) rescue nil
          break if data.nil?
          raise "Unable to Generate Unique Session key" if i == (GENERATE_MAX_TRIES-1)
        end
        
        session = new(sid)
        session.needs_new_cookie = true
        session
      end
      
      # Setup a new session or retreive an existing session.
      # 
      # ==== Parameters
      # request<Merb::Request>:: The Merb::Request that came in from Rack.
      # 
      # ==== Notes
      # If no sessions were found, a new SessionContainer will be generated.
      # 
      # ==== Returns
      # SessionContainer:: a SessionContainer.
      # 
      # :api: private
      def setup(request)
        session = retrieve(request.session_id)
        request.session = session
        # TODO Marshal.dump is slow - needs optimization
        session._fingerprint = Marshal.dump(request.session.to_hash).hash
        session
      end
            
      private
      
      # ==== Parameters
      # session_id<String:: The ID of the session to retrieve.
      #
      # ==== Returns
      # SessionStoreContainer:: SessionStoreContainer instance with the session data. If no
      #   sessions matched session_id, a new SessionStoreContainer will be generated.
      #
      # ==== Notes
      # If there are persisted exceptions callbacks to execute, they all get executed
      # when Memcache library raises an exception.
      # 
      # :api: private
      def retrieve(session_id)
        unless session_id.blank?
          begin
            session_data = store.retrieve_session(session_id)
          rescue => err
            Merb.logger.warn!("Could not retrieve session from #{self.name}: #{err.message}")
          end
          # Not in container, but assume that cookie exists
          session_data = new(session_id) if session_data.nil?
        else
          # No cookie...make a new session_id
          session_data = generate
        end
        if session_data.is_a?(self)
          session_data
        else
          # Recreate using the existing session as the data, when switching 
          # from another session type for example, eg. cookie to memcached
          # or when the data is just a hash
          new(session_id).update(session_data)
        end
      end

    end
    
    # Teardown and/or persist the current session.
    #
    # If @_destroy is true, clear out the session completely, including
    # removal of the session cookie itself.
    #
    # ==== Parameters
    # request<Merb::Request>:: The Merb::Request that came in from Rack.
    #
    # ==== Notes
    # The data (self) is converted to a Hash first, since a container might 
    # choose to do a full Marshal on the data, which would make it persist 
    # attributes like 'needs_new_cookie', which it shouldn't.
    # 
    # :api: private
    def finalize(request)
      if @_destroy
        store.delete_session(self.session_id)
        request.destroy_session_cookie
      else
        if _fingerprint != Marshal.dump(data = self.to_hash).hash
          begin
            store.store_session(request.session(self.class.session_store_type).session_id, data)
          rescue => err
            Merb.logger.warn!("Could not persist session to #{self.class.name}: #{err.message}")
          end
        end
        if needs_new_cookie || Merb::SessionMixin.needs_new_cookie?
          request.set_session_id_cookie(self.session_id)
        end
      end
    end
    
    # Regenerate the session ID.
    # 
    # :api: private
    def regenerate
      store.delete_session(self.session_id)
      self.session_id = Merb::SessionMixin.rand_uuid
      store.store_session(self.session_id, self)
    end
    
  end
end