Statistics
| Branch: | Tag: | Revision:

one / src / authm / AuthManager.cc @ bfaabf35

History | View | Annotate | Download (11.1 KB)

1
/* -------------------------------------------------------------------------- */
2
/* Copyright 2002-2011, OpenNebula Project Leads (OpenNebula.org)             */
3
/*                                                                            */
4
/* Licensed under the Apache License, Version 2.0 (the "License"); you may    */
5
/* not use this file except in compliance with the License. You may obtain    */
6
/* a copy of the License at                                                   */
7
/*                                                                            */
8
/* http://www.apache.org/licenses/LICENSE-2.0                                 */
9
/*                                                                            */
10
/* Unless required by applicable law or agreed to in writing, software        */
11
/* distributed under the License is distributed on an "AS IS" BASIS,          */
12
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   */
13
/* See the License for the specific language governing permissions and        */
14
/* limitations under the License.                                             */
15
/* -------------------------------------------------------------------------- */
16

    
17
#include "AuthManager.h"
18
#include "NebulaLog.h"
19
#include "SSLTools.h"
20

    
21
#include "Nebula.h"
22

    
23
/* -------------------------------------------------------------------------- */
24
/* -------------------------------------------------------------------------- */
25

    
26
time_t AuthManager::_time_out;
27

    
28
const char * AuthManager::auth_driver_name = "auth_exe";
29

    
30
/* -------------------------------------------------------------------------- */
31
/* -------------------------------------------------------------------------- */
32

    
33
void AuthRequest::add_auth(Object        ob,
34
                           const string& ob_id,
35
                           Operation     op,
36
                           int           owner,
37
                           bool          pub)
