~drizzle-trunk/drizzle/development

974.2.1 by Mark Atwood
add auth_http plugin
1
/*
2
 -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
3
 *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
4
*/
5
6
#include <drizzled/server_includes.h>
7
#include <drizzled/session.h>
8
#include <drizzled/plugin/authentication.h>
9
#include <drizzled/gettext.h>
10
11
#include <curl/curl.h>
12
971.1.72 by Monty Taylor
Migrated Mark's new plugin to new plugin registration.
13
#include <string>
14
15
using namespace std;
974.2.1 by Mark Atwood
add auth_http plugin
16
17
static bool sysvar_auth_http_enable= false;
18
static char* sysvar_auth_http_url= NULL;
19
1085.1.2 by Monty Taylor
Fixed -Wmissing-declarations
20
static size_t curl_cb_read(void *ptr, size_t size, size_t nmemb, void *stream)
974.2.1 by Mark Atwood
add auth_http plugin
21
{
22
  (void) ptr;
23
  (void) stream;
24
  return (size * nmemb);
25
}
26
27
28
class Auth_http : public Authentication
29
{
971.1.72 by Monty Taylor
Migrated Mark's new plugin to new plugin registration.
30
  CURLcode rv;
31
  CURL *curl_handle;
974.2.1 by Mark Atwood
add auth_http plugin
32
public:
971.1.72 by Monty Taylor
Migrated Mark's new plugin to new plugin registration.
33
  Auth_http() : Authentication()
974.2.1 by Mark Atwood
add auth_http plugin
34
  {
971.1.72 by Monty Taylor
Migrated Mark's new plugin to new plugin registration.
35
    // we are trusting that plugin initializers are called singlethreaded at startup
36
    // if something else also calls curl_global_init() in a threadrace while we are here,
37
    // we will crash the server. 
38
    curl_handle= curl_easy_init();
974.2.1 by Mark Atwood
add auth_http plugin
39
40
    // turn off curl stuff that might mess us up
971.1.72 by Monty Taylor
Migrated Mark's new plugin to new plugin registration.
41
    rv= curl_easy_setopt(curl_handle, CURLOPT_VERBOSE, 0);
974.2.1 by Mark Atwood
add auth_http plugin
42
    rv= curl_easy_setopt(curl_handle, CURLOPT_NOPROGRESS, 1);
43
    rv= curl_easy_setopt(curl_handle, CURLOPT_NOSIGNAL, 1);
44
45
    // do a HEAD instead of a default GET
46
    rv= curl_easy_setopt(curl_handle, CURLOPT_NOBODY, 1);
47
48
    // set the read callback.  this shouldnt get called, because we are doing a HEAD
49
    rv= curl_easy_setopt(curl_handle, CURLOPT_READFUNCTION, curl_cb_read);
971.1.72 by Monty Taylor
Migrated Mark's new plugin to new plugin registration.
50
  }
51
52
  ~Auth_http()
53
  {
54
    curl_easy_cleanup(curl_handle);
55
  }
56
57
  virtual bool authenticate(Session *session, const char *password)
58
  {
59
    long http_response_code;
60
61
    if (sysvar_auth_http_enable == false)
62
      return true;
63
64
    assert(session->security_ctx.user.c_str());
65
    assert(password);
66
974.2.1 by Mark Atwood
add auth_http plugin
67
68
    // set the parameters: url, username, password
69
    rv= curl_easy_setopt(curl_handle, CURLOPT_URL, sysvar_auth_http_url);
971.1.72 by Monty Taylor
Migrated Mark's new plugin to new plugin registration.
70
#if defined(HAVE_CURLOPT_USERNAME)
71
72
    rv= curl_easy_setopt(curl_handle, CURLOPT_USERNAME,
73
                         session->security_ctx.user.c_str());
974.2.1 by Mark Atwood
add auth_http plugin
74
    rv= curl_easy_setopt(curl_handle, CURLOPT_PASSWORD, password);
75
971.1.72 by Monty Taylor
Migrated Mark's new plugin to new plugin registration.
76
#else
77
78
    string userpwd= session->security_ctx.user;
79
    userpwd.append(":");
80
    userpwd.append(password);
81
    rv= curl_easy_setopt(curl_handle, CURLOPT_USERPWD, userpwd.c_str());
82
83
#endif /* defined(HAVE_CURLOPT_USERNAME) */
84
974.2.1 by Mark Atwood
add auth_http plugin
85
    // do it
86
    rv= curl_easy_perform(curl_handle);
87
88
    // what did we get? goes into http_response_code
89
    rv= curl_easy_getinfo(curl_handle, CURLINFO_RESPONSE_CODE, &http_response_code);
90
91
    // so here is an interesting question.
92
    // return true if the response_code is 2XX, or return false if its 4XX
93
    // for now, return false for 401, true otherwise
94
    // this means that if the url breaks, then anyone can log in
95
    // this might be the wrong thing
96
97
    if (http_response_code == 401)
98
      return false;
99
    return true;
100
  }
101
};
102
971.1.72 by Monty Taylor
Migrated Mark's new plugin to new plugin registration.
103
Auth_http* auth= NULL;
104
105
static int initialize(PluginRegistry &registry)
974.2.1 by Mark Atwood
add auth_http plugin
106
{
1089.1.2 by Brian Aker
Rename work (cheery pick from new-cleanup). Jay's fix for auth_http. Update
107
  /* 
108
   * Per libcurl manual, in multi-threaded applications, curl_global_init() should
109
   * be called *before* curl_easy_init()...which is called in Auto_http's 
110
   * constructor.
111
   */
112
  if (curl_global_init(CURL_GLOBAL_NOTHING) != 0)
113
    return 1;
114
971.1.72 by Monty Taylor
Migrated Mark's new plugin to new plugin registration.
115
  auth= new Auth_http();
116
  registry.add(auth);
974.2.1 by Mark Atwood
add auth_http plugin
117
118
  return 0;
119
}
120
971.1.72 by Monty Taylor
Migrated Mark's new plugin to new plugin registration.
121
static int finalize(PluginRegistry &registry)
974.2.1 by Mark Atwood
add auth_http plugin
122
{
123
  if (auth)
971.1.72 by Monty Taylor
Migrated Mark's new plugin to new plugin registration.
124
  {
125
    registry.remove(auth);
974.2.1 by Mark Atwood
add auth_http plugin
126
    delete auth;
1089.1.2 by Brian Aker
Rename work (cheery pick from new-cleanup). Jay's fix for auth_http. Update
127
128
    curl_global_cleanup();
971.1.72 by Monty Taylor
Migrated Mark's new plugin to new plugin registration.
129
  }
974.2.1 by Mark Atwood
add auth_http plugin
130
131
  return 0;
132
}
133
134
static DRIZZLE_SYSVAR_BOOL(
135
  enable,
136
  sysvar_auth_http_enable,
137
  PLUGIN_VAR_NOCMDARG,
138
  N_("Enable HTTP Auth check"),
139
  NULL, /* check func */
140
  NULL, /* update func */
141
  false /* default */);
142
143
144
static DRIZZLE_SYSVAR_STR(
145
  url,
146
  sysvar_auth_http_url,
147
  PLUGIN_VAR_READONLY,
148
  N_("URL for HTTP Auth check"),
149
  NULL, /* check func */
150
  NULL, /* update func*/
151
  "http://localhost/" /* default */);
152
153
static struct st_mysql_sys_var* auth_http_system_variables[]= {
154
  DRIZZLE_SYSVAR(enable),
155
  DRIZZLE_SYSVAR(url),
156
  NULL
157
};
158
159
160
drizzle_declare_plugin(auth_http)
161
{
162
  "auth_http",
163
  "0.1",
164
  "Mark Atwood",
971.1.76 by Monty Taylor
Fixed a comment string.
165
  "HTTP based authenication.",
974.2.1 by Mark Atwood
add auth_http plugin
166
  PLUGIN_LICENSE_GPL,
167
  initialize, /* Plugin Init */
168
  finalize, /* Plugin Deinit */
169
  NULL,   /* status variables */
170
  auth_http_system_variables,
171
  NULL    /* config options */
172
}
173
drizzle_declare_plugin_end;