[ci skip]
fix-635
Gert-Jan Timmer 2018-05-31 16:42:03 +02:00
parent f7f8019102
commit 4a33fcc1d2
4 changed files with 86 additions and 15 deletions

View File

@ -1308,7 +1308,7 @@ func (d *SQLiteDriver) Open(dsn string) (driver.Conn, error) {
// //
// If the SQLITE_USER table is not present in the database file, then // If the SQLITE_USER table is not present in the database file, then
// this interface is a harmless no-op returnning SQLITE_OK. // this interface is a harmless no-op returnning SQLITE_OK.
if err := conn.RegisterFunc("authenticate", conn.Authenticate, true); err != nil { if err := conn.RegisterFunc("authenticate", conn.Authenticate, false); err != nil {
return nil, err return nil, err
} }
// //
@ -1321,7 +1321,7 @@ func (d *SQLiteDriver) Open(dsn string) (driver.Conn, error) {
// The AuthUserAdd only works for the "main" database, not // The AuthUserAdd only works for the "main" database, not
// for any ATTACH-ed databases. Any call to AuthUserAdd by a // for any ATTACH-ed databases. Any call to AuthUserAdd by a
// non-admin user results in an error. // non-admin user results in an error.
if err := conn.RegisterFunc("auth_user_add", conn.AuthUserAdd, true); err != nil { if err := conn.RegisterFunc("auth_user_add", conn.AuthUserAdd, false); err != nil {
return nil, err return nil, err
} }
// //
@ -1330,7 +1330,7 @@ func (d *SQLiteDriver) Open(dsn string) (driver.Conn, error) {
// login credentials. Only an admin user can change another users login // login credentials. Only an admin user can change another users login
// credentials or admin privilege setting. No user may change their own // credentials or admin privilege setting. No user may change their own
// admin privilege setting. // admin privilege setting.
if err := conn.RegisterFunc("auth_user_change", conn.AuthUserChange, true); err != nil { if err := conn.RegisterFunc("auth_user_change", conn.AuthUserChange, false); err != nil {
return nil, err return nil, err
} }
// //
@ -1339,7 +1339,7 @@ func (d *SQLiteDriver) Open(dsn string) (driver.Conn, error) {
// which guarantees that there is always an admin user and hence that // which guarantees that there is always an admin user and hence that
// the database cannot be converted into a no-authentication-required // the database cannot be converted into a no-authentication-required
// database. // database.
if err := conn.RegisterFunc("auth_user_delete", conn.AuthUserDelete, true); err != nil { if err := conn.RegisterFunc("auth_user_delete", conn.AuthUserDelete, false); err != nil {
return nil, err return nil, err
} }

View File

@ -60,6 +60,7 @@ _sqlite3_auth_is_enabled(sqlite3* db)
*/ */
import "C" import "C"
import ( import (
"errors"
"unsafe" "unsafe"
) )
@ -67,6 +68,11 @@ const (
SQLITE_AUTH = C.SQLITE_AUTH 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 // Authenticate will perform an authentication of the provided username
// and password against the database. // and password against the database.
// //
@ -92,6 +98,9 @@ func (c *SQLiteConn) Authenticate(username, password string) error {
}() }()
rv := C._sqlite3_user_authenticate(c.db, cuser, cpass, C.int(len(password))) rv := C._sqlite3_user_authenticate(c.db, cuser, cpass, C.int(len(password)))
if rv == C.SQLITE_AUTH {
return ErrUnauthorized
}
if rv != C.SQLITE_OK { if rv != C.SQLITE_OK {
return c.lastError() return c.lastError()
} }
@ -113,6 +122,18 @@ func (c *SQLiteConn) AuthUserAdd(username, password string, admin bool) error {
isAdmin = 1 isAdmin = 1
} }
rv := c.authUserAdd(username, password, isAdmin)
switch rv {
case C.SQLITE_AUTH:
return ErrAdminRequired
case C.SQLITE_OK:
return nil
default:
return c.lastError()
}
}
func (c *SQLiteConn) authUserAdd(username, password string, admin int) int {
// Allocate C Variables // Allocate C Variables
cuser := C.CString(username) cuser := C.CString(username)
cpass := C.CString(password) cpass := C.CString(password)
@ -123,12 +144,7 @@ func (c *SQLiteConn) AuthUserAdd(username, password string, admin bool) error {
C.free(unsafe.Pointer(cpass)) C.free(unsafe.Pointer(cpass))
}() }()
rv := C._sqlite3_user_add(c.db, cuser, cpass, C.int(len(password)), C.int(isAdmin)) return int(C._sqlite3_user_add(c.db, cuser, cpass, C.int(len(password)), C.int(admin)))
if rv != C.SQLITE_OK {
return c.lastError()
}
return nil
} }
// AuthUserChange can be used to change a users // AuthUserChange can be used to change a users
@ -153,6 +169,9 @@ func (c *SQLiteConn) AuthUserChange(username, password string, admin bool) error
}() }()
rv := C._sqlite3_user_change(c.db, cuser, cpass, C.int(len(password)), C.int(isAdmin)) rv := C._sqlite3_user_change(c.db, cuser, cpass, C.int(len(password)), C.int(isAdmin))
if rv == C.SQLITE_AUTH {
return ErrAdminRequired
}
if rv != C.SQLITE_OK { if rv != C.SQLITE_OK {
return c.lastError() return c.lastError()
} }
@ -175,6 +194,9 @@ func (c *SQLiteConn) AuthUserDelete(username string) error {
}() }()
rv := C._sqlite3_user_delete(c.db, cuser) rv := C._sqlite3_user_delete(c.db, cuser)
if rv == SQLITE_AUTH {
return ErrAdminRequired
}
if rv != C.SQLITE_OK { if rv != C.SQLITE_OK {
return c.lastError() return c.lastError()
} }

