ef8bc60a174ca86469cc102d18c9a8c7d3188bf9
galt
  Tue Feb 11 01:24:49 2014 -0800
adding random sessionKey generation
diff --git src/hg/lib/cartDb.c src/hg/lib/cartDb.c
index c77d61a..92e6039 100644
--- src/hg/lib/cartDb.c
+++ src/hg/lib/cartDb.c
@@ -9,30 +9,31 @@
  * autodetect 
  *   or even better auto-upgrade of the userDb and sessionDb tables
  *   alter table userDb add column sessionKey varchar(255) NOT NULL default '';
  *   alter table sessionDb add column sessionKey varchar(255) NOT NULL default '';
  *
  * find and modify the .as and .sql corresponding to cartDb
  *
  *
  */
 
 #include "common.h"
 #include "linefile.h"
 #include "dystring.h"
 #include "jksql.h"
 #include "hgConfig.h"
+#include "base64.h"
 #include "cartDb.h"
 
 boolean cartDbHasSessionKey(struct sqlConnection *conn, char *table)
 /* Check to see if the table has the sessionKey field */
 {
 static boolean userDbInitialized = FALSE;
 static boolean sessionDbInitialized = FALSE;
 static boolean userDbHasSessionKey = FALSE;
 static boolean sessionDbHasSessionKey = FALSE;
 if (sameString(table, "userDb"))
     {
     if (!userDbInitialized)
 	{
 	userDbInitialized = TRUE;
 	if (sqlFieldIndex(conn, table, "sessionKey") >= 0)
@@ -70,30 +71,48 @@
     char *sessionKey = cfgOption2("browser", "sessionKey");
     if (!sessionKey)
 	sessionKey = "off";  // DEFAULT
     if (sameString(sessionKey, "on"))
 	useSessionKey = TRUE;
     else if (sameString(sessionKey, "off"))
 	useSessionKey = FALSE;
     else if (sameString(sessionKey, "autodetect"))
 	{
 	errAbort("brower.sessionKey=autodetect has not implemented yet."); // TODO
 	}
     }
 return useSessionKey;
 }
 
+char *cartDbMakeRandomKey(int numBits)
+/* Generate base64 encoding of a random key of at least size numBits returning string to be freed when done */
+{
+int numBytes = (numBits + 7) / 8;  // round up to nearest whole byte.
+numBytes = ((numBytes+2)/3)*3;  // round up to the nearest multiple of 3 to avoid equals-char padding in base64 output
+FILE *f = mustOpen("/dev/urandom", "r");   // open random system device for read-only access.
+char *binaryString = needMem(numBytes);
+mustRead(f, binaryString, numBytes); 
+carefulClose(&f);
+char * result = base64Encode(binaryString, numBytes); // converts 3 binary bytes into 4 printable characters
+int len = strlen(result);
+memSwapChar(result, len, '+', '-'); // replace + and / with characters that are URL-friendly.
+memSwapChar(result, len, '/', '@');
+freeMem(binaryString);
+return result;
+}
+
+
 void cartDbSecureId(char *buf, int bufSize, struct cartDb *cartDb)
 /* Return combined string of session id plus sessionKey in buf if turned on.*/
 {
 if (cartDbUseSessionKey() && !sameString(cartDb->sessionKey,""))
     safef(buf, bufSize, "%d_%s", cartDb->id, cartDb->sessionKey);
 else
     safef(buf, bufSize, "%d", cartDb->id);
 }
 
 unsigned int cartDbParseId(char *id, char **pSessionKey)
 /* Parse out the numeric id and id_sessionKey string if present. */
 {
 unsigned int result = 0;
 char *e = strchr(id, '_');
 if (e)