dav/main.c

changeset 734
b2cd82149116
parent 733
a7883961b5f4
child 739
bba6a6e221b4
--- a/dav/main.c	Sun Aug 08 14:59:02 2021 +0200
+++ b/dav/main.c	Sun Aug 08 16:49:47 2021 +0200
@@ -66,9 +66,6 @@
     }
 }
 
-static Repository* url2repo(char *url, char **path);
-static DavSession* connect_to_repo(Repository *repo, char *path, CmdArgs *a);
-
 //define DO_THE_TEST
 //include <libidav/davqlparser.h>
 //include <libidav/davqlexec.h>
@@ -346,91 +343,6 @@
 }
 
 
-int request_auth2(DavSession *sn, void *userdata) {
-    Repository *repo = userdata;
-    
-    char *user = NULL;
-    char ubuf[256];
-    if(repo->user) {
-       user = repo->user; 
-    } else {
-        fprintf(stderr, "User: ");
-        fflush(stderr);
-        user = fgets(ubuf, 256, stdin);
-    }
-    if(!user) {
-        return 0;
-    }
-    
-    char *password = util_password_input("Password: ");
-    if(!password || strlen(password) == 0) {
-        return 0;
-    }
-    
-    size_t ulen = strlen(user);
-    if(user[ulen-1] == '\n') {
-        user[ulen-1] = '\0';
-    }
-    
-    dav_session_set_auth(sn, user, password);
-    free(password);
-    
-    return 0;
-}
-
-static Repository* url2repo_s(sstr_t url, char **path) {
-    *path = NULL;
-    
-    int s;
-    if(sstrprefix(url, SC("http://"))) {
-        s = 7;
-    } else if(sstrprefix(url, SC("https://"))) {
-        s = 8;
-    } else {
-        s = 1;
-    }
-
-    // split URL into repository and path
-    sstr_t r = sstrsubs(url, s);
-    sstr_t p = sstrchr(r, '/');
-    r = sstrsubsl(url, 0, url.length-p.length);
-    if(p.length == 0) {
-        p = sstrn("/", 1);
-    }
-    
-    Repository *repo = get_repository(r);
-    if(repo) {
-        *path = sstrdup(p).ptr;
-    } else {
-        // TODO: who is responsible for freeing this repository?
-        // how can the callee know, if he has to call free()?
-        repo = calloc(1, sizeof(Repository));
-        repo->name = strdup("");
-        repo->decrypt_content = true;
-        repo->verification = true;
-        repo->authmethods = CURLAUTH_BASIC;
-        if(url.ptr[url.length-1] == '/') {
-            repo->url = sstrdup(url).ptr;
-            *path = strdup("/");
-        } else if (sstrchr(url, '/').length > 0) {
-            // TODO: fix the following workaround after
-            //       fixing the inconsistent behavior of util_url_*()
-            repo->url = util_url_base_s(url);
-            sstr_t truncated = sstrdup(url);
-            *path = strdup(util_url_path(truncated.ptr));
-            free(truncated.ptr);
-        } else {
-            repo->url = sstrdup(url).ptr;
-            *path = strdup("/");
-        }
-    }
-    
-    return repo;
-}
-
-static Repository* url2repo(char *url, char **path) {
-    return url2repo_s(sstr(url), path);
-}
 
 static int set_session_config(DavSession *sn, CmdArgs *a) {
     char *plain = cmd_getoption(a, "plain");
@@ -463,198 +375,6 @@
     }
 }
 
