dav/config.c

changeset 795
05647e862a17
parent 747
efbd59642577
child 796
81e0f67386a6
equal deleted inserted replaced
794:29d544c3c2b8 795:05647e862a17
29 #include <stdio.h> 29 #include <stdio.h>
30 #include <stdlib.h> 30 #include <stdlib.h>
31 #include <string.h> 31 #include <string.h>
32 #include <sys/types.h> 32 #include <sys/types.h>
33 #include <cx/hash_map.h> 33 #include <cx/hash_map.h>
34 #include <cx/utils.h>
34 #include <errno.h> 35 #include <errno.h>
35 #include <libxml/tree.h> 36 #include <libxml/tree.h>
36 37
37 #include "pwd.h" 38 #include "pwd.h"
38 #include "config.h" 39 #include "config.h"
39 #include "main.h" 40 #include "main.h"
40 #include "pwd.h" 41 #include "pwd.h"
42 #include "system.h"
43
41 #include <libidav/utils.h> 44 #include <libidav/utils.h>
45 #include <libidav/config.h>
42 46
43 #define xstreq(a,b) xmlStrEqual(BAD_CAST a, BAD_CAST b) 47 #define xstreq(a,b) xmlStrEqual(BAD_CAST a, BAD_CAST b)
44 #define xstrEQ(a,b) !xmlStrcasecmp(BAD_CAST a, BAD_CAST b) 48 #define xstrEQ(a,b) !xmlStrcasecmp(BAD_CAST a, BAD_CAST b)
45 49
46 #define print_error(lineno, ...) \ 50 #define print_error(lineno, ...) \
62 #endif /* _WIN32 */ 66 #endif /* _WIN32 */
63 67
64 static CxMap *repos; 68 static CxMap *repos;
65 static CxMap *keys; 69 static CxMap *keys;
66 70
71 static DavConfig *davconfig;
67 static PwdStore *pstore; 72 static PwdStore *pstore;
68 73
69 static char *secretstore_unlock_cmd; 74 static char *secretstore_unlock_cmd;
70 static char *secretstore_lock_cmd; 75 static char *secretstore_lock_cmd;
71 76
99 char *path = util_concat_path(davd, name); 104 char *path = util_concat_path(davd, name);
100 free(davd); 105 free(davd);
101 return path; 106 return path;
102 } 107 }
103 108
109 cxmutstr config_load_file(const char *path) {
110 FILE *file = sys_fopen(path, "r");
111 if(!file) {
112 return (cxmutstr){NULL,0};
113 }
114
115 CxBuffer buf;
116 cxBufferInit(&buf, NULL, 1024, cxDefaultAllocator, CX_BUFFER_AUTO_EXTEND);
117 cx_stream_copy(file, &buf, (cx_read_func)fread, (cx_write_func)cxBufferWrite);
118 fclose(file);
119
120 return cx_mutstrn(buf.space, buf.size);
121 }
122
104 int load_config(DavContext *ctx) { 123 int load_config(DavContext *ctx) {
105 context = ctx; 124 context = ctx;
106 // TODO: free the config somewhere 125 // TODO: free the config somewhere
107 repos = cxHashMapCreate(cxDefaultAllocator, CX_STORE_POINTERS, 16); 126 repos = cxHashMapCreate(cxDefaultAllocator, CX_STORE_POINTERS, 16);
108 keys = cxHashMapCreate(cxDefaultAllocator, CX_STORE_POINTERS, 16); 127 keys = cxHashMapCreate(cxDefaultAllocator, CX_STORE_POINTERS, 16);
125 } 144 }
126 return 1; 145 return 1;
127 } 146 }
128 147
129 xmlDoc *doc = xmlReadFile(file, NULL, 0); 148 xmlDoc *doc = xmlReadFile(file, NULL, 0);
149
150 cxmutstr config_content = config_load_file(file);
151 int config_error;
152 davconfig = dav_config_load(config_content, &config_error);
153 free(config_content.ptr);
154
130 free(file); 155 free(file);
131 if(!doc) { 156 if(!doc) {
132 fprintf(stderr, "Cannot load config.xml\n"); 157 fprintf(stderr, "Cannot load config.xml\n");
133 return 1; 158 return 1;
134 } 159 }
158 node = node->next; 183 node = node->next;
159 } 184 }
160 185
161 xmlFreeDoc(doc); 186 xmlFreeDoc(doc);
162 return ret; 187 return ret;
188 }
189
190 DavConfig* get_config(void) {
191 return davconfig;
192 }
193
194 int store_config(void) {
195 if(check_config_dir()) {
196 return 1;
197 }
198
199 CxBuffer *buf = dav_config2buf(davconfig);
200 if(!buf) {
201 return 1;
202 }
203
204 char *file = util_concat_path(ENV_HOME, ".dav/config.xml");
205 FILE *cout = sys_fopen(file, "w");
206 if(!cout) {
207 cxBufferFree(buf);
208 return 1;
209 }
210
211 // should only fail if we run out of disk space or something like that
212 // in that case, the config file is only destroyed
213 // could only be prevented, if we write to a temp file first and than
214 // rename it
215 fwrite(buf->space, buf->size, 1, cout);
216
217 cxBufferFree(buf);
218 fclose(cout);
219
220 return 0;
163 } 221 }
164 222
165 void free_config(void) { 223 void free_config(void) {
166 if(repos) { 224 if(repos) {
167 CxIterator i = cxMapIteratorValues(repos); 225 CxIterator i = cxMapIteratorValues(repos);
811 return ret; 869 return ret;
812 } 870 }
813 871
814 872
815 873
816 874 /*
817 Repository* url2repo_s(cxstring url, char **path) { 875 Repository* url2repo_s(cxstring url, char **path) {
818 *path = NULL; 876 *path = NULL;
819 877
820 int s; 878 int s;
821 if(cx_strprefix(url, CX_STR("http://"))) { 879 if(cx_strprefix(url, CX_STR("http://"))) {
865 } 923 }
866 924
867 Repository* url2repo(const char *url, char **path) { 925 Repository* url2repo(const char *url, char **path) {
868 return url2repo_s(cx_str(url), path); 926 return url2repo_s(cx_str(url), path);
869 } 927 }
928 */
870 929
871 static int decrypt_secrets(CmdArgs *a, PwdStore *secrets) { 930 static int decrypt_secrets(CmdArgs *a, PwdStore *secrets) {
872 if(cmd_getoption(a, "noinput")) { 931 if(cmd_getoption(a, "noinput")) {
873 return 1; 932 return 1;
874 } 933 }
958 1017
959 return 0; 1018 return 0;
960 } 1019 }
961 1020
962 1021
963 static int get_location_credentials(CmdArgs *a, Repository *repo, char *path, char **user, char **password) { 1022 static int get_location_credentials(CmdArgs *a, DavCfgRepository *repo, const char *path, char **user, char **password) {
964 PwdStore *secrets = get_pwdstore(); 1023 PwdStore *secrets = get_pwdstore();
965 if(!secrets) { 1024 if(!secrets) {
966 return 0; 1025 return 0;
967 } 1026 }
968 1027
974 locations->simple_destructor = (cx_destructor_func)free_cred_location; 1033 locations->simple_destructor = (cx_destructor_func)free_cred_location;
975 CxIterator i = cxListIterator(secrets->locations); 1034 CxIterator i = cxListIterator(secrets->locations);
976 cx_foreach(PwdIndexEntry*, e, i) { 1035 cx_foreach(PwdIndexEntry*, e, i) {
977 CxIterator entry_iter = cxListIterator(e->locations); 1036 CxIterator entry_iter = cxListIterator(e->locations);
978 cx_foreach(char *, loc, entry_iter) { 1037 cx_foreach(char *, loc, entry_iter) {
979 char *path; 1038 cxmutstr rpath;
980 Repository *r = url2repo(loc, &path); 1039 DavCfgRepository *r = dav_config_url2repo_s(davconfig, cx_str(loc), &rpath);
981 CredLocation *urlentry = calloc(1, sizeof(CredLocation)); 1040 CredLocation *urlentry = calloc(1, sizeof(CredLocation));
982 urlentry->id = e->id; 1041 urlentry->id = e->id;
983 urlentry->location = util_concat_path(r->url, path); 1042 urlentry->location = util_concat_path_s(cx_strcast(r->url.value), cx_strcast(rpath)).ptr;
984 cxListAdd(locations, urlentry); 1043 cxListAdd(locations, urlentry);
1044 free(rpath.ptr);
985 } 1045 }
986 } 1046 }
987 // the list must be sorted 1047 // the list must be sorted
988 cxListSort(locations); 1048 cxListSort(locations);
989 1049
990 // create full request url string and remove protocol prefix 1050 // create full request url string and remove protocol prefix
991 cxmutstr req_url_proto = cx_mutstr(util_concat_path(repo->url, path)); 1051 cxmutstr req_url_proto = util_concat_path_s(cx_strcast(repo->url.value), cx_str(path));
992 cxstring req_url = cx_strcast(req_url_proto); 1052 cxstring req_url = cx_strcast(req_url_proto);
993 if(cx_strprefix(req_url, CX_STR("http://"))) { 1053 if(cx_strprefix(req_url, CX_STR("http://"))) {
994 req_url = cx_strsubs(req_url, 7); 1054 req_url = cx_strsubs(req_url, 7);
995 } else if(cx_strprefix(req_url, CX_STR("https://"))) { 1055 } else if(cx_strprefix(req_url, CX_STR("https://"))) {
996 req_url = cx_strsubs(req_url, 8); 1056 req_url = cx_strsubs(req_url, 8);
1032 cxListDestroy(locations); 1092 cxListDestroy(locations);
1033 1093
1034 return ret; 1094 return ret;
1035 } 1095 }
1036 1096
1037 DavSession* connect_to_repo(DavContext *ctx, Repository *repo, char *path, dav_auth_func authfunc, CmdArgs *a) { 1097 DavSession* connect_to_repo(DavContext *ctx, DavCfgRepository *repo, const char *path, dav_auth_func authfunc, CmdArgs *a) {
1038 char *user = repo->user; 1098 cxmutstr decodedpw = dav_repository_get_decodedpassword(repo);
1039 char *password = repo->password; 1099
1100 char *user = repo->user.value.ptr;
1101 char *password = decodedpw.ptr;
1040 1102
1041 if(!user && !password) { 1103 if(!user && !password) {
1042 if(!get_stored_credentials(a, repo->stored_user, &user, &password)) { 1104 if(!get_stored_credentials(a, repo->stored_user.value.ptr, &user, &password)) {
1043 get_location_credentials(a, repo, path, &user, &password); 1105 get_location_credentials(a, repo, path, &user, &password);
1044 } 1106 }
1045 } 1107 }
1046 1108
1047 DavSession *sn = dav_session_new_auth(ctx, repo->url, user, password); 1109 DavSession *sn = dav_session_new_auth(ctx, repo->url.value.ptr, user, password);
1048 sn->flags = get_repository_flags(repo); 1110 if(password) {
1049 sn->key = dav_context_get_key(ctx, repo->default_key); 1111 free(password);
1112 }
1113
1114 sn->flags = dav_repository_get_flags(repo);
1115 sn->key = dav_context_get_key(ctx, repo->default_key.value.ptr);
1050 curl_easy_setopt(sn->handle, CURLOPT_HTTPAUTH, repo->authmethods); 1116 curl_easy_setopt(sn->handle, CURLOPT_HTTPAUTH, repo->authmethods);
1051 curl_easy_setopt(sn->handle, CURLOPT_SSLVERSION, repo->ssl_version); 1117 curl_easy_setopt(sn->handle, CURLOPT_SSLVERSION, repo->ssl_version);
1052 if(repo->cert) { 1118 if(repo->cert.value.ptr) {
1053 curl_easy_setopt(sn->handle, CURLOPT_CAINFO, repo->cert); 1119 curl_easy_setopt(sn->handle, CURLOPT_CAINFO, repo->cert.value.ptr);
1054 } 1120 }
1055 if(!repo->verification || cmd_getoption(a, "insecure")) { 1121 if(!repo->verification.value || cmd_getoption(a, "insecure")) {
1056 curl_easy_setopt(sn->handle, CURLOPT_SSL_VERIFYPEER, 0); 1122 curl_easy_setopt(sn->handle, CURLOPT_SSL_VERIFYPEER, 0);
1057 curl_easy_setopt(sn->handle, CURLOPT_SSL_VERIFYHOST, 0); 1123 curl_easy_setopt(sn->handle, CURLOPT_SSL_VERIFYHOST, 0);
1058 } 1124 }
1059 if(!cmd_getoption(a, "noinput")) { 1125 if(!cmd_getoption(a, "noinput")) {
1060 dav_session_set_authcallback(sn, authfunc, repo); 1126 dav_session_set_authcallback(sn, authfunc, repo);

mercurial