[409] | 1 | /* Copyright 2009, UCAR/Unidata and OPeNDAP, Inc. |
---|
| 2 | See the COPYRIGHT file for more information. */ |
---|
| 3 | |
---|
| 4 | #include "config.h" |
---|
| 5 | #include "ocinternal.h" |
---|
| 6 | #include "ocdebug.h" |
---|
| 7 | #include "ocdata.h" |
---|
| 8 | #include "occontent.h" |
---|
| 9 | |
---|
| 10 | #include "ocrc.h" |
---|
| 11 | |
---|
| 12 | /* Condition on libcurl version */ |
---|
| 13 | /* Set up an alias as needed */ |
---|
| 14 | #ifndef HAVE_CURLOPT_KEYPASSWD |
---|
| 15 | #define CURLOPT_KEYPASSWD CURLOPT_SSLKEYPASSWD |
---|
| 16 | #endif |
---|
| 17 | |
---|
| 18 | static char* combinecredentials(const char* user, const char* pwd); |
---|
| 19 | |
---|
| 20 | |
---|
| 21 | /* Set various general curl flags */ |
---|
| 22 | int |
---|
| 23 | ocset_curl_flags(OCstate* state) |
---|
| 24 | { |
---|
| 25 | CURLcode cstat = CURLE_OK; |
---|
| 26 | CURL* curl = state->curl; |
---|
| 27 | struct OCcurlflags* flags = &state->curlflags; |
---|
| 28 | |
---|
| 29 | #ifdef CURLOPT_ENCODING |
---|
| 30 | if (flags->compress) { |
---|
| 31 | cstat = curl_easy_setopt(curl, CURLOPT_ENCODING,"deflate, gzip"); |
---|
| 32 | if(cstat != CURLE_OK) goto done; |
---|
| 33 | OCDBG(1,"CURLOPT_ENCODING=deflate, gzip"); |
---|
| 34 | } |
---|
| 35 | #endif |
---|
| 36 | if (flags->cookiejar || flags->cookiefile) { |
---|
| 37 | cstat = curl_easy_setopt(curl, CURLOPT_COOKIESESSION, 1); |
---|
| 38 | if (cstat != CURLE_OK) goto done; |
---|
| 39 | OCDBG(1,"CURLOPT_COOKIESESSION=1"); |
---|
| 40 | } |
---|
| 41 | if (flags->cookiejar) { |
---|
| 42 | cstat = curl_easy_setopt(curl, CURLOPT_COOKIEJAR, flags->cookiejar); |
---|
| 43 | if (cstat != CURLE_OK) goto done; |
---|
| 44 | OCDBG1(1,"CURLOPT_COOKIEJAR=%s",flags->cookiejar); |
---|
| 45 | } |
---|
| 46 | if (flags->cookiefile) { |
---|
| 47 | cstat = curl_easy_setopt(curl, CURLOPT_COOKIEFILE, flags->cookiefile); |
---|
| 48 | if (cstat != CURLE_OK) goto done; |
---|
| 49 | OCDBG1(1,"CURLOPT_COOKIEFILE=%s",flags->cookiefile); |
---|
| 50 | } |
---|
| 51 | if (flags->verbose) { |
---|
| 52 | cstat = curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); |
---|
| 53 | if (cstat != CURLE_OK) goto done; |
---|
| 54 | OCDBG1(1,"CURLOPT_VERBOSE=%ld",1L); |
---|
| 55 | } |
---|
| 56 | |
---|
| 57 | if (flags->timeout) { |
---|
| 58 | cstat = curl_easy_setopt(curl, CURLOPT_TIMEOUT, (long)flags->timeout); |
---|
| 59 | if (cstat != CURLE_OK) goto done; |
---|
| 60 | OCDBG1(1,"CURLOPT_TIMEOUT=%ld",1L); |
---|
| 61 | } |
---|
| 62 | |
---|
| 63 | /* Following are always set */ |
---|
| 64 | cstat = curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); |
---|
| 65 | OCDBG1(1,"CURLOPT_FOLLOWLOCATION=%ld",1L); |
---|
| 66 | cstat = curl_easy_setopt(curl, CURLOPT_MAXREDIRS, 10L); |
---|
| 67 | OCDBG1(1,"CURLOPT_FOLLOWLOCATION=%ld",1L); |
---|
| 68 | |
---|
| 69 | cstat = curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, state->error.curlerrorbuf); |
---|
| 70 | OCDBG1(1,"CURLOPT_ERRORBUFFER",0); |
---|
| 71 | |
---|
| 72 | done: |
---|
| 73 | return cstat; |
---|
| 74 | } |
---|
| 75 | |
---|
| 76 | int |
---|
| 77 | ocset_proxy(OCstate* state) |
---|
| 78 | { |
---|
| 79 | CURLcode cstat; |
---|
| 80 | CURL* curl = state->curl; |
---|
| 81 | struct OCproxy *proxy = &state->proxy; |
---|
| 82 | struct OCcredentials *creds = &state->creds; |
---|
| 83 | |
---|
| 84 | cstat = curl_easy_setopt(curl, CURLOPT_PROXY, proxy->host); |
---|
| 85 | if (cstat != CURLE_OK) return OC_ECURL; |
---|
| 86 | OCDBG1(1,"CURLOPT_PROXY=%s",proxy->host); |
---|
| 87 | |
---|
| 88 | cstat = curl_easy_setopt(curl, CURLOPT_PROXYPORT, proxy->port); |
---|
| 89 | if (cstat != CURLE_OK) return OC_ECURL; |
---|
| 90 | OCDBG1(1,"CURLOPT_PROXYPORT=%d",proxy->port); |
---|
| 91 | |
---|
| 92 | if (creds->username) { |
---|
| 93 | char *combined = combinecredentials(creds->username,creds->password); |
---|
| 94 | if (!combined) return OC_ENOMEM; |
---|
| 95 | cstat = curl_easy_setopt(curl, CURLOPT_PROXYUSERPWD, combined); |
---|
| 96 | if (cstat != CURLE_OK) return OC_ECURL; |
---|
| 97 | OCDBG1(1,"CURLOPT_PROXYUSERPWD=%s",combined); |
---|
| 98 | #ifdef CURLOPT_PROXYAUTH |
---|
| 99 | cstat = curl_easy_setopt(curl, CURLOPT_PROXYAUTH, (long)CURLAUTH_ANY); |
---|
| 100 | if(cstat != CURLE_OK) goto fail; |
---|
| 101 | OCDBG1(1,"CURLOPT_PROXYAUTH=%ld",(long)CURLAUTH_ANY); |
---|
| 102 | #endif |
---|
| 103 | free(combined); |
---|
| 104 | } |
---|
| 105 | return OC_NOERR; |
---|
| 106 | } |
---|
| 107 | |
---|
| 108 | int |
---|
| 109 | ocset_ssl(OCstate* state) |
---|
| 110 | { |
---|
| 111 | CURLcode cstat = CURLE_OK; |
---|
| 112 | CURL* curl = state->curl; |
---|
| 113 | struct OCSSL* ssl = &state->ssl; |
---|
| 114 | long verify = (ssl->validate?1L:0L); |
---|
| 115 | cstat=curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, verify); |
---|
| 116 | if (cstat != CURLE_OK) goto fail; |
---|
| 117 | OCDBG1(1,"CURLOPT_SSL_VERIFYPEER=%ld",verify); |
---|
| 118 | cstat=curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, (verify?2L:0L)); |
---|
| 119 | if (cstat != CURLE_OK) goto fail; |
---|
| 120 | OCDBG1(1,"CURLOPT_SSL_VERIFYHOST=%ld",(verify?2L:0L)); |
---|
| 121 | #ifdef OCIGNORE |
---|
| 122 | if(verify) |
---|
| 123 | #endif |
---|
| 124 | { |
---|
| 125 | if(ssl->certificate) { |
---|
| 126 | cstat = curl_easy_setopt(curl, CURLOPT_SSLCERT, ssl->certificate); |
---|
| 127 | if(cstat != CURLE_OK) goto fail; |
---|
| 128 | OCDBG1(1,"CURLOPT_SSLCERT=%s",ssl->certificate); |
---|
| 129 | } |
---|
| 130 | if(ssl->key) { |
---|
| 131 | cstat = curl_easy_setopt(curl, CURLOPT_SSLKEY, ssl->key); |
---|
| 132 | if(cstat != CURLE_OK) goto fail; |
---|
| 133 | OCDBG1(1,"CURLOPT_SSLKEY=%s",ssl->key); |
---|
| 134 | } |
---|
| 135 | if(ssl->keypasswd) { |
---|
| 136 | /* libcurl prior to 7.16.4 used 'CURLOPT_SSLKEYPASSWD' */ |
---|
| 137 | cstat = curl_easy_setopt(curl, CURLOPT_KEYPASSWD, ssl->keypasswd); |
---|
| 138 | if(cstat != CURLE_OK) goto fail; |
---|
| 139 | OCDBG1(1,"CURLOPT_SSLKEY=%s",ssl->key); |
---|
| 140 | } |
---|
| 141 | if(ssl->cainfo) { |
---|
| 142 | cstat = curl_easy_setopt(curl, CURLOPT_CAINFO, ssl->cainfo); |
---|
| 143 | if(cstat != CURLE_OK) goto fail; |
---|
| 144 | OCDBG1(1,"CURLOPT_CAINFO=%s",ssl->cainfo); |
---|
| 145 | } |
---|
| 146 | if(ssl->capath) { |
---|
| 147 | cstat = curl_easy_setopt(curl, CURLOPT_CAPATH, ssl->capath); |
---|
| 148 | if(cstat != CURLE_OK) goto fail; |
---|
| 149 | OCDBG1(1,"CURLOPT_CAPATH=%s",ssl->capath); |
---|
| 150 | } |
---|
| 151 | { |
---|
| 152 | cstat = curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, ssl->verifypeer); |
---|
| 153 | if(cstat != CURLE_OK) goto fail; |
---|
| 154 | OCDBG1(1,"CURLOPT_SSL_VERIFYPEER=%d",ssl->verifypeer); |
---|
| 155 | } |
---|
| 156 | } |
---|
| 157 | return OC_NOERR; |
---|
| 158 | |
---|
| 159 | fail: |
---|
| 160 | return OC_ECURL; |
---|
| 161 | } |
---|
| 162 | |
---|
| 163 | /* This is called with arguments while the other functions in this file are |
---|
| 164 | * used with global values read from the.dodsrc file. The reason is that |
---|
| 165 | * we may have multiple password sources. |
---|
| 166 | */ |
---|
| 167 | int |
---|
| 168 | ocset_user_password(OCstate* state) |
---|
| 169 | { |
---|
| 170 | CURLcode cstat; |
---|
| 171 | CURL* curl = state->curl; |
---|
| 172 | char* combined = NULL; |
---|
| 173 | const char* userC = state->creds.username; |
---|
| 174 | const char* passwordC = state->creds.password; |
---|
| 175 | |
---|
| 176 | if(userC == NULL || passwordC == NULL) return OC_NOERR; |
---|
| 177 | |
---|
| 178 | combined = combinecredentials(userC,passwordC); |
---|
| 179 | if (!combined) return OC_ENOMEM; |
---|
| 180 | cstat = curl_easy_setopt(curl, CURLOPT_USERPWD, combined); |
---|
| 181 | if (cstat != CURLE_OK) goto done; |
---|
| 182 | OCDBG1(1,"CURLOPT_USERPWD=%s",combined); |
---|
| 183 | cstat = curl_easy_setopt(curl, CURLOPT_HTTPAUTH, (long) CURLAUTH_ANY); |
---|
| 184 | if (cstat != CURLE_OK) goto done; |
---|
| 185 | OCDBG1(1,"CURLOPT_HTTPAUTH=%ld",(long)CURLAUTH_ANY); |
---|
| 186 | |
---|
| 187 | done: |
---|
| 188 | if(combined != NULL) free(combined); |
---|
| 189 | return (cstat == CURLE_OK?OC_NOERR:OC_ECURL); |
---|
| 190 | } |
---|
| 191 | |
---|
| 192 | |
---|
| 193 | static char* |
---|
| 194 | combinecredentials(const char* user, const char* pwd) |
---|
| 195 | { |
---|
| 196 | int userPassSize = strlen(user) + strlen(pwd) + 2; |
---|
| 197 | char *userPassword = malloc(sizeof(char) * userPassSize); |
---|
| 198 | if (!userPassword) { |
---|
| 199 | oc_log(LOGERR,"Out of Memory\n"); |
---|
| 200 | return NULL; |
---|
| 201 | } |
---|
| 202 | strcpy(userPassword, user); |
---|
| 203 | strcat(userPassword, ":"); |
---|
| 204 | strcat(userPassword, pwd); |
---|
| 205 | return userPassword; |
---|
| 206 | } |
---|