~yolanda.robla/ubuntu/saucy/freeradius/dep-8-tests

« back to all changes in this revision

Viewing changes to src/main/auth.c

  • Committer: Bazaar Package Importer
  • Author(s): Josip Rodin
  • Date: 2009-11-23 03:57:37 UTC
  • mto: This revision was merged to the branch mainline in revision 7.
  • Revision ID: james.westby@ubuntu.com-20091123035737-snauioz5r9tf8sdr
Tags: upstream-2.1.7+dfsg
ImportĀ upstreamĀ versionĀ 2.1.7+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
2
 * auth.c       User authentication.
3
3
 *
4
 
 * Version:     $Id: auth.c,v 1.178 2008/04/18 09:29:49 aland Exp $
 
4
 * Version:     $Id$
5
5
 *
6
6
 *   This program is free software; you can redistribute it and/or modify
7
7
 *   it under the terms of the GNU General Public License as published by
23
23
 */
24
24
 
25
25
#include <freeradius-devel/ident.h>
26
 
RCSID("$Id: auth.c,v 1.178 2008/04/18 09:29:49 aland Exp $")
 
26
RCSID("$Id$")
27
27
 
28
28
#include <freeradius-devel/radiusd.h>
29
29
#include <freeradius-devel/modules.h>
60
60
 * Make sure user/pass are clean
61
61
 * and then log them
62
62
 */
63
 
