00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <config.h>
00021
00022 #include <curl/curl.h>
00023
00024 #include <string>
00025 #include <cassert>
00026 #include <boost/program_options.hpp>
00027 #include <drizzled/module/option_map.h>
00028 #include <drizzled/identifier.h>
00029 #include <drizzled/plugin/authentication.h>
00030 #include <drizzled/gettext.h>
00031 namespace po= boost::program_options;
00032 using namespace drizzled;
00033 using namespace std;
00034
00035 static size_t curl_cb_read(void *ptr, size_t size, size_t nmemb, void *stream)
00036 {
00037 (void) ptr;
00038 (void) stream;
00039 return (size * nmemb);
00040 }
00041
00042
00043 class Auth_http : public drizzled::plugin::Authentication
00044 {
00045 CURLcode rv;
00046 CURL *curl_handle;
00047 const std::string auth_url;
00048 public:
00049 Auth_http(std::string name_arg, const std::string &url_arg) :
00050 drizzled::plugin::Authentication(name_arg),
00051 auth_url(url_arg)
00052 {
00053
00054
00055
00056 curl_handle= curl_easy_init();
00057
00058
00059 rv= curl_easy_setopt(curl_handle, CURLOPT_VERBOSE, 0);
00060 rv= curl_easy_setopt(curl_handle, CURLOPT_NOPROGRESS, 1);
00061 rv= curl_easy_setopt(curl_handle, CURLOPT_NOSIGNAL, 1);
00062
00063
00064 rv= curl_easy_setopt(curl_handle, CURLOPT_NOBODY, 1);
00065
00066
00067 rv= curl_easy_setopt(curl_handle, CURLOPT_READFUNCTION, curl_cb_read);
00068 }
00069
00070 ~Auth_http()
00071 {
00072 curl_easy_cleanup(curl_handle);
00073 curl_global_cleanup();
00074 }
00075
00076 virtual bool authenticate(const identifier::User &sctx, const string &password)
00077 {
00078 long http_response_code;
00079
00080 assert(sctx.username().c_str());
00081
00082
00083 rv= curl_easy_setopt(curl_handle, CURLOPT_URL, auth_url.c_str());
00084 #if defined(HAVE_CURLOPT_USERNAME)
00085
00086 rv= curl_easy_setopt(curl_handle, CURLOPT_USERNAME,
00087 sctx.username().c_str());
00088 rv= curl_easy_setopt(curl_handle, CURLOPT_PASSWORD, password.c_str());
00089
00090 #else
00091
00092 string userpwd(sctx.username());
00093 userpwd.append(":");
00094 userpwd.append(password);
00095 rv= curl_easy_setopt(curl_handle, CURLOPT_USERPWD, userpwd.c_str());
00096
00097 #endif
00098
00099
00100 rv= curl_easy_perform(curl_handle);
00101
00102
00103 rv= curl_easy_getinfo(curl_handle, CURLINFO_RESPONSE_CODE, &http_response_code);
00104
00105
00106
00107
00108
00109
00110
00111 if (http_response_code == 401)
00112 return false;
00113 return true;
00114 }
00115 };
00116
00117 Auth_http* auth= NULL;
00118
00119 static int initialize(drizzled::module::Context &context)
00120 {
00121 const module::option_map &vm= context.getOptions();
00122
00123
00124
00125
00126
00127
00128 if (curl_global_init(CURL_GLOBAL_NOTHING) != 0)
00129 return 1;
00130
00131 const string auth_url(vm["url"].as<string>());
00132 if (auth_url.size() == 0)
00133 {
00134 errmsg_printf(error::ERROR,
00135 _("auth_http plugin loaded but required option url not "
00136 "specified. Against which URL are you intending on "
00137 "authenticating?\n"));
00138 return 1;
00139 }
00140
00141 auth= new Auth_http("auth_http", auth_url);
00142 context.add(auth);
00143 context.registerVariable(new sys_var_const_string_val("url", auth_url));
00144
00145 return 0;
00146 }
00147
00148 static void init_options(drizzled::module::option_context &context)
00149 {
00150 context("url", po::value<string>()->default_value(""),
00151 N_("URL for HTTP Auth check"));
00152 }
00153
00154
00155 DRIZZLE_DECLARE_PLUGIN
00156 {
00157 DRIZZLE_VERSION_ID,
00158 "auth-http",
00159 "0.1",
00160 "Mark Atwood",
00161 "HTTP based authenication.",
00162 PLUGIN_LICENSE_GPL,
00163 initialize,
00164 NULL,
00165 init_options
00166 }
00167 DRIZZLE_DECLARE_PLUGIN_END;