|
1
|
/* |
|
2
|
** Copyright (c) 2010 D. Richard Hipp |
|
3
|
** |
|
4
|
** This program is free software; you can redistribute it and/or |
|
5
|
** modify it under the terms of the Simplified BSD License (also |
|
6
|
** known as the "2-Clause License" or "FreeBSD License".) |
|
7
|
|
|
8
|
** This program is distributed in the hope that it will be useful, |
|
9
|
** but without any warranty; without even the implied warranty of |
|
10
|
** merchantability or fitness for a particular purpose. |
|
11
|
** |
|
12
|
** Author contact information: |
|
13
|
** [email protected] |
|
14
|
** http://www.hwaci.com/drh/ |
|
15
|
** |
|
16
|
******************************************************************************* |
|
17
|
** |
|
18
|
** This module contains the code that initializes the "sqlite3" command-line |
|
19
|
** shell against the repository database. The command-line shell itself |
|
20
|
** is a copy of the "shell.c" code from SQLite. This file contains logic |
|
21
|
** to initialize the code in shell.c. |
|
22
|
*/ |
|
23
|
#include "config.h" |
|
24
|
#include "sqlcmd.h" |
|
25
|
#include <stdlib.h> /* atexit() */ |
|
26
|
#include <zlib.h> |
|
27
|
#ifndef _WIN32 |
|
28
|
# include "linenoise.h" |
|
29
|
#endif |
|
30
|
|
|
31
|
/* |
|
32
|
** True if the "fossil sql" command has the --test flag. False otherwise. |
|
33
|
*/ |
|
34
|
static int local_bSqlCmdTest = 0; |
|
35
|
|
|
36
|
/* |
|
37
|
** Implementation of the "content(X)" SQL function. Return the complete |
|
38
|
** content of artifact identified by X as a blob. |
|
39
|
*/ |
|
40
|
static void sqlcmd_content( |
|
41
|
sqlite3_context *context, |
|
42
|
int argc, |
|
43
|
sqlite3_value **argv |
|
44
|
){ |
|
45
|
int rid; |
|
46
|
Blob cx; |
|
47
|
const char *zName; |
|
48
|
assert( argc==1 ); |
|
49
|
zName = (const char*)sqlite3_value_text(argv[0]); |
|
50
|
if( zName==0 ) return; |
|
51
|
g.db = sqlite3_context_db_handle(context); |
|
52
|
g.repositoryOpen = 1; |
|
53
|
rid = name_to_rid(zName); |
|
54
|
if( rid==0 ) return; |
|
55
|
if( content_get(rid, &cx) ){ |
|
56
|
sqlite3_result_blob(context, blob_buffer(&cx), blob_size(&cx), |
|
57
|
SQLITE_TRANSIENT); |
|
58
|
blob_reset(&cx); |
|
59
|
} |
|
60
|
} |
|
61
|
|
|
62
|
/* |
|
63
|
** Implementation of the "compress(X)" SQL function. The input X is |
|
64
|
** compressed using zLib and the output is returned. |
|
65
|
*/ |
|
66
|
static void sqlcmd_compress( |
|
67
|
sqlite3_context *context, |
|
68
|
int argc, |
|
69
|
sqlite3_value **argv |
|
70
|
){ |
|
71
|
const unsigned char *pIn; |
|
72
|
unsigned char *pOut; |
|
73
|
unsigned int nIn; |
|
74
|
unsigned long int nOut; |
|
75
|
int rc; |
|
76
|
|
|
77
|
pIn = sqlite3_value_blob(argv[0]); |
|
78
|
nIn = sqlite3_value_bytes(argv[0]); |
|
79
|
nOut = 13 + nIn + (nIn+999)/1000; |
|
80
|
pOut = sqlite3_malloc( nOut+4 ); |
|
81
|
pOut[0] = nIn>>24 & 0xff; |
|
82
|
pOut[1] = nIn>>16 & 0xff; |
|
83
|
pOut[2] = nIn>>8 & 0xff; |
|
84
|
pOut[3] = nIn & 0xff; |
|
85
|
rc = compress(&pOut[4], &nOut, pIn, nIn); |
|
86
|
if( rc==Z_OK ){ |
|
87
|
sqlite3_result_blob(context, pOut, nOut+4, sqlite3_free); |
|
88
|
}else if( rc==Z_MEM_ERROR ){ |
|
89
|
sqlite3_free(pOut); |
|
90
|
sqlite3_result_error_nomem(context); |
|
91
|
}else{ |
|
92
|
sqlite3_free(pOut); |
|
93
|
sqlite3_result_error(context, "input cannot be zlib compressed", -1); |
|
94
|
} |
|
95
|
} |
|
96
|
|
|
97
|
/* |
|
98
|
** Implementation of the "decompress(X)" SQL function. The argument X |
|
99
|
** is a blob which was obtained from compress(Y). The output will be |
|
100
|
** the value Y. |
|
101
|
*/ |
|
102
|
static void sqlcmd_decompress( |
|
103
|
sqlite3_context *context, |
|
104
|
int argc, |
|
105
|
sqlite3_value **argv |
|
106
|
){ |
|
107
|
const unsigned char *pIn; |
|
108
|
unsigned char *pOut; |
|
109
|
unsigned int nIn; |
|
110
|
unsigned long int nOut; |
|
111
|
int rc; |
|
112
|
|
|
113
|
pIn = sqlite3_value_blob(argv[0]); |
|
114
|
if( pIn==0 ) return; |
|
115
|
nIn = sqlite3_value_bytes(argv[0]); |
|
116
|
if( nIn<4 ) return; |
|
117
|
nOut = (pIn[0]<<24) + (pIn[1]<<16) + (pIn[2]<<8) + pIn[3]; |
|
118
|
pOut = sqlite3_malloc( nOut+1 ); |
|
119
|
rc = uncompress(pOut, &nOut, &pIn[4], nIn-4); |
|
120
|
if( rc==Z_OK ){ |
|
121
|
sqlite3_result_blob(context, pOut, nOut, sqlite3_free); |
|
122
|
}else if( rc==Z_MEM_ERROR ){ |
|
123
|
sqlite3_free(pOut); |
|
124
|
sqlite3_result_error_nomem(context); |
|
125
|
}else{ |
|
126
|
sqlite3_free(pOut); |
|
127
|
sqlite3_result_error(context, "input is not zlib compressed", -1); |
|
128
|
} |
|
129
|
} |
|
130
|
|
|
131
|
/* |
|
132
|
** Implementation of the "gather_artifact_stats(X)" SQL function. |
|
133
|
** That function merely calls the gather_artifact_stats() function |
|
134
|
** in stat.c to populate the ARTSTAT temporary table. |
|
135
|
*/ |
|
136
|
static void sqlcmd_gather_artifact_stats( |
|
137
|
sqlite3_context *context, |
|
138
|
int argc, |
|
139
|
sqlite3_value **argv |
|
140
|
){ |
|
141
|
gather_artifact_stats(1); |
|
142
|
} |
|
143
|
|
|
144
|
/* |
|
145
|
** Add the content(), compress(), decompress(), and |
|
146
|
** gather_artifact_stats() SQL functions to database connection db. |
|
147
|
*/ |
|
148
|
int add_content_sql_commands(sqlite3 *db){ |
|
149
|
sqlite3_create_function(db, "content", 1, SQLITE_UTF8, 0, |
|
150
|
sqlcmd_content, 0, 0); |
|
151
|
sqlite3_create_function(db, "compress", 1, SQLITE_UTF8, 0, |
|
152
|
sqlcmd_compress, 0, 0); |
|
153
|
sqlite3_create_function(db, "decompress", 1, SQLITE_UTF8, 0, |
|
154
|
sqlcmd_decompress, 0, 0); |
|
155
|
sqlite3_create_function(db, "gather_artifact_stats", 0, SQLITE_UTF8, 0, |
|
156
|
sqlcmd_gather_artifact_stats, 0, 0); |
|
157
|
return SQLITE_OK; |
|
158
|
} |
|
159
|
|
|
160
|
/* |
|
161
|
** Undocumented test SQL functions: |
|
162
|
** |
|
163
|
** db_protect(X) |
|
164
|
** db_protect_pop(X) |
|
165
|
** |
|
166
|
** These invoke the corresponding C routines. |
|
167
|
** |
|
168
|
** WARNING: |
|
169
|
** Do not instantiate these functions for any Fossil webpage or command |
|
170
|
** method other than the "fossil sql" command. If an attacker gains access |
|
171
|
** to these functions, he will be able to disable other defense mechanisms. |
|
172
|
** |
|
173
|
** This routines are for interactive testing only. They are experimental |
|
174
|
** and undocumented (apart from this comments) and might go away or change |
|
175
|
** in future releases. |
|
176
|
** |
|
177
|
** 2020-11-29: These functions are now only available if the "fossil sql" |
|
178
|
** command is started with the --test option. |
|
179
|
*/ |
|
180
|
static void sqlcmd_db_protect( |
|
181
|
sqlite3_context *context, |
|
182
|
int argc, |
|
183
|
sqlite3_value **argv |
|
184
|
){ |
|
185
|
unsigned mask = 0; |
|
186
|
const char *z = (const char*)sqlite3_value_text(argv[0]); |
|
187
|
if( z!=0 && local_bSqlCmdTest ){ |
|
188
|
if( sqlite3_stricmp(z,"user")==0 ) mask |= PROTECT_USER; |
|
189
|
if( sqlite3_stricmp(z,"config")==0 ) mask |= PROTECT_CONFIG; |
|
190
|
if( sqlite3_stricmp(z,"sensitive")==0 ) mask |= PROTECT_SENSITIVE; |
|
191
|
if( sqlite3_stricmp(z,"readonly")==0 ) mask |= PROTECT_READONLY; |
|
192
|
if( sqlite3_stricmp(z,"all")==0 ) mask |= PROTECT_ALL; |
|
193
|
db_protect(mask); |
|
194
|
} |
|
195
|
} |
|
196
|
static void sqlcmd_db_protect_pop( |
|
197
|
sqlite3_context *context, |
|
198
|
int argc, |
|
199
|
sqlite3_value **argv |
|
200
|
){ |
|
201
|
if( !local_bSqlCmdTest ) db_protect_pop(); |
|
202
|
} |
|
203
|
|
|
204
|
/* |
|
205
|
** This is the "automatic extension" initializer that runs right after |
|
206
|
** the connection to the repository database is opened. Set up the |
|
207
|
** database connection to be more useful to the human operator. |
|
208
|
*/ |
|
209
|
static int sqlcmd_autoinit( |
|
210
|
sqlite3 *db, |
|
211
|
const char **pzErrMsg, |
|
212
|
const void *notUsed |
|
213
|
){ |
|
214
|
int mTrace = SQLITE_TRACE_CLOSE; |
|
215
|
add_content_sql_commands(db); |
|
216
|
db_add_aux_functions(db); |
|
217
|
re_add_sql_func(db); |
|
218
|
search_sql_setup(db); |
|
219
|
foci_register(db); |
|
220
|
deltafunc_init(db); |
|
221
|
helptext_vtab_register(db); |
|
222
|
builtin_vtab_register(db); |
|
223
|
g.repositoryOpen = 1; |
|
224
|
g.db = db; |
|
225
|
sqlite3_busy_timeout(db, 10000); |
|
226
|
if( g.zRepositoryName ){ |
|
227
|
sqlite3_db_config(db, SQLITE_DBCONFIG_MAINDBNAME, "repository"); |
|
228
|
db_maybe_set_encryption_key(db, g.zRepositoryName); |
|
229
|
} |
|
230
|
if( g.zLocalDbName ){ |
|
231
|
char *zSql = sqlite3_mprintf("ATTACH %Q AS 'localdb' KEY ''", |
|
232
|
g.zLocalDbName); |
|
233
|
sqlite3_exec(db, zSql, 0, 0, 0); |
|
234
|
sqlite3_free(zSql); |
|
235
|
} |
|
236
|
if( g.zConfigDbName ){ |
|
237
|
char *zSql = sqlite3_mprintf("ATTACH %Q AS 'configdb' KEY ''", |
|
238
|
g.zConfigDbName); |
|
239
|
sqlite3_exec(db, zSql, 0, 0, 0); |
|
240
|
sqlite3_free(zSql); |
|
241
|
} |
|
242
|
(void)timeline_query_for_tty(); /* Registers wiki_to_text() as side-effect */ |
|
243
|
/* Arrange to trace close operations so that static prepared statements |
|
244
|
** will get cleaned up when the shell closes the database connection */ |
|
245
|
if( g.fSqlTrace ) mTrace |= SQLITE_TRACE_PROFILE; |
|
246
|
sqlite3_trace_v2(db, mTrace, db_sql_trace, 0); |
|
247
|
if( g.zRepositoryName ){ |
|
248
|
db_protect_only(PROTECT_NONE); |
|
249
|
sqlite3_set_authorizer(db, db_top_authorizer, db); |
|
250
|
if( local_bSqlCmdTest ){ |
|
251
|
sqlite3_create_function(db, "db_protect", 1, SQLITE_UTF8, 0, |
|
252
|
sqlcmd_db_protect, 0, 0); |
|
253
|
sqlite3_create_function(db, "db_protect_pop", 0, SQLITE_UTF8, 0, |
|
254
|
sqlcmd_db_protect_pop, 0, 0); |
|
255
|
sqlite3_create_function(db, "shared_secret", 2, SQLITE_UTF8, 0, |
|
256
|
sha1_shared_secret_sql_function, 0, 0); |
|
257
|
} |
|
258
|
} |
|
259
|
return SQLITE_OK; |
|
260
|
} |
|
261
|
|
|
262
|
/* |
|
263
|
** atexit() handler that cleans up global state modified by this module. |
|
264
|
*/ |
|
265
|
static void sqlcmd_atexit(void) { |
|
266
|
g.zConfigDbName = 0; /* prevent panic */ |
|
267
|
} |
|
268
|
|
|
269
|
/* |
|
270
|
** This routine is called by the sqlite3 command-line shell to |
|
271
|
** to load the name the Fossil repository database. |
|
272
|
*/ |
|
273
|
void sqlcmd_get_dbname(const char **pzRepoName){ |
|
274
|
*pzRepoName = g.zRepositoryName; |
|
275
|
} |
|
276
|
|
|
277
|
/* |
|
278
|
** This routine is called by the sqlite3 command-line shell to do |
|
279
|
** extra initialization prior to starting up the shell. |
|
280
|
*/ |
|
281
|
void sqlcmd_init_proc(void){ |
|
282
|
sqlite3_initialize(); |
|
283
|
sqlite3_auto_extension((void(*)(void))sqlcmd_autoinit); |
|
284
|
} |
|
285
|
|
|
286
|
#if USE_SEE |
|
287
|
/* |
|
288
|
** This routine is called by the patched sqlite3 command-line shell in order |
|
289
|
** to load the encryption key for the open Fossil database. The memory that |
|
290
|
** is pointed to by the value placed in pzKey must be obtained from malloc. |
|
291
|
*/ |
|
292
|
void fossil_key(const char **pzKey, int *pnKey){ |
|
293
|
char *zSavedKey = db_get_saved_encryption_key(); |
|
294
|
char *zKey; |
|
295
|
size_t savedKeySize = db_get_saved_encryption_key_size(); |
|
296
|
|
|
297
|
if( !db_is_valid_saved_encryption_key(zSavedKey, savedKeySize) ) return; |
|
298
|
zKey = (char*)malloc( savedKeySize ); |
|
299
|
if( zKey ){ |
|
300
|
memcpy(zKey, zSavedKey, savedKeySize); |
|
301
|
*pzKey = zKey; |
|
302
|
if( fossil_getenv("FOSSIL_USE_SEE_TEXTKEY")==0 ){ |
|
303
|
*pnKey = (int)strlen(zKey); |
|
304
|
}else{ |
|
305
|
*pnKey = -1; |
|
306
|
} |
|
307
|
}else{ |
|
308
|
fossil_fatal("failed to allocate %u bytes for key", savedKeySize); |
|
309
|
} |
|
310
|
} |
|
311
|
#endif |
|
312
|
|
|
313
|
/* |
|
314
|
** This routine closes the Fossil databases and/or invalidates the global |
|
315
|
** state variables that keep track of them. |
|
316
|
*/ |
|
317
|
static void fossil_close(int bDb, int noRepository){ |
|
318
|
if( bDb ) db_close(1); |
|
319
|
if( noRepository ) g.zRepositoryName = 0; |
|
320
|
g.db = 0; |
|
321
|
g.repositoryOpen = 0; |
|
322
|
g.localOpen = 0; |
|
323
|
} |
|
324
|
|
|
325
|
/* |
|
326
|
** COMMAND: sql |
|
327
|
** COMMAND: sqlite3* |
|
328
|
** |
|
329
|
** Usage: %fossil sql ?OPTIONS? |
|
330
|
** |
|
331
|
** Run the sqlite3 command-line shell on the Fossil repository |
|
332
|
** identified by the -R option, or on the current repository. |
|
333
|
** See https://www.sqlite.org/cli.html for additional information about |
|
334
|
** the sqlite3 command-line shell. |
|
335
|
** |
|
336
|
** WARNING: Careless use of this command can corrupt a Fossil repository |
|
337
|
** in ways that are unrecoverable. Be sure you know what you are doing before |
|
338
|
** running any SQL commands that modify the repository database. Use the |
|
339
|
** --readonly option to prevent accidental damage to the repository. |
|
340
|
** |
|
341
|
** Options: |
|
342
|
** --no-repository Skip opening the repository database |
|
343
|
** --readonly Open the repository read-only. No changes |
|
344
|
** are allowed. This is a recommended safety |
|
345
|
** precaution to prevent repository damage. |
|
346
|
** -R REPOSITORY Use REPOSITORY as the repository database |
|
347
|
** --test Enable some testing and analysis features |
|
348
|
** that are normally disabled. |
|
349
|
** |
|
350
|
** All of the standard sqlite3 command-line shell options should also |
|
351
|
** work. |
|
352
|
** |
|
353
|
** The following SQL extensions are provided with this Fossil-enhanced |
|
354
|
** version of the sqlite3 command-line shell: |
|
355
|
** |
|
356
|
** builtin A virtual table that contains one row for |
|
357
|
** each datafile that is built into the Fossil |
|
358
|
** binary. |
|
359
|
** |
|
360
|
** checkin_mtime(X,Y) Return the mtime for the file Y (a BLOB.RID) |
|
361
|
** found in check-in X (another BLOB.RID value). |
|
362
|
** |
|
363
|
** compress(X) Compress text X with the same algorithm used |
|
364
|
** to compress artifacts in the BLOB table. |
|
365
|
** |
|
366
|
** content(X) Return the content of artifact X. X can be an |
|
367
|
** artifact hash or hash prefix or a tag. Artifacts |
|
368
|
** are stored compressed and deltaed. This function |
|
369
|
** does all necessary decompression and undeltaing. |
|
370
|
** |
|
371
|
** decompress(X) Decompress text X. Undoes the work of |
|
372
|
** compress(X). |
|
373
|
** |
|
374
|
** delta_apply(X,D) Apply delta D to source blob X and return |
|
375
|
** the result. |
|
376
|
** |
|
377
|
** delta_create(X,Y) Create and return a delta that will convert |
|
378
|
** X into Y. |
|
379
|
** |
|
380
|
** delta_output_size(D) Return the number of bytes of output to expect |
|
381
|
** when applying delta D |
|
382
|
** |
|
383
|
** delta_parse(D) A table-valued function that deconstructs |
|
384
|
** delta D and returns rows for each element of |
|
385
|
** that delta. |
|
386
|
** |
|
387
|
** files_of_checkin(X) A table-valued function that returns info on |
|
388
|
** all files contained in check-in X. Example: |
|
389
|
** |
|
390
|
** SELECT * FROM files_of_checkin('trunk'); |
|
391
|
** |
|
392
|
** helptext A virtual table with one row for each command, |
|
393
|
** webpage, and setting together with the built-in |
|
394
|
** help text. |
|
395
|
** |
|
396
|
** now() Return the number of seconds since 1970. |
|
397
|
** |
|
398
|
** obscure(T) Obfuscate the text password T so that its |
|
399
|
** original value is not readily visible. Fossil |
|
400
|
** uses this same algorithm when storing passwords |
|
401
|
** of remote URLs. |
|
402
|
** |
|
403
|
** regexp The REGEXP operator works, unlike in |
|
404
|
** standard SQLite. |
|
405
|
** |
|
406
|
** symbolic_name_to_rid(X) Return the BLOB.RID corresponding to symbolic |
|
407
|
** name X. |
|
408
|
*/ |
|
409
|
void cmd_sqlite3(void){ |
|
410
|
int noRepository; |
|
411
|
char *zConfigDb; |
|
412
|
extern int sqlite3_shell(int, char**); |
|
413
|
#ifdef FOSSIL_ENABLE_TH1_HOOKS |
|
414
|
g.fNoThHook = 1; |
|
415
|
#endif |
|
416
|
noRepository = find_option("no-repository", 0, 0)!=0; |
|
417
|
local_bSqlCmdTest = find_option("test",0,0)!=0; |
|
418
|
if( !noRepository ){ |
|
419
|
db_find_and_open_repository(OPEN_ANY_SCHEMA, 0); |
|
420
|
} |
|
421
|
db_open_config(1,0); |
|
422
|
zConfigDb = fossil_strdup(g.zConfigDbName); |
|
423
|
fossil_close(1, noRepository); |
|
424
|
sqlite3_shutdown(); |
|
425
|
#ifndef _WIN32 |
|
426
|
linenoiseSetMultiLine(1); |
|
427
|
#endif |
|
428
|
atexit(sqlcmd_atexit); |
|
429
|
g.zConfigDbName = zConfigDb; |
|
430
|
g.argv[1] = "--noinit"; |
|
431
|
sqlite3_shell(g.argc, g.argv); |
|
432
|
sqlite3_cancel_auto_extension((void(*)(void))sqlcmd_autoinit); |
|
433
|
fossil_close(0, noRepository); |
|
434
|
} |
|
435
|
|