static int rad_authlog(const char *msg, REQUEST *request, int goodpass) {
64
 
 
 
63
static int rad_authlog(const char *msg, REQUEST *request, int goodpass)
 
64
{
 
65
        int logit;
 
66
        const char *extra_msg = NULL;
65
67
        char clean_password[1024];
66
68
        char clean_username[1024];
67
69
        char buf[1024];
 
70
        char extra[1024];
68
71
        VALUE_PAIR *username = NULL;
69
72
 
70
73
        if (!request->root->log_auth) {
86
89
        if (username == NULL) {
87
90
                strcpy(clean_username, "<no User-Name attribute>");
88
91
        } else {
89
 
                librad_safeprint((char *)username->vp_strvalue,
 
92
                fr_print_string((char *)username->vp_strvalue,
90
93
                                username->length,
91
94
                                clean_username, sizeof(clean_username));
92
95
        }
110
113
                } else if (pairfind(request->packet->vps, PW_CHAP_PASSWORD)) {
111
114
                        strcpy(clean_password, "<CHAP-Password>");
112
115
                } else {
113
 
                        librad_safeprint((char *)request->password->vp_strvalue,
 
116
                        fr_print_string((char *)request->password->vp_strvalue,
114
117
                                         request->password->length,
115
118
                                         clean_password, sizeof(clean_password));
116
119
                }
117
120
        }
118
121
 
119
122
        if (goodpass) {
120
 
                radlog(L_AUTH, "%s: [%s%s%s] (%s)",
121
 
                                msg,
122
 
                                clean_username,
123
 
                                request->root->log_auth_goodpass ? "/" : "",
124
 
                                request->root->log_auth_goodpass ? clean_password : "",
125
 
                                auth_name(buf, sizeof(buf), request, 1));
126
 
        } else {
127
 
                radlog(L_AUTH, "%s: [%s%s%s] (%s)",
128
 
                                msg,
129
 
                                clean_username,
130
 
                                request->root->log_auth_badpass ? "/" : "",
131
 
                                request->root->log_auth_badpass ? clean_password : "",
132
 
                                auth_name(buf, sizeof(buf), request, 1));
133
 
        }
 
123
                logit = request->root->log_auth_goodpass;
 
124
                extra_msg = request->root->auth_goodpass_msg;
 
125
        } else {
 
126
                logit = request->root->log_auth_badpass;
 
127
                extra_msg = request->root->auth_badpass_msg;
 
128
        }
 
129
 
 
130
        if (extra_msg) {
 
131
                extra[0] = ' ';
 
132
                radius_xlat(extra + 1, sizeof(extra) - 1, extra_msg, request,
 
133
                            NULL);
 
134
        } else {
 
135
                *extra = '\0';
 
136
        }
 
137
 
 
138
        radlog_request(L_AUTH, 0, request, "%s: [%s%s%s] (%s)%s",
 
139
                       msg,
 
140
                       clean_username,
 
141
                       logit ? "/" : "",
 
142
                       logit ? clean_password : "",
 
143
                       auth_name(buf, sizeof(buf), request, 1),
 
144
                       extra);
134
145
 
135
146
        return 0;
136
147
}
166
177
        while(((auth_type_pair = pairfind(cur_config_item, PW_AUTH_TYPE))) != NULL) {
167
178
                auth_type = auth_type_pair->vp_integer;
168
179
                auth_type_count++;
 
180
                DICT_VALUE *dv = dict_valbyattr(auth_type_pair->attribute,
 
181
                                                auth_type_pair->vp_integer);
169
182
 
170
 
                DEBUG2("  rad_check_password:  Found Auth-Type %s",
171
 
                                auth_type_pair->vp_strvalue);
 
183
                RDEBUG2("Found Auth-Type = %s",
 
184
                        (dv != NULL) ? dv->name : "?");
172
185
                cur_config_item = auth_type_pair->next;
173
186
 
174
187
                if (auth_type == PW_AUTHTYPE_REJECT) {
175
 
                        DEBUG2("  rad_check_password: Auth-Type = Reject, rejecting user");
 
188
                        RDEBUG2("Auth-Type = Reject, rejecting user");
176
189
                        return -2;
177
190
                }
178
191
        }
179
192
 
180
193
        if (( auth_type_count > 1) && (debug_flag)) {
181
 
                radlog(L_ERR, "Warning:  Found %d auth-types on request for user '%s'",
 
194
                radlog_request(L_ERR, 0, request, "Warning:  Found %d auth-types on request for user '%s'",
182
195
                        auth_type_count, request->username->vp_strvalue);
183
196
        }
184
197
 
188
201
         *  that means it is accepted and we do no further
189
202
         *  authentication
190
203
         */
191
 
        if ((auth_type == PW_AUTHTYPE_ACCEPT) || (request->proxy)) {
192
 
                DEBUG2("  rad_check_password: Auth-Type = Accept, accepting the user");
 
204
        if ((auth_type == PW_AUTHTYPE_ACCEPT)
 
205
#ifdef WITH_PROXY
 
206
            || (request->proxy)
 
207
#endif
 
208
            ) {
 
209
                RDEBUG2("Auth-Type = Accept, accepting the user");
193
210
                return 0;
194
211
        }
195
212
 
203
220
        if (password_pair) {
204
221
                DICT_ATTR *da;
205
222
 
206
 
                DEBUG("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
207
 
                DEBUG("!!!    Replacing User-Password in config items with Cleartext-Password.     !!!");
208
 
                DEBUG("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
209
 
                DEBUG("!!! Please update your configuration so that the \"known good\"               !!!");
210
 
                DEBUG("!!! clear text password is in Cleartext-Password, and not in User-Password. !!!");
211
 
                DEBUG("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
 
223
                RDEBUG("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
 
224
                RDEBUG("!!!    Replacing User-Password in config items with Cleartext-Password.     !!!");
 
225
                RDEBUG("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
 
226
                RDEBUG("!!! Please update your configuration so that the \"known good\"               !!!");
 
227
                RDEBUG("!!! clear text password is in Cleartext-Password, and not in User-Password. !!!");
 
228
                RDEBUG("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
212
229
                password_pair->attribute = PW_CLEARTEXT_PASSWORD;
213
230
                da = dict_attrbyvalue(PW_CLEARTEXT_PASSWORD);
214
231
                if (!da) {
215
 
                        radlog(L_ERR, "FATAL: You broke the dictionaries.  Please use the default dictionaries!");
 
232
                        radlog_request(L_ERR, 0, request, "FATAL: You broke the dictionaries.  Please use the default dictionaries!");
216
233
                        _exit(1);
217
234
                }
218
235
 
245
262
                        *
246
263
                        *       This is fail-safe.
247
264
                        */
248
 
                        DEBUG2("auth: No authenticate method (Auth-Type) configuration found for the request: Rejecting the user");
 
265
                        RDEBUG2("No authenticate method (Auth-Type) configuration found for the request: Rejecting the user");
249
266
                        return -2;
250
267
                }
251
268
        }
252
269
 
253
270
        switch(auth_type) {
254
 
                DICT_VALUE *dval;
255
 
 
256
271
                case PW_AUTHTYPE_CRYPT:
 
272
                        RDEBUG2("WARNING: Please update your configuration, and remove 'Auth-Type = Crypt'");
 
273
                        RDEBUG2("WARNING: Use the PAP module instead.");
 
274
 
257
275
                        /*
258
276
                         *      Find the password sent by the user. It
259
277
                         *      SHOULD be there, if it's not
261
279
                         */
262
280
                        auth_item = request->password;
263
281
                        if (auth_item == NULL) {
264
 
                                DEBUG2("auth: No User-Password or CHAP-Password attribute in the request");
 
282
                                RDEBUG2("No User-Password or CHAP-Password attribute in the request");
265
283
                                return -1;
266
284
                        }
267
285
 
268
 
                        DEBUG2("auth: type Crypt");
269
286
                        if (password_pair == NULL) {
270
 
                                DEBUG2("No Crypt-Password configured for the user");
 
287
                                RDEBUG2("No Crypt-Password configured for the user");
271
288
                                rad_authlog("Login incorrect "
272
289
                                        "(No Crypt-Password configured for the user)", request, 0);
273
290
                                return -1;
283
300
                        }
284
301
                        break;
285
302
                case PW_AUTHTYPE_LOCAL:
286
 
                        DEBUG2("auth: type Local");
 
303
                        RDEBUG2("WARNING: Please update your configuration, and remove 'Auth-Type = Local'");
 
304
                        RDEBUG2("WARNING: Use the PAP or CHAP modules instead.");
287
305
 
288
306
                        /*
289
307
                         *      Find the password sent by the user. It
295
313
                                auth_item = pairfind(request->packet->vps,
296
314
                                                     PW_CHAP_PASSWORD);
297
315
                        if (!auth_item) {
298
 
                                DEBUG2("auth: No User-Password or CHAP-Password attribute in the request");
 
316
                                RDEBUG2("No User-Password or CHAP-Password attribute in the request.");
 
317
                                RDEBUG2("Cannot perform authentication.");
299
318
                                return -1;
300
319
                        }
301
320
 
303
322
                         *      Plain text password.
304
323
                         */
305
324
                        if (password_pair == NULL) {
306
 
                                DEBUG2("auth: No password configured for the user");
 
325
                                RDEBUG2("No \"known good\" password was configured for the user.");
 
326
                                RDEBUG2("As a result, we cannot authenticate the user.");
307
327
                                rad_authlog("Login incorrect "
308
328
                                        "(No password configured for the user)", request, 0);
309
329
                                return -1;
315
335
                        if (auth_item->attribute == PW_USER_PASSWORD) {
316
336
                                if (strcmp((char *)password_pair->vp_strvalue,
317
337
                                           (char *)auth_item->vp_strvalue) != 0) {
318
 
                                        DEBUG2("auth: user supplied User-Password does NOT match local User-Password");
 
338
                                        RDEBUG2("User-Password in the request does NOT match \"known good\" password.");
319
339
                                        return -1;
320
340
                                }
321
 
                                DEBUG2("auth: user supplied User-Password matches local User-Password");
 
341
                                RDEBUG2("User-Password in the request is correct.");
322
342
                                break;
323
343
 
324
344
                        } else if (auth_item->attribute != PW_CHAP_PASSWORD) {
325
 
                                DEBUG2("The user did not supply a User-Password or a CHAP-Password attribute");
 
345
                                RDEBUG2("The user did not supply a User-Password or a CHAP-Password attribute");
326
346
                                rad_authlog("Login incorrect "
327
347
                                        "(no User-Password or CHAP-Password attribute)", request, 0);
328
348
                                return -1;
336
356
                         */
337
357
                        if (memcmp(my_chap + 1, auth_item->vp_strvalue + 1,
338
358
                                   CHAP_VALUE_LENGTH) != 0) {
339
 
                                DEBUG2("auth: user supplied CHAP-Password does NOT match local User-Password");
 
359
                                RDEBUG2("CHAP-Password is incorrect.");
340
360
                                return -1;
341
361
                        }
342
 
                        DEBUG2("auth: user supplied CHAP-Password matches local User-Password");
 
362
                        RDEBUG2("CHAP-Password is correct.");
343
363
                        break;
344
364
                default:
345
 
                        dval = dict_valbyattr(PW_AUTH_TYPE, auth_type);
346
 
                        if (dval) {
347
 
                                DEBUG2("auth: type \"%s\"", dval->name);
348
 
                        } else {
349
 
                                DEBUG2("auth: type UNKNOWN-%d", auth_type);
350
 
                        }
351
 
 
352
365
                        /*
353
366
                         *      See if there is a module that handles
354
367
                         *      this type, and turn the RLM_ return
402
415
         */
403
416
        vp = pairfind(request->config_items, PW_POST_AUTH_TYPE);
404
417
        if (vp) {
405
 
                DEBUG2("  Found Post-Auth-Type %s", vp->vp_strvalue);
 
418
                RDEBUG2("Using Post-Auth-Type %s", vp->vp_strvalue);
406
419
                postauth_type = vp->vp_integer;
407
420
        }
408
421
        result = module_post_auth(postauth_type, request);
446
459
int rad_authenticate(REQUEST *request)
447
460
{
448
461
        VALUE_PAIR      *namepair;
 
462
#ifdef WITH_SESSION_MGMT
449
463
        VALUE_PAIR      *check_item;
450
 
        VALUE_PAIR      *auth_item;
 
464
#endif
 
465
        VALUE_PAIR      *auth_item = NULL;
451
466
        VALUE_PAIR      *module_msg;
452
467
        VALUE_PAIR      *tmp = NULL;
453
468
        int             result;
454
 
        char            umsg[MAX_STRING_LEN + 1];
455
 
        const char      *user_msg = NULL;
456
469
        const char      *password;
457
 
        char            logstr[1024];
458
470
        char            autz_retry = 0;
459
471
        int             autz_type = 0;
460
472
 
461
473
        password = "";
462
474
 
 
475
#ifdef WITH_PROXY
463
476
        /*
464
477
         *      If this request got proxied to another server, we need
465
478
         *      to check whether it authenticated the request or not.
475
488
                                                &request->config_items,
476
489
                                                PW_AUTH_TYPE, PW_TYPE_INTEGER);
477
490
                        if (tmp) tmp->vp_integer = PW_AUTHTYPE_ACCEPT;
478
 
                        break;
 
491
                        goto authenticate;
 
492
 
479
493
                /*
480
494
                 *      Challenges are punted back to the NAS without any
481
495
                 *      further processing.
491
505
                 *      done by the server, by rejecting them here.
492
506
                 */
493
507
                case PW_AUTHENTICATION_REJECT:
494
 
                default:
495
508
                        rad_authlog("Login incorrect (Home Server says so)",
496
509
                                    request, 0);
497
510
                        request->reply->code = PW_AUTHENTICATION_REJECT;
498
511
                        return RLM_MODULE_REJECT;
 
512
 
 
513
                default:
 
514
                        rad_authlog("Login incorrect (Home Server failed to respond)",
 
515
                                    request, 0);
 
516
                        return RLM_MODULE_REJECT;
499
517
                }
500
518
        }
 
519
#endif
501
520
 
502
521
        /*
503
522
         *      Get the username from the request.
572
591
        if (!autz_retry) {
573
592
                tmp = pairfind(request->config_items, PW_AUTZ_TYPE);
574
593
                if (tmp) {
575
 
                        DEBUG2("  Found Autz-Type %s", tmp->vp_strvalue);
 
594
                        RDEBUG2("Using Autz-Type %s", tmp->vp_strvalue);
576
595
                        autz_type = tmp->vp_integer;
577
596
                        autz_retry = 1;
578
597
                        goto autz_redo;
585
604
         *      modules has decided that a proxy should be used. If
586
605
         *      so, get out of here and send the packet.
587
606
         */
588
 
        if ((request->proxy == NULL) &&
 
607
        if (
 
608
#ifdef WITH_PROXY
 
609
            (request->proxy == NULL) &&
 
610
#endif
589
611
            ((tmp = pairfind(request->config_items, PW_PROXY_TO_REALM)) != NULL)) {
590
612
                REALM *realm;
591
613
 
605
627
                 *      *the* LOCAL realm.
606
628
                 */
607
629
                if (realm &&(strcmp(realm->name, "LOCAL") != 0)) {
608
 
                        DEBUG2("  WARNING: You set Proxy-To-Realm = %s, but it is a LOCAL realm!  Cancelling invalid proxy request.", realm->name);
 
630
                        RDEBUG2("WARNING: You set Proxy-To-Realm = %s, but it is a LOCAL realm!  Cancelling proxy request.", realm->name);
609
631
                }
610
632
 
611
633
                if (!realm) {
612
 
                        DEBUG2("  WARNING: You set Proxy-To-Realm = %s, but the realm does not exist!  Cancelling invalid proxy request.", tmp->vp_strvalue);
 
634
                        RDEBUG2("WARNING: You set Proxy-To-Realm = %s, but the realm does not exist!  Cancelling invalid proxy request.", tmp->vp_strvalue);
613
635
                }
614
636
        }
615
637
 
 
638
#ifdef WITH_PROXY
 
639
 authenticate:
 
640
#endif
 
641
 
616
642
        /*
617
643
         *      Perhaps there is a Stripped-User-Name now.
618
644
         */
637
663
         *      wants to send back.
638
664
         */
639
665
        if (result < 0) {
640
 
                DEBUG2("auth: Failed to validate the user.");
 
666
                RDEBUG2("Failed to authenticate the user.");
641
667
                request->reply->code = PW_AUTHENTICATION_REJECT;
642
668
 
643
669
                if ((module_msg = pairfind(request->packet->vps,PW_MODULE_FAILURE_MESSAGE)) != NULL){
666
692
                }
667
693
        }
668
694
 
 
695
#ifdef WITH_SESSION_MGMT
669
696
        if (result >= 0 &&
670
697
            (check_item = pairfind(request->config_items, PW_SIMULTANEOUS_USE)) != NULL) {
671
698
                int r, session_type = 0;
 
699
                char            logstr[1024];
 
700
                char            umsg[MAX_STRING_LEN + 1];
 
701
                const char      *user_msg = NULL;
672
702
 
673
703
                tmp = pairfind(request->config_items, PW_SESSION_TYPE);
674
704
                if (tmp) {
675
 
                        DEBUG2("  Found Session-Type %s", tmp->vp_strvalue);
 
705
                        RDEBUG2("Using Session-Type %s", tmp->vp_strvalue);
676
706
                        session_type = tmp->vp_integer;
677
707
                }
678
708
 
690
720
 
691
721
                                if ((port_limit = pairfind(request->reply->vps, PW_PORT_LIMIT)) != NULL &&
692
722
                                        port_limit->vp_integer > check_item->vp_integer){
693
 
                                        DEBUG2("main auth: MPP is OK");
 
723
                                        RDEBUG2("MPP is OK");
694
724
                                        mpp_ok = 1;
695
725
                                }
696
726
                        }
724
754
                        }
725
755
                }
726
756
        }
 
757
#endif
727
758
 
728
759
        /*
729
760
         *      Result should be >= 0 here - if not, it means the user
734
765
        }
735
766
 
736
767
        /*
737
 
         *      We might need this later.  The 'password' string
738
 
         *      is NOT used anywhere below here, except for logging,
739
 
         *      so it should be safe...
740
 
         */
741
 
        if ((auth_item != NULL) && (auth_item->attribute == PW_CHAP_PASSWORD)) {
742
 
                password = "CHAP-Password";
743
 
        }
744
 
 
745
 
        /*
746
768
         *      Add the port number to the Framed-IP-Address if
747
769
         *      vp->addport is set.
748
770
         */
761
783
                  tmp->flags.addport = 0;
762
784
                  ip_ntoa(tmp->vp_strvalue, tmp->vp_integer);
763
785
                } else {
764
 
                        DEBUG2("WARNING: No NAS-Port attribute in request.  CANNOT return a Framed-IP-Address + NAS-Port.\n");
 
786
                        RDEBUG2("WARNING: No NAS-Port attribute in request.  CANNOT return a Framed-IP-Address + NAS-Port.\n");
765
787
                        pairdelete(&request->reply->vps, PW_FRAMED_IP_ADDRESS);
766
788
                }
767
789
        }