View File

@ -62,4 +62,9 @@ func (c *SQLiteConn) AuthUserDelete(username string) error {
return nil return nil
} }
// Check is database is protected by user authentication
func (c *SQLiteConn) AuthIsEnabled() (exists bool) {
return
}
// EOF // EOF

View File

@ -9,6 +9,7 @@ package sqlite3
import ( import (
"database/sql" "database/sql"
"fmt"
"os" "os"
"testing" "testing"
) )
@ -23,11 +24,6 @@ func TestAuthCreateDatabase(t *testing.T) {
} }
defer db.Close() defer db.Close()
// Ping database
if err := db.Ping(); err != nil {
t.Fatal(err)
}
var exists bool var exists bool
err = db.QueryRow("select count(type) from sqlite_master WHERE type='table' and name='sqlite_user';").Scan(&exists) err = db.QueryRow("select count(type) from sqlite_master WHERE type='table' and name='sqlite_user';").Scan(&exists)
if err != nil { if err != nil {
@ -38,3 +34,51 @@ func TestAuthCreateDatabase(t *testing.T) {
t.Fatal("failed to enable User Authentication") t.Fatal("failed to enable User Authentication")
} }
} }
func TestAuthorization(t *testing.T) {
tempFilename := TempFilename(t)
fmt.Println(tempFilename)
//defer os.Remove(tempFilename)
db, err := sql.Open("sqlite3", "file:"+tempFilename+"?_auth&_auth_user=admin&_auth_pass=admin")
if err != nil {
t.Fatal("Failed to open database:", err)
}
if _, err := db.Exec("select auth_user_add('user', 'user', false);"); err != nil {
t.Fatal(err)
}
var uname string
if err := db.QueryRow("select uname from sqlite_user where uname = 'user';").Scan(&uname); err != nil {
t.Fatal(err)
}
if uname != "user" {
t.Fatal("Failed to create normal user")
}
db.Close()
// Re-Open Database as User
// Add User should now fail because we are not admin
db, err = sql.Open("sqlite3", "file:"+tempFilename+"?_auth_user=user&_auth_pass=user")
if err != nil {
t.Fatal("Failed to open database:", err)
}
defer db.Close()
// Try to create normal user
var rv string
if err := db.QueryRow("select auth_user_add('user2', 'user2', false);").Scan(&rv); err != nil {
t.Fatal(err)
}
fmt.Printf("RV: %v\n", rv)
// if rv != SQLITE_AUTH {
// t.Fatal("Succeeded creating user while not admin")
// }
// // Try to create admin user
// if _, err := db.Exec("select auth_user_add('admin2', 'admin2', true);"); err != nil {
// t.Fatal(err)
// }
}