From 6a80b70b7aa22a4c9e649f76a3381d8cc62a4a6d Mon Sep 17 00:00:00 2001 From: Gert-Jan Timmer Date: Tue, 29 May 2018 13:41:52 +0200 Subject: [PATCH] Add: PRAGMA secure_delete ADD: Connection PRAGMA ADD: Build tag for secure_delete mode: FAST --- README.md | 2 ++ sqlite3.go | 34 +++++++++++++++++++++++++++++++ sqlite3_opt_secure_delete.go | 3 ++- sqlite3_opt_secure_delete_fast.go | 15 ++++++++++++++ 4 files changed, 53 insertions(+), 1 deletion(-) create mode 100644 sqlite3_opt_secure_delete_fast.go diff --git a/README.md b/README.md index 02e5b25..82b43f8 100644 --- a/README.md +++ b/README.md @@ -87,6 +87,7 @@ Boolean values can be one of: | Mutex Locking | `_mutex` | | Specify mutex mode. | | Query Only | `_query_only` | `boolean` | For more information see [PRAGMA query_only](https://www.sqlite.org/pragma.html#pragma_query_only) | | Recursive Triggers | `_recursive_triggers` \| `_rt` | `boolean` | For more information see [PRAGMA recursive_triggers](https://www.sqlite.org/pragma.html#pragma_recursive_triggers) | +| Secure Delete | `_secure_delete` | `boolean` \| `FAST` | For more information see [PRAGMA secure_delete](https://www.sqlite.org/pragma.html#pragma_secure_delete) | | Shared-Cache Mode | `cache` | | Set cache mode for more information see [sqlite.org](https://www.sqlite.org/sharedcache.html) | | Time Zone Location | `_loc` | auto | Specify location of time format. | | Transaction Lock | `_txlock` | | Specify locking behavior for transactions. | @@ -137,6 +138,7 @@ go build --tags "icu json1 fts5 secure_delete" | Introspect PRAGMAS | sqlite_introspect | This option adds some extra PRAGMA statements. | | JSON SQL Functions | sqlite_json | When this option is defined in the amalgamation, the JSON SQL functions are added to the build automatically | | Secure Delete | sqlite_secure_delete | This compile-time option changes the default setting of the secure_delete pragma.

When this option is not used, secure_delete defaults to off. When this option is present, secure_delete defaults to on.

The secure_delete setting causes deleted content to be overwritten with zeros. There is a small performance penalty since additional I/O must occur.

On the other hand, secure_delete can prevent fragments of sensitive information from lingering in unused parts of the database file after it has been deleted. See the documentation on the secure_delete pragma for additional information | +| Secure Delete (FAST) | sqlite_secure_delete_fast | For more information see [PRAGMA secure_delete](https://www.sqlite.org/pragma.html#pragma_secure_delete) | | Tracing / Debug | sqlite_trace | Activate trace functions | # Compilation diff --git a/sqlite3.go b/sqlite3.go index c9a6bfe..5783581 100644 --- a/sqlite3.go +++ b/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 { diff --git a/sqlite3_opt_secure_delete.go b/sqlite3_opt_secure_delete.go index d243297..0e2f280 100644 --- a/sqlite3_opt_secure_delete.go +++ b/sqlite3_opt_secure_delete.go @@ -1,4 +1,5 @@ // Copyright (C) 2014 Yasuhiro Matsumoto . +// Copyright (C) 2018 G.J.R. Timmer . // // 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" diff --git a/sqlite3_opt_secure_delete_fast.go b/sqlite3_opt_secure_delete_fast.go new file mode 100644 index 0000000..8f86b21 --- /dev/null +++ b/sqlite3_opt_secure_delete_fast.go @@ -0,0 +1,15 @@ +// Copyright (C) 2014 Yasuhiro Matsumoto . +// Copyright (C) 2018 G.J.R. Timmer . +// +// 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"