38
{
39
    ostringstream oss;
40
    bool          auth;
41

    
42
    oss << Object_to_str(ob) << ":";
43

    
44
    if (op == CREATE || op == INSTANTIATE) //encode the ob_id, it is a template
45
    {
46
        string * encoded_id = SSLTools::base64_encode(ob_id);
47

    
48
        if (encoded_id != 0)
49
        {
50
            oss << *encoded_id << ":";
51
            delete (encoded_id);
52
        }
53
        else
54
        {
55
            oss << "-:";
56
        }
57
    }
58
    else
59
    {
60
        oss << ob_id << ":";
61
    }
62

    
63
    oss << Operation_to_str(op) << ":";
64

    
65
    oss << owner << ":" << pub;
66

    
67
    // -------------------------------------------------------------------------
68
    // Authorize the request for self authorization
69
    // -------------------------------------------------------------------------
70

    
71
    if ( uid == 0 )
72
    {
73
        auth = true;
74
    }
75
    else
76
    {
77
        // TODO, the set of object ids is needed
78
        set<int> emtpy_set;
79

    
80
        int         ob_gid = 0;
81

    
82
        istringstream iss(ob_id);
83
        int ob_id_int;
84

    
85
        iss >> ob_id_int;
86

    
87
        Nebula&     nd   = Nebula::instance();
88
        AclManager* aclm = nd.get_aclm();
89

    
90
        auth = aclm->authorize(uid, emtpy_set, ob, ob_id_int, ob_gid, op);
91
    }
92

    
93
    self_authorize = self_authorize && auth;
94

    
95
    auths.push_back(oss.str());
96
}
97

    
98
/* -------------------------------------------------------------------------- */
99
/* -------------------------------------------------------------------------- */
100

    
101
extern "C" void * authm_action_loop(void *arg)
102
{
103
    AuthManager *  authm;
104

    
105
    if ( arg == 0 )
106
    {
107
        return 0;
108
    }
109

    
110
    authm = static_cast<AuthManager *>(arg);
111

    
112
    NebulaLog::log("AuM",Log::INFO,"Authorization Manager started.");
113

    
114
    authm->am.loop(authm->timer_period,0);
115

    
116
    NebulaLog::log("AuM",Log::INFO,"Authorization Manager stopped.");
117

    
118
    return 0;
119
}
120

    
121
/* -------------------------------------------------------------------------- */
122

    
123
int AuthManager::start()
124
{
125
    int               rc;
126
    pthread_attr_t    pattr;
127

    
128
    rc = MadManager::start();
129

    
130
    if ( rc != 0 )
131
    {
132
        return -1;
133
    }
134

    
135
    NebulaLog::log("AuM",Log::INFO,"Starting Auth Manager...");
136

    
137
    pthread_attr_init (&pattr);
138
    pthread_attr_setdetachstate (&pattr, PTHREAD_CREATE_JOINABLE);
139

    
140
    rc = pthread_create(&authm_thread,&pattr,authm_action_loop,(void *) this);
141

    
142
    return rc;
143
}
144

    
145
/* -------------------------------------------------------------------------- */
146
/* -------------------------------------------------------------------------- */
147

    
148
void AuthManager::trigger(Actions action, AuthRequest * request)
149
{
150
    string  aname;
151

    
152
    switch (action)
153
    {
154
    case AUTHENTICATE:
155
        aname = "AUTHENTICATE";
156
        break;
157

    
158
    case AUTHORIZE:
159
        aname = "AUTHORIZE";
160
        break;
161

    
162
    case FINALIZE:
163
        aname = ACTION_FINALIZE;
164
        break;
165

    
166
    default:
167
        return;
168
    }
169

    
170
    am.trigger(aname,request);
171
}
172

    
173
/* -------------------------------------------------------------------------- */
174
/* -------------------------------------------------------------------------- */
175

    
176
void AuthManager::do_action(const string &action, void * arg)
177
{
178
    AuthRequest * request;
179

    
180
    request  = static_cast<AuthRequest *>(arg);
181

    
182
    if (action == "AUTHENTICATE" && request != 0)
183
    {
184
        authenticate_action(request);
185
    }
186
    else if (action == "AUTHORIZE"  && request != 0)
187
    {
188
        authorize_action(request);
189
    }
190
    else if (action == ACTION_TIMER)
191
    {
192
        timer_action();
193
    }
194
    else if (action == ACTION_FINALIZE)
195
    {
196
        NebulaLog::log("AuM",Log::INFO,"Stopping Authorization Manager...");
197

    
198
        MadManager::stop();
199
    }
200
    else
201
    {
202
        ostringstream oss;
203
        oss << "Unknown action name: " << action;
204

    
205
        NebulaLog::log("AuM", Log::ERROR, oss);
206
    }
207
}
208

    
209
/* -------------------------------------------------------------------------- */
210
/* -------------------------------------------------------------------------- */
211

    
212
void AuthManager::authenticate_action(AuthRequest * ar)
213
{
214
    const AuthManagerDriver * authm_md;
215

    
216
    // ------------------------------------------------------------------------
217
    // Get the driver
218
    // ------------------------------------------------------------------------
219

    
220
    authm_md = get();
221

    
222
    if (authm_md == 0)
223
    {
224
        goto error_driver;
225
    }
226

    
227
    // ------------------------------------------------------------------------
228
    // Queue the request
229
    // ------------------------------------------------------------------------
230

    
231
    ar->id = add_request(ar);
232

    
233
    // ------------------------------------------------------------------------
234
    // Make the request to the driver
235
    // ---- --------------------------------------------------------------------
236

    
237

    
238
    authm_md->authenticate(ar->id,
239
                           ar->uid,
240
                           ar->username,
241
                           ar->password,
242
                           ar->session);
243
    return;
244

    
245
error_driver:
246
    ar->result  = false;
247
    ar->message = "Could not find Authorization driver";
248
    ar->notify();
249
}
250

    
251
/* -------------------------------------------------------------------------- */
252
/* -------------------------------------------------------------------------- */
253

    
254
void AuthManager::authorize_action(AuthRequest * ar)
255
{
256
    const AuthManagerDriver * authm_md;
257
    string auths;
258

    
259
    // ------------------------------------------------------------------------
260
    // Get the driver
261
    // ------------------------------------------------------------------------
262

    
263
    authm_md = get();
264

    
265
    if (authm_md == 0)
266
    {
267
        goto error_driver;
268
    }
269

    
270
    // ------------------------------------------------------------------------
271
    // Queue the request
272
    // ------------------------------------------------------------------------
273

    
274
    ar->id = add_request(ar);
275

    
276
    // ------------------------------------------------------------------------
277
    // Make the request to the driver
278
    // ------------------------------------------------------------------------
279

    
280
    auths = ar->get_auths();
281

    
282
    authm_md->authorize(ar->id, ar->uid, auths);
283

    
284
    return;
285

    
286
error_driver:
287
    ar->result  = false;
288
    ar->message = "Could not find Authorization driver";
289
    ar->notify();
290
}
291
/* -------------------------------------------------------------------------- */
292
/* -------------------------------------------------------------------------- */
293

    
294
void AuthManager::timer_action()
295
{
296
    map<int,AuthRequest *>::iterator it;
297

    
298
    time_t the_time = time(0);
299

    
300
    lock();
301

    
302
    it = auth_requests.begin();
303

    
304
    while ( it !=auth_requests.end())
305
    {
306
        if (the_time > it->second->time_out)
307
        {
308
            AuthRequest * ar = it->second;
309
            auth_requests.erase(it++);
310

    
311
            ar->result  = false;
312
            ar->timeout = true;
313
            ar->message = "Auth request timeout";
314

    
315
            ar->notify();
316
        }
317
        else
318
        {
319
            ++it;
320
        }
321
    }
322

    
323
    unlock();
324

    
325
}
326

    
327
/* -------------------------------------------------------------------------- */
328
/* -------------------------------------------------------------------------- */
329

    
330
int AuthManager::add_request(AuthRequest *ar)
331
{
332
    static int auth_id = 0;
333
    int id;
334

    
335
    lock();
336

    
337
    id = auth_id++;
338

    
339
    auth_requests.insert(auth_requests.end(),make_pair(id,ar));
340

    
341
    unlock();
342

    
343
    return id;
344
}
345

    
346
/* -------------------------------------------------------------------------- */
347
/* -------------------------------------------------------------------------- */
348

    
349
AuthRequest * AuthManager::get_request(int id)
350
{
351
    AuthRequest * ar = 0;
352
    map<int,AuthRequest *>::iterator it;
353
    ostringstream oss;
354

    
355
    lock();
356

    
357
    it=auth_requests.find(id);
358

    
359
    if ( it != auth_requests.end())
360
    {
361
        ar = it->second;
362

    
363
        auth_requests.erase(it);
364
    }
365

    
366
    unlock();
367

    
368
    return ar;
369
}
370

    
371
/* -------------------------------------------------------------------------- */
372
/* -------------------------------------------------------------------------- */
373

    
374
void AuthManager::notify_request(int auth_id,bool result,const string& message)
375
{
376

    
377
    AuthRequest * ar;
378

    
379
    ar = get_request(auth_id);
380

    
381
    if ( ar == 0 )
382
    {
383
        return;
384
    }
385

    
386
    ar->result = result;
387
    ar->message= message;
388

    
389
    ar->notify();
390
}
391

    
392
/* ************************************************************************** */
393
/* MAD Loading                                                                */
394
/* ************************************************************************** */
395

    
396
void AuthManager::load_mads(int uid)
397
{
398
    ostringstream                   oss;
399
    const VectorAttribute *         vattr;
400
    int                             rc;
401
    string                          name;
402
    AuthManagerDriver *             authm_driver = 0;
403

    
404
    oss << "Loading Auth. Manager driver.";
405

    
406
    NebulaLog::log("AuM",Log::INFO,oss);
407

    
408
    vattr = static_cast<const VectorAttribute *>(mad_conf[0]);
409

    
410
    if ( vattr == 0 )
411
    {
412
        NebulaLog::log("AuM",Log::ERROR,"Failed to load Auth. Manager driver.");
413
        return;
414
    }
415

    
416
    VectorAttribute auth_conf("AUTH_MAD",vattr->value());
417

    
418
    auth_conf.replace("NAME",auth_driver_name);
419

    
420
    authm_driver = new AuthManagerDriver(uid,auth_conf.value(),(uid!=0),this);
421

    
422
    rc = add(authm_driver);
423

    
424
    if ( rc == 0 )
425
    {
426
        oss.str("");
427
        oss << "\tAuth Manager loaded";
428

    
429
        NebulaLog::log("AuM",Log::INFO,oss);
430
    }
431
}