Return to curl_plugin.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / strongswan / src / libstrongswan / plugins / curl |
1.1 misho 1: /* 2: * Copyright (C) 2008 Martin Willi 3: * HSR Hochschule fuer Technik Rapperswil 4: * 5: * This program is free software; you can redistribute it and/or modify it 6: * under the terms of the GNU General Public License as published by the 7: * Free Software Foundation; either version 2 of the License, or (at your 8: * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. 9: * 10: * This program is distributed in the hope that it will be useful, but 11: * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 12: * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13: * for more details. 14: */ 15: 16: #include "curl_plugin.h" 17: 18: #include <library.h> 19: #include <utils/debug.h> 20: #include "curl_fetcher.h" 21: 22: #include <curl/curl.h> 23: 24: typedef struct private_curl_plugin_t private_curl_plugin_t; 25: 26: /** 27: * private data of curl_plugin 28: */ 29: struct private_curl_plugin_t { 30: 31: /** 32: * public functions 33: */ 34: curl_plugin_t public; 35: 36: /** 37: * Supported features, CURL protocols + 1 38: */ 39: plugin_feature_t *features; 40: 41: /** 42: * Number of supported features 43: */ 44: int count; 45: }; 46: 47: /** 48: * Append a feature to supported feature list 49: */ 50: static void add_feature(private_curl_plugin_t *this, plugin_feature_t f) 51: { 52: this->features = realloc(this->features, ++this->count * sizeof(f)); 53: this->features[this->count - 1] = f; 54: } 55: 56: /** 57: * Try to add a feature, and the appropriate SSL dependencies 58: */ 59: static void add_feature_with_ssl(private_curl_plugin_t *this, const char *ssl, 60: char *proto, plugin_feature_t f) 61: { 62: /* http://curl.haxx.se/libcurl/c/libcurl-tutorial.html#Multi-threading */ 63: if (strpfx(ssl, "OpenSSL") || strpfx(ssl, "LibreSSL")) 64: { 65: add_feature(this, f); 66: add_feature(this, PLUGIN_DEPENDS(CUSTOM, "openssl-threading")); 67: } 68: else if (strpfx(ssl, "GnuTLS")) 69: { 70: add_feature(this, f); 71: add_feature(this, PLUGIN_DEPENDS(CUSTOM, "gcrypt-threading")); 72: } 73: else if (strpfx(ssl, "NSS") || 74: strpfx(ssl, "BoringSSL")) 75: { 76: add_feature(this, f); 77: } 78: else 79: { 80: DBG1(DBG_LIB, "curl SSL backend '%s' not supported, %s disabled", 81: ssl, proto); 82: } 83: } 84: 85: /** 86: * Get supported protocols, build plugin feature set 87: */ 88: static bool query_protocols(private_curl_plugin_t *this) 89: { 90: 91: struct { 92: /* protocol we are interested in, suffixed with "://" */ 93: char *name; 94: /* require SSL library initialization? */ 95: bool ssl; 96: } protos[] = { 97: { "file://", FALSE, }, 98: { "http://", FALSE, }, 99: { "https://", TRUE, }, 100: { "ftp://", FALSE, }, 101: }; 102: curl_version_info_data *info; 103: char *name; 104: int i, j; 105: 106: add_feature(this, PLUGIN_REGISTER(FETCHER, curl_fetcher_create)); 107: 108: info = curl_version_info(CURLVERSION_NOW); 109: 110: for (i = 0; info->protocols[i]; i++) 111: { 112: for (j = 0; j < countof(protos); j++) 113: { 114: name = protos[j].name; 115: if (strlen(info->protocols[i]) == strlen(name) - strlen("://")) 116: { 117: if (strneq(info->protocols[i], name, 118: strlen(name) - strlen("://"))) 119: { 120: if (protos[j].ssl) 121: { 122: add_feature_with_ssl(this, info->ssl_version, name, 123: PLUGIN_PROVIDE(FETCHER, name)); 124: } 125: else 126: { 127: add_feature(this, PLUGIN_PROVIDE(FETCHER, name)); 128: } 129: } 130: } 131: } 132: } 133: 134: return this->count > 1; 135: } 136: 137: METHOD(plugin_t, get_name, char*, 138: private_curl_plugin_t *this) 139: { 140: return "curl"; 141: } 142: 143: METHOD(plugin_t, get_features, int, 144: private_curl_plugin_t *this, plugin_feature_t *features[]) 145: { 146: *features = this->features; 147: return this->count; 148: } 149: 150: METHOD(plugin_t, destroy, void, 151: private_curl_plugin_t *this) 152: { 153: curl_global_cleanup(); 154: free(this->features); 155: free(this); 156: } 157: 158: /* 159: * see header file 160: */ 161: plugin_t *curl_plugin_create() 162: { 163: CURLcode res; 164: private_curl_plugin_t *this; 165: 166: INIT(this, 167: .public = { 168: .plugin = { 169: .get_name = _get_name, 170: .get_features = _get_features, 171: .destroy = _destroy, 172: }, 173: }, 174: ); 175: 176: res = curl_global_init(CURL_GLOBAL_SSL); 177: if (res != CURLE_OK) 178: { 179: /* no SSL support? Try without */ 180: res = curl_global_init(CURL_GLOBAL_NOTHING); 181: } 182: if (res != CURLE_OK) 183: { 184: DBG1(DBG_LIB, "global libcurl initializing failed: %s", 185: curl_easy_strerror(res)); 186: destroy(this); 187: return NULL; 188: } 189: 190: if (!query_protocols(this)) 191: { 192: DBG1(DBG_LIB, "no usable CURL protocols found, curl disabled"); 193: destroy(this); 194: return NULL; 195: } 196: 197: return &this->public.plugin; 198: }