Fri, 04 Mar 2016 14:03:06 +0100
fixed macros with digits not highlighted
universe@25 | 1 | /* |
universe@25 | 2 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. |
universe@25 | 3 | * |
universe@25 | 4 | * Copyright 2015 Olaf Wintermann. All rights reserved. |
universe@25 | 5 | * |
universe@25 | 6 | * Redistribution and use in source and binary forms, with or without |
universe@25 | 7 | * modification, are permitted provided that the following conditions are met: |
universe@25 | 8 | * |
universe@25 | 9 | * 1. Redistributions of source code must retain the above copyright |
universe@25 | 10 | * notice, this list of conditions and the following disclaimer. |
universe@25 | 11 | * |
universe@25 | 12 | * 2. Redistributions in binary form must reproduce the above copyright |
universe@25 | 13 | * notice, this list of conditions and the following disclaimer in the |
universe@25 | 14 | * documentation and/or other materials provided with the distribution. |
universe@25 | 15 | * |
universe@25 | 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
universe@25 | 17 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
universe@25 | 18 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
universe@25 | 19 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE |
universe@25 | 20 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
universe@25 | 21 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
universe@25 | 22 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
universe@25 | 23 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
universe@25 | 24 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
universe@25 | 25 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
universe@25 | 26 | * POSSIBILITY OF SUCH DAMAGE. |
universe@25 | 27 | */ |
universe@25 | 28 | |
universe@25 | 29 | #include <time.h> |
universe@25 | 30 | #include <stdio.h> |
universe@25 | 31 | #include <stdlib.h> |
universe@25 | 32 | #include <string.h> |
universe@25 | 33 | #include <ucx/string.h> |
universe@25 | 34 | #include <ucx/buffer.h> |
universe@25 | 35 | #include <ucx/utils.h> |
universe@25 | 36 | #include <libxml/tree.h> |
universe@25 | 37 | #include <curl/curl.h> |
universe@25 | 38 | |
universe@25 | 39 | #include <openssl/sha.h> |
universe@25 | 40 | #include <openssl/hmac.h> |
universe@25 | 41 | #include <openssl/evp.h> |
universe@25 | 42 | #include <openssl/bio.h> |
universe@25 | 43 | #include <openssl/buffer.h> |
universe@25 | 44 | #include <openssl/rand.h> |
universe@25 | 45 | |
universe@25 | 46 | #include "utils.h" |
universe@25 | 47 | #include "crypto.h" |
universe@25 | 48 | #include "webdav.h" |
universe@25 | 49 | |
universe@33 | 50 | #define MACRO1337 1337L |
universe@25 | 51 | |
universe@31 | 52 | /* -------------------- This is a testing file. -------------------------- */ |
universe@31 | 53 | /* |
universe@25 | 54 | time_t util_parse_creationdate(char *str) { |
universe@25 | 55 | // example: 2012-11-29T21:35:35Z |
universe@25 | 56 | if(!str) { |
universe@25 | 57 | return 0; |
universe@25 | 58 | } |
universe@25 | 59 | // TODO |
universe@25 | 60 | return 0; |
universe@25 | 61 | } |
universe@31 | 62 | */ |
universe@25 | 63 | time_t util_parse_lastmodified(char *str) { |
universe@25 | 64 | // example: Thu, 29 Nov 2012 21:35:35 GMT |
universe@25 | 65 | if(!str) { |
universe@25 | 66 | return 0; |
universe@25 | 67 | } else { |
universe@25 | 68 | return curl_getdate(str, NULL); |
universe@25 | 69 | } |
universe@25 | 70 | } |
universe@25 | 71 | |
universe@25 | 72 | int util_getboolean(char *v) { |
universe@25 | 73 | if(v[0] == 'T' || v[0] == 't') { |
universe@25 | 74 | return 1; |
universe@25 | 75 | } |
universe@25 | 76 | return 0; |
universe@25 | 77 | } |
universe@25 | 78 | |
universe@25 | 79 | int util_strtoint(char *str, int64_t *value) { |
universe@25 | 80 | char *end; |
universe@25 | 81 | int64_t val = strtoll(str, &end, 0); |
universe@25 | 82 | if(strlen(end) == 0) { |
universe@25 | 83 | *value = val; |
universe@25 | 84 | return 1; |
universe@25 | 85 | } else { |
universe@25 | 86 | return 0; |
universe@25 | 87 | } |
universe@25 | 88 | } |
universe@25 | 89 | |
universe@25 | 90 | char* util_url_path(char *url) { |
universe@25 | 91 | char *path = NULL; |
universe@25 | 92 | size_t len = strlen(url); |
universe@25 | 93 | int slashcount = 0; |
universe@25 | 94 | int slmax; |
universe@25 | 95 | if(len > 7 && !strncasecmp(url, "http://", 7)) { |
universe@25 | 96 | slmax = 3; |
universe@25 | 97 | } else if(len > 8 && !strncasecmp(url, "https://", 8)) { |
universe@25 | 98 | slmax = 3; |
universe@25 | 99 | } else { |
universe@25 | 100 | slmax = 1; |
universe@25 | 101 | } |
universe@25 | 102 | char c; |
universe@25 | 103 | for(int i=0;i<len;i++) { |
universe@25 | 104 | c = url[i]; |
universe@25 | 105 | if(c == '/') { |
universe@25 | 106 | slashcount++; |
universe@25 | 107 | if(slashcount == slmax) { |
universe@25 | 108 | path = url + i; |
universe@25 | 109 | break; |
universe@25 | 110 | } |
universe@25 | 111 | } |
universe@25 | 112 | } |
universe@25 | 113 | return path; |
universe@25 | 114 | } |
universe@25 | 115 | |
universe@25 | 116 | char* util_url_decode(DavSession *sn, char *url) { |
universe@25 | 117 | char *unesc = curl_easy_unescape(sn->handle, url, strlen(url), NULL); |
universe@25 | 118 | char *ret = strdup(unesc); |
universe@25 | 119 | curl_free(unesc); |
universe@25 | 120 | return ret; |
universe@25 | 121 | } |
universe@25 | 122 | |
universe@25 | 123 | char* util_resource_name(char *url) { |
universe@25 | 124 | int si = 0; |
universe@25 | 125 | int osi = 0; |
universe@25 | 126 | int i = 0; |
universe@25 | 127 | int p = 0; |
universe@25 | 128 | char c; |
universe@25 | 129 | while((c = url[i]) != 0) { |
universe@25 | 130 | if(c == '/') { |
universe@25 | 131 | osi = si; |
universe@25 | 132 | si = i; |
universe@25 | 133 | p = 1; |
universe@25 | 134 | } |
universe@25 | 135 | i++; |
universe@25 | 136 | } |
universe@25 | 137 | |
universe@25 | 138 | char *name = url + si + p; |
universe@25 | 139 | if(name[0] == 0) { |
universe@25 | 140 | name = url + osi + p; |
universe@25 | 141 | if(name[0] == 0) { |
universe@25 | 142 | return url; |
universe@25 | 143 | } |
universe@25 | 144 | } |
universe@25 | 145 | |
universe@25 | 146 | return name; |
universe@25 | 147 | } |
universe@25 | 148 | |
universe@25 | 149 | int util_mkdir(char *path, mode_t mode) { |
universe@25 | 150 | #ifdef _WIN32 |
universe@25 | 151 | return mkdir(path); |
universe@25 | 152 | #else |
universe@25 | 153 | return mkdir(path, mode); |
universe@25 | 154 | #endif |
universe@25 | 155 | } |
universe@25 | 156 | |
universe@25 | 157 | char* util_concat_path(char *url_base, char *p) { |
universe@25 | 158 | sstr_t base = sstr(url_base); |
universe@25 | 159 | sstr_t path; |
universe@25 | 160 | if(p) { |
universe@25 | 161 | path = sstr(p); |
universe@25 | 162 | } else { |
universe@25 | 163 | path = sstrn("", 0); |
universe@25 | 164 | } |
universe@25 | 165 | |
universe@25 | 166 | int add_separator = 0; |
universe@25 | 167 | if(base.ptr[base.length-1] == '/') { |
universe@25 | 168 | if(path.ptr[0] == '/') { |
universe@25 | 169 | base.length--; |
universe@25 | 170 | } |
universe@25 | 171 | } else { |
universe@25 | 172 | if(path.length == 0 || path.ptr[0] != '/') { |
universe@25 | 173 | add_separator = 1; |
universe@25 | 174 | } |
universe@25 | 175 | } |
universe@25 | 176 | |
universe@25 | 177 | sstr_t url; |
universe@25 | 178 | if(add_separator) { |
universe@25 | 179 | url = sstrcat(3, base, sstr("/"), path); |
universe@25 | 180 | } else { |
universe@25 | 181 | url = sstrcat(2, base, path); |
universe@25 | 182 | } |
universe@25 | 183 | |
universe@25 | 184 | return url.ptr; |
universe@25 | 185 | } |
universe@25 | 186 | |
universe@25 | 187 | void util_set_url(DavSession *sn, char *href) { |
universe@25 | 188 | sstr_t base = sstr(sn->base_url); |
universe@25 | 189 | sstr_t href_str = sstr(href); |
universe@25 | 190 | |
universe@25 | 191 | char *base_path = util_url_path(sn->base_url); |
universe@25 | 192 | base.length -= strlen(base_path); |
universe@25 | 193 | |
universe@25 | 194 | sstr_t url = sstrcat(2, base, href_str); |
universe@25 | 195 | |
universe@25 | 196 | curl_easy_setopt(sn->handle, CURLOPT_URL, url.ptr); |
universe@25 | 197 | free(url.ptr); |
universe@25 | 198 | } |
universe@25 | 199 | |
universe@25 | 200 | char* util_path_to_url(DavSession *sn, char *path) { |
universe@25 | 201 | char *space = malloc(256); |
universe@25 | 202 | UcxBuffer *url = ucx_buffer_new(space, 256, UCX_BUFFER_AUTOEXTEND); |
universe@25 | 203 | |
universe@25 | 204 | // add base url |
universe@25 | 205 | ucx_buffer_write(sn->base_url, 1, strlen(sn->base_url), url); |
universe@25 | 206 | // remove trailing slash |
universe@25 | 207 | ucx_buffer_seek(url, -1, SEEK_CUR); |
universe@25 | 208 | |
universe@25 | 209 | sstr_t p = sstr(path); |
universe@25 | 210 | ssize_t ntk = 0; |
universe@25 | 211 | sstr_t *tks = sstrsplit(p, S("/"), &ntk); |
universe@25 | 212 | |
universe@25 | 213 | for(int i=0;i<ntk;i++) { |
universe@25 | 214 | sstr_t node = tks[i]; |
universe@25 | 215 | if(node.length > 0) { |
universe@25 | 216 | char *esc = curl_easy_escape(sn->handle, node.ptr, node.length); |
universe@25 | 217 | ucx_buffer_putc(url, '/'); |
universe@25 | 218 | ucx_buffer_write(esc, 1, strlen(esc), url); |
universe@25 | 219 | curl_free(esc); |
universe@25 | 220 | } |
universe@25 | 221 | free(node.ptr); |
universe@25 | 222 | } |
universe@25 | 223 | free(tks); |
universe@25 | 224 | if(path[p.length-1] == '/') { |
universe@25 | 225 | ucx_buffer_putc(url, '/'); |
universe@25 | 226 | } |
universe@25 | 227 | ucx_buffer_putc(url, 0); |
universe@25 | 228 | |
universe@25 | 229 | space = url->space; |
universe@25 | 230 | ucx_buffer_free(url); |
universe@25 | 231 | |
universe@25 | 232 | return space; |
universe@25 | 233 | } |
universe@25 | 234 | |
universe@25 | 235 | char* util_parent_path(char *path) { |
universe@25 | 236 | char *name = util_resource_name(path); |
universe@25 | 237 | size_t namelen = strlen(name); |
universe@25 | 238 | size_t pathlen = strlen(path); |
universe@25 | 239 | size_t parentlen = pathlen - namelen; |
universe@25 | 240 | char *parent = malloc(parentlen + 1); |
universe@25 | 241 | memcpy(parent, path, parentlen); |
universe@25 | 242 | parent[parentlen] = '\0'; |
universe@25 | 243 | return parent; |
universe@25 | 244 | } |
universe@25 | 245 | |
universe@25 | 246 | |
universe@25 | 247 | char* util_xml_get_text(xmlNode *elm) { |
universe@25 | 248 | xmlNode *node = elm->children; |
universe@25 | 249 | while(node) { |
universe@25 | 250 | if(node->type == XML_TEXT_NODE) { |
universe@25 | 251 | return (char*)node->content; |
universe@25 | 252 | } |
universe@25 | 253 | node = node->next; |
universe@25 | 254 | } |
universe@25 | 255 | return NULL; |
universe@25 | 256 | } |
universe@25 | 257 | |
universe@25 | 258 | |
universe@25 | 259 | char* util_base64decode(char *in) { |
universe@25 | 260 | int len = 0; |
universe@25 | 261 | return util_base64decode_len(in, &len); |
universe@25 | 262 | } |
universe@25 | 263 | |
universe@25 | 264 | char* util_base64decode_len(char* in, int *outlen) { |
universe@25 | 265 | size_t len = strlen(in); |
universe@25 | 266 | char *out = calloc(1, len); |
universe@25 | 267 | |
universe@25 | 268 | BIO* b = BIO_new_mem_buf(in, len); |
universe@25 | 269 | BIO *d = BIO_new(BIO_f_base64()); |
universe@25 | 270 | BIO_set_flags(d, BIO_FLAGS_BASE64_NO_NL); |
universe@25 | 271 | b = BIO_push(d, b); |
universe@25 | 272 | |
universe@25 | 273 | *outlen = BIO_read(b, out, len); |
universe@25 | 274 | BIO_free_all(b); |
universe@25 | 275 | |
universe@25 | 276 | return out; |
universe@25 | 277 | } |
universe@25 | 278 | |
universe@25 | 279 | char* util_base64encode(char *in, size_t len) { |
universe@25 | 280 | BIO *b; |
universe@25 | 281 | BIO *e; |
universe@25 | 282 | BUF_MEM *mem; |
universe@25 | 283 | |
universe@25 | 284 | e = BIO_new(BIO_f_base64()); |
universe@25 | 285 | b = BIO_new(BIO_s_mem()); |
universe@25 | 286 | |
universe@25 | 287 | e = BIO_push(e, b); |
universe@25 | 288 | BIO_write(e, in, len); |
universe@25 | 289 | BIO_flush(e); |
universe@25 | 290 | |
universe@25 | 291 | BIO_get_mem_ptr(e, &mem); |
universe@25 | 292 | char *out = malloc(mem->length); |
universe@25 | 293 | memcpy(out, mem->data, mem->length -1); |
universe@25 | 294 | out[mem->length - 1] = '\0'; |
universe@25 | 295 | |
universe@25 | 296 | BIO_free_all(e); |
universe@25 | 297 | |
universe@25 | 298 | return out; |
universe@25 | 299 | } |
universe@25 | 300 | |
universe@25 | 301 | char* util_encrypt_str(DavSession *sn, char *str, char *key) { |
universe@25 | 302 | DavKey *k = dav_context_get_key(sn->context, key); |
universe@25 | 303 | if(!k) { |
universe@25 | 304 | // TODO: session error |
universe@25 | 305 | return NULL; |
universe@25 | 306 | } |
universe@25 | 307 | |
universe@25 | 308 | char *enc_str = aes_encrypt(str, k); |
universe@25 | 309 | char *ret_str = dav_session_strdup(sn, enc_str); |
universe@25 | 310 | free(enc_str); |
universe@25 | 311 | return ret_str; |
universe@25 | 312 | } |
universe@25 | 313 | |
universe@31 | 314 | /* commented out for testing reasons */ |
universe@31 | 315 | /* |
universe@25 | 316 | char* util_decrypt_str(DavSession *sn, char *str, char *key) { |
universe@25 | 317 | DavKey *k = dav_context_get_key(sn->context, key); |
universe@25 | 318 | if(!k) { |
universe@25 | 319 | // TODO: session error |
universe@25 | 320 | return NULL; |
universe@25 | 321 | } |
universe@25 | 322 | |
universe@25 | 323 | char *dec_str = aes_decrypt(str, k); |
universe@25 | 324 | char *ret_str = dav_session_strdup(sn, dec_str); |
universe@25 | 325 | free(dec_str); |
universe@25 | 326 | return ret_str; |
universe@25 | 327 | } |
universe@31 | 328 | */ |
universe@25 | 329 | char* util_random_str() { |
universe@25 | 330 | unsigned char *str = malloc(25); |
universe@25 | 331 | str[24] = '\0'; |
universe@25 | 332 | |
universe@25 | 333 | sstr_t t = S( |
universe@25 | 334 | "01234567890" |
universe@25 | 335 | "abcdefghijklmnopqrstuvwxyz" |
universe@25 | 336 | "ABCDEFGHIJKLMNOPQRSTUVWXYZ"); |
universe@25 | 337 | const unsigned char *table = (const unsigned char*)t.ptr; |
universe@25 | 338 | |
universe@25 | 339 | RAND_pseudo_bytes(str, 24); |
universe@25 | 340 | for(int i=0;i<24;i++) { |
universe@25 | 341 | int c = str[i] % t.length; |
universe@25 | 342 | str[i] = table[c]; |
universe@25 | 343 | } |
universe@25 | 344 | |
universe@25 | 345 | return (char*)str; |
universe@25 | 346 | } |
universe@25 | 347 | |
universe@25 | 348 | /* |
universe@25 | 349 | * gets a substring from 0 to the appearance of the token |
universe@25 | 350 | * tokens are separated by space |
universe@25 | 351 | * sets sub to the substring and returns the remaining string |
universe@25 | 352 | */ |
universe@25 | 353 | sstr_t util_getsubstr_until_token(sstr_t str, sstr_t token, sstr_t *sub) { |
universe@25 | 354 | int i; |
universe@25 | 355 | int token_start = -1; |
universe@25 | 356 | int token_end = -1; |
universe@25 | 357 | for(i=0;i<=str.length;i++) { |
universe@25 | 358 | int c; |
universe@25 | 359 | if(i == str.length) { |
universe@25 | 360 | c = ' '; |
universe@25 | 361 | } else { |
universe@25 | 362 | c = str.ptr[i]; |
universe@25 | 363 | } |
universe@25 | 364 | if(c < 33) { |
universe@25 | 365 | if(token_start != -1) { |
universe@25 | 366 | token_end = i; |
universe@25 | 367 | size_t len = token_end - token_start; |
universe@25 | 368 | sstr_t tk = sstrsubsl(str, token_start, len); |
universe@25 | 369 | //printf("token: {%.*s}\n", token.length, token.ptr); |
universe@25 | 370 | if(!sstrcmp(tk, token)) { |
universe@25 | 371 | *sub = sstrtrim(sstrsubsl(str, 0, token_start)); |
universe@25 | 372 | break; |
universe@25 | 373 | } |
universe@25 | 374 | token_start = -1; |
universe@25 | 375 | token_end = -1; |
universe@25 | 376 | } |
universe@25 | 377 | } else { |
universe@25 | 378 | if(token_start == -1) { |
universe@25 | 379 | token_start = i; |
universe@25 | 380 | } |
universe@25 | 381 | } |
universe@25 | 382 | } |
universe@25 | 383 | |
universe@25 | 384 | if(i < str.length) { |
universe@25 | 385 | return sstrtrim(sstrsubs(str, i)); |
universe@25 | 386 | } else { |
universe@25 | 387 | str.ptr = NULL; |
universe@25 | 388 | str.length = 0; |
universe@25 | 389 | return str; |
universe@25 | 390 | } |
universe@25 | 391 | } |