-static int decrypt_secrets(CmdArgs *a, PwdStore *secrets) {
-    if(cmd_getoption(a, "noinput")) {
-        return 1;
-    }
-    
-    char *ps_password = NULL;
-    if(secrets->unlock_cmd && strlen(secrets->unlock_cmd) > 0) {
-        UcxBuffer *cmd_out = ucx_buffer_new(NULL, 128, UCX_BUFFER_AUTOEXTEND);
-        if(!util_exec_command(secrets->unlock_cmd, cmd_out)) {
-            // command successful, get first line from output without newline
-            // and use that as password for the secretstore
-            size_t len = 0;
-            for(size_t i=0;i<=cmd_out->size;i++) {
-                if(i == cmd_out->size || cmd_out->space[i] == '\n') {
-                    len = i;
-                    break;
-                }
-            }
-            if(len > 0) {
-                ps_password = malloc(len + 1);
-                memcpy(ps_password, cmd_out->space, len);
-                ps_password[len] = 0;
-            }
-        }
-        ucx_buffer_free(cmd_out);
-    }
-    
-    if(!ps_password) {
-        ps_password = util_password_input("Master password: ");
-        if(!ps_password) {
-            return 1;
-        }
-    }
-    
-    if(pwdstore_setpassword(secrets, ps_password)) {
-        fprintf(stderr, "Error: cannot create key from password\n");
-        return 1;
-    }
-    if(pwdstore_decrypt(secrets)) {
-        fprintf(stderr, "Error: cannot decrypt secrets store\n");
-        return 1;
-    }
-    return 0;
-}
-
-static int get_stored_credentials(CmdArgs *a, char *credid, char **user, char **password) {
-    if(!credid) {
-        return 0;
-    }
-    
-    PwdStore *secrets = get_pwdstore();
-    if(!secrets) {
-        fprintf(stderr, "Error: no secrets store available\n");
-        return 0;
-    }
-    
-    if(pwdstore_has_id(secrets, credid)) {
-        if(!secrets->isdecrypted) {
-            if(decrypt_secrets(a, secrets)) {
-                return 0;
-            }
-        }
-        
-        PwdEntry *s_cred = pwdstore_get(secrets, credid);
-        if(s_cred) {
-            *user = s_cred->user;
-            *password = s_cred->password;
-            return 1;
-        }
-    } else {
-        fprintf(stderr, "Error: credentials id '%s' not found\n", credid);
-    }
-    
-    return 0;
-}
-
-typedef struct CredLocation {
-    char *id;
-    char *location;
-} CredLocation;
-
-static int cmp_url_cred_entry(CredLocation *e1, CredLocation *e2, void *n) {
-    return strcmp(e2->location, e1->location);
-}
-
-static void free_cred_location(CredLocation *c) {
-    // c->id is not a copy, therefore we don't have to free it
-    free(c->location);
-    free(c);
-}
-
-static int get_location_credentials(CmdArgs *a, Repository *repo, char *path, char **user, char **password) {
-    PwdStore *secrets = get_pwdstore();
-    if(!secrets) {
-        return 0;
-    }
-    
-    /*
-     * The list secrets->location contains urls or repo names as
-     * location strings. We need a list, that contains only urls
-     */
-    UcxList *locations = NULL;
-    UCX_FOREACH(elm, secrets->locations) {
-        PwdIndexEntry *e = elm->data;
-        
-        UCX_FOREACH(loc, e->locations) {
-            char *path;
-            Repository *r = url2repo(loc->data, &path);
-            CredLocation *urlentry = calloc(1, sizeof(CredLocation));
-            urlentry->id = e->id;
-            urlentry->location = util_concat_path(r->url, path);
-            locations = ucx_list_append(locations, urlentry);
-        }
-    }
-    // the list must be sorted
-    locations = ucx_list_sort(locations, (cmp_func)cmp_url_cred_entry, NULL);
-    
-    // create full request url string and remove protocol prefix
-    sstr_t req_url_proto = sstr(util_concat_path(repo->url, path));
-    sstr_t req_url = req_url_proto;
-    if(sstrprefix(req_url, S("http://"))) {
-        req_url = sstrsubs(req_url, 7);
-    } else if(sstrprefix(req_url, S("https://"))) {
-        req_url = sstrsubs(req_url, 8);
-    }
-    
-    // iterate over sorted locations and check if a location is a prefix
-    // of the requested url
-    char *id = NULL;
-    int ret = 0;
-    UCX_FOREACH(elm, locations) {
-        CredLocation *cred = elm->data;
-        sstr_t cred_url = sstr(cred->location);
-        
-        // remove protocol prefix
-        if(sstrprefix(cred_url, S("http://"))) {
-            cred_url = sstrsubs(cred_url, 7);
-        } else if(sstrprefix(cred_url, S("https://"))) {
-            cred_url = sstrsubs(cred_url, 8);
-        }
-        
-        if(sstrprefix(req_url, cred_url)) {
-            id = cred->id;
-            break;
-        }
-    }
-    
-    // if an id is found and we can access the decrypted secret store
-    // we can set the user/password
-    if(id && (secrets->isdecrypted || !decrypt_secrets(a, secrets))) {
-        PwdEntry *cred = pwdstore_get(secrets, id);
-        if(cred) {
-            *user = cred->user;
-            *password = cred->password;
-            ret = 1;
-        }
-    }
-    
-    free(req_url_proto.ptr);
-    ucx_list_free_content(locations, (ucx_destructor)free_cred_location);
-    ucx_list_free(locations);
-    
-    return ret;
-}
-
-static DavSession* connect_to_repo(Repository *repo, char *path, CmdArgs *a) {
-    char *user = repo->user;
-    char *password = repo->password;
-    
-    if(!user && !password) {
-        if(!get_stored_credentials(a, repo->stored_user, &user, &password)) {
-            get_location_credentials(a, repo, path, &user, &password);
-        }
-    }
-    
-    DavSession *sn = dav_session_new_auth(ctx, repo->url, user, password);
-    sn->flags = get_repository_flags(repo);
-    sn->key = dav_context_get_key(ctx, repo->default_key);
-    curl_easy_setopt(sn->handle, CURLOPT_HTTPAUTH, repo->authmethods);
-    curl_easy_setopt(sn->handle, CURLOPT_SSLVERSION, repo->ssl_version);
-    if(repo->cert) {
-        curl_easy_setopt(sn->handle, CURLOPT_CAINFO, repo->cert);
-    }
-    if(!repo->verification || cmd_getoption(a, "insecure")) {
-        curl_easy_setopt(sn->handle, CURLOPT_SSL_VERIFYPEER, 0);
-        curl_easy_setopt(sn->handle, CURLOPT_SSL_VERIFYHOST, 0);
-    }
-    if(!cmd_getoption(a, "noinput")) {
-        dav_session_set_authcallback(sn, request_auth2, repo);
-    }
-    return sn;
-}
 
 int update_progress(DavResource *res, int64_t total, int64_t now, Progress *p) {
     int ret = 0;
@@ -698,7 +418,7 @@
     char *url = a->argv[0];
     char *path = NULL;
     Repository *repo = url2repo(url, &path);
-    DavSession *sn = connect_to_repo(repo, path, a);
+    DavSession *sn = connect_to_repo(ctx, repo, path, request_auth, a);
     
     if(set_session_config(sn, a)) {
         return -1;
@@ -877,7 +597,7 @@
     char *url = a->argv[0];
     char *path = NULL;
     Repository *repo = url2repo(url, &path);
-    DavSession *sn = connect_to_repo(repo, path, a);
+    DavSession *sn = connect_to_repo(ctx, repo, path, request_auth, a);
     
     if(set_session_config(sn, a)) {
         return -1;
@@ -1123,7 +843,7 @@
     char *url = a->argv[0];
     char *path = NULL;
     Repository *repo = url2repo(url, &path);
-    DavSession *sn = connect_to_repo(repo, path, a);
+    DavSession *sn = connect_to_repo(ctx, repo, path, request_auth, a);
     
     if(set_session_config(sn, a)) {
         return -1;
@@ -1421,7 +1141,7 @@
     char *url = a->argv[0];
     char *path = NULL;
     Repository *repo = url2repo(url, &path);
-    DavSession *sn = connect_to_repo(repo, path, a);
+    DavSession *sn = connect_to_repo(ctx, repo, path, request_auth, a);
     
     if(set_session_config(sn, a)) {
         return -1;
@@ -1760,7 +1480,7 @@
     char *url = a->argv[0];
     char *path = NULL;
     Repository *repo = url2repo(url, &path);
-    DavSession *sn = connect_to_repo(repo, path, a);
+    DavSession *sn = connect_to_repo(ctx, repo, path, request_auth, a);
     
     int exit_code = -1;
     assert(!!path && !!sn);
@@ -1829,7 +1549,7 @@
     char *srcpath = NULL;
     Repository *srcrepo = url2repo(srcurl, &srcpath);
     
-    DavSession *srcsn = connect_to_repo(srcrepo, srcpath, a);
+    DavSession *srcsn = connect_to_repo(ctx, srcrepo, srcpath, request_auth, a);
     if(set_session_config(srcsn, a)) {
         return -1;
     }
@@ -1854,7 +1574,7 @@
         char *srchost = util_url_base(srcrepo->url);
         char *desthost = util_url_base(destrepo->url);     
         if(!strcmp(srchost, desthost)) {
-            DavSession *destsn = connect_to_repo(destrepo, destpath, a);
+            DavSession *destsn = connect_to_repo(ctx, destrepo, destpath, request_auth, a);
             if(set_session_config(destsn, a)) {
                 return -1;
             }
@@ -1906,7 +1626,7 @@
     char *url = a->argv[0];
     char *path = NULL;
     Repository *repo = url2repo(url, &path);
-    DavSession *sn = connect_to_repo(repo, path, a);
+    DavSession *sn = connect_to_repo(ctx, repo, path, request_auth, a);
     
     if(set_session_config(sn, a)) {
         return -1;
@@ -1999,7 +1719,7 @@
         char *url = a->argv[0];
         char *path = NULL;
         Repository *repo = url2repo(url, &path);
-        DavSession *sn = connect_to_repo(repo, path, a);
+        DavSession *sn = connect_to_repo(ctx, repo, path, request_auth, a);
 
         DavResource *res = dav_resource_new(sn, path);
         char *date = NULL;
@@ -2030,7 +1750,7 @@
     char *url = a->argv[0];
     char *path = NULL;
     Repository *repo = url2repo(url, &path);
-    DavSession *sn = connect_to_repo(repo, path, a);
+    DavSession *sn = connect_to_repo(ctx, repo, path, request_auth, a);
     
     if(set_session_config(sn, a)) {
         return -1;
@@ -2104,7 +1824,7 @@
     char *url = a->argv[0];
     char *path = NULL;
     Repository *repo = url2repo(url, &path);
-    DavSession *sn = connect_to_repo(repo, path, a);
+    DavSession *sn = connect_to_repo(ctx, repo, path, request_auth, a);
     
     if(set_session_config(sn, a)) {
         return -1;
@@ -2167,7 +1887,7 @@
     char *url = a->argv[0];
     char *path = NULL;
     Repository *repo = url2repo(url, &path);
-    DavSession *sn = connect_to_repo(repo, path, a);
+    DavSession *sn = connect_to_repo(ctx, repo, path, request_auth, a);
     
     if(set_session_config(sn, a)) {
         return -1;
@@ -2208,7 +1928,7 @@
     char *url = a->argv[0];
     char *path = NULL;
     Repository *repo = url2repo(url, &path);
-    DavSession *sn = connect_to_repo(repo, path, a);
+    DavSession *sn = connect_to_repo(ctx, repo, path, request_auth, a);
     ucx_mempool_reg_destr(sn->mp, path, free);
     
     if(set_session_config(sn, a)) {
@@ -2280,7 +2000,7 @@
     char *url = a->argv[0];
     char *path = NULL;
     Repository *repo = url2repo(url, &path);
-    DavSession *sn = connect_to_repo(repo, path, a);
+    DavSession *sn = connect_to_repo(ctx, repo, path, request_auth, a);
     ucx_mempool_reg_destr(sn->mp, path, free);
     if(set_session_config(sn, a)) {
         return -1;
@@ -2340,7 +2060,7 @@
     char *url = a->argv[0];
     char *path = NULL;
     Repository *repo = url2repo(url, &path);
-    DavSession *sn = connect_to_repo(repo, path, a);
+    DavSession *sn = connect_to_repo(ctx, repo, path, request_auth, a);
     
     if(set_session_config(sn, a)) {
         return -1;
@@ -2436,7 +2156,7 @@
     char *url = a->argv[0];
     char *path = NULL;
     Repository *repo = url2repo(url, &path);
-    DavSession *sn = connect_to_repo(repo, path, a);
+    DavSession *sn = connect_to_repo(ctx, repo, path, request_auth, a);
     
     if(set_session_config(sn, a)) {
         return -1;
@@ -2463,7 +2183,7 @@
     char *url = a->argv[0];
     char *path = NULL;
     Repository *repo = url2repo(url, &path);
-    DavSession *sn = connect_to_repo(repo, path, a);
+    DavSession *sn = connect_to_repo(ctx, repo, path, request_auth, a);
     
     if(set_session_config(sn, a)) {
         return -1;
@@ -2490,7 +2210,7 @@
     char *url = a->argv[0];
     char *path = NULL;
     Repository *repo = url2repo(url, &path);
-    DavSession *sn = connect_to_repo(repo, path, a);
+    DavSession *sn = connect_to_repo(ctx, repo, path, request_auth, a);
     
     if(set_session_config(sn, a)) {
         return -1;
@@ -2516,7 +2236,7 @@
     char *url = a->argv[0];
     char *path = NULL;
     Repository *repo = url2repo(url, &path);
-    DavSession *sn = connect_to_repo(repo, path, a);
+    DavSession *sn = connect_to_repo(ctx, repo, path, request_auth, a);
     
     if(set_session_config(sn, a)) {
         return -1;
@@ -2543,7 +2263,7 @@
     char *url = a->argv[0];
     char *path = NULL;
     Repository *repo = url2repo(url, &path);
-    DavSession *sn = connect_to_repo(repo, path, a);
+    DavSession *sn = connect_to_repo(ctx, repo, path, request_auth, a);
     
     if(set_session_config(sn, a)) {
         return -1;
@@ -3383,7 +3103,7 @@
         
         char *path = NULL;
         Repository *repo = url2repo_s(url, &path);
-        DavSession *sn = connect_to_repo(repo, path, args);
+        DavSession *sn = connect_to_repo(ctx, repo, path, request_auth, args);
         if(!sn) {
             return 0;
         }

mercurial