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, ...) \ |
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); |
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); |
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); |