Date: | 2006/05/26 |
---|---|
Author: | Daniel Morissette |
Contact: | dmorissette at mapgears.com |
Last Edited: | 2006/08/11 |
Status: | Completed (2006/08/11) |
Version: | MapServer 4.10 |
This proposal provides a mechanism to protect database connection passwords used inside mapfiles by encrypting them instead of including them in plain text.
MapServer will be extended to allow the use of encrypted passwords as part of the CONNECTION string for the following layer types:
The Tiny Encryption Algorithm (TEA) at http://www.simonshepherd.supanet.com/tea.htm will be used for the encryption/decryption functions.
The implementation details follow...
In order to safely protect the encrypted information, an encryption key will be required by this mechanism. The key will NOT be stored in the mapfile: it will be stored in a separate file on the server and should be kept in a safe area by the server administrator (especially outside of the web server’s document directories).
The location of the encryption key can be specified by two mechanisms, either by setting the environment variable MS_ENCRYPTION_KEY or using a CONFIG directive:
CONFIG MS_ENCRYPTION_KEY "/path/to/mykey.txt"
A “msencrypt” command-line utility will be provided to create an encryption key and to encrypt passwords (or any string) for use in a mapfile.
To create an encryption key:
msencrypt -keygen /path/to/mykey.txt
To encrypt a password or any string:
msencrypt -key /path/to/mykey.txt <string_to_encrypt>
If the MS_ENCRYPTION_KEY environment variable is set then the -key argument does not need to be specified.
Since the result of encryption is binary data that is not suitable for inclusion directly in a MapServer mapfile, hex encoding will be used for the encrypted strings in the mapfile as well as for storing the encryption key to disk.
The { and } characters will be used as delimiters for encrypted strings inside database CONNECTIONs. This will allow the use of either plain text or encrypted passwords in mapfiles without any backwards compatibility issues.
e.g.
CONNECTIONTYPE ORACLESPATIAL
CONNECTION "user/{MIIBugIBAAKBgQCP0Yj+Seh8==}@service"
Any part of a CONNECTION string can be encrypted and not just the password. This will allow protecting other information such as login name, hostname or port numbers if necessary.
For reference, here are examples of typical connection strings for the layer types that will be affected:
CONNECTIONTYPE POSTGIS
CONNECTION "host=yourhostname dbname=yourdatabasename user=yourdbusername password=yourdbpassword port=yourpgport"
CONNECTIONTYPE SDE
CONNECTION "sdemachine.iastate.edu,port:5151,sde,username,password"
CONNECTIONTYPE ORACLESPATIAL
CONNECTION "user/pwd@service"
CONNECTIONTYPE OGR
CONNECTION "OCI:user/pwd@service"
A msDecryptString() function will be created, it will take a CONNECTION string as input and decrypt any encrypted component that it may find in it. This function will be called by the various msXXXLayerOpen() methods before opening the connection to the database.
char *msDecryptString(mapObj *map, const char *string)
The first time that msDecryptString() is called for a given mapfile, it will load the encryption key from the file and store the key in a new private member of the mapObj (char * encryption_key).
To reduce the chances of false matches in long CONNECTION strings such as OGR VRT data sources, msDecryptString() function will look for a pair of { + }, and then verify that all chars in the block are valid hex encoding chars (0-9,A-F) before proceeding with decryption.
Note that the decrypted string will never be stored in the layerObj, it will be kept local to the function that opens the connection and destroyed as soon as the function is done with it. This is to prevent exposing the decrypted information in error messages or in calls to msSaveMap().
map.h
mapfile.c
maporaclespatial.c
mappostgis.c
mappostgresql.c
mapsde.c
mapogr.cpp
None.
Adopted on 2006/06/01. +1: FrankW, DanielM, HowardB, YewondwossenA, SteveW