Diff
Not logged in

Differences From:

File src/db.c part of check-in [9d23230322] - Use the %/ substitution instead of %s when constructing windows pathnames. by drh on 2008-07-15 02:01:18. [view]

To:

File src/db.c part of check-in [f46fe42d6d] - Store private ticket fields (ex: the originators email address) as their SHA1 hash so that malefactors cannot read them. Add the new "concealed" table to the repository database and store mappings from SHA1 hashes back to email addresses in that table. Ticket a24ec6005f. Note: run "rebuild" on repositories after updating to this version of fossil in order to create the "concealed" table. Need to add the ability to manage the concealed table from the web interface and the ability to sync concealed content between trusted repositories. by drh on 2008-07-24 02:04:36. [view]

@@ -893,8 +893,93 @@
   }
 }
 
 /*
+** Convert the input string into an SHA1.  Make a notation in the
+** CONCEALED table so that the hash can be undo using the db_reveal()
+** function at some later time.
+**
+** The value returned is stored in static space and will be overwritten
+** on subsequent calls.
+*/
+char *db_conceal(const char *zContent, int n){
+  static char zHash[42];
+  Blob out;
+  sha1sum_step_text(zContent, n);
+  sha1sum_finish(&out);
+  strcpy(zHash, blob_str(&out));
+  blob_reset(&out);
+  db_multi_exec(
+     "INSERT OR IGNORE INTO concealed VALUES(%Q,%Q)",
+     zHash, zContent
+  );
+  return zHash;
+}
+
+/*
+** Attempt to look up the input in the CONCEALED table.  If found,
+** and if the okRdAddr permission is enabled then return the
+** original value for which the input is a hash.  If okRdAddr is
+** false or if the lookup fails, return the original input.
+**
+** In either case, the string returned is stored in space obtained
+** from malloc and should be freed by the calling function.
+*/
+char *db_reveal(const char *zKey){
+  char *zOut;
+  if( g.okRdAddr ){
+    zOut = db_text(0, "SELECT content FROM concealed WHERE hash=%Q", zKey);
+  }else{
+    zOut = 0;
+  }
+  if( zOut==0 ){
+    zOut = mprintf("%s", zKey);
+  }
+  return zOut;
+}
+
+/*
+** The conceal() SQL function.  Compute an SHA1 hash of the argument
+** and return that hash as a 40-character lower-case hex number.
+*/
+static void sha1_function(
+  sqlite3_context *context,
+  int argc,
+  sqlite3_value **argv
+){
+  const char *zIn;
+  int nIn;
+  char *zOut;
+  assert(argc==1);
+
+  zIn = (const char*)sqlite3_value_text(argv[0]);
+  if( zIn ){
+    nIn = sqlite3_value_bytes(argv[0]);
+    zOut = db_conceal(zIn, nIn);
+    sqlite3_result_text(context, zOut, -1, SQLITE_TRANSIENT);
+  }
+}
+
+/*
+** The reveal() SQL function invokes the db_reveal() function.
+*/
+static void reveal_function(
+  sqlite3_context *context,
+  int argc,
+  sqlite3_value **argv
+){
+  const char *zIn;
+  char *zOut;
+  assert(argc==1);
+
+  zIn = (const char*)sqlite3_value_text(argv[0]);
+  if( zIn ){
+    zOut = db_reveal(zIn);
+    sqlite3_result_text(context, zOut, -1, free);
+  }
+}
+
+/*
 ** This function registers auxiliary functions when the SQLite
 ** database connection is first established.
 */
 LOCAL void db_connection_init(void){
@@ -902,8 +987,14 @@
   if( once ){
     sqlite3_create_function(g.db, "print", -1, SQLITE_UTF8, 0,db_sql_print,0,0);
     sqlite3_create_function(
       g.db, "file_is_selected", 1, SQLITE_UTF8, 0, file_is_selected,0,0
+    );
+    sqlite3_create_function(
+      g.db, "conceal", 1, SQLITE_UTF8, 0, sha1_function,0,0
+    );
+    sqlite3_create_function(
+      g.db, "reveal", 1, SQLITE_UTF8, 0, reveal_function,0,0
     );
     if( g.fSqlTrace ){
       sqlite3_trace(g.db, db_sql_trace, 0);
     }