summaryrefslogtreecommitdiffstats
path: root/modules/session
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-07 02:04:06 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-07 02:04:06 +0000
commit5dff2d61cc1c27747ee398e04d8e02843aabb1f8 (patch)
treea67c336b406c8227bac912beb74a1ad3cdc55100 /modules/session
parentInitial commit. (diff)
downloadapache2-upstream.tar.xz
apache2-upstream.zip
Adding upstream version 2.4.38.upstream/2.4.38upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r--modules/session/Makefile.in4
-rw-r--r--modules/session/NWGNUmakefile257
-rw-r--r--modules/session/NWGNUsession254
-rw-r--r--modules/session/NWGNUsession_cookie253
-rw-r--r--modules/session/NWGNUsession_crypto255
-rw-r--r--modules/session/NWGNUsession_dbd253
-rw-r--r--modules/session/config.m468
-rw-r--r--modules/session/mod_session.c674
-rw-r--r--modules/session/mod_session.dep56
-rw-r--r--modules/session/mod_session.dsp115
-rw-r--r--modules/session/mod_session.h186
-rw-r--r--modules/session/mod_session.mak353
-rw-r--r--modules/session/mod_session_cookie.c284
-rw-r--r--modules/session/mod_session_cookie.dep49
-rw-r--r--modules/session/mod_session_cookie.dsp111
-rw-r--r--modules/session/mod_session_cookie.mak381
-rw-r--r--modules/session/mod_session_crypto.c805
-rw-r--r--modules/session/mod_session_crypto.dep57
-rw-r--r--modules/session/mod_session_crypto.dsp111
-rw-r--r--modules/session/mod_session_crypto.mak381
-rw-r--r--modules/session/mod_session_dbd.c640
-rw-r--r--modules/session/mod_session_dbd.dep60
-rw-r--r--modules/session/mod_session_dbd.dsp111
-rw-r--r--modules/session/mod_session_dbd.mak409
24 files changed, 6127 insertions, 0 deletions
diff --git a/modules/session/Makefile.in b/modules/session/Makefile.in
new file mode 100644
index 0000000..fb9dacf
--- /dev/null
+++ b/modules/session/Makefile.in
@@ -0,0 +1,4 @@
+# a modules Makefile has no explicit targets -- they will be defined by
+# whatever modules are enabled. just grab special.mk to deal with this.
+include $(top_srcdir)/build/special.mk
+
diff --git a/modules/session/NWGNUmakefile b/modules/session/NWGNUmakefile
new file mode 100644
index 0000000..85f3a31
--- /dev/null
+++ b/modules/session/NWGNUmakefile
@@ -0,0 +1,257 @@
+#
+# Declare the sub-directories to be built here
+#
+
+SUBDIRS = \
+ $(EOLIST)
+
+#
+# Get the 'head' of the build environment. This includes default targets and
+# paths to tools
+#
+
+include $(AP_WORK)/build/NWGNUhead.inc
+
+#
+# build this level's files
+
+#
+# Make sure all needed macro's are defined
+#
+ifneq "$(MAKECMDGOALS)" "clean"
+ifneq "$(findstring clobber_,$(MAKECMDGOALS))" "clobber_"
+APU_HAVE_CRYPTO = $(shell $(AWK) '/^\#define APU_HAVE_CRYPTO/{print $$3}' $(APRUTIL)/include/apu.h)
+endif
+endif
+
+#
+# These directories will be at the beginning of the include list, followed by
+# INCDIRS
+#
+XINCDIRS += \
+ $(EOLIST)
+
+#
+# These flags will come after CFLAGS
+#
+XCFLAGS += \
+ $(EOLIST)
+
+#
+# These defines will come after DEFINES
+#
+XDEFINES += \
+ $(EOLIST)
+
+#
+# These flags will be added to the link.opt file
+#
+XLFLAGS += \
+ $(EOLIST)
+
+#
+# These values will be appended to the correct variables based on the value of
+# RELEASE
+#
+ifeq "$(RELEASE)" "debug"
+XINCDIRS += \
+ $(EOLIST)
+
+XCFLAGS += \
+ $(EOLIST)
+
+XDEFINES += \
+ $(EOLIST)
+
+XLFLAGS += \
+ $(EOLIST)
+endif
+
+ifeq "$(RELEASE)" "noopt"
+XINCDIRS += \
+ $(EOLIST)
+
+XCFLAGS += \
+ $(EOLIST)
+
+XDEFINES += \
+ $(EOLIST)
+
+XLFLAGS += \
+ $(EOLIST)
+endif
+
+ifeq "$(RELEASE)" "release"
+XINCDIRS += \
+ $(EOLIST)
+
+XCFLAGS += \
+ $(EOLIST)
+
+XDEFINES += \
+ $(EOLIST)
+
+XLFLAGS += \
+ $(EOLIST)
+endif
+
+#
+# These are used by the link target if an NLM is being generated
+# This is used by the link 'name' directive to name the nlm. If left blank
+# TARGET_nlm (see below) will be used.
+#
+NLM_NAME =
+
+#
+# This is used by the link '-desc ' directive.
+# If left blank, NLM_NAME will be used.
+#
+NLM_DESCRIPTION =
+
+#
+# This is used by the '-threadname' directive. If left blank,
+# NLM_NAME Thread will be used.
+#
+NLM_THREAD_NAME =
+
+#
+# If this is specified, it will override VERSION value in
+# $(AP_WORK)/build/NWGNUenvironment.inc
+#
+NLM_VERSION =
+
+#
+# If this is specified, it will override the default of 64K
+#
+NLM_STACK_SIZE =
+
+
+#
+# If this is specified it will be used by the link '-entry' directive
+#
+NLM_ENTRY_SYM =
+
+#
+# If this is specified it will be used by the link '-exit' directive
+#
+NLM_EXIT_SYM =
+
+#
+# If this is specified it will be used by the link '-check' directive
+#
+NLM_CHECK_SYM =
+
+#
+# If these are specified it will be used by the link '-flags' directive
+#
+NLM_FLAGS =
+
+#
+# If this is specified it will be linked in with the XDCData option in the def
+# file instead of the default of $(NWOS)/apache.xdc. XDCData can be disabled
+# by setting APACHE_UNIPROC in the environment
+#
+XDCDATA =
+
+#
+# If there is an NLM target, put it here
+#
+TARGET_nlm = \
+ $(OBJDIR)/session.nlm \
+ $(OBJDIR)/session_cookie.nlm \
+ $(OBJDIR)/session_dbd.nlm \
+ $(EOLIST)
+
+# If the APU library has cryptp API then build the mod_session_crypto module
+ifeq "$(APU_HAVE_CRYPTO)" "1"
+TARGET_nlm += $(OBJDIR)/session_crypto.nlm
+endif
+
+#
+# If there is an LIB target, put it here
+#
+TARGET_lib = \
+ $(EOLIST)
+
+#
+# These are the OBJ files needed to create the NLM target above.
+# Paths must all use the '/' character
+#
+FILES_nlm_objs = \
+ $(EOLIST)
+
+#
+# These are the LIB files needed to create the NLM target above.
+# These will be added as a library command in the link.opt file.
+#
+FILES_nlm_libs = \
+ $(EOLIST)
+
+#
+# These are the modules that the above NLM target depends on to load.
+# These will be added as a module command in the link.opt file.
+#
+FILES_nlm_modules = \
+ $(EOLIST)
+
+#
+# If the nlm has a msg file, put it's path here
+#
+FILE_nlm_msg =
+
+#
+# If the nlm has a hlp file put it's path here
+#
+FILE_nlm_hlp =
+
+#
+# If this is specified, it will override $(NWOS)\copyright.txt.
+#
+FILE_nlm_copyright =
+
+#
+# Any additional imports go here
+#
+FILES_nlm_Ximports = \
+ $(EOLIST)
+
+#
+# Any symbols exported to here
+#
+FILES_nlm_exports = \
+ $(EOLIST)
+
+#
+# These are the OBJ files needed to create the LIB target above.
+# Paths must all use the '/' character
+#
+FILES_lib_objs = \
+ $(EOLIST)
+
+#
+# implement targets and dependancies (leave this section alone)
+#
+
+libs :: $(OBJDIR) $(TARGET_lib)
+
+nlms :: libs $(TARGET_nlm)
+
+#
+# Updated this target to create necessary directories and copy files to the
+# correct place. (See $(AP_WORK)/build/NWGNUhead.inc for examples)
+#
+install :: nlms FORCE
+ $(call COPY,$(OBJDIR)/*.nlm, $(INSTALLBASE)/modules/)
+
+#
+# Any specialized rules here
+#
+
+#
+# Include the 'tail' makefile that has targets that depend on variables defined
+# in this makefile
+#
+
+include $(APBUILD)/NWGNUtail.inc
+
+
diff --git a/modules/session/NWGNUsession b/modules/session/NWGNUsession
new file mode 100644
index 0000000..635e8c1
--- /dev/null
+++ b/modules/session/NWGNUsession
@@ -0,0 +1,254 @@
+#
+# Make sure all needed macro's are defined
+#
+
+#
+# Get the 'head' of the build environment if necessary. This includes default
+# targets and paths to tools
+#
+
+ifndef EnvironmentDefined
+include $(AP_WORK)/build/NWGNUhead.inc
+endif
+
+#
+# These directories will be at the beginning of the include list, followed by
+# INCDIRS
+#
+XINCDIRS += \
+ $(APR)/include \
+ $(APRUTIL)/include \
+ $(SRC)/include \
+ $(NWOS) \
+ $(EOLIST)
+
+#
+# These flags will come after CFLAGS
+#
+XCFLAGS += \
+ $(EOLIST)
+
+#
+# These defines will come after DEFINES
+#
+XDEFINES += \
+ $(EOLIST)
+
+#
+# These flags will be added to the link.opt file
+#
+XLFLAGS += \
+ $(EOLIST)
+
+#
+# These values will be appended to the correct variables based on the value of
+# RELEASE
+#
+ifeq "$(RELEASE)" "debug"
+XINCDIRS += \
+ $(EOLIST)
+
+XCFLAGS += \
+ $(EOLIST)
+
+XDEFINES += \
+ $(EOLIST)
+
+XLFLAGS += \
+ $(EOLIST)
+endif
+
+ifeq "$(RELEASE)" "noopt"
+XINCDIRS += \
+ $(EOLIST)
+
+XCFLAGS += \
+ $(EOLIST)
+
+XDEFINES += \
+ $(EOLIST)
+
+XLFLAGS += \
+ $(EOLIST)
+endif
+
+ifeq "$(RELEASE)" "release"
+XINCDIRS += \
+ $(EOLIST)
+
+XCFLAGS += \
+ $(EOLIST)
+
+XDEFINES += \
+ $(EOLIST)
+
+XLFLAGS += \
+ $(EOLIST)
+endif
+
+#
+# These are used by the link target if an NLM is being generated
+# This is used by the link 'name' directive to name the nlm. If left blank
+# TARGET_nlm (see below) will be used.
+#
+NLM_NAME = session
+
+#
+# This is used by the link '-desc ' directive.
+# If left blank, NLM_NAME will be used.
+#
+NLM_DESCRIPTION = Apache $(VERSION_STR) Session Module
+
+#
+# This is used by the '-threadname' directive. If left blank,
+# NLM_NAME Thread will be used.
+#
+NLM_THREAD_NAME = Session Module
+
+#
+# If this is specified, it will override VERSION value in
+# $(AP_WORK)/build/NWGNUenvironment.inc
+#
+NLM_VERSION =
+
+#
+# If this is specified, it will override the default of 64K
+#
+NLM_STACK_SIZE = 8192
+
+
+#
+# If this is specified it will be used by the link '-entry' directive
+#
+NLM_ENTRY_SYM =
+
+#
+# If this is specified it will be used by the link '-exit' directive
+#
+NLM_EXIT_SYM =
+
+#
+# If this is specified it will be used by the link '-check' directive
+#
+NLM_CHECK_SYM =
+
+#
+# If these are specified it will be used by the link '-flags' directive
+#
+NLM_FLAGS =
+
+#
+# If this is specified it will be linked in with the XDCData option in the def
+# file instead of the default of $(NWOS)/apache.xdc. XDCData can be disabled
+# by setting APACHE_UNIPROC in the environment
+#
+XDCDATA =
+
+#
+# If there is an NLM target, put it here
+#
+TARGET_nlm = \
+ $(OBJDIR)/$(NLM_NAME).nlm \
+ $(EOLIST)
+
+#
+# If there is an LIB target, put it here
+#
+TARGET_lib = \
+ $(EOLIST)
+
+#
+# These are the OBJ files needed to create the NLM target above.
+# Paths must all use the '/' character
+#
+FILES_nlm_objs = \
+ $(OBJDIR)/mod_session.o \
+ $(EOLIST)
+
+#
+# These are the LIB files needed to create the NLM target above.
+# These will be added as a library command in the link.opt file.
+#
+FILES_nlm_libs = \
+ $(PRELUDE) \
+ $(EOLIST)
+
+#
+# These are the modules that the above NLM target depends on to load.
+# These will be added as a module command in the link.opt file.
+#
+FILES_nlm_modules = \
+ aprlib \
+ libc \
+ $(EOLIST)
+
+#
+# If the nlm has a msg file, put it's path here
+#
+FILE_nlm_msg =
+
+#
+# If the nlm has a hlp file put it's path here
+#
+FILE_nlm_hlp =
+
+#
+# If this is specified, it will override $(NWOS)\copyright.txt.
+#
+FILE_nlm_copyright =
+
+#
+# Any additional imports go here
+#
+FILES_nlm_Ximports = \
+ @aprlib.imp \
+ @httpd.imp \
+ @libc.imp \
+ $(EOLIST)
+
+#
+# Any symbols exported to here
+#
+FILES_nlm_exports = \
+ session_module \
+ ap_hook_session_decode \
+ ap_hook_session_encode \
+ ap_hook_session_load \
+ ap_hook_session_save \
+ $(EOLIST)
+
+#
+# These are the OBJ files needed to create the LIB target above.
+# Paths must all use the '/' character
+#
+FILES_lib_objs = \
+ $(EOLIST)
+
+#
+# implement targets and dependancies (leave this section alone)
+#
+
+libs :: $(OBJDIR) $(TARGET_lib)
+
+nlms :: libs $(TARGET_nlm)
+
+#
+# Updated this target to create necessary directories and copy files to the
+# correct place. (See $(AP_WORK)/build/NWGNUhead.inc for examples)
+#
+install :: nlms FORCE
+
+#
+# Any specialized rules here
+#
+
+vpath %.c ../arch/netware
+
+#
+# Include the 'tail' makefile that has targets that depend on variables defined
+# in this makefile
+#
+
+include $(APBUILD)/NWGNUtail.inc
+
+
diff --git a/modules/session/NWGNUsession_cookie b/modules/session/NWGNUsession_cookie
new file mode 100644
index 0000000..93f9200
--- /dev/null
+++ b/modules/session/NWGNUsession_cookie
@@ -0,0 +1,253 @@
+#
+# Make sure all needed macro's are defined
+#
+
+#
+# Get the 'head' of the build environment if necessary. This includes default
+# targets and paths to tools
+#
+
+ifndef EnvironmentDefined
+include $(AP_WORK)/build/NWGNUhead.inc
+endif
+
+#
+# These directories will be at the beginning of the include list, followed by
+# INCDIRS
+#
+XINCDIRS += \
+ $(APR)/include \
+ $(APRUTIL)/include \
+ $(SRC)/include \
+ $(NWOS) \
+ $(EOLIST)
+
+#
+# These flags will come after CFLAGS
+#
+XCFLAGS += \
+ $(EOLIST)
+
+#
+# These defines will come after DEFINES
+#
+XDEFINES += \
+ $(EOLIST)
+
+#
+# These flags will be added to the link.opt file
+#
+XLFLAGS += \
+ $(EOLIST)
+
+#
+# These values will be appended to the correct variables based on the value of
+# RELEASE
+#
+ifeq "$(RELEASE)" "debug"
+XINCDIRS += \
+ $(EOLIST)
+
+XCFLAGS += \
+ $(EOLIST)
+
+XDEFINES += \
+ $(EOLIST)
+
+XLFLAGS += \
+ $(EOLIST)
+endif
+
+ifeq "$(RELEASE)" "noopt"
+XINCDIRS += \
+ $(EOLIST)
+
+XCFLAGS += \
+ $(EOLIST)
+
+XDEFINES += \
+ $(EOLIST)
+
+XLFLAGS += \
+ $(EOLIST)
+endif
+
+ifeq "$(RELEASE)" "release"
+XINCDIRS += \
+ $(EOLIST)
+
+XCFLAGS += \
+ $(EOLIST)
+
+XDEFINES += \
+ $(EOLIST)
+
+XLFLAGS += \
+ $(EOLIST)
+endif
+
+#
+# These are used by the link target if an NLM is being generated
+# This is used by the link 'name' directive to name the nlm. If left blank
+# TARGET_nlm (see below) will be used.
+#
+NLM_NAME = session_cookie
+
+#
+# This is used by the link '-desc ' directive.
+# If left blank, NLM_NAME will be used.
+#
+NLM_DESCRIPTION = Apache $(VERSION_STR) Session Cookie Module
+
+#
+# This is used by the '-threadname' directive. If left blank,
+# NLM_NAME Thread will be used.
+#
+NLM_THREAD_NAME = SessionCookie Module
+
+#
+# If this is specified, it will override VERSION value in
+# $(AP_WORK)/build/NWGNUenvironment.inc
+#
+NLM_VERSION =
+
+#
+# If this is specified, it will override the default of 64K
+#
+NLM_STACK_SIZE = 8192
+
+
+#
+# If this is specified it will be used by the link '-entry' directive
+#
+NLM_ENTRY_SYM =
+
+#
+# If this is specified it will be used by the link '-exit' directive
+#
+NLM_EXIT_SYM =
+
+#
+# If this is specified it will be used by the link '-check' directive
+#
+NLM_CHECK_SYM =
+
+#
+# If these are specified it will be used by the link '-flags' directive
+#
+NLM_FLAGS =
+
+#
+# If this is specified it will be linked in with the XDCData option in the def
+# file instead of the default of $(NWOS)/apache.xdc. XDCData can be disabled
+# by setting APACHE_UNIPROC in the environment
+#
+XDCDATA =
+
+#
+# If there is an NLM target, put it here
+#
+TARGET_nlm = \
+ $(OBJDIR)/$(NLM_NAME).nlm \
+ $(EOLIST)
+
+#
+# If there is an LIB target, put it here
+#
+TARGET_lib = \
+ $(EOLIST)
+
+#
+# These are the OBJ files needed to create the NLM target above.
+# Paths must all use the '/' character
+#
+FILES_nlm_objs = \
+ $(OBJDIR)/mod_session_cookie.o \
+ $(EOLIST)
+
+#
+# These are the LIB files needed to create the NLM target above.
+# These will be added as a library command in the link.opt file.
+#
+FILES_nlm_libs = \
+ $(PRELUDE) \
+ $(EOLIST)
+
+#
+# These are the modules that the above NLM target depends on to load.
+# These will be added as a module command in the link.opt file.
+#
+FILES_nlm_modules = \
+ aprlib \
+ libc \
+ session \
+ $(EOLIST)
+
+#
+# If the nlm has a msg file, put it's path here
+#
+FILE_nlm_msg =
+
+#
+# If the nlm has a hlp file put it's path here
+#
+FILE_nlm_hlp =
+
+#
+# If this is specified, it will override $(NWOS)\copyright.txt.
+#
+FILE_nlm_copyright =
+
+#
+# Any additional imports go here
+#
+FILES_nlm_Ximports = \
+ @aprlib.imp \
+ @httpd.imp \
+ @libc.imp \
+ ap_hook_session_load \
+ ap_hook_session_save \
+ $(EOLIST)
+
+#
+# Any symbols exported to here
+#
+FILES_nlm_exports = \
+ session_cookie_module \
+ $(EOLIST)
+
+#
+# These are the OBJ files needed to create the LIB target above.
+# Paths must all use the '/' character
+#
+FILES_lib_objs = \
+ $(EOLIST)
+
+#
+# implement targets and dependancies (leave this section alone)
+#
+
+libs :: $(OBJDIR) $(TARGET_lib)
+
+nlms :: libs $(TARGET_nlm)
+
+#
+# Updated this target to create necessary directories and copy files to the
+# correct place. (See $(AP_WORK)/build/NWGNUhead.inc for examples)
+#
+install :: nlms FORCE
+
+#
+# Any specialized rules here
+#
+
+vpath %.c ../arch/netware
+
+#
+# Include the 'tail' makefile that has targets that depend on variables defined
+# in this makefile
+#
+
+include $(APBUILD)/NWGNUtail.inc
+
+
diff --git a/modules/session/NWGNUsession_crypto b/modules/session/NWGNUsession_crypto
new file mode 100644
index 0000000..825065f
--- /dev/null
+++ b/modules/session/NWGNUsession_crypto
@@ -0,0 +1,255 @@
+#
+# Make sure all needed macro's are defined
+#
+
+#
+# Get the 'head' of the build environment if necessary. This includes default
+# targets and paths to tools
+#
+
+ifndef EnvironmentDefined
+include $(AP_WORK)/build/NWGNUhead.inc
+endif
+
+#
+# These directories will be at the beginning of the include list, followed by
+# INCDIRS
+#
+XINCDIRS += \
+ $(APR)/include \
+ $(APRUTIL)/include \
+ $(SRC)/include \
+ $(NWOS) \
+ $(EOLIST)
+
+#
+# These flags will come after CFLAGS
+#
+XCFLAGS += \
+ $(EOLIST)
+
+#
+# These defines will come after DEFINES
+#
+XDEFINES += \
+ $(EOLIST)
+
+#
+# These flags will be added to the link.opt file
+#
+XLFLAGS += \
+ $(EOLIST)
+
+#
+# These values will be appended to the correct variables based on the value of
+# RELEASE
+#
+ifeq "$(RELEASE)" "debug"
+XINCDIRS += \
+ $(EOLIST)
+
+XCFLAGS += \
+ $(EOLIST)
+
+XDEFINES += \
+ $(EOLIST)
+
+XLFLAGS += \
+ $(EOLIST)
+endif
+
+ifeq "$(RELEASE)" "noopt"
+XINCDIRS += \
+ $(EOLIST)
+
+XCFLAGS += \
+ $(EOLIST)
+
+XDEFINES += \
+ $(EOLIST)
+
+XLFLAGS += \
+ $(EOLIST)
+endif
+
+ifeq "$(RELEASE)" "release"
+XINCDIRS += \
+ $(EOLIST)
+
+XCFLAGS += \
+ $(EOLIST)
+
+XDEFINES += \
+ $(EOLIST)
+
+XLFLAGS += \
+ $(EOLIST)
+endif
+
+#
+# These are used by the link target if an NLM is being generated
+# This is used by the link 'name' directive to name the nlm. If left blank
+# TARGET_nlm (see below) will be used.
+#
+NLM_NAME = session_crypto
+
+#
+# This is used by the link '-desc ' directive.
+# If left blank, NLM_NAME will be used.
+#
+NLM_DESCRIPTION = Apache $(VERSION_STR) Session Crypto Module
+
+#
+# This is used by the '-threadname' directive. If left blank,
+# NLM_NAME Thread will be used.
+#
+NLM_THREAD_NAME = SessionCrypto Module
+
+#
+# If this is specified, it will override VERSION value in
+# $(AP_WORK)/build/NWGNUenvironment.inc
+#
+NLM_VERSION =
+
+#
+# If this is specified, it will override the default of 64K
+#
+NLM_STACK_SIZE = 8192
+
+
+#
+# If this is specified it will be used by the link '-entry' directive
+#
+NLM_ENTRY_SYM =
+
+#
+# If this is specified it will be used by the link '-exit' directive
+#
+NLM_EXIT_SYM =
+
+#
+# If this is specified it will be used by the link '-check' directive
+#
+NLM_CHECK_SYM =
+
+#
+# If these are specified it will be used by the link '-flags' directive
+#
+NLM_FLAGS =
+
+#
+# If this is specified it will be linked in with the XDCData option in the def
+# file instead of the default of $(NWOS)/apache.xdc. XDCData can be disabled
+# by setting APACHE_UNIPROC in the environment
+#
+XDCDATA =
+
+#
+# If there is an NLM target, put it here
+#
+TARGET_nlm = \
+ $(OBJDIR)/$(NLM_NAME).nlm \
+ $(EOLIST)
+
+#
+# If there is an LIB target, put it here
+#
+TARGET_lib = \
+ $(EOLIST)
+
+#
+# These are the OBJ files needed to create the NLM target above.
+# Paths must all use the '/' character
+#
+FILES_nlm_objs = \
+ $(OBJDIR)/mod_session_crypto.o \
+ $(EOLIST)
+
+#
+# These are the LIB files needed to create the NLM target above.
+# These will be added as a library command in the link.opt file.
+#
+FILES_nlm_libs = \
+ $(PRELUDE) \
+ $(EOLIST)
+
+#
+# These are the modules that the above NLM target depends on to load.
+# These will be added as a module command in the link.opt file.
+#
+FILES_nlm_modules = \
+ aprlib \
+ libc \
+ session \
+ $(EOLIST)
+
+#
+# If the nlm has a msg file, put it's path here
+#
+FILE_nlm_msg =
+
+#
+# If the nlm has a hlp file put it's path here
+#
+FILE_nlm_hlp =
+
+#
+# If this is specified, it will override $(NWOS)\copyright.txt.
+#
+FILE_nlm_copyright =
+
+#
+# Any additional imports go here
+#
+FILES_nlm_Ximports = \
+ @aprlib.imp \
+ @httpd.imp \
+ @libc.imp \
+ ap_hook_session_decode \
+ ap_hook_session_encode \
+ ap_hook_session_load \
+ ap_hook_session_save \
+ $(EOLIST)
+
+#
+# Any symbols exported to here
+#
+FILES_nlm_exports = \
+ session_crypto_module \
+ $(EOLIST)
+
+#
+# These are the OBJ files needed to create the LIB target above.
+# Paths must all use the '/' character
+#
+FILES_lib_objs = \
+ $(EOLIST)
+
+#
+# implement targets and dependancies (leave this section alone)
+#
+
+libs :: $(OBJDIR) $(TARGET_lib)
+
+nlms :: libs $(TARGET_nlm)
+
+#
+# Updated this target to create necessary directories and copy files to the
+# correct place. (See $(AP_WORK)/build/NWGNUhead.inc for examples)
+#
+install :: nlms FORCE
+
+#
+# Any specialized rules here
+#
+
+vpath %.c ../arch/netware
+
+#
+# Include the 'tail' makefile that has targets that depend on variables defined
+# in this makefile
+#
+
+include $(APBUILD)/NWGNUtail.inc
+
+
diff --git a/modules/session/NWGNUsession_dbd b/modules/session/NWGNUsession_dbd
new file mode 100644
index 0000000..9473d63
--- /dev/null
+++ b/modules/session/NWGNUsession_dbd
@@ -0,0 +1,253 @@
+#
+# Make sure all needed macro's are defined
+#
+
+#
+# Get the 'head' of the build environment if necessary. This includes default
+# targets and paths to tools
+#
+
+ifndef EnvironmentDefined
+include $(AP_WORK)/build/NWGNUhead.inc
+endif
+
+#
+# These directories will be at the beginning of the include list, followed by
+# INCDIRS
+#
+XINCDIRS += \
+ $(APR)/include \
+ $(APRUTIL)/include \
+ $(SRC)/include \
+ $(STDMOD)/database \
+ $(NWOS) \
+
+#
+# These flags will come after CFLAGS
+#
+XCFLAGS += \
+ $(EOLIST)
+
+#
+# These defines will come after DEFINES
+#
+XDEFINES += \
+ $(EOLIST)
+
+#
+# These flags will be added to the link.opt file
+#
+XLFLAGS += \
+ $(EOLIST)
+
+#
+# These values will be appended to the correct variables based on the value of
+# RELEASE
+#
+ifeq "$(RELEASE)" "debug"
+XINCDIRS += \
+ $(EOLIST)
+
+XCFLAGS += \
+ $(EOLIST)
+
+XDEFINES += \
+ $(EOLIST)
+
+XLFLAGS += \
+ $(EOLIST)
+endif
+
+ifeq "$(RELEASE)" "noopt"
+XINCDIRS += \
+ $(EOLIST)
+
+XCFLAGS += \
+ $(EOLIST)
+
+XDEFINES += \
+ $(EOLIST)
+
+XLFLAGS += \
+ $(EOLIST)
+endif
+
+ifeq "$(RELEASE)" "release"
+XINCDIRS += \
+ $(EOLIST)
+
+XCFLAGS += \
+ $(EOLIST)
+
+XDEFINES += \
+ $(EOLIST)
+
+XLFLAGS += \
+ $(EOLIST)
+endif
+
+#
+# These are used by the link target if an NLM is being generated
+# This is used by the link 'name' directive to name the nlm. If left blank
+# TARGET_nlm (see below) will be used.
+#
+NLM_NAME = session_dbd
+
+#
+# This is used by the link '-desc ' directive.
+# If left blank, NLM_NAME will be used.
+#
+NLM_DESCRIPTION = Apache $(VERSION_STR) Session Cookie Module
+
+#
+# This is used by the '-threadname' directive. If left blank,
+# NLM_NAME Thread will be used.
+#
+NLM_THREAD_NAME = SessionDbd Module
+
+#
+# If this is specified, it will override VERSION value in
+# $(AP_WORK)/build/NWGNUenvironment.inc
+#
+NLM_VERSION =
+
+#
+# If this is specified, it will override the default of 64K
+#
+NLM_STACK_SIZE = 8192
+
+
+#
+# If this is specified it will be used by the link '-entry' directive
+#
+NLM_ENTRY_SYM =
+
+#
+# If this is specified it will be used by the link '-exit' directive
+#
+NLM_EXIT_SYM =
+
+#
+# If this is specified it will be used by the link '-check' directive
+#
+NLM_CHECK_SYM =
+
+#
+# If these are specified it will be used by the link '-flags' directive
+#
+NLM_FLAGS =
+
+#
+# If this is specified it will be linked in with the XDCData option in the def
+# file instead of the default of $(NWOS)/apache.xdc. XDCData can be disabled
+# by setting APACHE_UNIPROC in the environment
+#
+XDCDATA =
+
+#
+# If there is an NLM target, put it here
+#
+TARGET_nlm = \
+ $(OBJDIR)/$(NLM_NAME).nlm \
+ $(EOLIST)
+
+#
+# If there is an LIB target, put it here
+#
+TARGET_lib = \
+ $(EOLIST)
+
+#
+# These are the OBJ files needed to create the NLM target above.
+# Paths must all use the '/' character
+#
+FILES_nlm_objs = \
+ $(OBJDIR)/mod_session_dbd.o \
+ $(EOLIST)
+
+#
+# These are the LIB files needed to create the NLM target above.
+# These will be added as a library command in the link.opt file.
+#
+FILES_nlm_libs = \
+ $(PRELUDE) \
+ $(EOLIST)
+
+#
+# These are the modules that the above NLM target depends on to load.
+# These will be added as a module command in the link.opt file.
+#
+FILES_nlm_modules = \
+ aprlib \
+ libc \
+ session \
+ $(EOLIST)
+
+#
+# If the nlm has a msg file, put it's path here
+#
+FILE_nlm_msg =
+
+#
+# If the nlm has a hlp file put it's path here
+#
+FILE_nlm_hlp =
+
+#
+# If this is specified, it will override $(NWOS)\copyright.txt.
+#
+FILE_nlm_copyright =
+
+#
+# Any additional imports go here
+#
+FILES_nlm_Ximports = \
+ @aprlib.imp \
+ @httpd.imp \
+ @libc.imp \
+ ap_hook_session_load \
+ ap_hook_session_save \
+ $(EOLIST)
+
+#
+# Any symbols exported to here
+#
+FILES_nlm_exports = \
+ session_dbd_module \
+ $(EOLIST)
+
+#
+# These are the OBJ files needed to create the LIB target above.
+# Paths must all use the '/' character
+#
+FILES_lib_objs = \
+ $(EOLIST)
+
+#
+# implement targets and dependancies (leave this section alone)
+#
+
+libs :: $(OBJDIR) $(TARGET_lib)
+
+nlms :: libs $(TARGET_nlm)
+
+#
+# Updated this target to create necessary directories and copy files to the
+# correct place. (See $(AP_WORK)/build/NWGNUhead.inc for examples)
+#
+install :: nlms FORCE
+
+#
+# Any specialized rules here
+#
+
+vpath %.c ../arch/netware
+
+#
+# Include the 'tail' makefile that has targets that depend on variables defined
+# in this makefile
+#
+
+include $(APBUILD)/NWGNUtail.inc
+
+
diff --git a/modules/session/config.m4 b/modules/session/config.m4
new file mode 100644
index 0000000..7a38185
--- /dev/null
+++ b/modules/session/config.m4
@@ -0,0 +1,68 @@
+dnl modules enabled in this directory by default
+
+if test -z "$enable_session" ; then
+ session_mods_enable=most
+else
+ session_mods_enable=$enable_session
+fi
+
+dnl Session
+
+dnl APACHE_MODULE(name, helptext[, objects[, structname[, default[, config]]]])
+
+APACHE_MODPATH_INIT(session)
+
+dnl Session modules; modules that are capable of storing key value pairs in
+dnl various places, such as databases, LDAP, or cookies.
+dnl
+session_cookie_objects='mod_session_cookie.lo'
+session_crypto_objects='mod_session_crypto.lo'
+session_dbd_objects='mod_session_dbd.lo'
+
+case "$host" in
+ *os2*)
+ # OS/2 DLLs must resolve all symbols at build time
+ # and we need some from main session module
+ session_cookie_objects="$session_cookie_objects mod_session.la"
+ session_crypto_objects="$session_crypto_objects mod_session.la"
+ session_dbd_objects="$session_dbd_objects mod_session.la"
+ ;;
+esac
+
+APACHE_MODULE(session, session module, , , most)
+APACHE_MODULE(session_cookie, session cookie module, $session_cookie_objects, , $session_mods_enable,,session)
+
+if test "$enable_session_crypto" != ""; then
+ session_mods_enable_crypto=$enable_session_crypto
+else
+ session_mods_enable_crypto=$session_mods_enable
+fi
+if test "$session_mods_enable_crypto" != "no"; then
+ saved_CPPFLAGS="$CPPFLAGS"
+ CPPFLAGS="$CPPFLAGS $APR_INCLUDES $APU_INCLUDES"
+ AC_TRY_COMPILE([#include <apr_crypto.h>],[
+#if APU_HAVE_CRYPTO == 0
+#error no crypto support
+#endif
+ ], [ap_HAVE_APR_CRYPTO="yes"], [ap_HAVE_APR_CRYPTO="no"])
+ CPPFLAGS="$saved_CPPFLAGS"
+ if test $ap_HAVE_APR_CRYPTO = "no"; then
+ AC_MSG_WARN([Your APR does not include SSL/EVP support. To enable it: configure --with-crypto])
+ if test "$enable_session_crypto" != "" -a "$enable_session_crypto" != "no"; then
+ AC_MSG_ERROR([mod_session_crypto cannot be enabled])
+ fi
+ session_mods_enable_crypto="no"
+ fi
+fi
+APACHE_MODULE(session_crypto, session crypto module, $session_crypto_objects, , $session_mods_enable_crypto, [
+if test "$session_mods_enable_crypto" = "no" ; then
+ enable_session_crypto=no
+fi
+],session)
+
+APACHE_MODULE(session_dbd, session dbd module, $session_dbd_objects, , $session_mods_enable,,session)
+
+APR_ADDTO(INCLUDES, [-I\$(top_srcdir)/$modpath_current])
+
+APACHE_MODPATH_FINISH
+
diff --git a/modules/session/mod_session.c b/modules/session/mod_session.c
new file mode 100644
index 0000000..64e6e4a
--- /dev/null
+++ b/modules/session/mod_session.c
@@ -0,0 +1,674 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "mod_session.h"
+#include "apr_lib.h"
+#include "apr_strings.h"
+#include "util_filter.h"
+#include "http_log.h"
+#include "http_request.h"
+#include "http_protocol.h"
+
+#define SESSION_EXPIRY "expiry"
+#define HTTP_SESSION "HTTP_SESSION"
+
+APR_HOOK_STRUCT(
+ APR_HOOK_LINK(session_load)
+ APR_HOOK_LINK(session_save)
+ APR_HOOK_LINK(session_encode)
+ APR_HOOK_LINK(session_decode)
+)
+APR_IMPLEMENT_EXTERNAL_HOOK_RUN_FIRST(ap, SESSION, int, session_load,
+ (request_rec * r, session_rec ** z), (r, z), DECLINED)
+APR_IMPLEMENT_EXTERNAL_HOOK_RUN_FIRST(ap, SESSION, int, session_save,
+ (request_rec * r, session_rec * z), (r, z), DECLINED)
+APR_IMPLEMENT_EXTERNAL_HOOK_RUN_ALL(ap, SESSION, int, session_encode,
+ (request_rec * r, session_rec * z), (r, z), OK, DECLINED)
+APR_IMPLEMENT_EXTERNAL_HOOK_RUN_ALL(ap, SESSION, int, session_decode,
+ (request_rec * r, session_rec * z), (r, z), OK, DECLINED)
+
+static int session_identity_encode(request_rec * r, session_rec * z);
+static int session_identity_decode(request_rec * r, session_rec * z);
+static int session_fixups(request_rec * r);
+
+/**
+ * Should the session be included within this URL.
+ *
+ * This function tests whether a session is valid for this URL. It uses the
+ * include and exclude arrays to determine whether they should be included.
+ */
+static int session_included(request_rec * r, session_dir_conf * conf)
+{
+
+ const char **includes = (const char **) conf->includes->elts;
+ const char **excludes = (const char **) conf->excludes->elts;
+ int included = 1; /* defaults to included */
+ int i;
+
+ if (conf->includes->nelts) {
+ included = 0;
+ for (i = 0; !included && i < conf->includes->nelts; i++) {
+ const char *include = includes[i];
+ if (strncmp(r->uri, include, strlen(include)) == 0) {
+ included = 1;
+ }
+ }
+ }
+
+ if (conf->excludes->nelts) {
+ for (i = 0; included && i < conf->excludes->nelts; i++) {
+ const char *exclude = excludes[i];
+ if (strncmp(r->uri, exclude, strlen(exclude)) == 0) {
+ included = 0;
+ }
+ }
+ }
+
+ return included;
+}
+
+/**
+ * Load the session.
+ *
+ * If the session doesn't exist, a blank one will be created.
+ *
+ * @param r The request
+ * @param z A pointer to where the session will be written.
+ */
+static apr_status_t ap_session_load(request_rec * r, session_rec ** z)
+{
+
+ session_dir_conf *dconf = ap_get_module_config(r->per_dir_config,
+ &session_module);
+ apr_time_t now;
+ session_rec *zz = NULL;
+ int rv = 0;
+
+ /* is the session enabled? */
+ if (!dconf || !dconf->enabled) {
+ return APR_SUCCESS;
+ }
+
+ /* should the session be loaded at all? */
+ if (!session_included(r, dconf)) {
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01814)
+ "excluded by configuration for: %s", r->uri);
+ return APR_SUCCESS;
+ }
+
+ /* load the session from the session hook */
+ rv = ap_run_session_load(r, &zz);
+ if (DECLINED == rv) {
+ ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(01815)
+ "session is enabled but no session modules have been configured, "
+ "session not loaded: %s", r->uri);
+ return APR_EGENERAL;
+ }
+ else if (OK != rv) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01816)
+ "error while loading the session, "
+ "session not loaded: %s", r->uri);
+ return rv;
+ }
+
+ /* found a session that hasn't expired? */
+ now = apr_time_now();
+
+ if (zz) {
+ /* load the session attibutes */
+ rv = ap_run_session_decode(r, zz);
+
+ /* having a session we cannot decode is just as good as having
+ none at all */
+ if (OK != rv) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01817)
+ "error while decoding the session, "
+ "session not loaded: %s", r->uri);
+ zz = NULL;
+ }
+
+ /* invalidate session if session is expired */
+ if (zz && zz->expiry && zz->expiry < now) {
+ zz = NULL;
+ }
+ }
+
+ /* no luck, create a blank session */
+ if (!zz) {
+ zz = (session_rec *) apr_pcalloc(r->pool, sizeof(session_rec));
+ zz->pool = r->pool;
+ zz->entries = apr_table_make(zz->pool, 10);
+ }
+
+ /* make sure the expiry and maxage are set, if present */
+ if (dconf->maxage) {
+ if (!zz->expiry) {
+ zz->expiry = now + dconf->maxage * APR_USEC_PER_SEC;
+ }
+ zz->maxage = dconf->maxage;
+ }
+
+ *z = zz;
+
+ return APR_SUCCESS;
+
+}
+
+/**
+ * Save the session.
+ *
+ * In most implementations the session is only saved if the dirty flag is
+ * true. This prevents the session being saved unnecessarily.
+ *
+ * @param r The request
+ * @param z A pointer to where the session will be written.
+ */
+static apr_status_t ap_session_save(request_rec * r, session_rec * z)
+{
+ if (z) {
+ apr_time_t now = apr_time_now();
+ int rv = 0;
+
+ session_dir_conf *dconf = ap_get_module_config(r->per_dir_config,
+ &session_module);
+
+ /* sanity checks, should we try save at all? */
+ if (z->written) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01818)
+ "attempt made to save the session twice, "
+ "session not saved: %s", r->uri);
+ return APR_EGENERAL;
+ }
+ if (z->expiry && z->expiry < now) {
+ ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(01819)
+ "attempt made to save a session when the session had already expired, "
+ "session not saved: %s", r->uri);
+ return APR_EGENERAL;
+ }
+
+ /* reset the expiry back to maxage, if the expiry is present */
+ if (dconf->maxage) {
+ z->expiry = now + dconf->maxage * APR_USEC_PER_SEC;
+ z->maxage = dconf->maxage;
+ }
+
+ /* reset the expiry before saving if present */
+ if (z->dirty && z->maxage) {
+ z->expiry = now + z->maxage * APR_USEC_PER_SEC;
+ }
+
+ /* encode the session */
+ rv = ap_run_session_encode(r, z);
+ if (OK != rv) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01820)
+ "error while encoding the session, "
+ "session not saved: %s", r->uri);
+ return rv;
+ }
+
+ /* try the save */
+ rv = ap_run_session_save(r, z);
+ if (DECLINED == rv) {
+ ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(01821)
+ "session is enabled but no session modules have been configured, "
+ "session not saved: %s", r->uri);
+ return APR_EGENERAL;
+ }
+ else if (OK != rv) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01822)
+ "error while saving the session, "
+ "session not saved: %s", r->uri);
+ return rv;
+ }
+ else {
+ z->written = 1;
+ }
+ }
+
+ return APR_SUCCESS;
+
+}
+
+/**
+ * Get a particular value from the session.
+ * @param r The current request.
+ * @param z The current session. If this value is NULL, the session will be
+ * looked up in the request, created if necessary, and saved to the request
+ * notes.
+ * @param key The key to get.
+ * @param value The buffer to write the value to.
+ */
+static apr_status_t ap_session_get(request_rec * r, session_rec * z,
+ const char *key, const char **value)
+{
+ if (!z) {
+ apr_status_t rv;
+ rv = ap_session_load(r, &z);
+ if (APR_SUCCESS != rv) {
+ return rv;
+ }
+ }
+ if (z && z->entries) {
+ *value = apr_table_get(z->entries, key);
+ }
+
+ return OK;
+}
+
+/**
+ * Set a particular value to the session.
+ *
+ * Using this method ensures that the dirty flag is set correctly, so that
+ * the session can be saved efficiently.
+ * @param r The current request.
+ * @param z The current session. If this value is NULL, the session will be
+ * looked up in the request, created if necessary, and saved to the request
+ * notes.
+ * @param key The key to set. The existing key value will be replaced.
+ * @param value The value to set.
+ */
+static apr_status_t ap_session_set(request_rec * r, session_rec * z,
+ const char *key, const char *value)
+{
+ if (!z) {
+ apr_status_t rv;
+ rv = ap_session_load(r, &z);
+ if (APR_SUCCESS != rv) {
+ return rv;
+ }
+ }
+ if (z) {
+ if (value) {
+ apr_table_set(z->entries, key, value);
+ }
+ else {
+ apr_table_unset(z->entries, key);
+ }
+ z->dirty = 1;
+ }
+ return APR_SUCCESS;
+}
+
+static int identity_count(void *v, const char *key, const char *val)
+{
+ int *count = v;
+ *count += strlen(key) * 3 + strlen(val) * 3 + 1;
+ return 1;
+}
+
+static int identity_concat(void *v, const char *key, const char *val)
+{
+ char *slider = v;
+ int length = strlen(slider);
+ slider += length;
+ if (length) {
+ *slider = '&';
+ slider++;
+ }
+ ap_escape_urlencoded_buffer(slider, key);
+ slider += strlen(slider);
+ *slider = '=';
+ slider++;
+ ap_escape_urlencoded_buffer(slider, val);
+ return 1;
+}
+
+/**
+ * Default identity encoding for the session.
+ *
+ * By default, the name value pairs in the session are URLEncoded, separated
+ * by equals, and then in turn separated by ampersand, in the format of an
+ * html form.
+ *
+ * This was chosen to make it easy for external code to unpack a session,
+ * should there be a need to do so.
+ *
+ * @param r The request pointer.
+ * @param z A pointer to where the session will be written.
+ */
+static apr_status_t session_identity_encode(request_rec * r, session_rec * z)
+{
+
+ char *buffer = NULL;
+ int length = 0;
+ if (z->expiry) {
+ char *expiry = apr_psprintf(z->pool, "%" APR_INT64_T_FMT, z->expiry);
+ apr_table_setn(z->entries, SESSION_EXPIRY, expiry);
+ }
+ apr_table_do(identity_count, &length, z->entries, NULL);
+ buffer = apr_pcalloc(r->pool, length + 1);
+ apr_table_do(identity_concat, buffer, z->entries, NULL);
+ z->encoded = buffer;
+ return OK;
+
+}
+
+/**
+ * Default identity decoding for the session.
+ *
+ * By default, the name value pairs in the session are URLEncoded, separated
+ * by equals, and then in turn separated by ampersand, in the format of an
+ * html form.
+ *
+ * This was chosen to make it easy for external code to unpack a session,
+ * should there be a need to do so.
+ *
+ * This function reverses that process, and populates the session table.
+ *
+ * Name / value pairs that are not encoded properly are ignored.
+ *
+ * @param r The request pointer.
+ * @param z A pointer to where the session will be written.
+ */
+static apr_status_t session_identity_decode(request_rec * r, session_rec * z)
+{
+
+ char *last = NULL;
+ char *encoded, *pair;
+ const char *sep = "&";
+
+ /* sanity check - anything to decode? */
+ if (!z->encoded) {
+ return OK;
+ }
+
+ /* decode what we have */
+ encoded = apr_pstrdup(r->pool, z->encoded);
+ pair = apr_strtok(encoded, sep, &last);
+ while (pair && pair[0]) {
+ char *plast = NULL;
+ const char *psep = "=";
+ char *key = apr_strtok(pair, psep, &plast);
+ char *val = apr_strtok(NULL, psep, &plast);
+ if (key && *key) {
+ if (!val || !*val) {
+ apr_table_unset(z->entries, key);
+ }
+ else if (!ap_unescape_urlencoded(key) && !ap_unescape_urlencoded(val)) {
+ if (!strcmp(SESSION_EXPIRY, key)) {
+ z->expiry = (apr_time_t) apr_atoi64(val);
+ }
+ else {
+ apr_table_set(z->entries, key, val);
+ }
+ }
+ }
+ pair = apr_strtok(NULL, sep, &last);
+ }
+ z->encoded = NULL;
+ return OK;
+
+}
+
+/**
+ * Ensure any changes to the session are committed.
+ *
+ * This is done in an output filter so that our options for where to
+ * store the session can include storing the session within a cookie:
+ * As an HTTP header, the cookie must be set before the output is
+ * written, but after the handler is run.
+ *
+ * NOTE: It is possible for internal redirects to cause more than one
+ * request to be present, and each request might have a session
+ * defined. We need to go through each session in turn, and save each
+ * one.
+ *
+ * The same session might appear in more than one request. The first
+ * attempt to save the session will be called
+ */
+static apr_status_t session_output_filter(ap_filter_t * f,
+ apr_bucket_brigade * in)
+{
+
+ /* save all the sessions in all the requests */
+ request_rec *r = f->r->main;
+ if (!r) {
+ r = f->r;
+ }
+ while (r) {
+ session_rec *z = NULL;
+ session_dir_conf *conf = ap_get_module_config(r->per_dir_config,
+ &session_module);
+
+ /* load the session, or create one if necessary */
+ /* when unset or on error, z will be NULL */
+ ap_session_load(r, &z);
+ if (!z || z->written) {
+ r = r->next;
+ continue;
+ }
+
+ /* if a header was specified, insert the new values from the header */
+ if (conf->header_set) {
+ const char *override = apr_table_get(r->err_headers_out, conf->header);
+ if (!override) {
+ override = apr_table_get(r->headers_out, conf->header);
+ }
+ if (override) {
+ apr_table_unset(r->err_headers_out, conf->header);
+ apr_table_unset(r->headers_out, conf->header);
+ z->encoded = override;
+ z->dirty = 1;
+ session_identity_decode(r, z);
+ }
+ }
+
+ /* save away the session, and we're done */
+ /* when unset or on error, we've complained to the log */
+ ap_session_save(r, z);
+
+ r = r->next;
+ }
+
+ /* remove ourselves from the filter chain */
+ ap_remove_output_filter(f);
+
+ /* send the data up the stack */
+ return ap_pass_brigade(f->next, in);
+
+}
+
+/**
+ * Insert the output filter.
+ */
+static void session_insert_output_filter(request_rec * r)
+{
+ ap_add_output_filter("MOD_SESSION_OUT", NULL, r, r->connection);
+}
+
+/**
+ * Fixups hook.
+ *
+ * Load the session within a fixup - this ensures that the session is
+ * properly loaded prior to the handler being called.
+ *
+ * The fixup is also responsible for injecting the session into the CGI
+ * environment, should the admin have configured it so.
+ *
+ * @param r The request
+ */
+static int session_fixups(request_rec * r)
+{
+ session_dir_conf *conf = ap_get_module_config(r->per_dir_config,
+ &session_module);
+
+ session_rec *z = NULL;
+
+ /* if an error occurs or no session has been configured, we ignore
+ * the broken session and allow it to be recreated from scratch on save
+ * if necessary.
+ */
+ ap_session_load(r, &z);
+
+ if (conf->env) {
+ if (z) {
+ session_identity_encode(r, z);
+ if (z->encoded) {
+ apr_table_set(r->subprocess_env, HTTP_SESSION, z->encoded);
+ z->encoded = NULL;
+ }
+ }
+ apr_table_unset(r->headers_in, "Session");
+ }
+
+ return OK;
+
+}
+
+
+static void *create_session_dir_config(apr_pool_t * p, char *dummy)
+{
+ session_dir_conf *new =
+ (session_dir_conf *) apr_pcalloc(p, sizeof(session_dir_conf));
+
+ new->includes = apr_array_make(p, 10, sizeof(const char **));
+ new->excludes = apr_array_make(p, 10, sizeof(const char **));
+
+ return (void *) new;
+}
+
+static void *merge_session_dir_config(apr_pool_t * p, void *basev, void *addv)
+{
+ session_dir_conf *new = (session_dir_conf *) apr_pcalloc(p, sizeof(session_dir_conf));
+ session_dir_conf *add = (session_dir_conf *) addv;
+ session_dir_conf *base = (session_dir_conf *) basev;
+
+ new->enabled = (add->enabled_set == 0) ? base->enabled : add->enabled;
+ new->enabled_set = add->enabled_set || base->enabled_set;
+ new->maxage = (add->maxage_set == 0) ? base->maxage : add->maxage;
+ new->maxage_set = add->maxage_set || base->maxage_set;
+ new->header = (add->header_set == 0) ? base->header : add->header;
+ new->header_set = add->header_set || base->header_set;
+ new->env = (add->env_set == 0) ? base->env : add->env;
+ new->env_set = add->env_set || base->env_set;
+ new->includes = apr_array_append(p, base->includes, add->includes);
+ new->excludes = apr_array_append(p, base->excludes, add->excludes);
+
+ return new;
+}
+
+
+static const char *
+ set_session_enable(cmd_parms * parms, void *dconf, int flag)
+{
+ session_dir_conf *conf = dconf;
+
+ conf->enabled = flag;
+ conf->enabled_set = 1;
+
+ return NULL;
+}
+
+static const char *
+ set_session_maxage(cmd_parms * parms, void *dconf, const char *arg)
+{
+ session_dir_conf *conf = dconf;
+
+ conf->maxage = atol(arg);
+ conf->maxage_set = 1;
+
+ return NULL;
+}
+
+static const char *
+ set_session_header(cmd_parms * parms, void *dconf, const char *arg)
+{
+ session_dir_conf *conf = dconf;
+
+ conf->header = arg;
+ conf->header_set = 1;
+
+ return NULL;
+}
+
+static const char *
+ set_session_env(cmd_parms * parms, void *dconf, int flag)
+{
+ session_dir_conf *conf = dconf;
+
+ conf->env = flag;
+ conf->env_set = 1;
+
+ return NULL;
+}
+
+static const char *add_session_include(cmd_parms * cmd, void *dconf, const char *f)
+{
+ session_dir_conf *conf = dconf;
+
+ const char **new = apr_array_push(conf->includes);
+ *new = f;
+
+ return NULL;
+}
+
+static const char *add_session_exclude(cmd_parms * cmd, void *dconf, const char *f)
+{
+ session_dir_conf *conf = dconf;
+
+ const char **new = apr_array_push(conf->excludes);
+ *new = f;
+
+ return NULL;
+}
+
+
+static const command_rec session_cmds[] =
+{
+ AP_INIT_FLAG("Session", set_session_enable, NULL, RSRC_CONF|OR_AUTHCFG,
+ "on if a session should be maintained for these URLs"),
+ AP_INIT_TAKE1("SessionMaxAge", set_session_maxage, NULL, RSRC_CONF|OR_AUTHCFG,
+ "length of time for which a session should be valid. Zero to disable"),
+ AP_INIT_TAKE1("SessionHeader", set_session_header, NULL, RSRC_CONF|OR_AUTHCFG,
+ "output header, if present, whose contents will be injected into the session."),
+ AP_INIT_FLAG("SessionEnv", set_session_env, NULL, RSRC_CONF|OR_AUTHCFG,
+ "on if a session should be written to the CGI environment. Defaults to off"),
+ AP_INIT_TAKE1("SessionInclude", add_session_include, NULL, RSRC_CONF|OR_AUTHCFG,
+ "URL prefixes to include in the session. Defaults to all URLs"),
+ AP_INIT_TAKE1("SessionExclude", add_session_exclude, NULL, RSRC_CONF|OR_AUTHCFG,
+ "URL prefixes to exclude from the session. Defaults to no URLs"),
+ {NULL}
+};
+
+static void register_hooks(apr_pool_t * p)
+{
+ ap_register_output_filter("MOD_SESSION_OUT", session_output_filter,
+ NULL, AP_FTYPE_CONTENT_SET);
+ ap_hook_insert_filter(session_insert_output_filter, NULL, NULL,
+ APR_HOOK_MIDDLE);
+ ap_hook_insert_error_filter(session_insert_output_filter,
+ NULL, NULL, APR_HOOK_MIDDLE);
+ ap_hook_fixups(session_fixups, NULL, NULL, APR_HOOK_MIDDLE);
+ ap_hook_session_encode(session_identity_encode, NULL, NULL,
+ APR_HOOK_REALLY_FIRST);
+ ap_hook_session_decode(session_identity_decode, NULL, NULL,
+ APR_HOOK_REALLY_LAST);
+ APR_REGISTER_OPTIONAL_FN(ap_session_get);
+ APR_REGISTER_OPTIONAL_FN(ap_session_set);
+ APR_REGISTER_OPTIONAL_FN(ap_session_load);
+ APR_REGISTER_OPTIONAL_FN(ap_session_save);
+}
+
+AP_DECLARE_MODULE(session) =
+{
+ STANDARD20_MODULE_STUFF,
+ create_session_dir_config, /* dir config creater */
+ merge_session_dir_config, /* dir merger --- default is to override */
+ NULL, /* server config */
+ NULL, /* merge server config */
+ session_cmds, /* command apr_table_t */
+ register_hooks /* register hooks */
+};
diff --git a/modules/session/mod_session.dep b/modules/session/mod_session.dep
new file mode 100644
index 0000000..d773317
--- /dev/null
+++ b/modules/session/mod_session.dep
@@ -0,0 +1,56 @@
+# Microsoft Developer Studio Generated Dependency File, included by mod_session.mak
+
+..\..\build\win32\httpd.rc : \
+ "..\..\include\ap_release.h"\
+
+
+.\mod_session.c : \
+ "..\..\include\ap_config.h"\
+ "..\..\include\ap_config_layout.h"\
+ "..\..\include\ap_hooks.h"\
+ "..\..\include\ap_mmn.h"\
+ "..\..\include\ap_regex.h"\
+ "..\..\include\ap_release.h"\
+ "..\..\include\apache_noprobes.h"\
+ "..\..\include\http_config.h"\
+ "..\..\include\http_log.h"\
+ "..\..\include\http_protocol.h"\
+ "..\..\include\http_request.h"\
+ "..\..\include\httpd.h"\
+ "..\..\include\os.h"\
+ "..\..\include\util_cfgtree.h"\
+ "..\..\include\util_filter.h"\
+ "..\..\srclib\apr-util\include\apr_buckets.h"\
+ "..\..\srclib\apr-util\include\apr_hooks.h"\
+ "..\..\srclib\apr-util\include\apr_optional.h"\
+ "..\..\srclib\apr-util\include\apr_optional_hooks.h"\
+ "..\..\srclib\apr-util\include\apr_uri.h"\
+ "..\..\srclib\apr-util\include\apr_uuid.h"\
+ "..\..\srclib\apr-util\include\apu.h"\
+ "..\..\srclib\apr\include\apr.h"\
+ "..\..\srclib\apr\include\apr_allocator.h"\
+ "..\..\srclib\apr\include\apr_dso.h"\
+ "..\..\srclib\apr\include\apr_errno.h"\
+ "..\..\srclib\apr\include\apr_file_info.h"\
+ "..\..\srclib\apr\include\apr_file_io.h"\
+ "..\..\srclib\apr\include\apr_general.h"\
+ "..\..\srclib\apr\include\apr_global_mutex.h"\
+ "..\..\srclib\apr\include\apr_inherit.h"\
+ "..\..\srclib\apr\include\apr_lib.h"\
+ "..\..\srclib\apr\include\apr_mmap.h"\
+ "..\..\srclib\apr\include\apr_network_io.h"\
+ "..\..\srclib\apr\include\apr_poll.h"\
+ "..\..\srclib\apr\include\apr_pools.h"\
+ "..\..\srclib\apr\include\apr_portable.h"\
+ "..\..\srclib\apr\include\apr_proc_mutex.h"\
+ "..\..\srclib\apr\include\apr_ring.h"\
+ "..\..\srclib\apr\include\apr_shm.h"\
+ "..\..\srclib\apr\include\apr_strings.h"\
+ "..\..\srclib\apr\include\apr_tables.h"\
+ "..\..\srclib\apr\include\apr_thread_mutex.h"\
+ "..\..\srclib\apr\include\apr_thread_proc.h"\
+ "..\..\srclib\apr\include\apr_time.h"\
+ "..\..\srclib\apr\include\apr_user.h"\
+ "..\..\srclib\apr\include\apr_want.h"\
+ ".\mod_session.h"\
+
diff --git a/modules/session/mod_session.dsp b/modules/session/mod_session.dsp
new file mode 100644
index 0000000..69dca0f
--- /dev/null
+++ b/modules/session/mod_session.dsp
@@ -0,0 +1,115 @@
+# Microsoft Developer Studio Project File - Name="mod_session" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=mod_session - Win32 Release
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "mod_session.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "mod_session.mak" CFG="mod_session - Win32 Release"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "mod_session - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "mod_session - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "mod_session - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c
+# ADD CPP /nologo /MD /W3 /O2 /Oy- /Zi /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "SESSION_DECLARE_EXPORT" /Fd"Release\mod_session_src" /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /fo"Release/mod_session.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_session.so" /d LONG_NAME="session_module for Apache"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /out:".\Release\mod_session.so" /base:@..\..\os\win32\BaseAddr.ref,mod_session.so
+# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Release\mod_session.so" /base:@..\..\os\win32\BaseAddr.ref,mod_session.so /opt:ref
+# Begin Special Build Tool
+TargetPath=.\Release\mod_session.so
+SOURCE="$(InputPath)"
+PostBuild_Desc=Embed .manifest
+PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
+# End Special Build Tool
+
+!ELSEIF "$(CFG)" == "mod_session - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MDd /W3 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
+# ADD CPP /nologo /MDd /W3 /EHsc /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "SESSION_DECLARE_EXPORT" /Fd"Debug\mod_session_src" /FD /c
+# ADD BASE MTL /nologo /D "_DEBUG" /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /fo"Debug/mod_session.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_session.so" /d LONG_NAME="session_module for Apache"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_session.so" /base:@..\..\os\win32\BaseAddr.ref,mod_session.so
+# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_session.so" /base:@..\..\os\win32\BaseAddr.ref,mod_session.so
+# Begin Special Build Tool
+TargetPath=.\Debug\mod_session.so
+SOURCE="$(InputPath)"
+PostBuild_Desc=Embed .manifest
+PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
+# End Special Build Tool
+
+!ENDIF
+
+# Begin Target
+
+# Name "mod_session - Win32 Release"
+# Name "mod_session - Win32 Debug"
+# Begin Source File
+
+SOURCE=.\mod_session.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\mod_session.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\build\win32\httpd.rc
+# End Source File
+# End Target
+# End Project
diff --git a/modules/session/mod_session.h b/modules/session/mod_session.h
new file mode 100644
index 0000000..a6dd5e9
--- /dev/null
+++ b/modules/session/mod_session.h
@@ -0,0 +1,186 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MOD_SESSION_H
+#define MOD_SESSION_H
+
+/* Create a set of SESSION_DECLARE(type), SESSION_DECLARE_NONSTD(type) and
+ * SESSION_DECLARE_DATA with appropriate export and import tags for the platform
+ */
+#if !defined(WIN32)
+#define SESSION_DECLARE(type) type
+#define SESSION_DECLARE_NONSTD(type) type
+#define SESSION_DECLARE_DATA
+#elif defined(SESSION_DECLARE_STATIC)
+#define SESSION_DECLARE(type) type __stdcall
+#define SESSION_DECLARE_NONSTD(type) type
+#define SESSION_DECLARE_DATA
+#elif defined(SESSION_DECLARE_EXPORT)
+#define SESSION_DECLARE(type) __declspec(dllexport) type __stdcall
+#define SESSION_DECLARE_NONSTD(type) __declspec(dllexport) type
+#define SESSION_DECLARE_DATA __declspec(dllexport)
+#else
+#define SESSION_DECLARE(type) __declspec(dllimport) type __stdcall
+#define SESSION_DECLARE_NONSTD(type) __declspec(dllimport) type
+#define SESSION_DECLARE_DATA __declspec(dllimport)
+#endif
+
+/**
+ * @file mod_session.h
+ * @brief Session Module for Apache
+ *
+ * @defgroup MOD_SESSION mod_session
+ * @ingroup APACHE_MODS
+ * @{
+ */
+
+#include "apr_hooks.h"
+#include "apr_optional.h"
+#include "apr_tables.h"
+#include "apr_uuid.h"
+#include "apr_pools.h"
+#include "apr_time.h"
+
+#include "httpd.h"
+#include "http_config.h"
+#include "ap_config.h"
+
+#define MOD_SESSION_NOTES_KEY "mod_session_key"
+
+/**
+ * Define the name of a username stored in the session, so that modules interested
+ * in the username can find it in a standard place.
+ */
+#define MOD_SESSION_USER "user"
+
+/**
+ * Define the name of a password stored in the session, so that modules interested
+ * in the password can find it in a standard place.
+ */
+#define MOD_SESSION_PW "pw"
+
+/**
+ * A session structure.
+ *
+ * At the core of the session is a set of name value pairs making up the
+ * session.
+ *
+ * The session might be uniquely identified by an anonymous uuid, or
+ * a remote_user value, or both.
+ */
+typedef struct {
+ apr_pool_t *pool; /* pool to be used for this session */
+ apr_uuid_t *uuid; /* anonymous uuid of this particular session */
+ const char *remote_user; /* user who owns this particular session */
+ apr_table_t *entries; /* key value pairs */
+ const char *encoded; /* the encoded version of the key value pairs */
+ apr_time_t expiry; /* if > 0, the time of expiry of this session */
+ long maxage; /* if > 0, the maxage of the session, from
+ * which expiry is calculated */
+ int dirty; /* dirty flag */
+ int cached; /* true if this session was loaded from a
+ * cache of some kind */
+ int written; /* true if this session has already been
+ * written */
+} session_rec;
+
+/**
+ * Structure to carry the per-dir session config.
+ */
+typedef struct {
+ int enabled; /* whether the session has been enabled for
+ * this directory */
+ int enabled_set;
+ long maxage; /* seconds until session expiry */
+ int maxage_set;
+ const char *header; /* header to inject session */
+ int header_set;
+ int env; /* whether the session has been enabled for
+ * this directory */
+ int env_set;
+ apr_array_header_t *includes; /* URL prefixes to be included. All
+ * URLs included if empty */
+ apr_array_header_t *excludes; /* URL prefixes to be excluded. No
+ * URLs excluded if empty */
+} session_dir_conf;
+
+/**
+ * Hook to load the session.
+ *
+ * If the session doesn't exist, a blank one will be created.
+ *
+ * @param r The request
+ * @param z A pointer to where the session will be written.
+ */
+APR_DECLARE_EXTERNAL_HOOK(ap, SESSION, apr_status_t, session_load,
+ (request_rec * r, session_rec ** z))
+
+/**
+ * Hook to save the session.
+ *
+ * In most implementations the session is only saved if the dirty flag is
+ * true. This prevents the session being saved unnecessarily.
+ *
+ * @param r The request
+ * @param z A pointer to where the session will be written.
+ */
+APR_DECLARE_EXTERNAL_HOOK(ap, SESSION, apr_status_t, session_save,
+ (request_rec * r, session_rec * z))
+
+/**
+ * Hook to encode the session.
+ *
+ * In the default implementation, the key value pairs are encoded using
+ * key value pairs separated by equals, in turn separated by ampersand,
+ * like a web form.
+ *
+ * @param r The request
+ * @param z A pointer to where the session will be written.
+ */
+APR_DECLARE_EXTERNAL_HOOK(ap, SESSION, apr_status_t, session_encode,
+ (request_rec * r, session_rec * z))
+
+/**
+ * Hook to decode the session.
+ *
+ * In the default implementation, the key value pairs are encoded using
+ * key value pairs separated by equals, in turn separated by ampersand,
+ * like a web form.
+ *
+ * @param r The request
+ * @param z A pointer to where the session will be written.
+ */
+APR_DECLARE_EXTERNAL_HOOK(ap, SESSION, apr_status_t, session_decode,
+ (request_rec * r, session_rec * z))
+
+APR_DECLARE_OPTIONAL_FN(
+ apr_status_t,
+ ap_session_get,
+ (request_rec * r, session_rec * z, const char *key, const char **value));
+APR_DECLARE_OPTIONAL_FN(apr_status_t, ap_session_set,
+ (request_rec * r, session_rec * z, const char *key, const char *value));
+APR_DECLARE_OPTIONAL_FN(apr_status_t, ap_session_load,
+ (request_rec *, session_rec **));
+APR_DECLARE_OPTIONAL_FN(apr_status_t, ap_session_save,
+ (request_rec *, session_rec *));
+
+/**
+ * The name of the module.
+ */
+extern module AP_MODULE_DECLARE_DATA session_module;
+
+#endif /* MOD_SESSION_H */
+/** @} */
diff --git a/modules/session/mod_session.mak b/modules/session/mod_session.mak
new file mode 100644
index 0000000..ce92fa6
--- /dev/null
+++ b/modules/session/mod_session.mak
@@ -0,0 +1,353 @@
+# Microsoft Developer Studio Generated NMAKE File, Based on mod_session.dsp
+!IF "$(CFG)" == ""
+CFG=mod_session - Win32 Release
+!MESSAGE No configuration specified. Defaulting to mod_session - Win32 Release.
+!ENDIF
+
+!IF "$(CFG)" != "mod_session - Win32 Release" && "$(CFG)" != "mod_session - Win32 Debug"
+!MESSAGE Invalid configuration "$(CFG)" specified.
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "mod_session.mak" CFG="mod_session - Win32 Release"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "mod_session - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "mod_session - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+!ERROR An invalid configuration is specified.
+!ENDIF
+
+!IF "$(OS)" == "Windows_NT"
+NULL=
+!ELSE
+NULL=nul
+!ENDIF
+
+!IF "$(CFG)" == "mod_session - Win32 Release"
+
+OUTDIR=.\Release
+INTDIR=.\Release
+DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
+# Begin Custom Macros
+OutDir=.\Release
+# End Custom Macros
+
+!IF "$(RECURSE)" == "0"
+
+ALL : "$(OUTDIR)\mod_session.so" "$(DS_POSTBUILD_DEP)"
+
+!ELSE
+
+ALL : "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_session.so" "$(DS_POSTBUILD_DEP)"
+
+!ENDIF
+
+!IF "$(RECURSE)" == "1"
+CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN"
+!ELSE
+CLEAN :
+!ENDIF
+ -@erase "$(INTDIR)\mod_session.obj"
+ -@erase "$(INTDIR)\mod_session.res"
+ -@erase "$(INTDIR)\mod_session_src.idb"
+ -@erase "$(INTDIR)\mod_session_src.pdb"
+ -@erase "$(OUTDIR)\mod_session.exp"
+ -@erase "$(OUTDIR)\mod_session.lib"
+ -@erase "$(OUTDIR)\mod_session.pdb"
+ -@erase "$(OUTDIR)\mod_session.so"
+
+"$(OUTDIR)" :
+ if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
+
+CPP=cl.exe
+CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "SESSION_DECLARE_EXPORT" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_session_src" /FD /c
+
+.c{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.c{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+MTL=midl.exe
+MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32
+RSC=rc.exe
+RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_session.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_session.so" /d LONG_NAME="session_module for Apache"
+BSC32=bscmake.exe
+BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_session.bsc"
+BSC32_SBRS= \
+
+LINK32=link.exe
+LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_session.pdb" /debug /out:"$(OUTDIR)\mod_session.so" /implib:"$(OUTDIR)\mod_session.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_session.so /opt:ref
+LINK32_OBJS= \
+ "$(INTDIR)\mod_session.obj" \
+ "$(INTDIR)\mod_session.res" \
+ "..\..\srclib\apr\Release\libapr-1.lib" \
+ "..\..\srclib\apr-util\Release\libaprutil-1.lib" \
+ "..\..\Release\libhttpd.lib"
+
+"$(OUTDIR)\mod_session.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
+ $(LINK32) @<<
+ $(LINK32_FLAGS) $(LINK32_OBJS)
+<<
+
+TargetPath=.\Release\mod_session.so
+SOURCE="$(InputPath)"
+PostBuild_Desc=Embed .manifest
+DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
+
+# Begin Custom Macros
+OutDir=.\Release
+# End Custom Macros
+
+"$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_session.so"
+ if exist .\Release\mod_session.so.manifest mt.exe -manifest .\Release\mod_session.so.manifest -outputresource:.\Release\mod_session.so;2
+ echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
+
+!ELSEIF "$(CFG)" == "mod_session - Win32 Debug"
+
+OUTDIR=.\Debug
+INTDIR=.\Debug
+DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
+# Begin Custom Macros
+OutDir=.\Debug
+# End Custom Macros
+
+!IF "$(RECURSE)" == "0"
+
+ALL : "$(OUTDIR)\mod_session.so" "$(DS_POSTBUILD_DEP)"
+
+!ELSE
+
+ALL : "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_session.so" "$(DS_POSTBUILD_DEP)"
+
+!ENDIF
+
+!IF "$(RECURSE)" == "1"
+CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN"
+!ELSE
+CLEAN :
+!ENDIF
+ -@erase "$(INTDIR)\mod_session.obj"
+ -@erase "$(INTDIR)\mod_session.res"
+ -@erase "$(INTDIR)\mod_session_src.idb"
+ -@erase "$(INTDIR)\mod_session_src.pdb"
+ -@erase "$(OUTDIR)\mod_session.exp"
+ -@erase "$(OUTDIR)\mod_session.lib"
+ -@erase "$(OUTDIR)\mod_session.pdb"
+ -@erase "$(OUTDIR)\mod_session.so"
+
+"$(OUTDIR)" :
+ if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
+
+CPP=cl.exe
+CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "SESSION_DECLARE_EXPORT" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_session_src" /FD /EHsc /c
+
+.c{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.c{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+MTL=midl.exe
+MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32
+RSC=rc.exe
+RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_session.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_session.so" /d LONG_NAME="session_module for Apache"
+BSC32=bscmake.exe
+BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_session.bsc"
+BSC32_SBRS= \
+
+LINK32=link.exe
+LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_session.pdb" /debug /out:"$(OUTDIR)\mod_session.so" /implib:"$(OUTDIR)\mod_session.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_session.so
+LINK32_OBJS= \
+ "$(INTDIR)\mod_session.obj" \
+ "$(INTDIR)\mod_session.res" \
+ "..\..\srclib\apr\Debug\libapr-1.lib" \
+ "..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
+ "..\..\Debug\libhttpd.lib"
+
+"$(OUTDIR)\mod_session.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
+ $(LINK32) @<<
+ $(LINK32_FLAGS) $(LINK32_OBJS)
+<<
+
+TargetPath=.\Debug\mod_session.so
+SOURCE="$(InputPath)"
+PostBuild_Desc=Embed .manifest
+DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
+
+# Begin Custom Macros
+OutDir=.\Debug
+# End Custom Macros
+
+"$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_session.so"
+ if exist .\Debug\mod_session.so.manifest mt.exe -manifest .\Debug\mod_session.so.manifest -outputresource:.\Debug\mod_session.so;2
+ echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
+
+!ENDIF
+
+
+!IF "$(NO_EXTERNAL_DEPS)" != "1"
+!IF EXISTS("mod_session.dep")
+!INCLUDE "mod_session.dep"
+!ELSE
+!MESSAGE Warning: cannot find "mod_session.dep"
+!ENDIF
+!ENDIF
+
+
+!IF "$(CFG)" == "mod_session - Win32 Release" || "$(CFG)" == "mod_session - Win32 Debug"
+
+!IF "$(CFG)" == "mod_session - Win32 Release"
+
+"libapr - Win32 Release" :
+ cd ".\..\..\srclib\apr"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release"
+ cd "..\..\modules\session"
+
+"libapr - Win32 ReleaseCLEAN" :
+ cd ".\..\..\srclib\apr"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN
+ cd "..\..\modules\session"
+
+!ELSEIF "$(CFG)" == "mod_session - Win32 Debug"
+
+"libapr - Win32 Debug" :
+ cd ".\..\..\srclib\apr"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug"
+ cd "..\..\modules\session"
+
+"libapr - Win32 DebugCLEAN" :
+ cd ".\..\..\srclib\apr"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN
+ cd "..\..\modules\session"
+
+!ENDIF
+
+!IF "$(CFG)" == "mod_session - Win32 Release"
+
+"libaprutil - Win32 Release" :
+ cd ".\..\..\srclib\apr-util"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release"
+ cd "..\..\modules\session"
+
+"libaprutil - Win32 ReleaseCLEAN" :
+ cd ".\..\..\srclib\apr-util"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN
+ cd "..\..\modules\session"
+
+!ELSEIF "$(CFG)" == "mod_session - Win32 Debug"
+
+"libaprutil - Win32 Debug" :
+ cd ".\..\..\srclib\apr-util"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug"
+ cd "..\..\modules\session"
+
+"libaprutil - Win32 DebugCLEAN" :
+ cd ".\..\..\srclib\apr-util"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN
+ cd "..\..\modules\session"
+
+!ENDIF
+
+!IF "$(CFG)" == "mod_session - Win32 Release"
+
+"libhttpd - Win32 Release" :
+ cd ".\..\.."
+ $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release"
+ cd ".\modules\session"
+
+"libhttpd - Win32 ReleaseCLEAN" :
+ cd ".\..\.."
+ $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN
+ cd ".\modules\session"
+
+!ELSEIF "$(CFG)" == "mod_session - Win32 Debug"
+
+"libhttpd - Win32 Debug" :
+ cd ".\..\.."
+ $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug"
+ cd ".\modules\session"
+
+"libhttpd - Win32 DebugCLEAN" :
+ cd ".\..\.."
+ $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN
+ cd ".\modules\session"
+
+!ENDIF
+
+SOURCE=..\..\build\win32\httpd.rc
+
+!IF "$(CFG)" == "mod_session - Win32 Release"
+
+
+"$(INTDIR)\mod_session.res" : $(SOURCE) "$(INTDIR)"
+ $(RSC) /l 0x409 /fo"$(INTDIR)\mod_session.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_session.so" /d LONG_NAME="session_module for Apache" $(SOURCE)
+
+
+!ELSEIF "$(CFG)" == "mod_session - Win32 Debug"
+
+
+"$(INTDIR)\mod_session.res" : $(SOURCE) "$(INTDIR)"
+ $(RSC) /l 0x409 /fo"$(INTDIR)\mod_session.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_session.so" /d LONG_NAME="session_module for Apache" $(SOURCE)
+
+
+!ENDIF
+
+SOURCE=.\mod_session.c
+
+"$(INTDIR)\mod_session.obj" : $(SOURCE) "$(INTDIR)"
+
+
+
+!ENDIF
+
diff --git a/modules/session/mod_session_cookie.c b/modules/session/mod_session_cookie.c
new file mode 100644
index 0000000..a010ee7
--- /dev/null
+++ b/modules/session/mod_session_cookie.c
@@ -0,0 +1,284 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "mod_session.h"
+#include "apr_lib.h"
+#include "apr_strings.h"
+#include "http_log.h"
+#include "util_cookies.h"
+
+#define MOD_SESSION_COOKIE "mod_session_cookie"
+
+module AP_MODULE_DECLARE_DATA session_cookie_module;
+
+/**
+ * Structure to carry the per-dir session config.
+ */
+typedef struct {
+ const char *name;
+ int name_set;
+ const char *name_attrs;
+ const char *name2;
+ int name2_set;
+ const char *name2_attrs;
+ int remove;
+ int remove_set;
+} session_cookie_dir_conf;
+
+/**
+ * Set the cookie and embed the session within it.
+ *
+ * This function adds an RFC2109 compliant Set-Cookie header for
+ * the cookie specified in SessionCookieName, and an RFC2965 compliant
+ * Set-Cookie2 header for the cookie specified in SessionCookieName2.
+ *
+ * If specified, the optional cookie attributes will be added to
+ * each cookie. If defaults are not specified, DEFAULT_ATTRS
+ * will be used.
+ *
+ * On success, this method will return APR_SUCCESS.
+ *
+ * @param r The request pointer.
+ * @param z A pointer to where the session will be written.
+ */
+static apr_status_t session_cookie_save(request_rec * r, session_rec * z)
+{
+
+ session_cookie_dir_conf *conf = ap_get_module_config(r->per_dir_config,
+ &session_cookie_module);
+
+ /* don't cache auth protected pages */
+ apr_table_addn(r->headers_out, "Cache-Control", "no-cache");
+
+ /* create RFC2109 compliant cookie */
+ if (conf->name_set) {
+ if (z->encoded && z->encoded[0]) {
+ ap_cookie_write(r, conf->name, z->encoded, conf->name_attrs,
+ z->maxage, r->err_headers_out,
+ NULL);
+ }
+ else {
+ ap_cookie_remove(r, conf->name, conf->name_attrs, r->headers_out,
+ r->err_headers_out, NULL);
+ }
+ }
+
+ /* create RFC2965 compliant cookie */
+ if (conf->name2_set) {
+ if (z->encoded && z->encoded[0]) {
+ ap_cookie_write2(r, conf->name2, z->encoded, conf->name2_attrs,
+ z->maxage, r->err_headers_out,
+ NULL);
+ }
+ else {
+ ap_cookie_remove2(r, conf->name2, conf->name2_attrs,
+ r->headers_out, r->err_headers_out, NULL);
+ }
+ }
+
+ if (conf->name_set || conf->name2_set) {
+ return OK;
+ }
+ return DECLINED;
+
+}
+
+/**
+ * Isolate the cookie with the name "name", and if present, extract
+ * the payload from the cookie.
+ *
+ * If the cookie is found, the cookie and any other cookies with the
+ * same name are removed from the cookies passed in the request, so
+ * that credentials are not leaked to a backend server or process.
+ *
+ * A missing or malformed cookie will cause this function to return
+ * APR_EGENERAL.
+ *
+ * On success, this returns APR_SUCCESS.
+ */
+static apr_status_t session_cookie_load(request_rec * r, session_rec ** z)
+{
+
+ session_cookie_dir_conf *conf = ap_get_module_config(r->per_dir_config,
+ &session_cookie_module);
+
+ session_rec *zz = NULL;
+ const char *val = NULL;
+ const char *note = NULL;
+ const char *name = NULL;
+ request_rec *m = r;
+
+ /* find the first redirect */
+ while (m->prev) {
+ m = m->prev;
+ }
+ /* find the main request */
+ while (m->main) {
+ m = m->main;
+ }
+
+ /* is our session in a cookie? */
+ if (conf->name2_set) {
+ name = conf->name2;
+ }
+ else if (conf->name_set) {
+ name = conf->name;
+ }
+ else {
+ return DECLINED;
+ }
+
+ /* first look in the notes */
+ note = apr_pstrcat(m->pool, MOD_SESSION_COOKIE, name, NULL);
+ zz = (session_rec *)apr_table_get(m->notes, note);
+ if (zz) {
+ *z = zz;
+ return OK;
+ }
+
+ /* otherwise, try parse the cookie */
+ ap_cookie_read(r, name, &val, conf->remove);
+
+ /* create a new session and return it */
+ zz = (session_rec *) apr_pcalloc(m->pool, sizeof(session_rec));
+ zz->pool = m->pool;
+ zz->entries = apr_table_make(m->pool, 10);
+ zz->encoded = val;
+ *z = zz;
+
+ /* put the session in the notes so we don't have to parse it again */
+ apr_table_setn(m->notes, note, (char *)zz);
+
+ return OK;
+
+}
+
+
+
+static void *create_session_cookie_dir_config(apr_pool_t * p, char *dummy)
+{
+ session_cookie_dir_conf *new =
+ (session_cookie_dir_conf *) apr_pcalloc(p, sizeof(session_cookie_dir_conf));
+
+ return (void *) new;
+}
+
+static void *merge_session_cookie_dir_config(apr_pool_t * p, void *basev,
+ void *addv)
+{
+ session_cookie_dir_conf *new = (session_cookie_dir_conf *)
+ apr_pcalloc(p, sizeof(session_cookie_dir_conf));
+ session_cookie_dir_conf *add = (session_cookie_dir_conf *) addv;
+ session_cookie_dir_conf *base = (session_cookie_dir_conf *) basev;
+
+ new->name = (add->name_set == 0) ? base->name : add->name;
+ new->name_attrs = (add->name_set == 0) ? base->name_attrs : add->name_attrs;
+ new->name_set = add->name_set || base->name_set;
+ new->name2 = (add->name2_set == 0) ? base->name2 : add->name2;
+ new->name2_attrs = (add->name2_set == 0) ? base->name2_attrs : add->name2_attrs;
+ new->name2_set = add->name2_set || base->name2_set;
+ new->remove = (add->remove_set == 0) ? base->remove : add->remove;
+ new->remove_set = add->remove_set || base->remove_set;
+
+ return new;
+}
+
+/**
+ * Sanity check a given string that it exists, is not empty,
+ * and does not contain special characters.
+ */
+static const char *check_string(cmd_parms * cmd, const char *string)
+{
+ if (!string || !*string || ap_strchr_c(string, '=') || ap_strchr_c(string, '&')) {
+ return apr_pstrcat(cmd->pool, cmd->directive->directive,
+ " cannot be empty, or contain '=' or '&'.",
+ NULL);
+ }
+ return NULL;
+}
+
+static const char *set_cookie_name(cmd_parms * cmd, void *config,
+ const char *args)
+{
+ char *last;
+ char *line = apr_pstrdup(cmd->pool, args);
+ session_cookie_dir_conf *conf = (session_cookie_dir_conf *) config;
+ char *cookie = apr_strtok(line, " \t", &last);
+ conf->name = cookie;
+ conf->name_set = 1;
+ while (apr_isspace(*last)) {
+ last++;
+ }
+ conf->name_attrs = last;
+ return check_string(cmd, cookie);
+}
+
+static const char *set_cookie_name2(cmd_parms * cmd, void *config,
+ const char *args)
+{
+ char *last;
+ char *line = apr_pstrdup(cmd->pool, args);
+ session_cookie_dir_conf *conf = (session_cookie_dir_conf *) config;
+ char *cookie = apr_strtok(line, " \t", &last);
+ conf->name2 = cookie;
+ conf->name2_set = 1;
+ while (apr_isspace(*last)) {
+ last++;
+ }
+ conf->name2_attrs = last;
+ return check_string(cmd, cookie);
+}
+
+static const char *
+ set_remove(cmd_parms * parms, void *dconf, int flag)
+{
+ session_cookie_dir_conf *conf = dconf;
+
+ conf->remove = flag;
+ conf->remove_set = 1;
+
+ return NULL;
+}
+
+static const command_rec session_cookie_cmds[] =
+{
+ AP_INIT_RAW_ARGS("SessionCookieName", set_cookie_name, NULL, RSRC_CONF|OR_AUTHCFG,
+ "The name of the RFC2109 cookie carrying the session"),
+ AP_INIT_RAW_ARGS("SessionCookieName2", set_cookie_name2, NULL, RSRC_CONF|OR_AUTHCFG,
+ "The name of the RFC2965 cookie carrying the session"),
+ AP_INIT_FLAG("SessionCookieRemove", set_remove, NULL, RSRC_CONF|OR_AUTHCFG,
+ "Set to 'On' to remove the session cookie from the headers "
+ "and hide the cookie from a backend server or process"),
+ {NULL}
+};
+
+static void register_hooks(apr_pool_t * p)
+{
+ ap_hook_session_load(session_cookie_load, NULL, NULL, APR_HOOK_MIDDLE);
+ ap_hook_session_save(session_cookie_save, NULL, NULL, APR_HOOK_MIDDLE);
+}
+
+AP_DECLARE_MODULE(session_cookie) =
+{
+ STANDARD20_MODULE_STUFF,
+ create_session_cookie_dir_config, /* dir config creater */
+ merge_session_cookie_dir_config, /* dir merger --- default is to
+ * override */
+ NULL, /* server config */
+ NULL, /* merge server config */
+ session_cookie_cmds, /* command apr_table_t */
+ register_hooks /* register hooks */
+};
diff --git a/modules/session/mod_session_cookie.dep b/modules/session/mod_session_cookie.dep
new file mode 100644
index 0000000..23d8727
--- /dev/null
+++ b/modules/session/mod_session_cookie.dep
@@ -0,0 +1,49 @@
+# Microsoft Developer Studio Generated Dependency File, included by mod_session_cookie.mak
+
+..\..\build\win32\httpd.rc : \
+ "..\..\include\ap_release.h"\
+
+
+.\mod_session_cookie.c : \
+ "..\..\include\ap_config.h"\
+ "..\..\include\ap_config_layout.h"\
+ "..\..\include\ap_hooks.h"\
+ "..\..\include\ap_mmn.h"\
+ "..\..\include\ap_regex.h"\
+ "..\..\include\ap_release.h"\
+ "..\..\include\apache_noprobes.h"\
+ "..\..\include\http_config.h"\
+ "..\..\include\http_log.h"\
+ "..\..\include\httpd.h"\
+ "..\..\include\os.h"\
+ "..\..\include\util_cfgtree.h"\
+ "..\..\include\util_cookies.h"\
+ "..\..\srclib\apr-util\include\apr_buckets.h"\
+ "..\..\srclib\apr-util\include\apr_hooks.h"\
+ "..\..\srclib\apr-util\include\apr_optional.h"\
+ "..\..\srclib\apr-util\include\apr_optional_hooks.h"\
+ "..\..\srclib\apr-util\include\apr_uri.h"\
+ "..\..\srclib\apr-util\include\apr_uuid.h"\
+ "..\..\srclib\apr-util\include\apu.h"\
+ "..\..\srclib\apr\include\apr.h"\
+ "..\..\srclib\apr\include\apr_allocator.h"\
+ "..\..\srclib\apr\include\apr_errno.h"\
+ "..\..\srclib\apr\include\apr_file_info.h"\
+ "..\..\srclib\apr\include\apr_file_io.h"\
+ "..\..\srclib\apr\include\apr_general.h"\
+ "..\..\srclib\apr\include\apr_inherit.h"\
+ "..\..\srclib\apr\include\apr_lib.h"\
+ "..\..\srclib\apr\include\apr_mmap.h"\
+ "..\..\srclib\apr\include\apr_network_io.h"\
+ "..\..\srclib\apr\include\apr_poll.h"\
+ "..\..\srclib\apr\include\apr_pools.h"\
+ "..\..\srclib\apr\include\apr_ring.h"\
+ "..\..\srclib\apr\include\apr_strings.h"\
+ "..\..\srclib\apr\include\apr_tables.h"\
+ "..\..\srclib\apr\include\apr_thread_mutex.h"\
+ "..\..\srclib\apr\include\apr_thread_proc.h"\
+ "..\..\srclib\apr\include\apr_time.h"\
+ "..\..\srclib\apr\include\apr_user.h"\
+ "..\..\srclib\apr\include\apr_want.h"\
+ ".\mod_session.h"\
+
diff --git a/modules/session/mod_session_cookie.dsp b/modules/session/mod_session_cookie.dsp
new file mode 100644
index 0000000..3a0c86a
--- /dev/null
+++ b/modules/session/mod_session_cookie.dsp
@@ -0,0 +1,111 @@
+# Microsoft Developer Studio Project File - Name="mod_session_cookie" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=mod_session_cookie - Win32 Release
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "mod_session_cookie.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "mod_session_cookie.mak" CFG="mod_session_cookie - Win32 Release"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "mod_session_cookie - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "mod_session_cookie - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "mod_session_cookie - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c
+# ADD CPP /nologo /MD /W3 /O2 /Oy- /Zi /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Release\mod_session_cookie_src" /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /fo"Release/mod_session_cookie.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_session_cookie.so" /d LONG_NAME="session_cookie_module for Apache"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /out:".\Release\mod_session_cookie.so" /base:@..\..\os\win32\BaseAddr.ref,mod_session_cookie.so
+# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Release\mod_session_cookie.so" /base:@..\..\os\win32\BaseAddr.ref,mod_session_cookie.so /opt:ref
+# Begin Special Build Tool
+TargetPath=.\Release\mod_session_cookie.so
+SOURCE="$(InputPath)"
+PostBuild_Desc=Embed .manifest
+PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
+# End Special Build Tool
+
+!ELSEIF "$(CFG)" == "mod_session_cookie - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MDd /W3 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
+# ADD CPP /nologo /MDd /W3 /EHsc /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Debug\mod_session_cookie_src" /FD /c
+# ADD BASE MTL /nologo /D "_DEBUG" /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /fo"Debug/mod_session_cookie.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_session_cookie.so" /d LONG_NAME="session_cookie_module for Apache"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_session_cookie.so" /base:@..\..\os\win32\BaseAddr.ref,mod_session_cookie.so
+# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_session_cookie.so" /base:@..\..\os\win32\BaseAddr.ref,mod_session_cookie.so
+# Begin Special Build Tool
+TargetPath=.\Debug\mod_session_cookie.so
+SOURCE="$(InputPath)"
+PostBuild_Desc=Embed .manifest
+PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
+# End Special Build Tool
+
+!ENDIF
+
+# Begin Target
+
+# Name "mod_session_cookie - Win32 Release"
+# Name "mod_session_cookie - Win32 Debug"
+# Begin Source File
+
+SOURCE=.\mod_session_cookie.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\build\win32\httpd.rc
+# End Source File
+# End Target
+# End Project
diff --git a/modules/session/mod_session_cookie.mak b/modules/session/mod_session_cookie.mak
new file mode 100644
index 0000000..014f1e3
--- /dev/null
+++ b/modules/session/mod_session_cookie.mak
@@ -0,0 +1,381 @@
+# Microsoft Developer Studio Generated NMAKE File, Based on mod_session_cookie.dsp
+!IF "$(CFG)" == ""
+CFG=mod_session_cookie - Win32 Release
+!MESSAGE No configuration specified. Defaulting to mod_session_cookie - Win32 Release.
+!ENDIF
+
+!IF "$(CFG)" != "mod_session_cookie - Win32 Release" && "$(CFG)" != "mod_session_cookie - Win32 Debug"
+!MESSAGE Invalid configuration "$(CFG)" specified.
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "mod_session_cookie.mak" CFG="mod_session_cookie - Win32 Release"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "mod_session_cookie - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "mod_session_cookie - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+!ERROR An invalid configuration is specified.
+!ENDIF
+
+!IF "$(OS)" == "Windows_NT"
+NULL=
+!ELSE
+NULL=nul
+!ENDIF
+
+!IF "$(CFG)" == "mod_session_cookie - Win32 Release"
+
+OUTDIR=.\Release
+INTDIR=.\Release
+DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
+# Begin Custom Macros
+OutDir=.\Release
+# End Custom Macros
+
+!IF "$(RECURSE)" == "0"
+
+ALL : "$(OUTDIR)\mod_session_cookie.so" "$(DS_POSTBUILD_DEP)"
+
+!ELSE
+
+ALL : "mod_session - Win32 Release" "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_session_cookie.so" "$(DS_POSTBUILD_DEP)"
+
+!ENDIF
+
+!IF "$(RECURSE)" == "1"
+CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" "mod_session - Win32 ReleaseCLEAN"
+!ELSE
+CLEAN :
+!ENDIF
+ -@erase "$(INTDIR)\mod_session_cookie.obj"
+ -@erase "$(INTDIR)\mod_session_cookie.res"
+ -@erase "$(INTDIR)\mod_session_cookie_src.idb"
+ -@erase "$(INTDIR)\mod_session_cookie_src.pdb"
+ -@erase "$(OUTDIR)\mod_session_cookie.exp"
+ -@erase "$(OUTDIR)\mod_session_cookie.lib"
+ -@erase "$(OUTDIR)\mod_session_cookie.pdb"
+ -@erase "$(OUTDIR)\mod_session_cookie.so"
+
+"$(OUTDIR)" :
+ if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
+
+CPP=cl.exe
+CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_session_cookie_src" /FD /c
+
+.c{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.c{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+MTL=midl.exe
+MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32
+RSC=rc.exe
+RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_session_cookie.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_session_cookie.so" /d LONG_NAME="session_cookie_module for Apache"
+BSC32=bscmake.exe
+BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_session_cookie.bsc"
+BSC32_SBRS= \
+
+LINK32=link.exe
+LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_session_cookie.pdb" /debug /out:"$(OUTDIR)\mod_session_cookie.so" /implib:"$(OUTDIR)\mod_session_cookie.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_session_cookie.so /opt:ref
+LINK32_OBJS= \
+ "$(INTDIR)\mod_session_cookie.obj" \
+ "$(INTDIR)\mod_session_cookie.res" \
+ "..\..\srclib\apr\Release\libapr-1.lib" \
+ "..\..\srclib\apr-util\Release\libaprutil-1.lib" \
+ "..\..\Release\libhttpd.lib" \
+ "$(OUTDIR)\mod_session.lib"
+
+"$(OUTDIR)\mod_session_cookie.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
+ $(LINK32) @<<
+ $(LINK32_FLAGS) $(LINK32_OBJS)
+<<
+
+TargetPath=.\Release\mod_session_cookie.so
+SOURCE="$(InputPath)"
+PostBuild_Desc=Embed .manifest
+DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
+
+# Begin Custom Macros
+OutDir=.\Release
+# End Custom Macros
+
+"$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_session_cookie.so"
+ if exist .\Release\mod_session_cookie.so.manifest mt.exe -manifest .\Release\mod_session_cookie.so.manifest -outputresource:.\Release\mod_session_cookie.so;2
+ echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
+
+!ELSEIF "$(CFG)" == "mod_session_cookie - Win32 Debug"
+
+OUTDIR=.\Debug
+INTDIR=.\Debug
+DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
+# Begin Custom Macros
+OutDir=.\Debug
+# End Custom Macros
+
+!IF "$(RECURSE)" == "0"
+
+ALL : "$(OUTDIR)\mod_session_cookie.so" "$(DS_POSTBUILD_DEP)"
+
+!ELSE
+
+ALL : "mod_session - Win32 Debug" "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_session_cookie.so" "$(DS_POSTBUILD_DEP)"
+
+!ENDIF
+
+!IF "$(RECURSE)" == "1"
+CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" "mod_session - Win32 DebugCLEAN"
+!ELSE
+CLEAN :
+!ENDIF
+ -@erase "$(INTDIR)\mod_session_cookie.obj"
+ -@erase "$(INTDIR)\mod_session_cookie.res"
+ -@erase "$(INTDIR)\mod_session_cookie_src.idb"
+ -@erase "$(INTDIR)\mod_session_cookie_src.pdb"
+ -@erase "$(OUTDIR)\mod_session_cookie.exp"
+ -@erase "$(OUTDIR)\mod_session_cookie.lib"
+ -@erase "$(OUTDIR)\mod_session_cookie.pdb"
+ -@erase "$(OUTDIR)\mod_session_cookie.so"
+
+"$(OUTDIR)" :
+ if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
+
+CPP=cl.exe
+CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_session_cookie_src" /FD /EHsc /c
+
+.c{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.c{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+MTL=midl.exe
+MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32
+RSC=rc.exe
+RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_session_cookie.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_session_cookie.so" /d LONG_NAME="session_cookie_module for Apache"
+BSC32=bscmake.exe
+BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_session_cookie.bsc"
+BSC32_SBRS= \
+
+LINK32=link.exe
+LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_session_cookie.pdb" /debug /out:"$(OUTDIR)\mod_session_cookie.so" /implib:"$(OUTDIR)\mod_session_cookie.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_session_cookie.so
+LINK32_OBJS= \
+ "$(INTDIR)\mod_session_cookie.obj" \
+ "$(INTDIR)\mod_session_cookie.res" \
+ "..\..\srclib\apr\Debug\libapr-1.lib" \
+ "..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
+ "..\..\Debug\libhttpd.lib" \
+ "$(OUTDIR)\mod_session.lib"
+
+"$(OUTDIR)\mod_session_cookie.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
+ $(LINK32) @<<
+ $(LINK32_FLAGS) $(LINK32_OBJS)
+<<
+
+TargetPath=.\Debug\mod_session_cookie.so
+SOURCE="$(InputPath)"
+PostBuild_Desc=Embed .manifest
+DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
+
+# Begin Custom Macros
+OutDir=.\Debug
+# End Custom Macros
+
+"$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_session_cookie.so"
+ if exist .\Debug\mod_session_cookie.so.manifest mt.exe -manifest .\Debug\mod_session_cookie.so.manifest -outputresource:.\Debug\mod_session_cookie.so;2
+ echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
+
+!ENDIF
+
+
+!IF "$(NO_EXTERNAL_DEPS)" != "1"
+!IF EXISTS("mod_session_cookie.dep")
+!INCLUDE "mod_session_cookie.dep"
+!ELSE
+!MESSAGE Warning: cannot find "mod_session_cookie.dep"
+!ENDIF
+!ENDIF
+
+
+!IF "$(CFG)" == "mod_session_cookie - Win32 Release" || "$(CFG)" == "mod_session_cookie - Win32 Debug"
+
+!IF "$(CFG)" == "mod_session_cookie - Win32 Release"
+
+"libapr - Win32 Release" :
+ cd ".\..\..\srclib\apr"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release"
+ cd "..\..\modules\session"
+
+"libapr - Win32 ReleaseCLEAN" :
+ cd ".\..\..\srclib\apr"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN
+ cd "..\..\modules\session"
+
+!ELSEIF "$(CFG)" == "mod_session_cookie - Win32 Debug"
+
+"libapr - Win32 Debug" :
+ cd ".\..\..\srclib\apr"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug"
+ cd "..\..\modules\session"
+
+"libapr - Win32 DebugCLEAN" :
+ cd ".\..\..\srclib\apr"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN
+ cd "..\..\modules\session"
+
+!ENDIF
+
+!IF "$(CFG)" == "mod_session_cookie - Win32 Release"
+
+"libaprutil - Win32 Release" :
+ cd ".\..\..\srclib\apr-util"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release"
+ cd "..\..\modules\session"
+
+"libaprutil - Win32 ReleaseCLEAN" :
+ cd ".\..\..\srclib\apr-util"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN
+ cd "..\..\modules\session"
+
+!ELSEIF "$(CFG)" == "mod_session_cookie - Win32 Debug"
+
+"libaprutil - Win32 Debug" :
+ cd ".\..\..\srclib\apr-util"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug"
+ cd "..\..\modules\session"
+
+"libaprutil - Win32 DebugCLEAN" :
+ cd ".\..\..\srclib\apr-util"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN
+ cd "..\..\modules\session"
+
+!ENDIF
+
+!IF "$(CFG)" == "mod_session_cookie - Win32 Release"
+
+"libhttpd - Win32 Release" :
+ cd ".\..\.."
+ $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release"
+ cd ".\modules\session"
+
+"libhttpd - Win32 ReleaseCLEAN" :
+ cd ".\..\.."
+ $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN
+ cd ".\modules\session"
+
+!ELSEIF "$(CFG)" == "mod_session_cookie - Win32 Debug"
+
+"libhttpd - Win32 Debug" :
+ cd ".\..\.."
+ $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug"
+ cd ".\modules\session"
+
+"libhttpd - Win32 DebugCLEAN" :
+ cd ".\..\.."
+ $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN
+ cd ".\modules\session"
+
+!ENDIF
+
+!IF "$(CFG)" == "mod_session_cookie - Win32 Release"
+
+"mod_session - Win32 Release" :
+ cd "."
+ $(MAKE) /$(MAKEFLAGS) /F ".\mod_session.mak" CFG="mod_session - Win32 Release"
+ cd "."
+
+"mod_session - Win32 ReleaseCLEAN" :
+ cd "."
+ $(MAKE) /$(MAKEFLAGS) /F ".\mod_session.mak" CFG="mod_session - Win32 Release" RECURSE=1 CLEAN
+ cd "."
+
+!ELSEIF "$(CFG)" == "mod_session_cookie - Win32 Debug"
+
+"mod_session - Win32 Debug" :
+ cd "."
+ $(MAKE) /$(MAKEFLAGS) /F ".\mod_session.mak" CFG="mod_session - Win32 Debug"
+ cd "."
+
+"mod_session - Win32 DebugCLEAN" :
+ cd "."
+ $(MAKE) /$(MAKEFLAGS) /F ".\mod_session.mak" CFG="mod_session - Win32 Debug" RECURSE=1 CLEAN
+ cd "."
+
+!ENDIF
+
+SOURCE=..\..\build\win32\httpd.rc
+
+!IF "$(CFG)" == "mod_session_cookie - Win32 Release"
+
+
+"$(INTDIR)\mod_session_cookie.res" : $(SOURCE) "$(INTDIR)"
+ $(RSC) /l 0x409 /fo"$(INTDIR)\mod_session_cookie.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_session_cookie.so" /d LONG_NAME="session_cookie_module for Apache" $(SOURCE)
+
+
+!ELSEIF "$(CFG)" == "mod_session_cookie - Win32 Debug"
+
+
+"$(INTDIR)\mod_session_cookie.res" : $(SOURCE) "$(INTDIR)"
+ $(RSC) /l 0x409 /fo"$(INTDIR)\mod_session_cookie.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_session_cookie.so" /d LONG_NAME="session_cookie_module for Apache" $(SOURCE)
+
+
+!ENDIF
+
+SOURCE=.\mod_session_cookie.c
+
+"$(INTDIR)\mod_session_cookie.obj" : $(SOURCE) "$(INTDIR)"
+
+
+
+!ENDIF
+
diff --git a/modules/session/mod_session_crypto.c b/modules/session/mod_session_crypto.c
new file mode 100644
index 0000000..996620d
--- /dev/null
+++ b/modules/session/mod_session_crypto.c
@@ -0,0 +1,805 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "mod_session.h"
+#include "apu_version.h"
+#include "apr_base64.h" /* for apr_base64_decode et al */
+#include "apr_lib.h"
+#include "apr_md5.h"
+#include "apr_strings.h"
+#include "http_log.h"
+#include "http_core.h"
+
+#if APU_MAJOR_VERSION == 1 && APU_MINOR_VERSION < 4
+
+#error session_crypto_module requires APU v1.4.0 or later
+
+#elif APU_HAVE_CRYPTO == 0
+
+#error Crypto support must be enabled in APR
+
+#else
+
+#include "apr_crypto.h" /* for apr_*_crypt et al */
+
+#define CRYPTO_KEY "session_crypto_context"
+
+module AP_MODULE_DECLARE_DATA session_crypto_module;
+
+/**
+ * Structure to carry the per-dir session config.
+ */
+typedef struct {
+ apr_array_header_t *passphrases;
+ int passphrases_set;
+ const char *cipher;
+ int cipher_set;
+} session_crypto_dir_conf;
+
+/**
+ * Structure to carry the server wide session config.
+ */
+typedef struct {
+ const char *library;
+ const char *params;
+ int library_set;
+} session_crypto_conf;
+
+/* Wrappers around apr_siphash24() and apr_crypto_equals(),
+ * available in APU-1.6/APR-2.0 only.
+ */
+#if APU_MAJOR_VERSION > 1 || (APU_MAJOR_VERSION == 1 && APU_MINOR_VERSION >= 6)
+
+#include "apr_siphash.h"
+
+#define AP_SIPHASH_DSIZE APR_SIPHASH_DSIZE
+#define AP_SIPHASH_KSIZE APR_SIPHASH_KSIZE
+#define ap_siphash24_auth apr_siphash24_auth
+
+#define ap_crypto_equals apr_crypto_equals
+
+#else
+
+#define AP_SIPHASH_DSIZE 8
+#define AP_SIPHASH_KSIZE 16
+
+#define ROTL64(x, n) (((x) << (n)) | ((x) >> (64 - (n))))
+
+#define U8TO64_LE(p) \
+ (((apr_uint64_t)((p)[0]) ) | \
+ ((apr_uint64_t)((p)[1]) << 8) | \
+ ((apr_uint64_t)((p)[2]) << 16) | \
+ ((apr_uint64_t)((p)[3]) << 24) | \
+ ((apr_uint64_t)((p)[4]) << 32) | \
+ ((apr_uint64_t)((p)[5]) << 40) | \
+ ((apr_uint64_t)((p)[6]) << 48) | \
+ ((apr_uint64_t)((p)[7]) << 56))
+
+#define U64TO8_LE(p, v) \
+do { \
+ (p)[0] = (unsigned char)((v) ); \
+ (p)[1] = (unsigned char)((v) >> 8); \
+ (p)[2] = (unsigned char)((v) >> 16); \
+ (p)[3] = (unsigned char)((v) >> 24); \
+ (p)[4] = (unsigned char)((v) >> 32); \
+ (p)[5] = (unsigned char)((v) >> 40); \
+ (p)[6] = (unsigned char)((v) >> 48); \
+ (p)[7] = (unsigned char)((v) >> 56); \
+} while (0)
+
+#define SIPROUND() \
+do { \
+ v0 += v1; v1=ROTL64(v1,13); v1 ^= v0; v0=ROTL64(v0,32); \
+ v2 += v3; v3=ROTL64(v3,16); v3 ^= v2; \
+ v0 += v3; v3=ROTL64(v3,21); v3 ^= v0; \
+ v2 += v1; v1=ROTL64(v1,17); v1 ^= v2; v2=ROTL64(v2,32); \
+} while(0)
+
+static apr_uint64_t ap_siphash24(const void *src, apr_size_t len,
+ const unsigned char key[AP_SIPHASH_KSIZE])
+{
+ const unsigned char *ptr, *end;
+ apr_uint64_t v0, v1, v2, v3, m;
+ apr_uint64_t k0, k1;
+ unsigned int rem;
+
+ k0 = U8TO64_LE(key + 0);
+ k1 = U8TO64_LE(key + 8);
+ v3 = k1 ^ (apr_uint64_t)0x7465646279746573ULL;
+ v2 = k0 ^ (apr_uint64_t)0x6c7967656e657261ULL;
+ v1 = k1 ^ (apr_uint64_t)0x646f72616e646f6dULL;
+ v0 = k0 ^ (apr_uint64_t)0x736f6d6570736575ULL;
+
+ rem = (unsigned int)(len & 0x7);
+ for (ptr = src, end = ptr + len - rem; ptr < end; ptr += 8) {
+ m = U8TO64_LE(ptr);
+ v3 ^= m;
+ SIPROUND();
+ SIPROUND();
+ v0 ^= m;
+ }
+ m = (apr_uint64_t)(len & 0xff) << 56;
+ switch (rem) {
+ case 7: m |= (apr_uint64_t)ptr[6] << 48;
+ case 6: m |= (apr_uint64_t)ptr[5] << 40;
+ case 5: m |= (apr_uint64_t)ptr[4] << 32;
+ case 4: m |= (apr_uint64_t)ptr[3] << 24;
+ case 3: m |= (apr_uint64_t)ptr[2] << 16;
+ case 2: m |= (apr_uint64_t)ptr[1] << 8;
+ case 1: m |= (apr_uint64_t)ptr[0];
+ case 0: break;
+ }
+ v3 ^= m;
+ SIPROUND();
+ SIPROUND();
+ v0 ^= m;
+
+ v2 ^= 0xff;
+ SIPROUND();
+ SIPROUND();
+ SIPROUND();
+ SIPROUND();
+
+ return v0 ^ v1 ^ v2 ^ v3;
+}
+
+static void ap_siphash24_auth(unsigned char out[AP_SIPHASH_DSIZE],
+ const void *src, apr_size_t len,
+ const unsigned char key[AP_SIPHASH_KSIZE])
+{
+ apr_uint64_t h;
+ h = ap_siphash24(src, len, key);
+ U64TO8_LE(out, h);
+}
+
+static int ap_crypto_equals(const void *buf1, const void *buf2,
+ apr_size_t size)
+{
+ const unsigned char *p1 = buf1;
+ const unsigned char *p2 = buf2;
+ unsigned char diff = 0;
+ apr_size_t i;
+
+ for (i = 0; i < size; ++i) {
+ diff |= p1[i] ^ p2[i];
+ }
+
+ return 1 & ((diff - 1) >> 8);
+}
+
+#endif
+
+static void compute_auth(const void *src, apr_size_t len,
+ const char *passphrase, apr_size_t passlen,
+ unsigned char auth[AP_SIPHASH_DSIZE])
+{
+ unsigned char key[APR_MD5_DIGESTSIZE];
+
+ /* XXX: if we had a way to get the raw bytes from an apr_crypto_key_t
+ * we could use them directly (not available in APR-1.5.x).
+ * MD5 is 128bit too, so use it to get a suitable siphash key
+ * from the passphrase.
+ */
+ apr_md5(key, passphrase, passlen);
+
+ ap_siphash24_auth(auth, src, len, key);
+}
+
+/**
+ * Initialise the encryption as per the current config.
+ *
+ * Returns APR_SUCCESS if successful.
+ */
+static apr_status_t crypt_init(request_rec *r,
+ const apr_crypto_t *f, apr_crypto_block_key_type_e **cipher,
+ session_crypto_dir_conf * dconf)
+{
+ apr_status_t res;
+ apr_hash_t *ciphers;
+
+ res = apr_crypto_get_block_key_types(&ciphers, f);
+ if (APR_SUCCESS != res) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, res, r, APLOGNO(01823)
+ "no ciphers returned by APR. "
+ "session encryption not possible");
+ return res;
+ }
+
+ *cipher = apr_hash_get(ciphers, dconf->cipher, APR_HASH_KEY_STRING);
+ if (!(*cipher)) {
+ apr_hash_index_t *hi;
+ const void *key;
+ apr_ssize_t klen;
+ int sum = 0;
+ int offset = 0;
+ char *options = NULL;
+
+ for (hi = apr_hash_first(r->pool, ciphers); hi; hi = apr_hash_next(hi)) {
+ apr_hash_this(hi, NULL, &klen, NULL);
+ sum += klen + 2;
+ }
+ for (hi = apr_hash_first(r->pool, ciphers); hi; hi = apr_hash_next(hi)) {
+ apr_hash_this(hi, &key, &klen, NULL);
+ if (!options) {
+ options = apr_palloc(r->pool, sum + 1);
+ }
+ else {
+ options[offset++] = ',';
+ options[offset++] = ' ';
+ }
+ strncpy(options + offset, key, klen);
+ offset += klen;
+ }
+ options[offset] = 0;
+
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, res, r, APLOGNO(01824)
+ "cipher '%s' not recognised by crypto driver. "
+ "session encryption not possible, options: %s", dconf->cipher, options);
+
+ return APR_EGENERAL;
+ }
+
+ return APR_SUCCESS;
+}
+
+/**
+ * Encrypt the string given as per the current config.
+ *
+ * Returns APR_SUCCESS if successful.
+ */
+static apr_status_t encrypt_string(request_rec * r, const apr_crypto_t *f,
+ session_crypto_dir_conf *dconf, const char *in, char **out)
+{
+ apr_status_t res;
+ apr_crypto_key_t *key = NULL;
+ apr_size_t ivSize = 0;
+ apr_crypto_block_t *block = NULL;
+ unsigned char *encrypt = NULL;
+ unsigned char *combined = NULL;
+ apr_size_t encryptlen, tlen, combinedlen;
+ char *base64;
+ apr_size_t blockSize = 0;
+ const unsigned char *iv = NULL;
+ apr_uuid_t salt;
+ apr_crypto_block_key_type_e *cipher;
+ const char *passphrase;
+ apr_size_t passlen;
+
+ /* use a uuid as a salt value, and prepend it to our result */
+ apr_uuid_get(&salt);
+ res = crypt_init(r, f, &cipher, dconf);
+ if (res != APR_SUCCESS) {
+ return res;
+ }
+
+ /* encrypt using the first passphrase in the list */
+ passphrase = APR_ARRAY_IDX(dconf->passphrases, 0, const char *);
+ passlen = strlen(passphrase);
+ res = apr_crypto_passphrase(&key, &ivSize, passphrase, passlen,
+ (unsigned char *) (&salt), sizeof(apr_uuid_t),
+ *cipher, APR_MODE_CBC, 1, 4096, f, r->pool);
+ if (APR_STATUS_IS_ENOKEY(res)) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, res, r, APLOGNO(01825)
+ "the passphrase '%s' was empty", passphrase);
+ }
+ if (APR_STATUS_IS_EPADDING(res)) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, res, r, APLOGNO(01826)
+ "padding is not supported for cipher");
+ }
+ if (APR_STATUS_IS_EKEYTYPE(res)) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, res, r, APLOGNO(01827)
+ "the key type is not known");
+ }
+ if (APR_SUCCESS != res) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, res, r, APLOGNO(01828)
+ "encryption could not be configured.");
+ return res;
+ }
+
+ res = apr_crypto_block_encrypt_init(&block, &iv, key, &blockSize, r->pool);
+ if (APR_SUCCESS != res) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, res, r, APLOGNO(01829)
+ "apr_crypto_block_encrypt_init failed");
+ return res;
+ }
+
+ /* encrypt the given string */
+ res = apr_crypto_block_encrypt(&encrypt, &encryptlen,
+ (const unsigned char *)in, strlen(in),
+ block);
+ if (APR_SUCCESS != res) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, res, r, APLOGNO(01830)
+ "apr_crypto_block_encrypt failed");
+ return res;
+ }
+ res = apr_crypto_block_encrypt_finish(encrypt + encryptlen, &tlen, block);
+ if (APR_SUCCESS != res) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, res, r, APLOGNO(01831)
+ "apr_crypto_block_encrypt_finish failed");
+ return res;
+ }
+ encryptlen += tlen;
+
+ /* prepend the salt and the iv to the result (keep room for the MAC) */
+ combinedlen = AP_SIPHASH_DSIZE + sizeof(apr_uuid_t) + ivSize + encryptlen;
+ combined = apr_palloc(r->pool, combinedlen);
+ memcpy(combined + AP_SIPHASH_DSIZE, &salt, sizeof(apr_uuid_t));
+ memcpy(combined + AP_SIPHASH_DSIZE + sizeof(apr_uuid_t), iv, ivSize);
+ memcpy(combined + AP_SIPHASH_DSIZE + sizeof(apr_uuid_t) + ivSize,
+ encrypt, encryptlen);
+ /* authenticate the whole salt+IV+ciphertext with a leading MAC */
+ compute_auth(combined + AP_SIPHASH_DSIZE, combinedlen - AP_SIPHASH_DSIZE,
+ passphrase, passlen, combined);
+
+ /* base64 encode the result (APR handles the trailing '\0') */
+ base64 = apr_palloc(r->pool, apr_base64_encode_len(combinedlen));
+ apr_base64_encode(base64, (const char *) combined, combinedlen);
+ *out = base64;
+
+ return res;
+
+}
+
+/**
+ * Decrypt the string given as per the current config.
+ *
+ * Returns APR_SUCCESS if successful.
+ */
+static apr_status_t decrypt_string(request_rec * r, const apr_crypto_t *f,
+ session_crypto_dir_conf *dconf, const char *in, char **out)
+{
+ apr_status_t res;
+ apr_crypto_key_t *key = NULL;
+ apr_size_t ivSize = 0;
+ apr_crypto_block_t *block = NULL;
+ unsigned char *decrypted = NULL;
+ apr_size_t decryptedlen, tlen;
+ apr_size_t decodedlen;
+ char *decoded;
+ apr_size_t blockSize = 0;
+ apr_crypto_block_key_type_e *cipher;
+ unsigned char auth[AP_SIPHASH_DSIZE];
+ int i = 0;
+
+ /* strip base64 from the string */
+ decoded = apr_palloc(r->pool, apr_base64_decode_len(in));
+ decodedlen = apr_base64_decode(decoded, in);
+ decoded[decodedlen] = '\0';
+
+ /* sanity check - decoded too short? */
+ if (decodedlen < (AP_SIPHASH_DSIZE + sizeof(apr_uuid_t))) {
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, r, APLOGNO(10005)
+ "too short to decrypt, aborting");
+ return APR_ECRYPT;
+ }
+
+ res = crypt_init(r, f, &cipher, dconf);
+ if (res != APR_SUCCESS) {
+ return res;
+ }
+
+ /* try each passphrase in turn */
+ for (; i < dconf->passphrases->nelts; i++) {
+ const char *passphrase = APR_ARRAY_IDX(dconf->passphrases, i, char *);
+ apr_size_t passlen = strlen(passphrase);
+ apr_size_t len = decodedlen - AP_SIPHASH_DSIZE;
+ unsigned char *slider = (unsigned char *)decoded + AP_SIPHASH_DSIZE;
+
+ /* Verify authentication of the whole salt+IV+ciphertext by computing
+ * the MAC and comparing it (timing safe) with the one in the payload.
+ */
+ compute_auth(slider, len, passphrase, passlen, auth);
+ if (!ap_crypto_equals(auth, decoded, AP_SIPHASH_DSIZE)) {
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, res, r, APLOGNO(10006)
+ "auth does not match, skipping");
+ continue;
+ }
+
+ /* encrypt using the first passphrase in the list */
+ res = apr_crypto_passphrase(&key, &ivSize, passphrase, passlen,
+ slider, sizeof(apr_uuid_t),
+ *cipher, APR_MODE_CBC, 1, 4096,
+ f, r->pool);
+ if (APR_STATUS_IS_ENOKEY(res)) {
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, res, r, APLOGNO(01832)
+ "the passphrase '%s' was empty", passphrase);
+ continue;
+ }
+ else if (APR_STATUS_IS_EPADDING(res)) {
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, res, r, APLOGNO(01833)
+ "padding is not supported for cipher");
+ continue;
+ }
+ else if (APR_STATUS_IS_EKEYTYPE(res)) {
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, res, r, APLOGNO(01834)
+ "the key type is not known");
+ continue;
+ }
+ else if (APR_SUCCESS != res) {
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, res, r, APLOGNO(01835)
+ "encryption could not be configured.");
+ continue;
+ }
+
+ /* sanity check - decoded too short? */
+ if (len < (sizeof(apr_uuid_t) + ivSize)) {
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, r, APLOGNO(01836)
+ "too short to decrypt, skipping");
+ res = APR_ECRYPT;
+ continue;
+ }
+
+ /* bypass the salt at the start of the decoded block */
+ slider += sizeof(apr_uuid_t);
+ len -= sizeof(apr_uuid_t);
+
+ res = apr_crypto_block_decrypt_init(&block, &blockSize, slider, key,
+ r->pool);
+ if (APR_SUCCESS != res) {
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, res, r, APLOGNO(01837)
+ "apr_crypto_block_decrypt_init failed");
+ continue;
+ }
+
+ /* bypass the iv at the start of the decoded block */
+ slider += ivSize;
+ len -= ivSize;
+
+ /* decrypt the given string */
+ res = apr_crypto_block_decrypt(&decrypted, &decryptedlen,
+ slider, len, block);
+ if (res) {
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, res, r, APLOGNO(01838)
+ "apr_crypto_block_decrypt failed");
+ continue;
+ }
+ *out = (char *) decrypted;
+
+ res = apr_crypto_block_decrypt_finish(decrypted + decryptedlen, &tlen, block);
+ if (APR_SUCCESS != res) {
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, res, r, APLOGNO(01839)
+ "apr_crypto_block_decrypt_finish failed");
+ continue;
+ }
+ decryptedlen += tlen;
+ decrypted[decryptedlen] = 0;
+
+ break;
+ }
+
+ if (APR_SUCCESS != res) {
+ ap_log_rerror(APLOG_MARK, APLOG_INFO, res, r, APLOGNO(01840)
+ "decryption failed");
+ }
+
+ return res;
+
+}
+
+/**
+ * Crypto encoding for the session.
+ *
+ * @param r The request pointer.
+ * @param z A pointer to where the session will be written.
+ */
+static apr_status_t session_crypto_encode(request_rec * r, session_rec * z)
+{
+
+ char *encoded = NULL;
+ apr_status_t res;
+ const apr_crypto_t *f = NULL;
+ session_crypto_dir_conf *dconf = ap_get_module_config(r->per_dir_config,
+ &session_crypto_module);
+
+ if (dconf->passphrases_set && z->encoded && *z->encoded) {
+ apr_pool_userdata_get((void **)&f, CRYPTO_KEY, r->server->process->pconf);
+ res = encrypt_string(r, f, dconf, z->encoded, &encoded);
+ if (res != OK) {
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, res, r, APLOGNO(01841)
+ "encrypt session failed");
+ return res;
+ }
+ z->encoded = encoded;
+ }
+
+ return OK;
+
+}
+
+/**
+ * Crypto decoding for the session.
+ *
+ * @param r The request pointer.
+ * @param z A pointer to where the session will be written.
+ */
+static apr_status_t session_crypto_decode(request_rec * r,
+ session_rec * z)
+{
+
+ char *encoded = NULL;
+ apr_status_t res;
+ const apr_crypto_t *f = NULL;
+ session_crypto_dir_conf *dconf = ap_get_module_config(r->per_dir_config,
+ &session_crypto_module);
+
+ if ((dconf->passphrases_set) && z->encoded && *z->encoded) {
+ apr_pool_userdata_get((void **)&f, CRYPTO_KEY,
+ r->server->process->pconf);
+ res = decrypt_string(r, f, dconf, z->encoded, &encoded);
+ if (res != APR_SUCCESS) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, res, r, APLOGNO(01842)
+ "decrypt session failed, wrong passphrase?");
+ return res;
+ }
+ z->encoded = encoded;
+ }
+
+ return OK;
+
+}
+
+/**
+ * Initialise the SSL in the post_config hook.
+ */
+static int session_crypto_init(apr_pool_t *p, apr_pool_t *plog,
+ apr_pool_t *ptemp, server_rec *s)
+{
+ const apr_crypto_driver_t *driver = NULL;
+ apr_crypto_t *f = NULL;
+
+ session_crypto_conf *conf = ap_get_module_config(s->module_config,
+ &session_crypto_module);
+
+ /* session_crypto_init() will be called twice. Don't bother
+ * going through all of the initialization on the first call
+ * because it will just be thrown away.*/
+ if (ap_state_query(AP_SQ_MAIN_STATE) == AP_SQ_MS_CREATE_PRE_CONFIG) {
+ return OK;
+ }
+
+ if (conf->library) {
+
+ const apu_err_t *err = NULL;
+ apr_status_t rv;
+
+ rv = apr_crypto_init(p);
+ if (APR_SUCCESS != rv) {
+ ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, APLOGNO(01843)
+ "APR crypto could not be initialised");
+ return rv;
+ }
+
+ rv = apr_crypto_get_driver(&driver, conf->library, conf->params, &err, p);
+ if (APR_EREINIT == rv) {
+ ap_log_error(APLOG_MARK, APLOG_WARNING, rv, s, APLOGNO(01844)
+ "warning: crypto for '%s' was already initialised, "
+ "using existing configuration", conf->library);
+ rv = APR_SUCCESS;
+ }
+ if (APR_SUCCESS != rv && err) {
+ ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, APLOGNO(01845)
+ "The crypto library '%s' could not be loaded: %s (%s: %d)", conf->library, err->msg, err->reason, err->rc);
+ return rv;
+ }
+ if (APR_ENOTIMPL == rv) {
+ ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, APLOGNO(01846)
+ "The crypto library '%s' could not be found",
+ conf->library);
+ return rv;
+ }
+ if (APR_SUCCESS != rv || !driver) {
+ ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, APLOGNO(01847)
+ "The crypto library '%s' could not be loaded",
+ conf->library);
+ return rv;
+ }
+
+ rv = apr_crypto_make(&f, driver, conf->params, p);
+ if (APR_SUCCESS != rv) {
+ ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, APLOGNO(01848)
+ "The crypto library '%s' could not be initialised",
+ conf->library);
+ return rv;
+ }
+
+ ap_log_error(APLOG_MARK, APLOG_INFO, rv, s, APLOGNO(01849)
+ "The crypto library '%s' was loaded successfully",
+ conf->library);
+
+ apr_pool_userdata_set((const void *)f, CRYPTO_KEY,
+ apr_pool_cleanup_null, s->process->pconf);
+
+ }
+
+ return OK;
+}
+
+static void *create_session_crypto_config(apr_pool_t * p, server_rec *s)
+{
+ session_crypto_conf *new =
+ (session_crypto_conf *) apr_pcalloc(p, sizeof(session_crypto_conf));
+
+ /* if no library has been configured, set the recommended library
+ * as a sensible default.
+ */
+#ifdef APU_CRYPTO_RECOMMENDED_DRIVER
+ new->library = APU_CRYPTO_RECOMMENDED_DRIVER;
+#endif
+
+ return (void *) new;
+}
+
+static void *create_session_crypto_dir_config(apr_pool_t * p, char *dummy)
+{
+ session_crypto_dir_conf *new =
+ (session_crypto_dir_conf *) apr_pcalloc(p, sizeof(session_crypto_dir_conf));
+
+ new->passphrases = apr_array_make(p, 10, sizeof(char *));
+
+ /* default cipher AES256-SHA */
+ new->cipher = "aes256";
+
+ return (void *) new;
+}
+
+static void *merge_session_crypto_dir_config(apr_pool_t * p, void *basev, void *addv)
+{
+ session_crypto_dir_conf *new = (session_crypto_dir_conf *) apr_pcalloc(p, sizeof(session_crypto_dir_conf));
+ session_crypto_dir_conf *add = (session_crypto_dir_conf *) addv;
+ session_crypto_dir_conf *base = (session_crypto_dir_conf *) basev;
+
+ new->passphrases = (add->passphrases_set == 0) ? base->passphrases : add->passphrases;
+ new->passphrases_set = add->passphrases_set || base->passphrases_set;
+ new->cipher = (add->cipher_set == 0) ? base->cipher : add->cipher;
+ new->cipher_set = add->cipher_set || base->cipher_set;
+
+ return new;
+}
+
+static const char *set_crypto_driver(cmd_parms * cmd, void *config, const char *arg)
+{
+ session_crypto_conf *conf =
+ (session_crypto_conf *)ap_get_module_config(cmd->server->module_config,
+ &session_crypto_module);
+
+ const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
+
+ if (err != NULL) {
+ return err;
+ }
+
+ conf->library = ap_getword_conf(cmd->pool, &arg);
+ conf->params = arg;
+ conf->library_set = 1;
+
+ return NULL;
+}
+
+static const char *set_crypto_passphrase(cmd_parms * cmd, void *config, const char *arg)
+{
+ int arglen = strlen(arg);
+ char **argv;
+ char *result;
+ const char **passphrase;
+ session_crypto_dir_conf *dconf = (session_crypto_dir_conf *) config;
+
+ passphrase = apr_array_push(dconf->passphrases);
+
+ if ((arglen > 5) && strncmp(arg, "exec:", 5) == 0) {
+ if (apr_tokenize_to_argv(arg+5, &argv, cmd->temp_pool) != APR_SUCCESS) {
+ return apr_pstrcat(cmd->pool,
+ "Unable to parse exec arguments from ",
+ arg+5, NULL);
+ }
+ argv[0] = ap_server_root_relative(cmd->temp_pool, argv[0]);
+
+ if (!argv[0]) {
+ return apr_pstrcat(cmd->pool,
+ "Invalid SessionCryptoPassphrase exec location:",
+ arg+5, NULL);
+ }
+ result = ap_get_exec_line(cmd->pool,
+ (const char*)argv[0], (const char * const *)argv);
+
+ if(!result) {
+ return apr_pstrcat(cmd->pool,
+ "Unable to get bind password from exec of ",
+ arg+5, NULL);
+ }
+ *passphrase = result;
+ }
+ else {
+ *passphrase = arg;
+ }
+
+ dconf->passphrases_set = 1;
+
+ return NULL;
+}
+
+static const char *set_crypto_passphrase_file(cmd_parms *cmd, void *config,
+ const char *filename)
+{
+ char buffer[MAX_STRING_LEN];
+ char *arg;
+ const char *args;
+ ap_configfile_t *file;
+ apr_status_t rv;
+
+ filename = ap_server_root_relative(cmd->temp_pool, filename);
+ rv = ap_pcfg_openfile(&file, cmd->temp_pool, filename);
+ if (rv != APR_SUCCESS) {
+ return apr_psprintf(cmd->pool, "%s: Could not open file %s: %pm",
+ cmd->cmd->name, filename, &rv);
+ }
+
+ while (!(ap_cfg_getline(buffer, sizeof(buffer), file))) {
+ args = buffer;
+ while (*(arg = ap_getword_conf(cmd->pool, &args)) != '\0') {
+ if (*arg == '#') {
+ break;
+ }
+ set_crypto_passphrase(cmd, config, arg);
+ }
+ }
+
+ ap_cfg_closefile(file);
+
+ return NULL;
+}
+
+static const char *set_crypto_cipher(cmd_parms * cmd, void *config, const char *cipher)
+{
+ session_crypto_dir_conf *dconf = (session_crypto_dir_conf *) config;
+
+ dconf->cipher = cipher;
+ dconf->cipher_set = 1;
+
+ return NULL;
+}
+
+static const command_rec session_crypto_cmds[] =
+{
+ AP_INIT_ITERATE("SessionCryptoPassphrase", set_crypto_passphrase, NULL, RSRC_CONF|OR_AUTHCFG,
+ "The passphrase(s) used to encrypt the session. First will be used for encryption, all phrases will be accepted for decryption"),
+ AP_INIT_TAKE1("SessionCryptoPassphraseFile", set_crypto_passphrase_file, NULL, RSRC_CONF|ACCESS_CONF,
+ "File containing passphrase(s) used to encrypt the session, one per line. First will be used for encryption, all phrases will be accepted for decryption"),
+ AP_INIT_TAKE1("SessionCryptoCipher", set_crypto_cipher, NULL, RSRC_CONF|OR_AUTHCFG,
+ "The underlying crypto cipher to use"),
+ AP_INIT_RAW_ARGS("SessionCryptoDriver", set_crypto_driver, NULL, RSRC_CONF,
+ "The underlying crypto library driver to use"),
+ { NULL }
+};
+
+static void register_hooks(apr_pool_t * p)
+{
+ ap_hook_session_encode(session_crypto_encode, NULL, NULL, APR_HOOK_LAST);
+ ap_hook_session_decode(session_crypto_decode, NULL, NULL, APR_HOOK_FIRST);
+ ap_hook_post_config(session_crypto_init, NULL, NULL, APR_HOOK_LAST);
+}
+
+AP_DECLARE_MODULE(session_crypto) =
+{
+ STANDARD20_MODULE_STUFF,
+ create_session_crypto_dir_config, /* dir config creater */
+ merge_session_crypto_dir_config, /* dir merger --- default is to override */
+ create_session_crypto_config, /* server config */
+ NULL, /* merge server config */
+ session_crypto_cmds, /* command apr_table_t */
+ register_hooks /* register hooks */
+};
+
+#endif
diff --git a/modules/session/mod_session_crypto.dep b/modules/session/mod_session_crypto.dep
new file mode 100644
index 0000000..fff2fa5
--- /dev/null
+++ b/modules/session/mod_session_crypto.dep
@@ -0,0 +1,57 @@
+# Microsoft Developer Studio Generated Dependency File, included by mod_session_crypto.mak
+
+..\..\build\win32\httpd.rc : \
+ "..\..\include\ap_release.h"\
+
+
+.\mod_session_crypto.c : \
+ "..\..\include\ap_config.h"\
+ "..\..\include\ap_config_layout.h"\
+ "..\..\include\ap_expr.h"\
+ "..\..\include\ap_hooks.h"\
+ "..\..\include\ap_mmn.h"\
+ "..\..\include\ap_regex.h"\
+ "..\..\include\ap_release.h"\
+ "..\..\include\apache_noprobes.h"\
+ "..\..\include\http_config.h"\
+ "..\..\include\http_core.h"\
+ "..\..\include\http_log.h"\
+ "..\..\include\httpd.h"\
+ "..\..\include\os.h"\
+ "..\..\include\util_cfgtree.h"\
+ "..\..\include\util_filter.h"\
+ "..\..\srclib\apr-util\include\apr_base64.h"\
+ "..\..\srclib\apr-util\include\apr_buckets.h"\
+ "..\..\srclib\apr-util\include\apr_crypto.h"\
+ "..\..\srclib\apr-util\include\apr_hooks.h"\
+ "..\..\srclib\apr-util\include\apr_optional.h"\
+ "..\..\srclib\apr-util\include\apr_optional_hooks.h"\
+ "..\..\srclib\apr-util\include\apr_uri.h"\
+ "..\..\srclib\apr-util\include\apr_uuid.h"\
+ "..\..\srclib\apr-util\include\apu.h"\
+ "..\..\srclib\apr-util\include\apu_errno.h"\
+ "..\..\srclib\apr-util\include\apu_version.h"\
+ "..\..\srclib\apr\include\apr.h"\
+ "..\..\srclib\apr\include\apr_allocator.h"\
+ "..\..\srclib\apr\include\apr_errno.h"\
+ "..\..\srclib\apr\include\apr_file_info.h"\
+ "..\..\srclib\apr\include\apr_file_io.h"\
+ "..\..\srclib\apr\include\apr_general.h"\
+ "..\..\srclib\apr\include\apr_hash.h"\
+ "..\..\srclib\apr\include\apr_inherit.h"\
+ "..\..\srclib\apr\include\apr_lib.h"\
+ "..\..\srclib\apr\include\apr_mmap.h"\
+ "..\..\srclib\apr\include\apr_network_io.h"\
+ "..\..\srclib\apr\include\apr_poll.h"\
+ "..\..\srclib\apr\include\apr_pools.h"\
+ "..\..\srclib\apr\include\apr_ring.h"\
+ "..\..\srclib\apr\include\apr_strings.h"\
+ "..\..\srclib\apr\include\apr_tables.h"\
+ "..\..\srclib\apr\include\apr_thread_mutex.h"\
+ "..\..\srclib\apr\include\apr_thread_proc.h"\
+ "..\..\srclib\apr\include\apr_time.h"\
+ "..\..\srclib\apr\include\apr_user.h"\
+ "..\..\srclib\apr\include\apr_version.h"\
+ "..\..\srclib\apr\include\apr_want.h"\
+ ".\mod_session.h"\
+
diff --git a/modules/session/mod_session_crypto.dsp b/modules/session/mod_session_crypto.dsp
new file mode 100644
index 0000000..37aba02
--- /dev/null
+++ b/modules/session/mod_session_crypto.dsp
@@ -0,0 +1,111 @@
+# Microsoft Developer Studio Project File - Name="mod_session_crypto" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=mod_session_crypto - Win32 Release
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "mod_session_crypto.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "mod_session_crypto.mak" CFG="mod_session_crypto - Win32 Release"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "mod_session_crypto - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "mod_session_crypto - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "mod_session_crypto - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c
+# ADD CPP /nologo /MD /W3 /O2 /Oy- /Zi /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Release\mod_session_crypto_src" /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /fo"Release/mod_session_crypto.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_session_crypto.so" /d LONG_NAME="session_crypto_module for Apache"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /out:".\Release\mod_session_crypto.so" /base:@..\..\os\win32\BaseAddr.ref,mod_session_crypto.so
+# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Release\mod_session_crypto.so" /base:@..\..\os\win32\BaseAddr.ref,mod_session_crypto.so /opt:ref
+# Begin Special Build Tool
+TargetPath=.\Release\mod_session_crypto.so
+SOURCE="$(InputPath)"
+PostBuild_Desc=Embed .manifest
+PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
+# End Special Build Tool
+
+!ELSEIF "$(CFG)" == "mod_session_crypto - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MDd /W3 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
+# ADD CPP /nologo /MDd /W3 /EHsc /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Debug\mod_session_crypto_src" /FD /c
+# ADD BASE MTL /nologo /D "_DEBUG" /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /fo"Debug/mod_session_crypto.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_session_crypto.so" /d LONG_NAME="session_crypto_module for Apache"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_session_crypto.so" /base:@..\..\os\win32\BaseAddr.ref,mod_session_crypto.so
+# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_session_crypto.so" /base:@..\..\os\win32\BaseAddr.ref,mod_session_crypto.so
+# Begin Special Build Tool
+TargetPath=.\Debug\mod_session_crypto.so
+SOURCE="$(InputPath)"
+PostBuild_Desc=Embed .manifest
+PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
+# End Special Build Tool
+
+!ENDIF
+
+# Begin Target
+
+# Name "mod_session_crypto - Win32 Release"
+# Name "mod_session_crypto - Win32 Debug"
+# Begin Source File
+
+SOURCE=.\mod_session_crypto.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\build\win32\httpd.rc
+# End Source File
+# End Target
+# End Project
diff --git a/modules/session/mod_session_crypto.mak b/modules/session/mod_session_crypto.mak
new file mode 100644
index 0000000..13a4c67
--- /dev/null
+++ b/modules/session/mod_session_crypto.mak
@@ -0,0 +1,381 @@
+# Microsoft Developer Studio Generated NMAKE File, Based on mod_session_crypto.dsp
+!IF "$(CFG)" == ""
+CFG=mod_session_crypto - Win32 Release
+!MESSAGE No configuration specified. Defaulting to mod_session_crypto - Win32 Release.
+!ENDIF
+
+!IF "$(CFG)" != "mod_session_crypto - Win32 Release" && "$(CFG)" != "mod_session_crypto - Win32 Debug"
+!MESSAGE Invalid configuration "$(CFG)" specified.
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "mod_session_crypto.mak" CFG="mod_session_crypto - Win32 Release"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "mod_session_crypto - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "mod_session_crypto - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+!ERROR An invalid configuration is specified.
+!ENDIF
+
+!IF "$(OS)" == "Windows_NT"
+NULL=
+!ELSE
+NULL=nul
+!ENDIF
+
+!IF "$(CFG)" == "mod_session_crypto - Win32 Release"
+
+OUTDIR=.\Release
+INTDIR=.\Release
+DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
+# Begin Custom Macros
+OutDir=.\Release
+# End Custom Macros
+
+!IF "$(RECURSE)" == "0"
+
+ALL : "$(OUTDIR)\mod_session_crypto.so" "$(DS_POSTBUILD_DEP)"
+
+!ELSE
+
+ALL : "mod_session - Win32 Release" "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_session_crypto.so" "$(DS_POSTBUILD_DEP)"
+
+!ENDIF
+
+!IF "$(RECURSE)" == "1"
+CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" "mod_session - Win32 ReleaseCLEAN"
+!ELSE
+CLEAN :
+!ENDIF
+ -@erase "$(INTDIR)\mod_session_crypto.obj"
+ -@erase "$(INTDIR)\mod_session_crypto.res"
+ -@erase "$(INTDIR)\mod_session_crypto_src.idb"
+ -@erase "$(INTDIR)\mod_session_crypto_src.pdb"
+ -@erase "$(OUTDIR)\mod_session_crypto.exp"
+ -@erase "$(OUTDIR)\mod_session_crypto.lib"
+ -@erase "$(OUTDIR)\mod_session_crypto.pdb"
+ -@erase "$(OUTDIR)\mod_session_crypto.so"
+
+"$(OUTDIR)" :
+ if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
+
+CPP=cl.exe
+CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_session_crypto_src" /FD /c
+
+.c{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.c{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+MTL=midl.exe
+MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32
+RSC=rc.exe
+RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_session_crypto.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_session_crypto.so" /d LONG_NAME="session_crypto_module for Apache"
+BSC32=bscmake.exe
+BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_session_crypto.bsc"
+BSC32_SBRS= \
+
+LINK32=link.exe
+LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_session_crypto.pdb" /debug /out:"$(OUTDIR)\mod_session_crypto.so" /implib:"$(OUTDIR)\mod_session_crypto.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_session_crypto.so /opt:ref
+LINK32_OBJS= \
+ "$(INTDIR)\mod_session_crypto.obj" \
+ "$(INTDIR)\mod_session_crypto.res" \
+ "..\..\srclib\apr\Release\libapr-1.lib" \
+ "..\..\srclib\apr-util\Release\libaprutil-1.lib" \
+ "..\..\Release\libhttpd.lib" \
+ "$(OUTDIR)\mod_session.lib"
+
+"$(OUTDIR)\mod_session_crypto.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
+ $(LINK32) @<<
+ $(LINK32_FLAGS) $(LINK32_OBJS)
+<<
+
+TargetPath=.\Release\mod_session_crypto.so
+SOURCE="$(InputPath)"
+PostBuild_Desc=Embed .manifest
+DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
+
+# Begin Custom Macros
+OutDir=.\Release
+# End Custom Macros
+
+"$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_session_crypto.so"
+ if exist .\Release\mod_session_crypto.so.manifest mt.exe -manifest .\Release\mod_session_crypto.so.manifest -outputresource:.\Release\mod_session_crypto.so;2
+ echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
+
+!ELSEIF "$(CFG)" == "mod_session_crypto - Win32 Debug"
+
+OUTDIR=.\Debug
+INTDIR=.\Debug
+DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
+# Begin Custom Macros
+OutDir=.\Debug
+# End Custom Macros
+
+!IF "$(RECURSE)" == "0"
+
+ALL : "$(OUTDIR)\mod_session_crypto.so" "$(DS_POSTBUILD_DEP)"
+
+!ELSE
+
+ALL : "mod_session - Win32 Debug" "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_session_crypto.so" "$(DS_POSTBUILD_DEP)"
+
+!ENDIF
+
+!IF "$(RECURSE)" == "1"
+CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" "mod_session - Win32 DebugCLEAN"
+!ELSE
+CLEAN :
+!ENDIF
+ -@erase "$(INTDIR)\mod_session_crypto.obj"
+ -@erase "$(INTDIR)\mod_session_crypto.res"
+ -@erase "$(INTDIR)\mod_session_crypto_src.idb"
+ -@erase "$(INTDIR)\mod_session_crypto_src.pdb"
+ -@erase "$(OUTDIR)\mod_session_crypto.exp"
+ -@erase "$(OUTDIR)\mod_session_crypto.lib"
+ -@erase "$(OUTDIR)\mod_session_crypto.pdb"
+ -@erase "$(OUTDIR)\mod_session_crypto.so"
+
+"$(OUTDIR)" :
+ if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
+
+CPP=cl.exe
+CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_session_crypto_src" /FD /EHsc /c
+
+.c{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.c{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+MTL=midl.exe
+MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32
+RSC=rc.exe
+RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_session_crypto.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_session_crypto.so" /d LONG_NAME="session_crypto_module for Apache"
+BSC32=bscmake.exe
+BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_session_crypto.bsc"
+BSC32_SBRS= \
+
+LINK32=link.exe
+LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_session_crypto.pdb" /debug /out:"$(OUTDIR)\mod_session_crypto.so" /implib:"$(OUTDIR)\mod_session_crypto.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_session_crypto.so
+LINK32_OBJS= \
+ "$(INTDIR)\mod_session_crypto.obj" \
+ "$(INTDIR)\mod_session_crypto.res" \
+ "..\..\srclib\apr\Debug\libapr-1.lib" \
+ "..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
+ "..\..\Debug\libhttpd.lib" \
+ "$(OUTDIR)\mod_session.lib"
+
+"$(OUTDIR)\mod_session_crypto.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
+ $(LINK32) @<<
+ $(LINK32_FLAGS) $(LINK32_OBJS)
+<<
+
+TargetPath=.\Debug\mod_session_crypto.so
+SOURCE="$(InputPath)"
+PostBuild_Desc=Embed .manifest
+DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
+
+# Begin Custom Macros
+OutDir=.\Debug
+# End Custom Macros
+
+"$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_session_crypto.so"
+ if exist .\Debug\mod_session_crypto.so.manifest mt.exe -manifest .\Debug\mod_session_crypto.so.manifest -outputresource:.\Debug\mod_session_crypto.so;2
+ echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
+
+!ENDIF
+
+
+!IF "$(NO_EXTERNAL_DEPS)" != "1"
+!IF EXISTS("mod_session_crypto.dep")
+!INCLUDE "mod_session_crypto.dep"
+!ELSE
+!MESSAGE Warning: cannot find "mod_session_crypto.dep"
+!ENDIF
+!ENDIF
+
+
+!IF "$(CFG)" == "mod_session_crypto - Win32 Release" || "$(CFG)" == "mod_session_crypto - Win32 Debug"
+
+!IF "$(CFG)" == "mod_session_crypto - Win32 Release"
+
+"libapr - Win32 Release" :
+ cd ".\..\..\srclib\apr"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release"
+ cd "..\..\modules\session"
+
+"libapr - Win32 ReleaseCLEAN" :
+ cd ".\..\..\srclib\apr"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN
+ cd "..\..\modules\session"
+
+!ELSEIF "$(CFG)" == "mod_session_crypto - Win32 Debug"
+
+"libapr - Win32 Debug" :
+ cd ".\..\..\srclib\apr"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug"
+ cd "..\..\modules\session"
+
+"libapr - Win32 DebugCLEAN" :
+ cd ".\..\..\srclib\apr"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN
+ cd "..\..\modules\session"
+
+!ENDIF
+
+!IF "$(CFG)" == "mod_session_crypto - Win32 Release"
+
+"libaprutil - Win32 Release" :
+ cd ".\..\..\srclib\apr-util"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release"
+ cd "..\..\modules\session"
+
+"libaprutil - Win32 ReleaseCLEAN" :
+ cd ".\..\..\srclib\apr-util"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN
+ cd "..\..\modules\session"
+
+!ELSEIF "$(CFG)" == "mod_session_crypto - Win32 Debug"
+
+"libaprutil - Win32 Debug" :
+ cd ".\..\..\srclib\apr-util"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug"
+ cd "..\..\modules\session"
+
+"libaprutil - Win32 DebugCLEAN" :
+ cd ".\..\..\srclib\apr-util"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN
+ cd "..\..\modules\session"
+
+!ENDIF
+
+!IF "$(CFG)" == "mod_session_crypto - Win32 Release"
+
+"libhttpd - Win32 Release" :
+ cd ".\..\.."
+ $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release"
+ cd ".\modules\session"
+
+"libhttpd - Win32 ReleaseCLEAN" :
+ cd ".\..\.."
+ $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN
+ cd ".\modules\session"
+
+!ELSEIF "$(CFG)" == "mod_session_crypto - Win32 Debug"
+
+"libhttpd - Win32 Debug" :
+ cd ".\..\.."
+ $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug"
+ cd ".\modules\session"
+
+"libhttpd - Win32 DebugCLEAN" :
+ cd ".\..\.."
+ $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN
+ cd ".\modules\session"
+
+!ENDIF
+
+!IF "$(CFG)" == "mod_session_crypto - Win32 Release"
+
+"mod_session - Win32 Release" :
+ cd "."
+ $(MAKE) /$(MAKEFLAGS) /F ".\mod_session.mak" CFG="mod_session - Win32 Release"
+ cd "."
+
+"mod_session - Win32 ReleaseCLEAN" :
+ cd "."
+ $(MAKE) /$(MAKEFLAGS) /F ".\mod_session.mak" CFG="mod_session - Win32 Release" RECURSE=1 CLEAN
+ cd "."
+
+!ELSEIF "$(CFG)" == "mod_session_crypto - Win32 Debug"
+
+"mod_session - Win32 Debug" :
+ cd "."
+ $(MAKE) /$(MAKEFLAGS) /F ".\mod_session.mak" CFG="mod_session - Win32 Debug"
+ cd "."
+
+"mod_session - Win32 DebugCLEAN" :
+ cd "."
+ $(MAKE) /$(MAKEFLAGS) /F ".\mod_session.mak" CFG="mod_session - Win32 Debug" RECURSE=1 CLEAN
+ cd "."
+
+!ENDIF
+
+SOURCE=..\..\build\win32\httpd.rc
+
+!IF "$(CFG)" == "mod_session_crypto - Win32 Release"
+
+
+"$(INTDIR)\mod_session_crypto.res" : $(SOURCE) "$(INTDIR)"
+ $(RSC) /l 0x409 /fo"$(INTDIR)\mod_session_crypto.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_session_crypto.so" /d LONG_NAME="session_crypto_module for Apache" $(SOURCE)
+
+
+!ELSEIF "$(CFG)" == "mod_session_crypto - Win32 Debug"
+
+
+"$(INTDIR)\mod_session_crypto.res" : $(SOURCE) "$(INTDIR)"
+ $(RSC) /l 0x409 /fo"$(INTDIR)\mod_session_crypto.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_session_crypto.so" /d LONG_NAME="session_crypto_module for Apache" $(SOURCE)
+
+
+!ENDIF
+
+SOURCE=.\mod_session_crypto.c
+
+"$(INTDIR)\mod_session_crypto.obj" : $(SOURCE) "$(INTDIR)"
+
+
+
+!ENDIF
+
diff --git a/modules/session/mod_session_dbd.c b/modules/session/mod_session_dbd.c
new file mode 100644
index 0000000..0be7306
--- /dev/null
+++ b/modules/session/mod_session_dbd.c
@@ -0,0 +1,640 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "mod_session.h"
+#include "apr_lib.h"
+#include "apr_strings.h"
+#include "http_log.h"
+#include "util_cookies.h"
+#include "apr_dbd.h"
+#include "mod_dbd.h"
+#include "mpm_common.h"
+
+#define MOD_SESSION_DBD "mod_session_dbd"
+
+module AP_MODULE_DECLARE_DATA session_dbd_module;
+
+/**
+ * Structure to carry the per-dir session config.
+ */
+typedef struct {
+ const char *name;
+ int name_set;
+ const char *name_attrs;
+ const char *name2;
+ int name2_set;
+ const char *name2_attrs;
+ int peruser;
+ int peruser_set;
+ int remove;
+ int remove_set;
+ const char *selectlabel;
+ const char *insertlabel;
+ const char *updatelabel;
+ const char *deletelabel;
+} session_dbd_dir_conf;
+
+/* optional function - look it up once in post_config */
+static ap_dbd_t *(*session_dbd_acquire_fn) (request_rec *) = NULL;
+static void (*session_dbd_prepare_fn) (server_rec *, const char *, const char *) = NULL;
+
+/**
+ * Initialise the database.
+ *
+ * If the mod_dbd module is missing, this method will return APR_EGENERAL.
+ */
+static apr_status_t dbd_init(request_rec *r, const char *query, ap_dbd_t **dbdp,
+ apr_dbd_prepared_t **statementp)
+{
+ ap_dbd_t *dbd;
+ apr_dbd_prepared_t *statement;
+
+ if (!session_dbd_prepare_fn || !session_dbd_acquire_fn) {
+ session_dbd_prepare_fn = APR_RETRIEVE_OPTIONAL_FN(ap_dbd_prepare);
+ session_dbd_acquire_fn = APR_RETRIEVE_OPTIONAL_FN(ap_dbd_acquire);
+ if (!session_dbd_prepare_fn || !session_dbd_acquire_fn) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01850)
+ "You must load mod_dbd to enable AuthDBD functions");
+ return APR_EGENERAL;
+ }
+ }
+
+ dbd = session_dbd_acquire_fn(r);
+ if (!dbd) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01851)
+ "failed to acquire database connection");
+ return APR_EGENERAL;
+ }
+
+ statement = apr_hash_get(dbd->prepared, query, APR_HASH_KEY_STRING);
+ if (!statement) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01852)
+ "failed to find the prepared statement called '%s'", query);
+ return APR_EGENERAL;
+ }
+
+ *dbdp = dbd;
+ *statementp = statement;
+
+ return APR_SUCCESS;
+}
+
+/**
+ * Load the session by the key specified.
+ *
+ * The session value is allocated using the passed apr_pool_t.
+ */
+static apr_status_t dbd_load(apr_pool_t *p, request_rec * r,
+ const char *key, const char **val)
+{
+
+ apr_status_t rv;
+ ap_dbd_t *dbd = NULL;
+ apr_dbd_prepared_t *statement = NULL;
+ apr_dbd_results_t *res = NULL;
+ apr_dbd_row_t *row = NULL;
+ apr_int64_t expiry = (apr_int64_t) apr_time_now();
+
+ session_dbd_dir_conf *conf = ap_get_module_config(r->per_dir_config,
+ &session_dbd_module);
+
+ if (conf->selectlabel == NULL) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01853)
+ "no SessionDBDselectlabel has been specified");
+ return APR_EGENERAL;
+ }
+
+ rv = dbd_init(r, conf->selectlabel, &dbd, &statement);
+ if (rv) {
+ return rv;
+ }
+ rv = apr_dbd_pvbselect(dbd->driver, r->pool, dbd->handle, &res, statement,
+ 0, key, &expiry, NULL);
+ if (rv) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01854)
+ "query execution error saving session '%s' "
+ "in database using query '%s': %s", key, conf->selectlabel,
+ apr_dbd_error(dbd->driver, dbd->handle, rv));
+ return APR_EGENERAL;
+ }
+ for (rv = apr_dbd_get_row(dbd->driver, r->pool, res, &row, -1);
+ rv != -1;
+ rv = apr_dbd_get_row(dbd->driver, r->pool, res, &row, -1)) {
+ if (rv != 0) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01855)
+ "error retrieving results while saving '%s' "
+ "in database using query '%s': %s", key, conf->selectlabel,
+ apr_dbd_error(dbd->driver, dbd->handle, rv));
+ return APR_EGENERAL;
+ }
+ if (*val == NULL) {
+ *val = apr_pstrdup(p, apr_dbd_get_entry(dbd->driver, row, 0));
+ }
+ /* we can't break out here or row won't get cleaned up */
+ }
+
+ return APR_SUCCESS;
+
+}
+
+/**
+ * Load the session by firing off a dbd query.
+ *
+ * If the session is anonymous, the session key will be extracted from
+ * the cookie specified. Failing that, the session key will be extracted
+ * from the GET parameters.
+ *
+ * If the session is keyed by the username, the session will be extracted
+ * by that.
+ *
+ * If no session is found, an empty session will be created.
+ *
+ * On success, this returns OK.
+ */
+static apr_status_t session_dbd_load(request_rec * r, session_rec ** z)
+{
+
+ session_dbd_dir_conf *conf = ap_get_module_config(r->per_dir_config,
+ &session_dbd_module);
+
+ apr_status_t ret = APR_SUCCESS;
+ session_rec *zz = NULL;
+ const char *name = NULL;
+ const char *note = NULL;
+ const char *val = NULL;
+ const char *key = NULL;
+ request_rec *m = r->main ? r->main : r;
+
+ /* is our session in a cookie? */
+ if (conf->name2_set) {
+ name = conf->name2;
+ }
+ else if (conf->name_set) {
+ name = conf->name;
+ }
+ else if (conf->peruser_set && r->user) {
+ name = r->user;
+ }
+ else {
+ return DECLINED;
+ }
+
+ /* first look in the notes */
+ note = apr_pstrcat(m->pool, MOD_SESSION_DBD, name, NULL);
+ zz = (session_rec *)apr_table_get(m->notes, note);
+ if (zz) {
+ *z = zz;
+ return OK;
+ }
+
+ /* load anonymous sessions */
+ if (conf->name_set || conf->name2_set) {
+
+ /* load an RFC2109 or RFC2965 compliant cookie */
+ ap_cookie_read(r, name, &key, conf->remove);
+ if (key) {
+ ret = dbd_load(m->pool, r, key, &val);
+ if (ret != APR_SUCCESS) {
+ return ret;
+ }
+ }
+
+ }
+
+ /* load named session */
+ else if (conf->peruser) {
+ if (r->user) {
+ ret = dbd_load(m->pool, r, r->user, &val);
+ if (ret != APR_SUCCESS) {
+ return ret;
+ }
+ }
+ }
+
+ /* otherwise not for us */
+ else {
+ return DECLINED;
+ }
+
+ /* create a new session and return it */
+ zz = (session_rec *) apr_pcalloc(m->pool, sizeof(session_rec));
+ zz->pool = m->pool;
+ zz->entries = apr_table_make(zz->pool, 10);
+ if (key && val) {
+ apr_uuid_t *uuid = apr_pcalloc(zz->pool, sizeof(apr_uuid_t));
+ if (APR_SUCCESS == apr_uuid_parse(uuid, key)) {
+ zz->uuid = uuid;
+ }
+ }
+ zz->encoded = val;
+ *z = zz;
+
+ /* put the session in the notes so we don't have to parse it again */
+ apr_table_setn(m->notes, note, (char *)zz);
+
+ return OK;
+
+}
+
+/**
+ * Save the session by the key specified.
+ */
+static apr_status_t dbd_save(request_rec * r, const char *oldkey,
+ const char *newkey, const char *val, apr_int64_t expiry)
+{
+
+ apr_status_t rv;
+ ap_dbd_t *dbd = NULL;
+ apr_dbd_prepared_t *statement;
+ int rows = 0;
+
+ session_dbd_dir_conf *conf = ap_get_module_config(r->per_dir_config,
+ &session_dbd_module);
+
+ if (conf->updatelabel == NULL) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01856)
+ "no SessionDBDupdatelabel has been specified");
+ return APR_EGENERAL;
+ }
+
+ rv = dbd_init(r, conf->updatelabel, &dbd, &statement);
+ if (rv) {
+ return rv;
+ }
+
+ if (oldkey) {
+ rv = apr_dbd_pvbquery(dbd->driver, r->pool, dbd->handle, &rows,
+ statement, val, &expiry, newkey, oldkey, NULL);
+ if (rv) {
+ ap_log_rerror(
+ APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01857) "query execution error updating session '%s' "
+ "using database query '%s': %s/%s", oldkey, newkey, conf->updatelabel, apr_dbd_error(dbd->driver, dbd->handle, rv));
+ return APR_EGENERAL;
+ }
+
+ /*
+ * if some rows were updated it means a session existed and was updated,
+ * so we are done.
+ */
+ if (rows != 0) {
+ return APR_SUCCESS;
+ }
+ }
+
+ if (conf->insertlabel == NULL) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01858)
+ "no SessionDBDinsertlabel has been specified");
+ return APR_EGENERAL;
+ }
+
+ rv = dbd_init(r, conf->insertlabel, &dbd, &statement);
+ if (rv) {
+ return rv;
+ }
+ rv = apr_dbd_pvbquery(dbd->driver, r->pool, dbd->handle, &rows, statement,
+ val, &expiry, newkey, NULL);
+ if (rv) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01859)
+ "query execution error inserting session '%s' "
+ "in database with '%s': %s", newkey, conf->insertlabel,
+ apr_dbd_error(dbd->driver, dbd->handle, rv));
+ return APR_EGENERAL;
+ }
+
+ /*
+ * if some rows were inserted it means a session was inserted, so we are
+ * done.
+ */
+ if (rows != 0) {
+ return APR_SUCCESS;
+ }
+
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01860)
+ "the session insert query did not cause any rows to be added "
+ "to the database for session '%s', session not inserted", newkey);
+
+ return APR_EGENERAL;
+
+}
+
+/**
+ * Remove the session by the key specified.
+ */
+static apr_status_t dbd_remove(request_rec * r, const char *key)
+{
+
+ apr_status_t rv;
+ ap_dbd_t *dbd;
+ apr_dbd_prepared_t *statement;
+ int rows = 0;
+
+ session_dbd_dir_conf *conf = ap_get_module_config(r->per_dir_config,
+ &session_dbd_module);
+
+ if (conf->deletelabel == NULL) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01862)
+ "no SessionDBDdeletelabel has been specified");
+ return APR_EGENERAL;
+ }
+
+ rv = dbd_init(r, conf->deletelabel, &dbd, &statement);
+ if (rv != APR_SUCCESS) {
+ /* No need to do additional error logging here, it has already
+ been done in dbd_init if needed */
+ return rv;
+ }
+
+ rv = apr_dbd_pvbquery(dbd->driver, r->pool, dbd->handle, &rows, statement,
+ key, NULL);
+ if (rv != APR_SUCCESS) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01864)
+ "query execution error removing session '%s' "
+ "from database", key);
+ return rv;
+ }
+
+ return APR_SUCCESS;
+
+}
+
+/**
+ * Clean out expired sessions.
+ *
+ * TODO: We need to figure out a way to clean out expired sessions from the database.
+ * The monitor hook doesn't help us that much, as we have no handle into the
+ * server, and so we need to come up with a way to do this safely.
+ */
+static apr_status_t dbd_clean(apr_pool_t *p, server_rec *s)
+{
+
+ return APR_ENOTIMPL;
+
+}
+
+/**
+ * Save the session by firing off a dbd query.
+ *
+ * If the session is anonymous, save the session and write a cookie
+ * containing the uuid.
+ *
+ * If the session is keyed to the username, save the session using
+ * the username as a key.
+ *
+ * On success, this method will return APR_SUCCESS.
+ *
+ * @param r The request pointer.
+ * @param z A pointer to where the session will be written.
+ */
+static apr_status_t session_dbd_save(request_rec * r, session_rec * z)
+{
+
+ apr_status_t ret = APR_SUCCESS;
+ session_dbd_dir_conf *conf = ap_get_module_config(r->per_dir_config,
+ &session_dbd_module);
+
+ /* support anonymous sessions */
+ if (conf->name_set || conf->name2_set) {
+ char *oldkey = NULL, *newkey = NULL;
+
+ /* don't cache pages with a session */
+ apr_table_addn(r->headers_out, "Cache-Control", "no-cache");
+
+ /* if the session is new or changed, make a new session ID */
+ if (z->uuid) {
+ oldkey = apr_pcalloc(r->pool, APR_UUID_FORMATTED_LENGTH + 1);
+ apr_uuid_format(oldkey, z->uuid);
+ }
+ if (z->dirty || !oldkey) {
+ z->uuid = apr_pcalloc(z->pool, sizeof(apr_uuid_t));
+ apr_uuid_get(z->uuid);
+ newkey = apr_pcalloc(r->pool, APR_UUID_FORMATTED_LENGTH + 1);
+ apr_uuid_format(newkey, z->uuid);
+ }
+ else {
+ newkey = oldkey;
+ }
+
+ /* save the session with the uuid as key */
+ if (z->encoded && z->encoded[0]) {
+ ret = dbd_save(r, oldkey, newkey, z->encoded, z->expiry);
+ }
+ else {
+ ret = dbd_remove(r, oldkey);
+ }
+ if (ret != APR_SUCCESS) {
+ return ret;
+ }
+
+ /* create RFC2109 compliant cookie */
+ if (conf->name_set) {
+ ap_cookie_write(r, conf->name, newkey, conf->name_attrs, z->maxage,
+ r->headers_out, r->err_headers_out, NULL);
+ }
+
+ /* create RFC2965 compliant cookie */
+ if (conf->name2_set) {
+ ap_cookie_write2(r, conf->name2, newkey, conf->name2_attrs, z->maxage,
+ r->headers_out, r->err_headers_out, NULL);
+ }
+
+ return OK;
+
+ }
+
+ /* save named session */
+ else if (conf->peruser) {
+
+ /* don't cache pages with a session */
+ apr_table_addn(r->headers_out, "Cache-Control", "no-cache");
+
+ if (r->user) {
+ ret = dbd_save(r, r->user, r->user, z->encoded, z->expiry);
+ if (ret != APR_SUCCESS) {
+ return ret;
+ }
+ return OK;
+ }
+ else {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01865)
+ "peruser sessions can only be saved if a user is logged in, "
+ "session not saved: %s", r->uri);
+ }
+ }
+
+ return DECLINED;
+
+}
+
+/**
+ * This function performs housekeeping on the database, deleting expired
+ * sessions.
+ */
+static int session_dbd_monitor(apr_pool_t *p, server_rec *s)
+{
+ /* TODO handle housekeeping */
+ dbd_clean(p, s);
+ return OK;
+}
+
+
+static void *create_session_dbd_dir_config(apr_pool_t * p, char *dummy)
+{
+ session_dbd_dir_conf *new =
+ (session_dbd_dir_conf *) apr_pcalloc(p, sizeof(session_dbd_dir_conf));
+
+ new->remove = 1;
+
+ new->selectlabel = "selectsession";
+ new->insertlabel = "insertsession";
+ new->updatelabel = "updatesession";
+ new->deletelabel = "deletesession";
+
+ return (void *) new;
+}
+
+static void *merge_session_dbd_dir_config(apr_pool_t * p, void *basev, void *addv)
+{
+ session_dbd_dir_conf *new = (session_dbd_dir_conf *) apr_pcalloc(p, sizeof(session_dbd_dir_conf));
+ session_dbd_dir_conf *add = (session_dbd_dir_conf *) addv;
+ session_dbd_dir_conf *base = (session_dbd_dir_conf *) basev;
+
+ new->name = (add->name_set == 0) ? base->name : add->name;
+ new->name_attrs = (add->name_set == 0) ? base->name_attrs : add->name_attrs;
+ new->name_set = add->name_set || base->name_set;
+ new->name2 = (add->name2_set == 0) ? base->name2 : add->name2;
+ new->name2_attrs = (add->name2_set == 0) ? base->name2_attrs : add->name2_attrs;
+ new->name2_set = add->name2_set || base->name2_set;
+ new->peruser = (add->peruser_set == 0) ? base->peruser : add->peruser;
+ new->peruser_set = add->peruser_set || base->peruser_set;
+ new->remove = (add->remove_set == 0) ? base->remove : add->remove;
+ new->remove_set = add->remove_set || base->remove_set;
+ new->selectlabel = (!add->selectlabel) ? base->selectlabel : add->selectlabel;
+ new->updatelabel = (!add->updatelabel) ? base->updatelabel : add->updatelabel;
+ new->insertlabel = (!add->insertlabel) ? base->insertlabel : add->insertlabel;
+ new->deletelabel = (!add->deletelabel) ? base->deletelabel : add->deletelabel;
+
+ return new;
+}
+
+/**
+ * Sanity check a given string that it exists, is not empty,
+ * and does not contain special characters.
+ */
+static const char *check_string(cmd_parms * cmd, const char *string)
+{
+ if (APR_SUCCESS != ap_cookie_check_string(string)) {
+ return apr_pstrcat(cmd->pool, cmd->directive->directive,
+ " cannot be empty, or contain '=', ';' or '&'.",
+ NULL);
+ }
+ return NULL;
+}
+
+static const char *
+ set_dbd_peruser(cmd_parms * parms, void *dconf, int flag)
+{
+ session_dbd_dir_conf *conf = dconf;
+
+ conf->peruser = flag;
+ conf->peruser_set = 1;
+
+ return NULL;
+}
+
+static const char *
+ set_dbd_cookie_remove(cmd_parms * parms, void *dconf, int flag)
+{
+ session_dbd_dir_conf *conf = dconf;
+
+ conf->remove = flag;
+ conf->remove_set = 1;
+
+ return NULL;
+}
+
+static const char *set_cookie_name(cmd_parms * cmd, void *config, const char *args)
+{
+ char *last;
+ char *line = apr_pstrdup(cmd->pool, args);
+ session_dbd_dir_conf *conf = (session_dbd_dir_conf *) config;
+ char *cookie = apr_strtok(line, " \t", &last);
+ conf->name = cookie;
+ conf->name_set = 1;
+ while (apr_isspace(*last)) {
+ last++;
+ }
+ conf->name_attrs = last;
+ return check_string(cmd, cookie);
+}
+
+static const char *set_cookie_name2(cmd_parms * cmd, void *config, const char *args)
+{
+ char *last;
+ char *line = apr_pstrdup(cmd->pool, args);
+ session_dbd_dir_conf *conf = (session_dbd_dir_conf *) config;
+ char *cookie = apr_strtok(line, " \t", &last);
+ conf->name2 = cookie;
+ conf->name2_set = 1;
+ while (apr_isspace(*last)) {
+ last++;
+ }
+ conf->name2_attrs = last;
+ return check_string(cmd, cookie);
+}
+
+static const command_rec session_dbd_cmds[] =
+{
+ AP_INIT_TAKE1("SessionDBDSelectLabel", ap_set_string_slot,
+ (void *) APR_OFFSETOF(session_dbd_dir_conf, selectlabel), RSRC_CONF|OR_AUTHCFG,
+ "Query label used to select a new session"),
+ AP_INIT_TAKE1("SessionDBDInsertLabel", ap_set_string_slot,
+ (void *) APR_OFFSETOF(session_dbd_dir_conf, insertlabel), RSRC_CONF|OR_AUTHCFG,
+ "Query label used to insert a new session"),
+ AP_INIT_TAKE1("SessionDBDUpdateLabel", ap_set_string_slot,
+ (void *) APR_OFFSETOF(session_dbd_dir_conf, updatelabel), RSRC_CONF|OR_AUTHCFG,
+ "Query label used to update an existing session"),
+ AP_INIT_TAKE1("SessionDBDDeleteLabel", ap_set_string_slot,
+ (void *) APR_OFFSETOF(session_dbd_dir_conf, deletelabel), RSRC_CONF|OR_AUTHCFG,
+ "Query label used to delete an existing session"),
+ AP_INIT_FLAG("SessionDBDPerUser", set_dbd_peruser, NULL, RSRC_CONF|OR_AUTHCFG,
+ "Save the session per user"),
+ AP_INIT_FLAG("SessionDBDCookieRemove", set_dbd_cookie_remove, NULL, RSRC_CONF|OR_AUTHCFG,
+ "Remove the session cookie after session load. On by default."),
+ AP_INIT_RAW_ARGS("SessionDBDCookieName", set_cookie_name, NULL, RSRC_CONF|OR_AUTHCFG,
+ "The name of the RFC2109 cookie carrying the session key"),
+ AP_INIT_RAW_ARGS("SessionDBDCookieName2", set_cookie_name2, NULL, RSRC_CONF|OR_AUTHCFG,
+ "The name of the RFC2965 cookie carrying the session key"),
+ {NULL}
+};
+
+static void register_hooks(apr_pool_t * p)
+{
+ ap_hook_session_load(session_dbd_load, NULL, NULL, APR_HOOK_MIDDLE);
+ ap_hook_session_save(session_dbd_save, NULL, NULL, APR_HOOK_MIDDLE);
+ ap_hook_monitor(session_dbd_monitor, NULL, NULL, APR_HOOK_MIDDLE);
+}
+
+AP_DECLARE_MODULE(session_dbd) =
+{
+ STANDARD20_MODULE_STUFF,
+ create_session_dbd_dir_config, /* dir config creater */
+ merge_session_dbd_dir_config, /* dir merger --- default is to
+ * override */
+ NULL, /* server config */
+ NULL, /* merge server config */
+ session_dbd_cmds, /* command apr_table_t */
+ register_hooks /* register hooks */
+};
diff --git a/modules/session/mod_session_dbd.dep b/modules/session/mod_session_dbd.dep
new file mode 100644
index 0000000..9cb6808
--- /dev/null
+++ b/modules/session/mod_session_dbd.dep
@@ -0,0 +1,60 @@
+# Microsoft Developer Studio Generated Dependency File, included by mod_session_dbd.mak
+
+..\..\build\win32\httpd.rc : \
+ "..\..\include\ap_release.h"\
+
+
+.\mod_session_dbd.c : \
+ "..\..\include\ap_config.h"\
+ "..\..\include\ap_config_layout.h"\
+ "..\..\include\ap_hooks.h"\
+ "..\..\include\ap_mmn.h"\
+ "..\..\include\ap_mpm.h"\
+ "..\..\include\ap_regex.h"\
+ "..\..\include\ap_release.h"\
+ "..\..\include\apache_noprobes.h"\
+ "..\..\include\http_config.h"\
+ "..\..\include\http_log.h"\
+ "..\..\include\httpd.h"\
+ "..\..\include\mpm_common.h"\
+ "..\..\include\os.h"\
+ "..\..\include\scoreboard.h"\
+ "..\..\include\util_cfgtree.h"\
+ "..\..\include\util_cookies.h"\
+ "..\..\srclib\apr-util\include\apr_buckets.h"\
+ "..\..\srclib\apr-util\include\apr_dbd.h"\
+ "..\..\srclib\apr-util\include\apr_hooks.h"\
+ "..\..\srclib\apr-util\include\apr_optional.h"\
+ "..\..\srclib\apr-util\include\apr_optional_hooks.h"\
+ "..\..\srclib\apr-util\include\apr_uri.h"\
+ "..\..\srclib\apr-util\include\apr_uuid.h"\
+ "..\..\srclib\apr-util\include\apu.h"\
+ "..\..\srclib\apr\include\apr.h"\
+ "..\..\srclib\apr\include\apr_allocator.h"\
+ "..\..\srclib\apr\include\apr_dso.h"\
+ "..\..\srclib\apr\include\apr_errno.h"\
+ "..\..\srclib\apr\include\apr_file_info.h"\
+ "..\..\srclib\apr\include\apr_file_io.h"\
+ "..\..\srclib\apr\include\apr_general.h"\
+ "..\..\srclib\apr\include\apr_global_mutex.h"\
+ "..\..\srclib\apr\include\apr_hash.h"\
+ "..\..\srclib\apr\include\apr_inherit.h"\
+ "..\..\srclib\apr\include\apr_lib.h"\
+ "..\..\srclib\apr\include\apr_mmap.h"\
+ "..\..\srclib\apr\include\apr_network_io.h"\
+ "..\..\srclib\apr\include\apr_poll.h"\
+ "..\..\srclib\apr\include\apr_pools.h"\
+ "..\..\srclib\apr\include\apr_portable.h"\
+ "..\..\srclib\apr\include\apr_proc_mutex.h"\
+ "..\..\srclib\apr\include\apr_ring.h"\
+ "..\..\srclib\apr\include\apr_shm.h"\
+ "..\..\srclib\apr\include\apr_strings.h"\
+ "..\..\srclib\apr\include\apr_tables.h"\
+ "..\..\srclib\apr\include\apr_thread_mutex.h"\
+ "..\..\srclib\apr\include\apr_thread_proc.h"\
+ "..\..\srclib\apr\include\apr_time.h"\
+ "..\..\srclib\apr\include\apr_user.h"\
+ "..\..\srclib\apr\include\apr_want.h"\
+ "..\database\mod_dbd.h"\
+ ".\mod_session.h"\
+
diff --git a/modules/session/mod_session_dbd.dsp b/modules/session/mod_session_dbd.dsp
new file mode 100644
index 0000000..055b4e5
--- /dev/null
+++ b/modules/session/mod_session_dbd.dsp
@@ -0,0 +1,111 @@
+# Microsoft Developer Studio Project File - Name="mod_session_dbd" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=mod_session_dbd - Win32 Release
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "mod_session_dbd.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "mod_session_dbd.mak" CFG="mod_session_dbd - Win32 Release"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "mod_session_dbd - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "mod_session_dbd - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "mod_session_dbd - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c
+# ADD CPP /nologo /MD /W3 /O2 /Oy- /Zi /I "../database" /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Release\mod_session_dbd_src" /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /fo"Release/mod_session_dbd.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_session_dbd.so" /d LONG_NAME="session_dbd_module for Apache"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /out:".\Release\mod_session_dbd.so" /base:@..\..\os\win32\BaseAddr.ref,mod_session_dbd.so
+# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Release\mod_session_dbd.so" /base:@..\..\os\win32\BaseAddr.ref,mod_session_dbd.so /opt:ref
+# Begin Special Build Tool
+TargetPath=.\Release\mod_session_dbd.so
+SOURCE="$(InputPath)"
+PostBuild_Desc=Embed .manifest
+PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
+# End Special Build Tool
+
+!ELSEIF "$(CFG)" == "mod_session_dbd - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MDd /W3 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
+# ADD CPP /nologo /MDd /W3 /EHsc /Zi /Od /I "../database" /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Debug\mod_session_dbd_src" /FD /c
+# ADD BASE MTL /nologo /D "_DEBUG" /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /fo"Debug/mod_session_dbd.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_session_dbd.so" /d LONG_NAME="session_dbd_module for Apache"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_session_dbd.so" /base:@..\..\os\win32\BaseAddr.ref,mod_session_dbd.so
+# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_session_dbd.so" /base:@..\..\os\win32\BaseAddr.ref,mod_session_dbd.so
+# Begin Special Build Tool
+TargetPath=.\Debug\mod_session_dbd.so
+SOURCE="$(InputPath)"
+PostBuild_Desc=Embed .manifest
+PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
+# End Special Build Tool
+
+!ENDIF
+
+# Begin Target
+
+# Name "mod_session_dbd - Win32 Release"
+# Name "mod_session_dbd - Win32 Debug"
+# Begin Source File
+
+SOURCE=.\mod_session_dbd.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\build\win32\httpd.rc
+# End Source File
+# End Target
+# End Project
diff --git a/modules/session/mod_session_dbd.mak b/modules/session/mod_session_dbd.mak
new file mode 100644
index 0000000..e16c61e
--- /dev/null
+++ b/modules/session/mod_session_dbd.mak
@@ -0,0 +1,409 @@
+# Microsoft Developer Studio Generated NMAKE File, Based on mod_session_dbd.dsp
+!IF "$(CFG)" == ""
+CFG=mod_session_dbd - Win32 Release
+!MESSAGE No configuration specified. Defaulting to mod_session_dbd - Win32 Release.
+!ENDIF
+
+!IF "$(CFG)" != "mod_session_dbd - Win32 Release" && "$(CFG)" != "mod_session_dbd - Win32 Debug"
+!MESSAGE Invalid configuration "$(CFG)" specified.
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "mod_session_dbd.mak" CFG="mod_session_dbd - Win32 Release"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "mod_session_dbd - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "mod_session_dbd - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+!ERROR An invalid configuration is specified.
+!ENDIF
+
+!IF "$(OS)" == "Windows_NT"
+NULL=
+!ELSE
+NULL=nul
+!ENDIF
+
+!IF "$(CFG)" == "mod_session_dbd - Win32 Release"
+
+OUTDIR=.\Release
+INTDIR=.\Release
+DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
+# Begin Custom Macros
+OutDir=.\Release
+# End Custom Macros
+
+!IF "$(RECURSE)" == "0"
+
+ALL : "$(OUTDIR)\mod_session_dbd.so" "$(DS_POSTBUILD_DEP)"
+
+!ELSE
+
+ALL : "mod_session - Win32 Release" "mod_dbd - Win32 Release" "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_session_dbd.so" "$(DS_POSTBUILD_DEP)"
+
+!ENDIF
+
+!IF "$(RECURSE)" == "1"
+CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" "mod_dbd - Win32 ReleaseCLEAN" "mod_session - Win32 ReleaseCLEAN"
+!ELSE
+CLEAN :
+!ENDIF
+ -@erase "$(INTDIR)\mod_session_dbd.obj"
+ -@erase "$(INTDIR)\mod_session_dbd.res"
+ -@erase "$(INTDIR)\mod_session_dbd_src.idb"
+ -@erase "$(INTDIR)\mod_session_dbd_src.pdb"
+ -@erase "$(OUTDIR)\mod_session_dbd.exp"
+ -@erase "$(OUTDIR)\mod_session_dbd.lib"
+ -@erase "$(OUTDIR)\mod_session_dbd.pdb"
+ -@erase "$(OUTDIR)\mod_session_dbd.so"
+
+"$(OUTDIR)" :
+ if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
+
+CPP=cl.exe
+CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../database" /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_session_dbd_src" /FD /c
+
+.c{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.c{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+MTL=midl.exe
+MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32
+RSC=rc.exe
+RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_session_dbd.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_session_dbd.so" /d LONG_NAME="session_dbd_module for Apache"
+BSC32=bscmake.exe
+BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_session_dbd.bsc"
+BSC32_SBRS= \
+
+LINK32=link.exe
+LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_session_dbd.pdb" /debug /out:"$(OUTDIR)\mod_session_dbd.so" /implib:"$(OUTDIR)\mod_session_dbd.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_session_dbd.so /opt:ref
+LINK32_OBJS= \
+ "$(INTDIR)\mod_session_dbd.obj" \
+ "$(INTDIR)\mod_session_dbd.res" \
+ "..\..\srclib\apr\Release\libapr-1.lib" \
+ "..\..\srclib\apr-util\Release\libaprutil-1.lib" \
+ "..\..\Release\libhttpd.lib" \
+ "..\database\Release\mod_dbd.lib" \
+ "$(OUTDIR)\mod_session.lib"
+
+"$(OUTDIR)\mod_session_dbd.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
+ $(LINK32) @<<
+ $(LINK32_FLAGS) $(LINK32_OBJS)
+<<
+
+TargetPath=.\Release\mod_session_dbd.so
+SOURCE="$(InputPath)"
+PostBuild_Desc=Embed .manifest
+DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
+
+# Begin Custom Macros
+OutDir=.\Release
+# End Custom Macros
+
+"$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_session_dbd.so"
+ if exist .\Release\mod_session_dbd.so.manifest mt.exe -manifest .\Release\mod_session_dbd.so.manifest -outputresource:.\Release\mod_session_dbd.so;2
+ echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
+
+!ELSEIF "$(CFG)" == "mod_session_dbd - Win32 Debug"
+
+OUTDIR=.\Debug
+INTDIR=.\Debug
+DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
+# Begin Custom Macros
+OutDir=.\Debug
+# End Custom Macros
+
+!IF "$(RECURSE)" == "0"
+
+ALL : "$(OUTDIR)\mod_session_dbd.so" "$(DS_POSTBUILD_DEP)"
+
+!ELSE
+
+ALL : "mod_session - Win32 Debug" "mod_dbd - Win32 Debug" "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_session_dbd.so" "$(DS_POSTBUILD_DEP)"
+
+!ENDIF
+
+!IF "$(RECURSE)" == "1"
+CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" "mod_dbd - Win32 DebugCLEAN" "mod_session - Win32 DebugCLEAN"
+!ELSE
+CLEAN :
+!ENDIF
+ -@erase "$(INTDIR)\mod_session_dbd.obj"
+ -@erase "$(INTDIR)\mod_session_dbd.res"
+ -@erase "$(INTDIR)\mod_session_dbd_src.idb"
+ -@erase "$(INTDIR)\mod_session_dbd_src.pdb"
+ -@erase "$(OUTDIR)\mod_session_dbd.exp"
+ -@erase "$(OUTDIR)\mod_session_dbd.lib"
+ -@erase "$(OUTDIR)\mod_session_dbd.pdb"
+ -@erase "$(OUTDIR)\mod_session_dbd.so"
+
+"$(OUTDIR)" :
+ if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
+
+CPP=cl.exe
+CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../database" /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_session_dbd_src" /FD /EHsc /c
+
+.c{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.c{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+MTL=midl.exe
+MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32
+RSC=rc.exe
+RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_session_dbd.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_session_dbd.so" /d LONG_NAME="session_dbd_module for Apache"
+BSC32=bscmake.exe
+BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_session_dbd.bsc"
+BSC32_SBRS= \
+
+LINK32=link.exe
+LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_session_dbd.pdb" /debug /out:"$(OUTDIR)\mod_session_dbd.so" /implib:"$(OUTDIR)\mod_session_dbd.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_session_dbd.so
+LINK32_OBJS= \
+ "$(INTDIR)\mod_session_dbd.obj" \
+ "$(INTDIR)\mod_session_dbd.res" \
+ "..\..\srclib\apr\Debug\libapr-1.lib" \
+ "..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
+ "..\..\Debug\libhttpd.lib" \
+ "..\database\Debug\mod_dbd.lib" \
+ "$(OUTDIR)\mod_session.lib"
+
+"$(OUTDIR)\mod_session_dbd.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
+ $(LINK32) @<<
+ $(LINK32_FLAGS) $(LINK32_OBJS)
+<<
+
+TargetPath=.\Debug\mod_session_dbd.so
+SOURCE="$(InputPath)"
+PostBuild_Desc=Embed .manifest
+DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
+
+# Begin Custom Macros
+OutDir=.\Debug
+# End Custom Macros
+
+"$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_session_dbd.so"
+ if exist .\Debug\mod_session_dbd.so.manifest mt.exe -manifest .\Debug\mod_session_dbd.so.manifest -outputresource:.\Debug\mod_session_dbd.so;2
+ echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
+
+!ENDIF
+
+
+!IF "$(NO_EXTERNAL_DEPS)" != "1"
+!IF EXISTS("mod_session_dbd.dep")
+!INCLUDE "mod_session_dbd.dep"
+!ELSE
+!MESSAGE Warning: cannot find "mod_session_dbd.dep"
+!ENDIF
+!ENDIF
+
+
+!IF "$(CFG)" == "mod_session_dbd - Win32 Release" || "$(CFG)" == "mod_session_dbd - Win32 Debug"
+
+!IF "$(CFG)" == "mod_session_dbd - Win32 Release"
+
+"libapr - Win32 Release" :
+ cd ".\..\..\srclib\apr"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release"
+ cd "..\..\modules\session"
+
+"libapr - Win32 ReleaseCLEAN" :
+ cd ".\..\..\srclib\apr"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN
+ cd "..\..\modules\session"
+
+!ELSEIF "$(CFG)" == "mod_session_dbd - Win32 Debug"
+
+"libapr - Win32 Debug" :
+ cd ".\..\..\srclib\apr"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug"
+ cd "..\..\modules\session"
+
+"libapr - Win32 DebugCLEAN" :
+ cd ".\..\..\srclib\apr"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN
+ cd "..\..\modules\session"
+
+!ENDIF
+
+!IF "$(CFG)" == "mod_session_dbd - Win32 Release"
+
+"libaprutil - Win32 Release" :
+ cd ".\..\..\srclib\apr-util"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release"
+ cd "..\..\modules\session"
+
+"libaprutil - Win32 ReleaseCLEAN" :
+ cd ".\..\..\srclib\apr-util"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN
+ cd "..\..\modules\session"
+
+!ELSEIF "$(CFG)" == "mod_session_dbd - Win32 Debug"
+
+"libaprutil - Win32 Debug" :
+ cd ".\..\..\srclib\apr-util"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug"
+ cd "..\..\modules\session"
+
+"libaprutil - Win32 DebugCLEAN" :
+ cd ".\..\..\srclib\apr-util"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN
+ cd "..\..\modules\session"
+
+!ENDIF
+
+!IF "$(CFG)" == "mod_session_dbd - Win32 Release"
+
+"libhttpd - Win32 Release" :
+ cd ".\..\.."
+ $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release"
+ cd ".\modules\session"
+
+"libhttpd - Win32 ReleaseCLEAN" :
+ cd ".\..\.."
+ $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN
+ cd ".\modules\session"
+
+!ELSEIF "$(CFG)" == "mod_session_dbd - Win32 Debug"
+
+"libhttpd - Win32 Debug" :
+ cd ".\..\.."
+ $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug"
+ cd ".\modules\session"
+
+"libhttpd - Win32 DebugCLEAN" :
+ cd ".\..\.."
+ $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN
+ cd ".\modules\session"
+
+!ENDIF
+
+!IF "$(CFG)" == "mod_session_dbd - Win32 Release"
+
+"mod_dbd - Win32 Release" :
+ cd ".\..\database"
+ $(MAKE) /$(MAKEFLAGS) /F ".\mod_dbd.mak" CFG="mod_dbd - Win32 Release"
+ cd "..\session"
+
+"mod_dbd - Win32 ReleaseCLEAN" :
+ cd ".\..\database"
+ $(MAKE) /$(MAKEFLAGS) /F ".\mod_dbd.mak" CFG="mod_dbd - Win32 Release" RECURSE=1 CLEAN
+ cd "..\session"
+
+!ELSEIF "$(CFG)" == "mod_session_dbd - Win32 Debug"
+
+"mod_dbd - Win32 Debug" :
+ cd ".\..\database"
+ $(MAKE) /$(MAKEFLAGS) /F ".\mod_dbd.mak" CFG="mod_dbd - Win32 Debug"
+ cd "..\session"
+
+"mod_dbd - Win32 DebugCLEAN" :
+ cd ".\..\database"
+ $(MAKE) /$(MAKEFLAGS) /F ".\mod_dbd.mak" CFG="mod_dbd - Win32 Debug" RECURSE=1 CLEAN
+ cd "..\session"
+
+!ENDIF
+
+!IF "$(CFG)" == "mod_session_dbd - Win32 Release"
+
+"mod_session - Win32 Release" :
+ cd "."
+ $(MAKE) /$(MAKEFLAGS) /F ".\mod_session.mak" CFG="mod_session - Win32 Release"
+ cd "."
+
+"mod_session - Win32 ReleaseCLEAN" :
+ cd "."
+ $(MAKE) /$(MAKEFLAGS) /F ".\mod_session.mak" CFG="mod_session - Win32 Release" RECURSE=1 CLEAN
+ cd "."
+
+!ELSEIF "$(CFG)" == "mod_session_dbd - Win32 Debug"
+
+"mod_session - Win32 Debug" :
+ cd "."
+ $(MAKE) /$(MAKEFLAGS) /F ".\mod_session.mak" CFG="mod_session - Win32 Debug"
+ cd "."
+
+"mod_session - Win32 DebugCLEAN" :
+ cd "."
+ $(MAKE) /$(MAKEFLAGS) /F ".\mod_session.mak" CFG="mod_session - Win32 Debug" RECURSE=1 CLEAN
+ cd "."
+
+!ENDIF
+
+SOURCE=..\..\build\win32\httpd.rc
+
+!IF "$(CFG)" == "mod_session_dbd - Win32 Release"
+
+
+"$(INTDIR)\mod_session_dbd.res" : $(SOURCE) "$(INTDIR)"
+ $(RSC) /l 0x409 /fo"$(INTDIR)\mod_session_dbd.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_session_dbd.so" /d LONG_NAME="session_dbd_module for Apache" $(SOURCE)
+
+
+!ELSEIF "$(CFG)" == "mod_session_dbd - Win32 Debug"
+
+
+"$(INTDIR)\mod_session_dbd.res" : $(SOURCE) "$(INTDIR)"
+ $(RSC) /l 0x409 /fo"$(INTDIR)\mod_session_dbd.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_session_dbd.so" /d LONG_NAME="session_dbd_module for Apache" $(SOURCE)
+
+
+!ENDIF
+
+SOURCE=.\mod_session_dbd.c
+
+"$(INTDIR)\mod_session_dbd.obj" : $(SOURCE) "$(INTDIR)"
+
+
+
+!ENDIF
+