auth.go 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357
  1. package sqlite
  2. // #include <stdint.h>
  3. // #include <sqlite3.h>
  4. // #include "wrappers.h"
  5. //
  6. // static int sqlite3_go_set_authorizer(sqlite3* conn, uintptr_t id) {
  7. // return sqlite3_set_authorizer(conn, c_auth_tramp, (void*)id);
  8. // }
  9. import "C"
  10. import (
  11. "errors"
  12. "fmt"
  13. "strings"
  14. "sync"
  15. )
  16. // An Authorizer is called during statement preparation to see whether an action
  17. // is allowed by the application. See https://sqlite.org/c3ref/set_authorizer.html
  18. type Authorizer interface {
  19. Authorize(info ActionInfo) AuthResult
  20. }
  21. // SetAuthorizer registers an authorizer for the database connection.
  22. // SetAuthorizer(nil) clears any authorizer previously set.
  23. func (conn *Conn) SetAuthorizer(auth Authorizer) error {
  24. if auth == nil {
  25. if conn.authorizer == -1 {
  26. return nil
  27. }
  28. conn.releaseAuthorizer()
  29. res := C.sqlite3_set_authorizer(conn.conn, nil, nil)
  30. return reserr("SetAuthorizer", "", "", res)
  31. }
  32. authFuncs.mu.Lock()
  33. id := authFuncs.next
  34. next := authFuncs.next + 1
  35. if next < 0 {
  36. authFuncs.mu.Unlock()
  37. return errors.New("sqlite: authorizer function id overflow")
  38. }
  39. authFuncs.next = next
  40. authFuncs.m[id] = auth
  41. authFuncs.mu.Unlock()
  42. res := C.sqlite3_go_set_authorizer(conn.conn, C.uintptr_t(id))
  43. return reserr("SetAuthorizer", "", "", res)
  44. }
  45. func (conn *Conn) releaseAuthorizer() {
  46. if conn.authorizer == -1 {
  47. return
  48. }
  49. authFuncs.mu.Lock()
  50. delete(authFuncs.m, conn.authorizer)
  51. authFuncs.mu.Unlock()
  52. conn.authorizer = -1
  53. }
  54. var authFuncs = struct {
  55. mu sync.RWMutex
  56. m map[int]Authorizer
  57. next int
  58. }{
  59. m: make(map[int]Authorizer),
  60. }
  61. //export go_sqlite_auth_tramp
  62. func go_sqlite_auth_tramp(id uintptr, action C.int, cArg1, cArg2 *C.char, cDB *C.char, cTrigger *C.char) C.int {
  63. authFuncs.mu.RLock()
  64. auth := authFuncs.m[int(id)]
  65. authFuncs.mu.RUnlock()
  66. var arg1, arg2, database, trigger string
  67. if cArg1 != nil {
  68. arg1 = C.GoString(cArg1)
  69. }
  70. if cArg2 != nil {
  71. arg2 = C.GoString(cArg2)
  72. }
  73. if cDB != nil {
  74. database = C.GoString(cDB)
  75. }
  76. if cTrigger != nil {
  77. trigger = C.GoString(cTrigger)
  78. }
  79. return C.int(auth.Authorize(newActionInfo(OpType(action), arg1, arg2, database, trigger)))
  80. }
  81. // AuthorizeFunc is a function that implements Authorizer.
  82. type AuthorizeFunc func(info ActionInfo) AuthResult
  83. // Authorize calls f.
  84. func (f AuthorizeFunc) Authorize(info ActionInfo) AuthResult {
  85. return f(info)
  86. }
  87. // AuthResult is the result of a call to an Authorizer. The zero value is
  88. // SQLITE_OK.
  89. type AuthResult int
  90. // Possible return values of an Authorizer.
  91. const (
  92. // Cause the entire SQL statement to be rejected with an error.
  93. SQLITE_DENY = AuthResult(C.SQLITE_DENY)
  94. // Disallow the specific action but allow the SQL statement to continue to
  95. // be compiled.
  96. SQLITE_IGNORE = AuthResult(C.SQLITE_IGNORE)
  97. )
  98. // String returns the C constant name of the result.
  99. func (result AuthResult) String() string {
  100. switch result {
  101. default:
  102. var buf [20]byte
  103. return "SQLITE_UNKNOWN_AUTH_RESULT(" + string(itoa(buf[:], int64(result))) + ")"
  104. case AuthResult(C.SQLITE_OK):
  105. return "SQLITE_OK"
  106. case SQLITE_DENY:
  107. return "SQLITE_DENY"
  108. case SQLITE_IGNORE:
  109. return "SQLITE_IGNORE"
  110. }
  111. }
  112. // ActionInfo holds information about an action to be authorized.
  113. //
  114. // Only the fields relevant to the Action are populated when this is passed to
  115. // an Authorizer.
  116. //
  117. // https://sqlite.org/c3ref/c_alter_table.html
  118. type ActionInfo struct {
  119. Action OpType
  120. Index string
  121. Table string
  122. Column string
  123. Trigger string
  124. View string
  125. Function string
  126. Pragma string
  127. PragmaArg string
  128. Operation string
  129. Filename string
  130. Module string
  131. Database string
  132. Savepoint string
  133. InnerMostTrigger string
  134. }
  135. // newActionInfo returns an ActionInfo with the correct fields relevant to the
  136. // action.
  137. func newActionInfo(action OpType, arg1, arg2, database, trigger string) ActionInfo {
  138. // We use the blank identifier with unused args below simply for visual
  139. // consistency between the cases.
  140. a := ActionInfo{Action: action, Database: database, InnerMostTrigger: trigger}
  141. switch action {
  142. case SQLITE_DROP_INDEX,
  143. SQLITE_DROP_TEMP_INDEX,
  144. SQLITE_CREATE_INDEX,
  145. SQLITE_CREATE_TEMP_INDEX:
  146. /* Index Name Table Name */
  147. a.Index = arg1
  148. a.Table = arg2
  149. case SQLITE_DELETE,
  150. SQLITE_DROP_TABLE,
  151. SQLITE_DROP_TEMP_TABLE,
  152. SQLITE_INSERT,
  153. SQLITE_ANALYZE,
  154. SQLITE_CREATE_TABLE,
  155. SQLITE_CREATE_TEMP_TABLE:
  156. /* Table Name NULL */
  157. a.Table = arg1
  158. _ = arg2
  159. case SQLITE_CREATE_TEMP_TRIGGER,
  160. SQLITE_CREATE_TRIGGER,
  161. SQLITE_DROP_TEMP_TRIGGER,
  162. SQLITE_DROP_TRIGGER:
  163. /* Trigger Name Table Name */
  164. a.Trigger = arg1
  165. a.Table = arg2
  166. case SQLITE_CREATE_TEMP_VIEW,
  167. SQLITE_CREATE_VIEW,
  168. SQLITE_DROP_TEMP_VIEW,
  169. SQLITE_DROP_VIEW:
  170. /* View Name NULL */
  171. a.View = arg1
  172. _ = arg2
  173. case SQLITE_PRAGMA:
  174. /* Pragma Name 1st arg or NULL */
  175. a.Pragma = arg1
  176. a.PragmaArg = arg2
  177. case SQLITE_READ,
  178. SQLITE_UPDATE:
  179. /* Table Name Column Name */
  180. a.Table = arg1
  181. a.Column = arg2
  182. case SQLITE_TRANSACTION:
  183. /* Operation NULL */
  184. a.Operation = arg1
  185. _ = arg2
  186. case SQLITE_ATTACH:
  187. /* Filename NULL */
  188. a.Filename = arg1
  189. _ = arg2
  190. case SQLITE_DETACH:
  191. /* Database Name NULL */
  192. a.Database = arg1
  193. _ = arg2
  194. case SQLITE_ALTER_TABLE:
  195. /* Database Name Table Name */
  196. a.Database = arg1
  197. a.Table = arg2
  198. case SQLITE_REINDEX:
  199. /* Index Name NULL */
  200. a.Index = arg1
  201. _ = arg2
  202. case SQLITE_CREATE_VTABLE,
  203. SQLITE_DROP_VTABLE:
  204. /* Table Name Module Name */
  205. a.Table = arg1
  206. a.Module = arg2
  207. case SQLITE_FUNCTION:
  208. /* NULL Function Name */
  209. _ = arg1
  210. a.Function = arg2
  211. case SQLITE_SAVEPOINT:
  212. /* Operation Savepoint Name */
  213. a.Operation = arg1
  214. a.Savepoint = arg2
  215. case SQLITE_RECURSIVE,
  216. SQLITE_SELECT:
  217. /* NULL NULL */
  218. _ = arg1
  219. _ = arg2
  220. case SQLITE_COPY:
  221. /* No longer used */
  222. default:
  223. panic(fmt.Errorf("unknown action: %v", action))
  224. }
  225. return a
  226. }
  227. // String returns a string describing only the fields relevant to `a.Action`.
  228. func (a ActionInfo) String() string {
  229. switch a.Action {
  230. case SQLITE_DROP_INDEX,
  231. SQLITE_DROP_TEMP_INDEX,
  232. SQLITE_CREATE_INDEX,
  233. SQLITE_CREATE_TEMP_INDEX:
  234. /* Index Name Table Name */
  235. return fmt.Sprintf("%v: Index: %q Table: %q",
  236. a.Action, a.Index, a.Table)
  237. case SQLITE_DELETE,
  238. SQLITE_DROP_TABLE,
  239. SQLITE_DROP_TEMP_TABLE,
  240. SQLITE_INSERT,
  241. SQLITE_ANALYZE,
  242. SQLITE_CREATE_TABLE,
  243. SQLITE_CREATE_TEMP_TABLE:
  244. /* Table Name NULL */
  245. return fmt.Sprintf("%v: Table: %q", a.Action, a.Table)
  246. case SQLITE_CREATE_TEMP_TRIGGER,
  247. SQLITE_CREATE_TRIGGER,
  248. SQLITE_DROP_TEMP_TRIGGER,
  249. SQLITE_DROP_TRIGGER:
  250. /* Trigger Name Table Name */
  251. return fmt.Sprintf("%v: Trigger: %q Table: %q",
  252. a.Action, a.Trigger, a.Table)
  253. case SQLITE_CREATE_TEMP_VIEW,
  254. SQLITE_CREATE_VIEW,
  255. SQLITE_DROP_TEMP_VIEW,
  256. SQLITE_DROP_VIEW:
  257. /* View Name NULL */
  258. return fmt.Sprintf("%v: View: %q", a.Action, a.View)
  259. case SQLITE_PRAGMA:
  260. /* Pragma Name 1st arg or NULL */
  261. return fmt.Sprintf("%v: Pragma: %q",
  262. a.Action, strings.TrimSpace(a.Pragma+" "+a.PragmaArg))
  263. case SQLITE_READ,
  264. SQLITE_UPDATE:
  265. /* Table Name Column Name */
  266. return fmt.Sprintf("%v: Table: %q Column: %q",
  267. a.Action, a.Table, a.Column)
  268. case SQLITE_TRANSACTION:
  269. /* Operation NULL */
  270. return fmt.Sprintf("%v: Operation: %q", a.Action, a.Operation)
  271. case SQLITE_ATTACH:
  272. /* Filename NULL */
  273. return fmt.Sprintf("%v: Filename: %q", a.Action, a.Filename)
  274. case SQLITE_DETACH:
  275. /* Database Name NULL */
  276. return fmt.Sprintf("%v: Database: %q", a.Action, a.Database)
  277. case SQLITE_ALTER_TABLE:
  278. /* Database Name Table Name */
  279. return fmt.Sprintf("%v: Database: %q Table: %q",
  280. a.Action, a.Database, a.Table)
  281. case SQLITE_REINDEX:
  282. /* Index Name NULL */
  283. return fmt.Sprintf("%v: Index: %q", a.Action, a.Index)
  284. case SQLITE_CREATE_VTABLE,
  285. SQLITE_DROP_VTABLE:
  286. /* Table Name Module Name */
  287. return fmt.Sprintf("%v: Table: %q Module: %q",
  288. a.Action, a.Table, a.Module)
  289. case SQLITE_FUNCTION:
  290. /* NULL Function Name */
  291. return fmt.Sprintf("%v: Function: %q", a.Action, a.Function)
  292. case SQLITE_SAVEPOINT:
  293. /* Operation Savepoint Name */
  294. return fmt.Sprintf("%v: Operation: %q Savepoint: %q",
  295. a.Action, a.Operation, a.Savepoint)
  296. case SQLITE_RECURSIVE,
  297. SQLITE_SELECT:
  298. /* NULL NULL */
  299. return fmt.Sprintf("%v:", a.Action)
  300. case SQLITE_COPY:
  301. /* No longer used */
  302. return fmt.Sprintf("%v:", a.Action)
  303. default:
  304. return fmt.Sprintf("unknown action: %v", a.Action)
  305. }
  306. }