diff options
-rw-r--r-- | ck.1 | 20 | ||||
-rw-r--r-- | src/actions.h | 1 | ||||
-rw-r--r-- | src/add.c | 15 | ||||
-rw-r--r-- | src/clparser.h | 2 | ||||
-rw-r--r-- | src/confparser.c | 12 | ||||
-rw-r--r-- | src/confparser.h | 13 | ||||
-rw-r--r-- | src/dblayer.c | 21 | ||||
-rw-r--r-- | src/dblayer.h | 2 | ||||
-rw-r--r-- | src/init.c | 45 | ||||
-rw-r--r-- | src/list.c | 2 | ||||
-rw-r--r-- | src/queries.c | 32 | ||||
-rw-r--r-- | src/queries.h | 8 | ||||
-rw-r--r-- | test/add.sh (renamed from test/01_add) | 0 | ||||
-rw-r--r-- | test/delete.sh (renamed from test/03_delete) | 0 | ||||
-rw-r--r-- | test/edit.sh (renamed from test/06_edit) | 0 | ||||
-rw-r--r-- | test/init.sh (renamed from test/00_init) | 0 | ||||
-rw-r--r-- | test/init_no_secret.sh | 38 | ||||
-rw-r--r-- | test/list.sh (renamed from test/02_list) | 0 | ||||
-rw-r--r-- | test/restore.sh (renamed from test/05_restore) | 0 | ||||
-rw-r--r-- | test/search.sh (renamed from test/04_search) | 0 |
20 files changed, 180 insertions, 31 deletions
@@ -14,7 +14,8 @@ ck \- manage configuration across the system \" Init .SY ck .B init -.I VERSION_CONTROL_DIR SECRET_DIR +.I VERSION_CONTROL_DIR +.RI [ SECRET_DIR ] .YS \" Add .SY ck @@ -100,7 +101,7 @@ based command line interface. needs a database and an rc file to run. It also needs two directories (stored in the rc file), the .I VERSION_CONRTOL_DIR -and the +and (optionally) the .IR SECRET_DIR . This is where the configurations will end up after they are added to .BR ck . @@ -217,14 +218,24 @@ database .RI ( ckdb ) and initialize it. Create the ck config file .RI ( ckrc ) -and add the directory paths to it. +and add the directory paths to it. If +.I SECRET_DIR +is not passed, the +.B \-s +flag will be disabled in the +.B add +action, and this +.B ck +instance won't be able to +store secret configs. .TP 2 .B USAGE .ns .RS 2 .SY ck .B init -.I VERSION_CONTROL_DIR SECRET_DIR +.I VERSION_CONTROL_DIR +.RI [ SECRET_DIR ] .YS .RE .TP 2 @@ -254,6 +265,7 @@ flag in .EX $ ck init /home/ckuser/configs/vc home/ckuser/configs/sec $ ck i configs/vc configs/sec +$ ck i ~/scripts # no secret dir provided .EE .SS "ADD CONFIG" Add a diff --git a/src/actions.h b/src/actions.h index 1b7ef05..0cf4b8f 100644 --- a/src/actions.h +++ b/src/actions.h @@ -28,6 +28,7 @@ enum AddOptErrors { ADD_NO_ERR = 0, ADD_ERR_WRONG_CONFIG, ADD_ERR_LINK_CONFIG, + ADD_ERR_NO_SECRET, ADD_ERR_WRONG_FLAGS }; typedef enum AddOptErrors AddOptErr; @@ -204,7 +204,7 @@ static int add_transaction_try(DB *db, const AddOpt * const opt, const char *hom } static int link_config(const AddOpt *opt, const char* newPath) { - hLOG("Linking %s -> %s\n", newPath, opt->confPath); + hLOG("Linking %s -> %s", newPath, opt->confPath); if (util_symlink_file(newPath, opt->confPath) != 0) { ERR("Could not link file."); return -1; @@ -222,7 +222,7 @@ static int move_config(const AddOpt *opt, char *progDir, char *ret) { return -1; } strcpy(ret, newPath); - hLOG("Moving %s -> %s\n", opt->confPath, newPath); + hLOG("Moving %s -> %s", opt->confPath, newPath); if (util_move_file(opt->confPath, newPath) != 0) { ERR("Could not move file."); return -1; @@ -230,7 +230,7 @@ static int move_config(const AddOpt *opt, char *progDir, char *ret) { return 0; } -static AddOpt add_make_options(cklist *args) { +static AddOpt add_make_options(cklist *args, DB *db) { list_rewind(args); /* since we are here, the first two arguments must exist */ AddOpt addOpt = { @@ -254,6 +254,10 @@ static AddOpt add_make_options(cklist *args) { while (list_next(args)) { if (strcmp(list_get(args), "-s") == 0 && addOpt.secret == 0) { + if (!secret_enabled(db)) { + addOpt.err = ADD_ERR_NO_SECRET; + return addOpt; + } addOpt.secret = 1; } else if (strcmp(list_get(args), "-p") == 0 && addOpt.prime == 0) { addOpt.prime = 1; @@ -304,10 +308,13 @@ int run_ADD(UserOpt * opt, Conf *conf) { if (open_DB(&db, opt)) { return -1; } - AddOpt addOpt = add_make_options(opt->args); + AddOpt addOpt = add_make_options(opt->args, &db); switch (addOpt.err) { case ADD_NO_ERR: break; + case ADD_ERR_NO_SECRET: + ERR("Secret is not enabled for this ck instance."); + goto error; case ADD_ERR_LINK_CONFIG: ERR("%s is a link.", addOpt.confPath); goto error; diff --git a/src/clparser.h b/src/clparser.h index 4208a91..afb6260 100644 --- a/src/clparser.h +++ b/src/clparser.h @@ -22,7 +22,7 @@ /* NAME | MIN ACCEPTED ARGS | MAX ACCEPTED ARGS */ #define CK_ACTIONS \ - X(INIT, 2 , 2) \ + X(INIT, 1 , 2) \ X(ADD, 2, 4) \ X(DEL, 1, 2) \ X(EDIT, 1, 5) \ diff --git a/src/confparser.c b/src/confparser.c index 6c01e6d..48f0c71 100644 --- a/src/confparser.c +++ b/src/confparser.c @@ -16,7 +16,7 @@ ERRLOG(configfile); static const char * const CONFIG_NAME = "/ckrc"; void initialize_conf(Conf *c) { -#define X(var, str, name) \ +#define X(var, str, name, optional) \ c->var = NULL; CONFIG_VARIABLES_TABLE #undef X @@ -35,7 +35,7 @@ ConfVar match_variables(char *line, char matched[]) { if (line[0] == '#' || str_is_empty(line)) { return CV_NO_VAL_OR_COMMENT; } -#define X(var, str, name) \ +#define X(var, str, name, optional) \ if (sscanf(line, str, matched) == 1) { \ return CV_##var; \ } @@ -109,7 +109,7 @@ int config_file_parse(Conf *conf, UserOpt *opt) { return -1; } switch(match_variables(line, matched)) { -#define X(var, str, name) \ +#define X(var, str, name, optional) \ case CV_##var: \ conf->var = malloc(strlen(matched)+1); \ strcpy(conf->var, matched); \ @@ -131,8 +131,8 @@ int config_file_parse(Conf *conf, UserOpt *opt) { } /* Could add an optional row that would make the config var * optional. */ -#define X(var, str, name) \ - if (!conf->var) { \ +#define X(var, str, name, optional) \ + if (!optional && !conf->var) { \ ERR("Missing %s", name); \ return -1; \ } @@ -142,7 +142,7 @@ int config_file_parse(Conf *conf, UserOpt *opt) { } void free_conf(Conf *conf) { -#define X(var,str,name) \ +#define X(var, str, name, optional) \ if (conf->var) { \ free(conf->var); \ } diff --git a/src/confparser.h b/src/confparser.h index ebcf0c7..10e7e18 100644 --- a/src/confparser.h +++ b/src/confparser.h @@ -18,15 +18,16 @@ #include "clparser.h" -#define CONFIG_VARIABLES_TABLE \ - X(vc_dir, " version_control_dir = %s ", "Version Control directory") \ - X(scrt_dir, " secret_dir = %s " , "Secret directory") \ - X(home_dir, " home_dir = %s " , "Home directory") +/* name | match str | desc | optional */ +#define CONFIG_VARIABLES_TABLE \ + X(vc_dir, " version_control_dir = %s ", "Version Control directory", 0) \ + X(scrt_dir, " secret_dir = %s " , "Secret directory", 1) \ + X(home_dir, " home_dir = %s " , "Home directory", 0) enum ConfingVariables { CV_NO_VAL_OR_COMMENT, CV_WRONG_VAL, -#define X(var, str, name) CV_##var, +#define X(var, str, name, optional) CV_##var, CONFIG_VARIABLES_TABLE #undef X }; @@ -34,7 +35,7 @@ typedef enum ConfingVariables ConfVar; typedef struct ConfigValues Conf; struct ConfigValues { -#define X(var, str, name) char* var; +#define X(var, str, name, optional) char* var; CONFIG_VARIABLES_TABLE #undef X }; diff --git a/src/dblayer.c b/src/dblayer.c index f13236c..3a8dd4f 100644 --- a/src/dblayer.c +++ b/src/dblayer.c @@ -315,3 +315,24 @@ int get_program_paths(DB *db, cklist *ckl, const char* pName, int bname, int att } return -1; } + +int secret_enabled(DB *db) { + sqlite3_stmt *stmt; + int rc; + + char sql[STR_M] = ""; + dbh_form_query_secret_enabled(sql); + + rc = sqlite3_prepare_v2(db->ptr, sql, -1, &stmt, 0); + if (rc != SQLITE_OK) { + ERR("while preparing secret_enabled sql."); + return -2; + } + int enabled = 1; + while (sqlite3_step(stmt) == SQLITE_ROW) { + enabled = sqlite3_column_int(stmt, 0); + break; + } + sqlite3_finalize(stmt); + return enabled; +} diff --git a/src/dblayer.h b/src/dblayer.h index 08299f1..fb3ab90 100644 --- a/src/dblayer.h +++ b/src/dblayer.h @@ -63,8 +63,8 @@ int get_pid_from_cid(DB *db, int cid); void print_suggested_configs(DB *db, const char *pName); -/* list.c */ int list_get_paths(DB *db, cklist *ckl, int bName, int attr, const char *home); int list_get_programs(DB *db, cklist *ckl); +int secret_enabled(DB *db); #endif /* DBLAYER_H */ @@ -15,15 +15,18 @@ ERRLOG(init); static int init_create_config_file(UserOpt *opt) { char absVCdir[STR_L] = ""; - if (!util_file_exists(list_get_at(opt->args, 0), absVCdir)) { + list_rewind(opt->args); + if (!util_file_exists(list_get(opt->args), absVCdir)) { ERR("Version control directory: %s does not exist.", list_get_at(opt->args, 0)); return 1; } char absSRdir[STR_L] = ""; - if (!util_file_exists(list_get_at(opt->args, 1), absSRdir)) { - ERR("Secret directory: %s does not exist.", list_get_at(opt->args, 1)); - return 1; + if (list_next(opt->args)) { + if (!util_file_exists(list_get_at(opt->args, 1), absSRdir)) { + ERR("Secret directory: %s does not exist.", list_get_at(opt->args, 1)); + return 1; + } } if (!util_file_exists(opt->confDir, NULL)) { @@ -43,10 +46,13 @@ static int init_create_config_file(UserOpt *opt) { strcat(tmp, "\n"); fputs(tmp, f); - strcpy(tmp, "secret_dir = "); - strcat(tmp, absSRdir); - strcat(tmp, "\n"); - fputs(tmp, f); + /* if absSRdir is not equal to "" */ + if (strcmp(absSRdir, "")) { + strcpy(tmp, "secret_dir = "); + strcat(tmp, absSRdir); + strcat(tmp, "\n"); + fputs(tmp, f); + } strcpy(tmp, "home_dir = "); strcat(tmp, getenv("HOME")); @@ -57,6 +63,27 @@ static int init_create_config_file(UserOpt *opt) { return 0; } +static int set_secret_enabled(DB *db, int enabled) { + sqlite3_stmt *stmt; + int rc; + + char sql[STR_M] = ""; + dbh_form_query_set_secret_enabled(sql); + + rc = sqlite3_prepare_v2(db->ptr, sql, -1, &stmt, 0); + if (rc != SQLITE_OK) { + ERR("while preparing set_secret_enabled sql."); + return -2; + } + sqlite3_bind_int(stmt, 1, enabled); + if (sqlite3_step(stmt) != SQLITE_DONE) { + ERR("while excecuting set_secret_enabled sql."); + return -1; + } + sqlite3_finalize(stmt); + return 0; +} + static void init_make_tables(DB *db) { char sql[STR_L] = ""; dbh_form_query_make_tables(sql); @@ -84,6 +111,8 @@ int run_INIT(UserOpt * opt, Conf *conf) { return -1; } init_make_tables(&db); + /* If there are two arguments secret is enabled */ + set_secret_enabled(&db, list_size(opt->args) == 2); sqlite3_close(db.ptr); hLOG("Initialized empty ckdb."); return 0; @@ -244,7 +244,7 @@ int run_LIST(UserOpt *opt, Conf *conf) { strcat(tmp, "ck configuration directory path: "); strcat(tmp, opt->confDir); list_add(the_list, tmp); -#define X(var, str, name) \ +#define X(var, str, name, optional) \ strcpy(tmp, ""); \ strcat(tmp, name); \ strcat(tmp, ": "); \ diff --git a/src/queries.c b/src/queries.c index 15e5acb..ddd9250 100644 --- a/src/queries.c +++ b/src/queries.c @@ -40,6 +40,14 @@ void dbh_form_query_make_tables(char *query) { strcat(tmp, COL_REL_CONFIG_ID); strcat(tmp, " INT NOT NULL);"); + strcat(tmp, "CREATE TABLE "); + strcat(tmp, TBL_CTX); + strcat(tmp, "("); + strcat(tmp, COL_CTX_KEY); + strcat(tmp, " TEXT NOT NULL, "); + strcat(tmp, COL_CTX_VAL); + strcat(tmp, " INT NOT NULL);"); + strcpy(query, tmp); } @@ -226,3 +234,27 @@ void dbh_form_query_get_pid_from_cid(char *query) { strcpy(query, tmp); } + +void dbh_form_query_secret_enabled(char *query) { + char tmp[STR_M] = "SELECT "; + strcat(tmp, COL_CTX_VAL); + strcat(tmp, " FROM "); + strcat(tmp, TBL_CTX); + strcat(tmp, " WHERE "); + strcat(tmp, COL_CTX_KEY); + strcat(tmp, " = \""); + strcat(tmp, KEY_CTX_SECRET); + strcat(tmp, "\";"); + + strcpy(query, tmp); +} + +void dbh_form_query_set_secret_enabled(char *query) { + char tmp[STR_L] = "INSERT INTO "; + strcat(tmp, TBL_CTX); + strcat(tmp, " VALUES(\""); + strcat(tmp, KEY_CTX_SECRET); + strcat(tmp, "\", ?);"); + + strcpy(query, tmp); +} diff --git a/src/queries.h b/src/queries.h index 7d5ec47..aaaa862 100644 --- a/src/queries.h +++ b/src/queries.h @@ -24,6 +24,7 @@ #define TBL_PROGRAM "PROGRAM" #define TBL_CONFIG "CONFIG" #define TBL_REL "REL" +#define TBL_CTX "CONTEXT" #define COL_PROGRAM_ID "ID" #define COL_PROGRAM_NAME "NAME" @@ -36,6 +37,11 @@ #define COL_REL_PROGRAM_ID "PID" #define COL_REL_CONFIG_ID "CID" +#define COL_CTX_KEY "KEY" +#define COL_CTX_VAL "VAL" + +#define KEY_CTX_SECRET "secret_enabled" + #define __BEGIN_TRANSACTION__ sqlite3_exec(db->ptr, "BEGIN TRANSACTION;", NULL, NULL, NULL); #define __END_TRANSACTION__ sqlite3_exec(db->ptr, "END TRANSACTION;", NULL, NULL, NULL); @@ -59,4 +65,6 @@ void dbh_form_query_select_from_joined_like(char *query, const char *selection, void dbh_form_query_delete_x_from_y(char *query, const char *x, const char *y); void dbh_form_query_count_program_relations(char *query); void dbh_form_query_get_pid_from_cid(char *query); +void dbh_form_query_secret_enabled(char *query); +void dbh_form_query_set_secret_enabled(char *query); #endif /* DBHELPER_H */ diff --git a/test/01_add b/test/add.sh index 05cf13f..05cf13f 100644 --- a/test/01_add +++ b/test/add.sh diff --git a/test/03_delete b/test/delete.sh index 7e31d66..7e31d66 100644 --- a/test/03_delete +++ b/test/delete.sh diff --git a/test/06_edit b/test/edit.sh index 65419b1..65419b1 100644 --- a/test/06_edit +++ b/test/edit.sh diff --git a/test/00_init b/test/init.sh index a38c81c..a38c81c 100644 --- a/test/00_init +++ b/test/init.sh diff --git a/test/init_no_secret.sh b/test/init_no_secret.sh new file mode 100644 index 0000000..b135377 --- /dev/null +++ b/test/init_no_secret.sh @@ -0,0 +1,38 @@ +running init_no_secret + +mkdir -p $TEST_LOCATION/vc + +exec $BIN/ck -c $BIN init $TEST_LOCATION/vc >&${V} & +wait $! + +if [ $? -ne 0 ]; then + err "ck crashed." +fi + +if [ ! -f $BIN/ckrc ]; then + err "Config file not created." +fi + +if [ "$(sqlite3 $BIN/ckdb "select VAL from CONTEXT where KEY = 'secret_enabled';")" != "0" ]; then + err "secret_enabled should be 0." +fi + +# setup test configs +echo "Test 1" > $BIN/test1.conf + +exec $BIN/ck -c $BIN add prog1 test1.conf -s >&${V} & +wait $! + +if [ $? -eq 0 ]; then + err "Adding secret should fail" +fi + +exec $BIN/ck -c $BIN add prog1 test1.conf >&${V} & +wait $! + +if [ $? -ne 0 ]; then + err "ck crashed." +fi + +clear_tests > /dev/null 2>&1 +echo -e $PASS diff --git a/test/02_list b/test/list.sh index e330dad..e330dad 100644 --- a/test/02_list +++ b/test/list.sh diff --git a/test/05_restore b/test/restore.sh index 2d60cb9..2d60cb9 100644 --- a/test/05_restore +++ b/test/restore.sh diff --git a/test/04_search b/test/search.sh index a315730..a315730 100644 --- a/test/04_search +++ b/test/search.sh |