This file is indexed.

/usr/lib/ruby/vendor_ruby/merb-core/dispatch/session.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
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
require 'merb-core/dispatch/session/container'
require 'merb-core/dispatch/session/store_container'

# Try to require SecureRandom from the Ruby 1.9.x
begin
  require 'securerandom'
rescue LoadError
end

module Merb
  class Config
    # Returns stores list constructed from
    # configured session stores (:session_stores config option)
    # or default one (:session_store config option).
    # 
    # :api: private
    def self.session_stores
      @session_stores ||= begin
        config_stores = Array(
          Merb::Config[:session_stores] || Merb::Config[:session_store]
        )
        config_stores.map { |name| name.to_sym }
      end
    end
  end # Config
  
  # The Merb::Session module gets mixed into Merb::SessionContainer to allow
  # app-level functionality (usually found in ./merb/session/session.rb) for
  # session.
  #
  # You can use this module to implement additional methods to simplify
  # building wizard-like application components,
  # authentication frameworks, etc.
  # 
  # Session configuration options:
  #
  # :session_id_key           The key by which a session value/id is
  #                           retrieved; defaults to _session_id
  #
  # :session_expiry           When to expire the session cookie;
  #                           by defaults session expires when browser quits.
  #
  # :session_secret_key       A secret string which is used to sign/validate
  #                           session data; min. 16 chars
  #
  # :default_cookie_domain    The default domain to write cookies for.
  module Session    
  end
  
  # This is mixed into Merb::Controller on framework boot.
  module SessionMixin
    # Raised when no suitable session store has been setup.
    class NoSessionContainer < StandardError; end
    
    # Raised when storing more data than the available space reserved.
    class SessionOverflow < StandardError; end
    
    # :api: private
    def self.included(base)
      # Register a callback to finalize sessions - needs to run before the cookie
      # callback extracts Set-Cookie headers from request.cookies.
      base._after_dispatch_callbacks.unshift lambda { |c| c.request.finalize_session }
    end
    
    # ==== Parameters
    # session_store<String>:: The type of session store to access.
    #
    # ==== Returns
    # SessionContainer:: The session that was extracted from the request object.
    #
    # :api: public
    def session(session_store = nil)
      request.session(session_store)
    end
    
    # Module methods
    
    # ==== Returns
    # String:: A random 32 character string for use as a unique session ID.
    #
    # :api: private
    def rand_uuid
      if defined?(SecureRandom)
        SecureRandom.hex(16)
      else
        values = [
          rand(0x0010000),
          rand(0x0010000),
          rand(0x0010000),
          rand(0x0010000),
          rand(0x0010000),
          rand(0x1000000),
          rand(0x1000000),
        ]
        "%04x%04x%04x%04x%04x%06x%06x" % values
      end
    end
    
    # Marks this session as needing a new cookie.
    # 
    # :api: private
    def needs_new_cookie!
      @_new_cookie = true
    end
    
    # Does session need new cookie?
    # 
    # ==== Returns
    # Boolean:: true if a new cookie is needed, false otherwise.
    # 
    # :api: private
    def needs_new_cookie?
      @_new_cookie
    end
    
    module_function :rand_uuid, :needs_new_cookie!, :needs_new_cookie?
    
    module RequestMixin
      
      # Adds class methods to Merb::Request object.
      # Sets up repository of session store types.
      # Sets the session ID key and expiry values.
      #
      # :api: private
      def self.included(base)
        base.extend ClassMethods
        
        # Keep track of all known session store types.
        base.cattr_accessor :registered_session_types
        base.registered_session_types = Dictionary.new
        base.class_inheritable_accessor :_session_id_key, :_session_secret_key,
                                        :_session_expiry, :_session_secure,
                                        :_session_http_only, :_default_cookie_domain
        
        base._session_id_key        = Merb::Config[:session_id_key] || '_session_id'
        base._session_expiry        = Merb::Config[:session_expiry] || 0
        base._session_secret_key    = Merb::Config[:session_secret_key]
        base._session_secure        = Merb::Config[:session_secure] || false
        base._session_http_only     = Merb::Config[:session_http_only] || false
        base._default_cookie_domain = Merb::Config[:default_cookie_domain]
      end
      
      module ClassMethods
        
        # ==== Parameters
        # name<~to_sym>:: Name of the session type to register.
        # class_name<String>:: The corresponding class name.
        #
        # === Notres
        # This is automatically called when Merb::SessionContainer is subclassed.
        # 
        # :api: private
        def register_session_type(name, class_name)
          self.registered_session_types[name.to_sym] = class_name
        end
        
      end
      
      # The default session store type.
      # 
      # :api: private
      def default_session_store
        Merb::Config[:session_store] && Merb::Config[:session_store].to_sym
      end
      
      # ==== Returns
      # Hash:: All active session stores by type.
      # 
      # :api: private
      def session_stores
        @session_stores ||= {}
      end
      
      # Returns session container. Merb is able to handle multiple session
      # stores, hence a parameter to pick it.
      #
      # ==== Parameters
      # session_store<String>:: The type of session store to access,
      # defaults to default_session_store.
      #
      # === Notes
      # If no suitable session store type is given, it defaults to
      # cookie-based sessions.
      # 
      # ==== Returns
      # SessionContainer::
      #   an instance of a session store extending Merb::SessionContainer.
      # 
      # :api: public
      def session(session_store = nil)
        session_store ||= default_session_store
        if class_name = self.class.registered_session_types[session_store]
          session_stores[session_store] ||= Object.full_const_get(class_name).setup(self)
        elsif fallback = self.class.registered_session_types.keys.first
          Merb.logger.warn "Session store '#{session_store}' not found. Check your configuration in init file."
          Merb.logger.warn "Falling back to #{fallback} session store."
          session(fallback)
        else
          msg = "No session store set. Set it in init file like this: c[:session_store] = 'activerecord'"
          Merb.logger.error!(msg)
          raise NoSessionContainer, msg            
        end
      end
      
      # ==== Parameters
      # new_session<Merb::SessionContainer>:: A session store instance.
      #
      # === Notes
      # The session is assigned internally by its session_store_type key.
      # 
      # :api: private
      def session=(new_session)
        if self.session?(new_session.class.session_store_type)
          original_session_id = self.session(new_session.class.session_store_type).session_id
          if new_session.session_id != original_session_id
            set_session_id_cookie(new_session.session_id)
          end
        end
        session_stores[new_session.class.session_store_type] = new_session
      end
      
      # Whether a session has been setup
      # 
      # ==== Returns
      # Boolean:: true if the session is part of the session stores configured.
      # 
      # :api: private
      def session?(session_store = nil)
        (session_store ? [session_store] : session_stores).any? do |type, store|
          store.is_a?(Merb::SessionContainer)
        end
      end
      
      # Teardown and/or persist the current sessions.
      # 
      # :api: private
      def finalize_session
        session_stores.each { |name, store| store.finalize(self) }
      end
      alias :finalize_sessions :finalize_session
      
      # Assign default cookie values
      # 
      # :api: private
      def default_cookies
        defaults = {}
        if route && route.allow_fixation? && params.key?(_session_id_key)
          Merb.logger.info("Fixated session id: #{_session_id_key}")
          defaults[_session_id_key] = params[_session_id_key]
        end
        defaults
      end

      # Sets session cookie value.
      #
      # ==== Parameters
      # value<String>:: The value of the session cookie; either the session id or the actual encoded data.
      # options<Hash>:: Cookie options like domain, path and expired.
      # 
      # :api: private
      def set_session_cookie_value(value, options = {})
        defaults = {}
        defaults[:expires]   = Time.now + _session_expiry if _session_expiry > 0
        defaults[:domain]    = _default_cookie_domain if _default_cookie_domain
        defaults[:secure]    = _session_secure
        defaults[:http_only] = _session_http_only
        cookies.set_cookie(_session_id_key, value, defaults.merge(options))
      end
      alias :set_session_id_cookie :set_session_cookie_value

      # ==== Returns
      # String:: The value of the session cookie; either the session id or the actual encoded data.
      # 
      # :api: private
      def session_cookie_value
        cookies[_session_id_key]
      end
      alias :session_id :session_cookie_value
      
      # Destroy the session cookie.
      # 
      # :api: private
      def destroy_session_cookie
        cookies.delete(_session_id_key)
      end
      
    end
  end
end