mirror of https://github.com/go-gitea/gitea
Update vendor/go-sqlite3 (#5133)
parent
6759237eda
commit
2ce72d4e00
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,120 @@ |
|||||||
|
// 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.
|
||||||
|
|
||||||
|
package sqlite3 |
||||||
|
|
||||||
|
import ( |
||||||
|
"crypto/sha1" |
||||||
|
"crypto/sha256" |
||||||
|
"crypto/sha512" |
||||||
|
) |
||||||
|
|
||||||
|
// This file provides several different implementations for the
|
||||||
|
// default embedded sqlite_crypt function.
|
||||||
|
// This function is uses a ceasar-cypher by default
|
||||||
|
// and is used within the UserAuthentication module to encode
|
||||||
|
// the password.
|
||||||
|
//
|
||||||
|
// The provided functions can be used as an overload to the sqlite_crypt
|
||||||
|
// function through the use of the RegisterFunc on the connection.
|
||||||
|
//
|
||||||
|
// Because the functions can serv a purpose to an end-user
|
||||||
|
// without using the UserAuthentication module
|
||||||
|
// the functions are default compiled in.
|
||||||
|
//
|
||||||
|
// From SQLITE3 - user-auth.txt
|
||||||
|
// The sqlite_user.pw field is encoded by a built-in SQL function
|
||||||
|
// "sqlite_crypt(X,Y)". The two arguments are both BLOBs. The first argument
|
||||||
|
// is the plaintext password supplied to the sqlite3_user_authenticate()
|
||||||
|
// interface. The second argument is the sqlite_user.pw value and is supplied
|
||||||
|
// so that the function can extract the "salt" used by the password encoder.
|
||||||
|
// The result of sqlite_crypt(X,Y) is another blob which is the value that
|
||||||
|
// ends up being stored in sqlite_user.pw. To verify credentials X supplied
|
||||||
|
// by the sqlite3_user_authenticate() routine, SQLite runs:
|
||||||
|
//
|
||||||
|
// sqlite_user.pw == sqlite_crypt(X, sqlite_user.pw)
|
||||||
|
//
|
||||||
|
// To compute an appropriate sqlite_user.pw value from a new or modified
|
||||||
|
// password X, sqlite_crypt(X,NULL) is run. A new random salt is selected
|
||||||
|
// when the second argument is NULL.
|
||||||
|
//
|
||||||
|
// The built-in version of of sqlite_crypt() uses a simple Ceasar-cypher
|
||||||
|
// which prevents passwords from being revealed by searching the raw database
|
||||||
|
// for ASCII text, but is otherwise trivally broken. For better password
|
||||||
|
// security, the database should be encrypted using the SQLite Encryption
|
||||||
|
// Extension or similar technology. Or, the application can use the
|
||||||
|
// sqlite3_create_function() interface to provide an alternative
|
||||||
|
// implementation of sqlite_crypt() that computes a stronger password hash,
|
||||||
|
// perhaps using a cryptographic hash function like SHA1.
|
||||||
|
|
||||||
|
// CryptEncoderSHA1 encodes a password with SHA1
|
||||||
|
func CryptEncoderSHA1(pass []byte, hash interface{}) []byte { |
||||||
|
h := sha1.Sum(pass) |
||||||
|
return h[:] |
||||||
|
} |
||||||
|
|
||||||
|
// CryptEncoderSSHA1 encodes a password with SHA1 with the
|
||||||
|
// configured salt.
|
||||||
|
func CryptEncoderSSHA1(salt string) func(pass []byte, hash interface{}) []byte { |
||||||
|
return func(pass []byte, hash interface{}) []byte { |
||||||
|
s := []byte(salt) |
||||||
|
p := append(pass, s...) |
||||||
|
h := sha1.Sum(p) |
||||||
|
return h[:] |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// CryptEncoderSHA256 encodes a password with SHA256
|
||||||
|
func CryptEncoderSHA256(pass []byte, hash interface{}) []byte { |
||||||
|
h := sha256.Sum256(pass) |
||||||
|
return h[:] |
||||||
|
} |
||||||
|
|
||||||
|
// CryptEncoderSSHA256 encodes a password with SHA256
|
||||||
|
// with the configured salt
|
||||||
|
func CryptEncoderSSHA256(salt string) func(pass []byte, hash interface{}) []byte { |
||||||
|
return func(pass []byte, hash interface{}) []byte { |
||||||
|
s := []byte(salt) |
||||||
|
p := append(pass, s...) |
||||||
|
h := sha256.Sum256(p) |
||||||
|
return h[:] |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// CryptEncoderSHA384 encodes a password with SHA384
|
||||||
|
func CryptEncoderSHA384(pass []byte, hash interface{}) []byte { |
||||||
|
h := sha512.Sum384(pass) |
||||||
|
return h[:] |
||||||
|
} |
||||||
|
|
||||||
|
// CryptEncoderSSHA384 encodes a password with SHA384
|
||||||
|
// with the configured salt
|
||||||
|
func CryptEncoderSSHA384(salt string) func(pass []byte, hash interface{}) []byte { |
||||||
|
return func(pass []byte, hash interface{}) []byte { |
||||||
|
s := []byte(salt) |
||||||
|
p := append(pass, s...) |
||||||
|
h := sha512.Sum384(p) |
||||||
|
return h[:] |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// CryptEncoderSHA512 encodes a password with SHA512
|
||||||
|
func CryptEncoderSHA512(pass []byte, hash interface{}) []byte { |
||||||
|
h := sha512.Sum512(pass) |
||||||
|
return h[:] |
||||||
|
} |
||||||
|
|
||||||
|
// CryptEncoderSSHA512 encodes a password with SHA512
|
||||||
|
// with the configured salt
|
||||||
|
func CryptEncoderSSHA512(salt string) func(pass []byte, hash interface{}) []byte { |
||||||
|
return func(pass []byte, hash interface{}) []byte { |
||||||
|
s := []byte(salt) |
||||||
|
p := append(pass, s...) |
||||||
|
h := sha512.Sum512(p) |
||||||
|
return h[:] |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// EOF
|
@ -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_allow_uri_authority
|
||||||
|
|
||||||
|
package sqlite3 |
||||||
|
|
||||||
|
/* |
||||||
|
#cgo CFLAGS: -DSQLITE_ALLOW_URI_AUTHORITY |
||||||
|
#cgo LDFLAGS: -lm |
||||||
|
*/ |
||||||
|
import "C" |
@ -0,0 +1,16 @@ |
|||||||
|
// 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 !windows
|
||||||
|
// +build sqlite_app_armor
|
||||||
|
|
||||||
|
package sqlite3 |
||||||
|
|
||||||
|
/* |
||||||
|
#cgo CFLAGS: -DSQLITE_ENABLE_API_ARMOR |
||||||
|
#cgo LDFLAGS: -lm |
||||||
|
*/ |
||||||
|
import "C" |
@ -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_foreign_keys
|
||||||
|
|
||||||
|
package sqlite3 |
||||||
|
|
||||||
|
/* |
||||||
|
#cgo CFLAGS: -DSQLITE_DEFAULT_FOREIGN_KEYS=1 |
||||||
|
#cgo LDFLAGS: -lm |
||||||
|
*/ |
||||||
|
import "C" |
@ -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_introspect
|
||||||
|
|
||||||
|
package sqlite3 |
||||||
|
|
||||||
|
/* |
||||||
|
#cgo CFLAGS: -DSQLITE_INTROSPECTION_PRAGMAS |
||||||
|
#cgo LDFLAGS: -lm |
||||||
|
*/ |
||||||
|
import "C" |
@ -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
|
||||||
|
|
||||||
|
package sqlite3 |
||||||
|
|
||||||
|
/* |
||||||
|
#cgo CFLAGS: -DSQLITE_SECURE_DELETE=1 |
||||||
|
#cgo LDFLAGS: -lm |
||||||
|
*/ |
||||||
|
import "C" |
@ -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" |
@ -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_stat4
|
||||||
|
|
||||||
|
package sqlite3 |
||||||
|
|
||||||
|
/* |
||||||
|
#cgo CFLAGS: -DSQLITE_ENABLE_STAT4 |
||||||
|
#cgo LDFLAGS: -lm |
||||||
|
*/ |
||||||
|
import "C" |
@ -0,0 +1,85 @@ |
|||||||
|
// Copyright (C) 2018 Yasuhiro Matsumoto <mattn.jp@gmail.com>.
|
||||||
|
//
|
||||||
|
// Use of this source code is governed by an MIT-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
#ifdef SQLITE_ENABLE_UNLOCK_NOTIFY |
||||||
|
#include <stdio.h> |
||||||
|
#include <sqlite3-binding.h> |
||||||
|
|
||||||
|
extern int unlock_notify_wait(sqlite3 *db); |
||||||
|
|
||||||
|
int |
||||||
|
_sqlite3_step_blocking(sqlite3_stmt *stmt) |
||||||
|
{ |
||||||
|
int rv; |
||||||
|
sqlite3* db; |
||||||
|
|
||||||
|
db = sqlite3_db_handle(stmt); |
||||||
|
for (;;) { |
||||||
|
rv = sqlite3_step(stmt); |
||||||
|
if (rv != SQLITE_LOCKED) { |
||||||
|
break; |
||||||
|
} |
||||||
|
if (sqlite3_extended_errcode(db) != SQLITE_LOCKED_SHAREDCACHE) { |
||||||
|
break; |
||||||
|
} |
||||||
|
rv = unlock_notify_wait(db); |
||||||
|
if (rv != SQLITE_OK) { |
||||||
|
break; |
||||||
|
} |
||||||
|
sqlite3_reset(stmt); |
||||||
|
} |
||||||
|
|
||||||
|
return rv; |
||||||
|
} |
||||||
|
|
||||||
|
int |
||||||
|
_sqlite3_step_row_blocking(sqlite3_stmt* stmt, long long* rowid, long long* changes) |
||||||
|
{ |
||||||
|
int rv; |
||||||
|
sqlite3* db; |
||||||
|
|
||||||
|
db = sqlite3_db_handle(stmt); |
||||||
|
for (;;) { |
||||||
|
rv = sqlite3_step(stmt); |
||||||
|
if (rv!=SQLITE_LOCKED) { |
||||||
|
break; |
||||||
|
} |
||||||
|
if (sqlite3_extended_errcode(db) != SQLITE_LOCKED_SHAREDCACHE) { |
||||||
|
break; |
||||||
|
} |
||||||
|
rv = unlock_notify_wait(db); |
||||||
|
if (rv != SQLITE_OK) { |
||||||
|
break; |
||||||
|
} |
||||||
|
sqlite3_reset(stmt); |
||||||
|
} |
||||||
|
|
||||||
|
*rowid = (long long) sqlite3_last_insert_rowid(db); |
||||||
|
*changes = (long long) sqlite3_changes(db); |
||||||
|
return rv; |
||||||
|
} |
||||||
|
|
||||||
|
int |
||||||
|
_sqlite3_prepare_v2_blocking(sqlite3 *db, const char *zSql, int nBytes, sqlite3_stmt **ppStmt, const char **pzTail) |
||||||
|
{ |
||||||
|
int rv; |
||||||
|
|
||||||
|
for (;;) { |
||||||
|
rv = sqlite3_prepare_v2(db, zSql, nBytes, ppStmt, pzTail); |
||||||
|
if (rv!=SQLITE_LOCKED) { |
||||||
|
break; |
||||||
|
} |
||||||
|
if (sqlite3_extended_errcode(db) != SQLITE_LOCKED_SHAREDCACHE) { |
||||||
|
break; |
||||||
|
} |
||||||
|
rv = unlock_notify_wait(db); |
||||||
|
if (rv != SQLITE_OK) { |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return rv; |
||||||
|
} |
||||||
|
#endif |
@ -0,0 +1,92 @@ |
|||||||
|
// Copyright (C) 2018 Yasuhiro Matsumoto <mattn.jp@gmail.com>.
|
||||||
|
//
|
||||||
|
// Use of this source code is governed by an MIT-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build cgo
|
||||||
|
// +build sqlite_unlock_notify
|
||||||
|
|
||||||
|
package sqlite3 |
||||||
|
|
||||||
|
/* |
||||||
|
#cgo CFLAGS: -DSQLITE_ENABLE_UNLOCK_NOTIFY |
||||||
|
|
||||||
|
#include <stdlib.h> |
||||||
|
#include <sqlite3-binding.h> |
||||||
|
|
||||||
|
extern void unlock_notify_callback(void *arg, int argc); |
||||||
|
*/ |
||||||
|
import "C" |
||||||
|
import ( |
||||||
|
"fmt" |
||||||
|
"sync" |
||||||
|
"unsafe" |
||||||
|
) |
||||||
|
|
||||||
|
type unlock_notify_table struct { |
||||||
|
sync.Mutex |
||||||
|
seqnum uint |
||||||
|
table map[uint]chan struct{} |
||||||
|
} |
||||||
|
|
||||||
|
var unt unlock_notify_table = unlock_notify_table{table: make(map[uint]chan struct{})} |
||||||
|
|
||||||
|
func (t *unlock_notify_table) add(c chan struct{}) uint { |
||||||
|
t.Lock() |
||||||
|
defer t.Unlock() |
||||||
|
h := t.seqnum |
||||||
|
t.table[h] = c |
||||||
|
t.seqnum++ |
||||||
|
return h |
||||||
|
} |
||||||
|
|
||||||
|
func (t *unlock_notify_table) remove(h uint) { |
||||||
|
t.Lock() |
||||||
|
defer t.Unlock() |
||||||
|
delete(t.table, h) |
||||||
|
} |
||||||
|
|
||||||
|
func (t *unlock_notify_table) get(h uint) chan struct{} { |
||||||
|
t.Lock() |
||||||
|
defer t.Unlock() |
||||||
|
c, ok := t.table[h] |
||||||
|
if !ok { |
||||||
|
panic(fmt.Sprintf("Non-existent key for unlcok-notify channel: %d", h)) |
||||||
|
} |
||||||
|
return c |
||||||
|
} |
||||||
|
|
||||||
|
//export unlock_notify_callback
|
||||||
|
func unlock_notify_callback(argv unsafe.Pointer, argc C.int) { |
||||||
|
for i := 0; i < int(argc); i++ { |
||||||
|
parg := ((*(*[1 << 30]*[1]uint)(argv))[i]) |
||||||
|
arg := *parg |
||||||
|
h := arg[0] |
||||||
|
c := unt.get(h) |
||||||
|
c <- struct{}{} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
//export unlock_notify_wait
|
||||||
|
func unlock_notify_wait(db *C.sqlite3) C.int { |
||||||
|
// It has to be a bufferred channel to not block in sqlite_unlock_notify
|
||||||
|
// as sqlite_unlock_notify could invoke the callback before it returns.
|
||||||
|
c := make(chan struct{}, 1) |
||||||
|
defer close(c) |
||||||
|
|
||||||
|
h := unt.add(c) |
||||||
|
defer unt.remove(h) |
||||||
|
|
||||||
|
pargv := C.malloc(C.sizeof_uint) |
||||||
|
defer C.free(pargv) |
||||||
|
|
||||||
|
argv := (*[1]uint)(pargv) |
||||||
|
argv[0] = h |
||||||
|
if rv := C.sqlite3_unlock_notify(db, (*[0]byte)(C.unlock_notify_callback), unsafe.Pointer(pargv)); rv != C.SQLITE_OK { |
||||||
|
return rv |
||||||
|
} |
||||||
|
|
||||||
|
<-c |
||||||
|
|
||||||
|
return C.SQLITE_OK |
||||||
|
} |
@ -0,0 +1,289 @@ |
|||||||
|
// 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_userauth
|
||||||
|
|
||||||
|
package sqlite3 |
||||||
|
|
||||||
|
/* |
||||||
|
#cgo CFLAGS: -DSQLITE_USER_AUTHENTICATION |
||||||
|
#cgo LDFLAGS: -lm |
||||||
|
#ifndef USE_LIBSQLITE3 |
||||||
|
#include <sqlite3-binding.h> |
||||||
|
#else |
||||||
|
#include <sqlite3.h> |
||||||
|
#endif |
||||||
|
#include <stdlib.h> |
||||||
|
|
||||||
|
static int |
||||||
|
_sqlite3_user_authenticate(sqlite3* db, const char* zUsername, const char* aPW, int nPW) |
||||||
|
{ |
||||||
|
return sqlite3_user_authenticate(db, zUsername, aPW, nPW); |
||||||
|
} |
||||||
|
|
||||||
|
static int |
||||||
|
_sqlite3_user_add(sqlite3* db, const char* zUsername, const char* aPW, int nPW, int isAdmin) |
||||||
|
{ |
||||||
|
return sqlite3_user_add(db, zUsername, aPW, nPW, isAdmin); |
||||||
|
} |
||||||
|
|
||||||
|
static int |
||||||
|
_sqlite3_user_change(sqlite3* db, const char* zUsername, const char* aPW, int nPW, int isAdmin) |
||||||
|
{ |
||||||
|
return sqlite3_user_change(db, zUsername, aPW, nPW, isAdmin); |
||||||
|
} |
||||||
|
|
||||||
|
static int |
||||||
|
_sqlite3_user_delete(sqlite3* db, const char* zUsername) |
||||||
|
{ |
||||||
|
return sqlite3_user_delete(db, zUsername); |
||||||
|
} |
||||||
|
|
||||||
|
static int |
||||||
|
_sqlite3_auth_enabled(sqlite3* db) |
||||||
|
{ |
||||||
|
int exists = -1; |
||||||
|
|
||||||
|
sqlite3_stmt *stmt; |
||||||
|
sqlite3_prepare_v2(db, "select count(type) from sqlite_master WHERE type='table' and name='sqlite_user';", -1, &stmt, NULL); |
||||||
|
|
||||||
|
while ( sqlite3_step(stmt) == SQLITE_ROW) { |
||||||
|
exists = sqlite3_column_int(stmt, 0); |
||||||
|
} |
||||||
|
|
||||||
|
sqlite3_finalize(stmt); |
||||||
|
|
||||||
|
return exists; |
||||||
|
} |
||||||
|
*/ |
||||||
|
import "C" |
||||||
|
import ( |
||||||
|
"errors" |
||||||
|
"unsafe" |
||||||
|
) |
||||||
|
|
||||||
|
const ( |
||||||
|
SQLITE_AUTH = C.SQLITE_AUTH |
||||||
|
) |
||||||
|
|
||||||
|
var ( |
||||||
|
ErrUnauthorized = errors.New("SQLITE_AUTH: Unauthorized") |
||||||
|
ErrAdminRequired = errors.New("SQLITE_AUTH: Unauthorized; Admin Privileges Required") |
||||||
|
) |
||||||
|
|
||||||
|
// Authenticate will perform an authentication of the provided username
|
||||||
|
// and password against the database.
|
||||||
|
//
|
||||||
|
// If a database contains the SQLITE_USER table, then the
|
||||||
|
// call to Authenticate must be invoked with an
|
||||||
|
// appropriate username and password prior to enable read and write
|
||||||
|
//access to the database.
|
||||||
|
//
|
||||||
|
// Return SQLITE_OK on success or SQLITE_ERROR if the username/password
|
||||||
|
// combination is incorrect or unknown.
|
||||||
|
//
|
||||||
|
// If the SQLITE_USER table is not present in the database file, then
|
||||||
|
// this interface is a harmless no-op returnning SQLITE_OK.
|
||||||
|
func (c *SQLiteConn) Authenticate(username, password string) error { |
||||||
|
rv := c.authenticate(username, password) |
||||||
|
switch rv { |
||||||
|
case C.SQLITE_ERROR, C.SQLITE_AUTH: |
||||||
|
return ErrUnauthorized |
||||||
|
case C.SQLITE_OK: |
||||||
|
return nil |
||||||
|
default: |
||||||
|
return c.lastError() |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// authenticate provides the actual authentication to SQLite.
|
||||||
|
// This is not exported for usage in Go.
|
||||||
|
// It is however exported for usage within SQL by the user.
|
||||||
|
//
|
||||||
|
// Returns:
|
||||||
|
// C.SQLITE_OK (0)
|
||||||
|
// C.SQLITE_ERROR (1)
|
||||||
|
// C.SQLITE_AUTH (23)
|
||||||
|
func (c *SQLiteConn) authenticate(username, password string) int { |
||||||
|
// Allocate C Variables
|
||||||
|
cuser := C.CString(username) |
||||||
|
cpass := C.CString(password) |
||||||
|
|
||||||
|
// Free C Variables
|
||||||
|
defer func() { |
||||||
|
C.free(unsafe.Pointer(cuser)) |
||||||
|
C.free(unsafe.Pointer(cpass)) |
||||||
|
}() |
||||||
|
|
||||||
|
return int(C._sqlite3_user_authenticate(c.db, cuser, cpass, C.int(len(password)))) |
||||||
|
} |
||||||
|
|
||||||
|
// AuthUserAdd can be used (by an admin user only)
|
||||||
|
// to create a new user. When called on a no-authentication-required
|
||||||
|
// database, this routine converts the database into an authentication-
|
||||||
|
// required database, automatically makes the added user an
|
||||||
|
// administrator, and logs in the current connection as that user.
|
||||||
|
// The AuthUserAdd only works for the "main" database, not
|
||||||
|
// for any ATTACH-ed databases. Any call to AuthUserAdd by a
|
||||||
|
// non-admin user results in an error.
|
||||||
|
func (c *SQLiteConn) AuthUserAdd(username, password string, admin bool) error { |
||||||
|
isAdmin := 0 |
||||||
|
if admin { |
||||||
|
isAdmin = 1 |
||||||
|
} |
||||||
|
|
||||||
|
rv := c.authUserAdd(username, password, isAdmin) |
||||||
|
switch rv { |
||||||
|
case C.SQLITE_ERROR, C.SQLITE_AUTH: |
||||||
|
return ErrAdminRequired |
||||||
|
case C.SQLITE_OK: |
||||||
|
return nil |
||||||
|
default: |
||||||
|
return c.lastError() |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// authUserAdd enables the User Authentication if not enabled.
|
||||||
|
// Otherwise it will add a user.
|
||||||
|
//
|
||||||
|
// When user authentication is already enabled then this function
|
||||||
|
// can only be called by an admin.
|
||||||
|
//
|
||||||
|
// This is not exported for usage in Go.
|
||||||
|
// It is however exported for usage within SQL by the user.
|
||||||
|
//
|
||||||
|
// Returns:
|
||||||
|
// C.SQLITE_OK (0)
|
||||||
|
// C.SQLITE_ERROR (1)
|
||||||
|
// C.SQLITE_AUTH (23)
|
||||||
|
func (c *SQLiteConn) authUserAdd(username, password string, admin int) int { |
||||||
|
// Allocate C Variables
|
||||||
|
cuser := C.CString(username) |
||||||
|
cpass := C.CString(password) |
||||||
|
|
||||||
|
// Free C Variables
|
||||||
|
defer func() { |
||||||
|
C.free(unsafe.Pointer(cuser)) |
||||||
|
C.free(unsafe.Pointer(cpass)) |
||||||
|
}() |
||||||
|
|
||||||
|
return int(C._sqlite3_user_add(c.db, cuser, cpass, C.int(len(password)), C.int(admin))) |
||||||
|
} |
||||||
|
|
||||||
|
// AuthUserChange can be used to change a users
|
||||||
|
// login credentials or admin privilege. Any user can change their own
|
||||||
|
// login credentials. Only an admin user can change another users login
|
||||||
|
// credentials or admin privilege setting. No user may change their own
|
||||||
|
// admin privilege setting.
|
||||||
|
func (c *SQLiteConn) AuthUserChange(username, password string, admin bool) error { |
||||||
|
isAdmin := 0 |
||||||
|
if admin { |
||||||
|
isAdmin = 1 |
||||||
|
} |
||||||
|
|
||||||
|
rv := c.authUserChange(username, password, isAdmin) |
||||||
|
switch rv { |
||||||
|
case C.SQLITE_ERROR, C.SQLITE_AUTH: |
||||||
|
return ErrAdminRequired |
||||||
|
case C.SQLITE_OK: |
||||||
|
return nil |
||||||
|
default: |
||||||
|
return c.lastError() |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// authUserChange allows to modify a user.
|
||||||
|
// Users can change their own password.
|
||||||
|
//
|
||||||
|
// Only admins can change passwords for other users
|
||||||
|
// and modify the admin flag.
|
||||||
|
//
|
||||||
|
// The admin flag of the current logged in user cannot be changed.
|
||||||
|
// THis ensures that their is always an admin.
|
||||||
|
//
|
||||||
|
// This is not exported for usage in Go.
|
||||||
|
// It is however exported for usage within SQL by the user.
|
||||||
|
//
|
||||||
|
// Returns:
|
||||||
|
// C.SQLITE_OK (0)
|
||||||
|
// C.SQLITE_ERROR (1)
|
||||||
|
// C.SQLITE_AUTH (23)
|
||||||
|
func (c *SQLiteConn) authUserChange(username, password string, admin int) int { |
||||||
|
// Allocate C Variables
|
||||||
|
cuser := C.CString(username) |
||||||
|
cpass := C.CString(password) |
||||||
|
|
||||||
|
// Free C Variables
|
||||||
|
defer func() { |
||||||
|
C.free(unsafe.Pointer(cuser)) |
||||||
|
C.free(unsafe.Pointer(cpass)) |
||||||
|
}() |
||||||
|
|
||||||
|
return int(C._sqlite3_user_change(c.db, cuser, cpass, C.int(len(password)), C.int(admin))) |
||||||
|
} |
||||||
|
|
||||||
|
// AuthUserDelete can be used (by an admin user only)
|
||||||
|
// to delete a user. The currently logged-in user cannot be deleted,
|
||||||
|
// which guarantees that there is always an admin user and hence that
|
||||||
|
// the database cannot be converted into a no-authentication-required
|
||||||
|
// database.
|
||||||
|
func (c *SQLiteConn) AuthUserDelete(username string) error { |
||||||
|
rv := c.authUserDelete(username) |
||||||
|
switch rv { |
||||||
|
case C.SQLITE_ERROR, C.SQLITE_AUTH: |
||||||
|
return ErrAdminRequired |
||||||
|
case C.SQLITE_OK: |
||||||
|
return nil |
||||||
|
default: |
||||||
|
return c.lastError() |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// authUserDelete can be used to delete a user.
|
||||||
|
//
|
||||||
|
// This function can only be executed by an admin.
|
||||||
|
//
|
||||||
|
// This is not exported for usage in Go.
|
||||||
|
// It is however exported for usage within SQL by the user.
|
||||||
|
//
|
||||||
|
// Returns:
|
||||||
|
// C.SQLITE_OK (0)
|
||||||
|
// C.SQLITE_ERROR (1)
|
||||||
|
// C.SQLITE_AUTH (23)
|
||||||
|
func (c *SQLiteConn) authUserDelete(username string) int { |
||||||
|
// Allocate C Variables
|
||||||
|
cuser := C.CString(username) |
||||||
|
|
||||||
|
// Free C Variables
|
||||||
|
defer func() { |
||||||
|
C.free(unsafe.Pointer(cuser)) |
||||||
|
}() |
||||||
|
|
||||||
|
return int(C._sqlite3_user_delete(c.db, cuser)) |
||||||
|
} |
||||||
|
|
||||||
|
// AuthEnabled checks if the database is protected by user authentication
|
||||||
|
func (c *SQLiteConn) AuthEnabled() (exists bool) { |
||||||
|
rv := c.authEnabled() |
||||||
|
if rv == 1 { |
||||||
|
exists = true |
||||||
|
} |
||||||
|
|
||||||
|
return |
||||||
|
} |
||||||
|
|
||||||
|
// authEnabled perform the actual check for user authentication.
|
||||||
|
//
|
||||||
|
// This is not exported for usage in Go.
|
||||||
|
// It is however exported for usage within SQL by the user.
|
||||||
|
//
|
||||||
|
// Returns:
|
||||||
|
// 0 - Disabled
|
||||||
|
// 1 - Enabled
|
||||||
|
func (c *SQLiteConn) authEnabled() int { |
||||||
|
return int(C._sqlite3_auth_enabled(c.db)) |
||||||
|
} |
||||||
|
|
||||||
|
// EOF
|
@ -0,0 +1,152 @@ |
|||||||
|
// 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_userauth
|
||||||
|
|
||||||
|
package sqlite3 |
||||||
|
|
||||||
|
import ( |
||||||
|
"C" |
||||||
|
) |
||||||
|
|
||||||
|
// Authenticate will perform an authentication of the provided username
|
||||||
|
// and password against the database.
|
||||||
|
//
|
||||||
|
// If a database contains the SQLITE_USER table, then the
|
||||||
|
// call to Authenticate must be invoked with an
|
||||||
|
// appropriate username and password prior to enable read and write
|
||||||
|
//access to the database.
|
||||||
|
//
|
||||||
|
// Return SQLITE_OK on success or SQLITE_ERROR if the username/password
|
||||||
|
// combination is incorrect or unknown.
|
||||||
|
//
|
||||||
|
// If the SQLITE_USER table is not present in the database file, then
|
||||||
|
// this interface is a harmless no-op returnning SQLITE_OK.
|
||||||
|
func (c *SQLiteConn) Authenticate(username, password string) error { |
||||||
|
// NOOP
|
||||||
|
return nil |
||||||
|
} |
||||||
|
|
||||||
|
// authenticate provides the actual authentication to SQLite.
|
||||||
|
// This is not exported for usage in Go.
|
||||||
|
// It is however exported for usage within SQL by the user.
|
||||||
|
//
|
||||||
|
// Returns:
|
||||||
|
// C.SQLITE_OK (0)
|
||||||
|
// C.SQLITE_ERROR (1)
|
||||||
|
// C.SQLITE_AUTH (23)
|
||||||
|
func (c *SQLiteConn) authenticate(username, password string) int { |
||||||
|
// NOOP
|
||||||
|
return 0 |
||||||
|
} |
||||||
|
|
||||||
|
// AuthUserAdd can be used (by an admin user only)
|
||||||
|
// to create a new user. When called on a no-authentication-required
|
||||||
|
// database, this routine converts the database into an authentication-
|
||||||
|
// required database, automatically makes the added user an
|
||||||
|
// administrator, and logs in the current connection as that user.
|
||||||
|
// The AuthUserAdd only works for the "main" database, not
|
||||||
|
// for any ATTACH-ed databases. Any call to AuthUserAdd by a
|
||||||
|
// non-admin user results in an error.
|
||||||
|
func (c *SQLiteConn) AuthUserAdd(username, password string, admin bool) error { |
||||||
|
// NOOP
|
||||||
|
return nil |
||||||
|
} |
||||||
|
|
||||||
|
// authUserAdd enables the User Authentication if not enabled.
|
||||||
|
// Otherwise it will add a user.
|
||||||
|
//
|
||||||
|
// When user authentication is already enabled then this function
|
||||||
|
// can only be called by an admin.
|
||||||
|
//
|
||||||
|
// This is not exported for usage in Go.
|
||||||
|
// It is however exported for usage within SQL by the user.
|
||||||
|
//
|
||||||
|
// Returns:
|
||||||
|
// C.SQLITE_OK (0)
|
||||||
|
// C.SQLITE_ERROR (1)
|
||||||
|
// C.SQLITE_AUTH (23)
|
||||||
|
func (c *SQLiteConn) authUserAdd(username, password string, admin int) int { |
||||||
|
// NOOP
|
||||||
|
return 0 |
||||||
|
} |
||||||
|
|
||||||
|
// AuthUserChange can be used to change a users
|
||||||
|
// login credentials or admin privilege. Any user can change their own
|
||||||
|
// login credentials. Only an admin user can change another users login
|
||||||
|
// credentials or admin privilege setting. No user may change their own
|
||||||
|
// admin privilege setting.
|
||||||
|
func (c *SQLiteConn) AuthUserChange(username, password string, admin bool) error { |
||||||
|
// NOOP
|
||||||
|
return nil |
||||||
|
} |
||||||
|
|
||||||
|
// authUserChange allows to modify a user.
|
||||||
|
// Users can change their own password.
|
||||||
|
//
|
||||||
|
// Only admins can change passwords for other users
|
||||||
|
// and modify the admin flag.
|
||||||
|
//
|
||||||
|
// The admin flag of the current logged in user cannot be changed.
|
||||||
|
// THis ensures that their is always an admin.
|
||||||
|
//
|
||||||
|
// This is not exported for usage in Go.
|
||||||
|
// It is however exported for usage within SQL by the user.
|
||||||
|
//
|
||||||
|
// Returns:
|
||||||
|
// C.SQLITE_OK (0)
|
||||||
|
// C.SQLITE_ERROR (1)
|
||||||
|
// C.SQLITE_AUTH (23)
|
||||||
|
func (c *SQLiteConn) authUserChange(username, password string, admin int) int { |
||||||
|
// NOOP
|
||||||
|
return 0 |
||||||
|
} |
||||||
|
|
||||||
|
// AuthUserDelete can be used (by an admin user only)
|
||||||
|
// to delete a user. The currently logged-in user cannot be deleted,
|
||||||
|
// which guarantees that there is always an admin user and hence that
|
||||||
|
// the database cannot be converted into a no-authentication-required
|
||||||
|
// database.
|
||||||
|
func (c *SQLiteConn) AuthUserDelete(username string) error { |
||||||
|
// NOOP
|
||||||
|
return nil |
||||||
|
} |
||||||
|
|
||||||
|
// authUserDelete can be used to delete a user.
|
||||||
|
//
|
||||||
|
// This function can only be executed by an admin.
|
||||||
|
//
|
||||||
|
// This is not exported for usage in Go.
|
||||||
|
// It is however exported for usage within SQL by the user.
|
||||||
|
//
|
||||||
|
// Returns:
|
||||||
|
// C.SQLITE_OK (0)
|
||||||
|
// C.SQLITE_ERROR (1)
|
||||||
|
// C.SQLITE_AUTH (23)
|
||||||
|
func (c *SQLiteConn) authUserDelete(username string) int { |
||||||
|
// NOOP
|
||||||
|
return 0 |
||||||
|
} |
||||||
|
|
||||||
|
// AuthEnabled checks if the database is protected by user authentication
|
||||||
|
func (c *SQLiteConn) AuthEnabled() (exists bool) { |
||||||
|
// NOOP
|
||||||
|
return false |
||||||
|
} |
||||||
|
|
||||||
|
// authEnabled perform the actual check for user authentication.
|
||||||
|
//
|
||||||
|
// This is not exported for usage in Go.
|
||||||
|
// It is however exported for usage within SQL by the user.
|
||||||
|
//
|
||||||
|
// Returns:
|
||||||
|
// 0 - Disabled
|
||||||
|
// 1 - Enabled
|
||||||
|
func (c *SQLiteConn) authEnabled() int { |
||||||
|
// NOOP
|
||||||
|
return 0 |
||||||
|
} |
||||||
|
|
||||||
|
// EOF
|
@ -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_vacuum_full
|
||||||
|
|
||||||
|
package sqlite3 |
||||||
|
|
||||||
|
/* |
||||||
|
#cgo CFLAGS: -DSQLITE_DEFAULT_AUTOVACUUM=1 |
||||||
|
#cgo LDFLAGS: -lm |
||||||
|
*/ |
||||||
|
import "C" |
@ -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_vacuum_incr
|
||||||
|
|
||||||
|
package sqlite3 |
||||||
|
|
||||||
|
/* |
||||||
|
#cgo CFLAGS: -DSQLITE_DEFAULT_AUTOVACUUM=2 |
||||||
|
#cgo LDFLAGS: -lm |
||||||
|
*/ |
||||||
|
import "C" |
@ -0,0 +1,14 @@ |
|||||||
|
// Copyright (C) 2018 Yasuhiro Matsumoto <mattn.jp@gmail.com>.
|
||||||
|
//
|
||||||
|
// Use of this source code is governed by an MIT-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build solaris
|
||||||
|
|
||||||
|
package sqlite3 |
||||||
|
|
||||||
|
/* |
||||||
|
#cgo CFLAGS: -D__EXTENSIONS__=1 |
||||||
|
#cgo LDFLAGS: -lc |
||||||
|
*/ |
||||||
|
import "C" |
@ -0,0 +1,39 @@ |
|||||||
|
// 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 cgo
|
||||||
|
|
||||||
|
package sqlite3 |
||||||
|
|
||||||
|
// usleep is a function available on *nix based systems.
|
||||||
|
// This function is not present in Windows.
|
||||||
|
// Windows has a sleep function but this works with seconds
|
||||||
|
// and not with microseconds as usleep.
|
||||||
|
//
|
||||||
|
// This code should improve performance on windows because
|
||||||
|
// without the presence of usleep SQLite waits 1 second.
|
||||||
|
//
|
||||||
|
// Source: https://stackoverflow.com/questions/5801813/c-usleep-is-obsolete-workarounds-for-windows-mingw?utm_medium=organic&utm_source=google_rich_qa&utm_campaign=google_rich_qa
|
||||||
|
|
||||||
|
/* |
||||||
|
#include <windows.h> |
||||||
|
|
||||||
|
void usleep(__int64 usec) |
||||||
|
{ |
||||||
|
HANDLE timer; |
||||||
|
LARGE_INTEGER ft; |
||||||
|
|
||||||
|
// Convert to 100 nanosecond interval, negative value indicates relative time
|
||||||
|
ft.QuadPart = -(10*usec); |
||||||
|
|
||||||
|
timer = CreateWaitableTimer(NULL, TRUE, NULL); |
||||||
|
SetWaitableTimer(timer, &ft, 0, NULL, NULL, 0); |
||||||
|
WaitForSingleObject(timer, INFINITE); |
||||||
|
CloseHandle(timer); |
||||||
|
} |
||||||
|
*/ |
||||||
|
import "C" |
||||||
|
|
||||||
|
// EOF
|
@ -0,0 +1,21 @@ |
|||||||
|
// +build !cgo
|
||||||
|
|
||||||
|
package sqlite3 |
||||||
|
|
||||||
|
import ( |
||||||
|
"database/sql" |
||||||
|
"database/sql/driver" |
||||||
|
"errors" |
||||||
|
) |
||||||
|
|
||||||
|
func init() { |
||||||
|
sql.Register("sqlite3", &SQLiteDriverMock{}) |
||||||
|
} |
||||||
|
|
||||||
|
type SQLiteDriverMock struct{} |
||||||
|
|
||||||
|
var errorMsg = errors.New("Binary was compiled with 'CGO_ENABLED=0', go-sqlite3 requires cgo to work. This is a stub") |
||||||
|
|
||||||
|
func (SQLiteDriverMock) Open(s string) (driver.Conn, error) { |
||||||
|
return nil, errorMsg |
||||||
|
} |
Loading…
Reference in new issue