Browse Source

Add: PRAGMA secure_delete

ADD: Connection PRAGMA
ADD: Build tag for secure_delete mode: FAST
Gert-Jan Timmer 11 months ago
parent
commit
6a80b70b7a
4 changed files with 53 additions and 1 deletions
  1. 2 0
      README.md
  2. 34 0
      sqlite3.go
  3. 2 1
      sqlite3_opt_secure_delete.go
  4. 15 0
      sqlite3_opt_secure_delete_fast.go

File diff suppressed because it is too large
+ 2 - 0
README.md


+ 34 - 0
sqlite3.go

@@ -862,6 +862,10 @@ func errorString(err Error) string {
 //   _recursive_triggers=Boolean | _rt=Boolean
 //     Enable or disable recursive triggers.
 //
+//   _secure_delete=Boolean|FAST
+//     When secure_delete is on, SQLite overwrites deleted content with zeros.
+//     https://www.sqlite.org/pragma.html#pragma_secure_delete
+//
 //   _vacuum=X
 //     0 | none - Auto Vacuum disabled
 //     1 | full - Auto Vacuum FULL
@@ -889,6 +893,7 @@ func (d *SQLiteDriver) Open(dsn string) (driver.Conn, error) {
 	lockingMode := "NORMAL"
 	queryOnly := -1
 	recursiveTriggers := -1
+	secureDelete := "DEFAULT"
 
 	pos := strings.IndexRune(dsn, '?')
 	if pos >= 1 {
@@ -1109,6 +1114,23 @@ func (d *SQLiteDriver) Open(dsn string) (driver.Conn, error) {
 			}
 		}
 
+		// Secure Delete (_secure_delete)
+		//
+		// https://www.sqlite.org/pragma.html#pragma_secure_delete
+		//
+		if val := params.Get("_secure_delete"); val != "" {
+			switch strings.ToLower(val) {
+			case "0", "no", "false", "off":
+				secureDelete = "OFF"
+			case "1", "yes", "true", "on":
+				secureDelete = "ON"
+			case "fast":
+				secureDelete = "FAST"
+			default:
+				return nil, fmt.Errorf("Invalid _recursive_triggers: %v, expecting boolean value of '0 1 false true no yes off on'", val)
+			}
+		}
+
 		if !strings.HasPrefix(dsn, "file:") {
 			dsn = dsn[:pos]
 		}
@@ -1214,6 +1236,18 @@ func (d *SQLiteDriver) Open(dsn string) (driver.Conn, error) {
 		}
 	}
 
+	// Secure Delete
+	//
+	// Because this package can set the compile time flag SQLITE_SECURE_DELETE with a build tag
+	// the default value for secureDelete var is 'DEFAULT' this way
+	// you can compile with secure_delete 'ON' and disable it for a specific database connection.
+	if secureDelete != "DEFAULT" {
+		if err := exec(fmt.Sprintf("PRAGMA secure_delete = %s;", secureDelete)); err != nil {
+			C.sqlite3_close_v2(db)
+			return nil, err
+		}
+	}
+
 	conn := &SQLiteConn{db: db, loc: loc, txlock: txlock}
 
 	if len(d.Extensions) > 0 {

+ 2 - 1
sqlite3_opt_secure_delete.go

@@ -1,4 +1,5 @@
 // Copyright (C) 2014 Yasuhiro Matsumoto <mattn.jp@gmail.com>.
+// Copyright (C) 2018 G.J.R. Timmer <gjr.timmer@gmail.com>.
 //
 // Use of this source code is governed by an MIT-style
 // license that can be found in the LICENSE file.
@@ -8,7 +9,7 @@
 package sqlite3
 
 /*
-#cgo CFLAGS: -DSQLITE_SECURE_DELETE
+#cgo CFLAGS: -DSQLITE_SECURE_DELETE=1
 #cgo LDFLAGS: -lm
 */
 import "C"

+ 15 - 0
sqlite3_opt_secure_delete_fast.go

@@ -0,0 +1,15 @@
+// Copyright (C) 2014 Yasuhiro Matsumoto <mattn.jp@gmail.com>.
+// Copyright (C) 2018 G.J.R. Timmer <gjr.timmer@gmail.com>.
+//
+// Use of this source code is governed by an MIT-style
+// license that can be found in the LICENSE file.
+
+// +build sqlite_secure_delete_fast
+
+package sqlite3
+
+/*
+#cgo CFLAGS: -DSQLITE_SECURE_DELETE=FAST
+#cgo LDFLAGS: -lm
+*/
+import "C"