OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-3.0/] [packages/] [net/] [ppp/] [current/] [src/] [auth.c] - Blame information for rev 786

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 786 skrzyp
//==========================================================================
2
//
3
//      src/auth.c
4
//
5
//==========================================================================
6
// ####ECOSGPLCOPYRIGHTBEGIN####                                            
7
// -------------------------------------------                              
8
// This file is part of eCos, the Embedded Configurable Operating System.   
9
// Copyright (C) 2003 Free Software Foundation, Inc.                        
10
//
11
// eCos is free software; you can redistribute it and/or modify it under    
12
// the terms of the GNU General Public License as published by the Free     
13
// Software Foundation; either version 2 or (at your option) any later      
14
// version.                                                                 
15
//
16
// eCos is distributed in the hope that it will be useful, but WITHOUT      
17
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or    
18
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License    
19
// for more details.                                                        
20
//
21
// You should have received a copy of the GNU General Public License        
22
// along with eCos; if not, write to the Free Software Foundation, Inc.,    
23
// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.            
24
//
25
// As a special exception, if other files instantiate templates or use      
26
// macros or inline functions from this file, or you compile this file      
27
// and link it with other works to produce a work based on this file,       
28
// this file does not by itself cause the resulting work to be covered by   
29
// the GNU General Public License. However the source code for this file    
30
// must still be made available in accordance with section (3) of the GNU   
31
// General Public License v2.                                               
32
//
33
// This exception does not invalidate any other reasons why a work based    
34
// on this file might be covered by the GNU General Public License.         
35
// -------------------------------------------                              
36
// ####ECOSGPLCOPYRIGHTEND####                                              
37
// ####BSDALTCOPYRIGHTBEGIN####                                             
38
// -------------------------------------------                              
39
// Portions of this software may have been derived from FreeBSD, OpenBSD,   
40
// or other sources, and if so are covered by the appropriate copyright     
41
// and license included herein.                                             
42
// -------------------------------------------                              
43
// ####BSDALTCOPYRIGHTEND####                                               
44
//==========================================================================
45
 
46
/*
47
 * auth.c - PPP authentication and phase control.
48
 *
49
 * Copyright (c) 1993 The Australian National University.
50
 * All rights reserved.
51
 *
52
 * Redistribution and use in source and binary forms are permitted
53
 * provided that the above copyright notice and this paragraph are
54
 * duplicated in all such forms and that any documentation,
55
 * advertising materials, and other materials related to such
56
 * distribution and use acknowledge that the software was developed
57
 * by the Australian National University.  The name of the University
58
 * may not be used to endorse or promote products derived from this
59
 * software without specific prior written permission.
60
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
61
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
62
 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
63
 *
64
 * Copyright (c) 1989 Carnegie Mellon University.
65
 * All rights reserved.
66
 *
67
 * Redistribution and use in source and binary forms are permitted
68
 * provided that the above copyright notice and this paragraph are
69
 * duplicated in all such forms and that any documentation,
70
 * advertising materials, and other materials related to such
71
 * distribution and use acknowledge that the software was developed
72
 * by Carnegie Mellon University.  The name of the
73
 * University may not be used to endorse or promote products derived
74
 * from this software without specific prior written permission.
75
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
76
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
77
 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
78
 */
79
 
80
#ifndef lint
81
//static char rcsid[] = "$FreeBSD: src/usr.sbin/pppd/auth.c,v 1.24.2.1 2000/12/11 01:03:37 obrien Exp $";
82
#endif
83
 
84
#include <stdio.h>
85
#include <stddef.h>
86
#include <stdlib.h>
87
#include <unistd.h>
88
#include <cyg/ppp/syslog.h>
89
#ifndef __ECOS
90
#include <paths.h>
91
#endif
92
//#include <pwd.h>
93
#include <string.h>
94
#include <sys/types.h>
95
#include <sys/stat.h>
96
#include <sys/socket.h>
97
//#include <utmp.h>
98
#include <fcntl.h>
99
#if defined(_PATH_LASTLOG) && defined(_linux_)
100
#include <lastlog.h>
101
#endif
102
 
103
#include <netdb.h>
104
#include <netinet/in.h>
105
#include <arpa/inet.h>
106
#include <sys/time.h>
107
//#include <utmp.h>
108
 
109
#ifdef USE_PAM
110
#include <security/pam_appl.h>
111
#endif
112
 
113
#ifdef HAS_SHADOW
114
#include <shadow.h>
115
#ifndef PW_PPP
116
#define PW_PPP PW_LOGIN
117
#endif
118
#endif
119
 
120
#include "cyg/ppp/pppd.h"
121
#include "cyg/ppp/fsm.h"
122
#include "cyg/ppp/lcp.h"
123
#include "cyg/ppp/ipcp.h"
124
#include "cyg/ppp/upap.h"
125
#include "cyg/ppp/chap.h"
126
#ifdef CBCP_SUPPORT
127
#include "cyg/ppp/cbcp.h"
128
#endif
129
//#include "cyg/ppp/pathnames.h"
130
 
131
/* Used for storing a sequence of words.  Usually malloced. */
132
struct wordlist {
133
    struct wordlist     *next;
134
    char                word[1];
135
};
136
 
137
/* Bits in scan_authfile return value */
138
#define NONWILD_SERVER  1
139
#define NONWILD_CLIENT  2
140
 
141
#define ISWILD(word)    (word[0] == '*' && word[1] == 0)
142
 
143
#define FALSE   0
144
#define TRUE    1
145
 
146
/* The name by which the peer authenticated itself to us. */
147
char peer_authname[MAXNAMELEN];
148
 
149
/* Records which authentication operations haven't completed yet. */
150
static int auth_pending[NUM_PPP];
151
 
152
/* Set if we have successfully called plogin() */
153
//static int logged_in;
154
 
155
/* Set if not wild or blank */
156
//static int non_wildclient;
157
 
158
/* Set if we have run the /etc/ppp/auth-up script. */
159
//static int did_authup;
160
 
161
/* List of addresses which the peer may use. */
162
static struct wordlist *addresses[NUM_PPP];
163
 
164
/* Number of network protocols which we have opened. */
165
static int num_np_open;
166
 
167
/* Number of network protocols which have come up. */
168
static int num_np_up;
169
 
170
/* Set if we got the contents of passwd[] from the pap-secrets file. */
171
static int passwd_from_file;
172
 
173
/* Bits in auth_pending[] */
174
#define PAP_WITHPEER    1
175
#define PAP_PEER        2
176
#define CHAP_WITHPEER   4
177
#define CHAP_PEER       8
178
 
179
extern char *crypt __P((const char *, const char *));
180
 
181
/* Prototypes for procedures local to this file. */
182
 
183
static void network_phase __P((int));
184
static void check_idle __P((void *));
185
static void connect_time_expired __P((void *));
186
static int  null_login __P((int));
187
static int  get_pap_passwd __P((char *));
188
static int  have_pap_secret __P((void));
189
static int  have_chap_secret __P((char *, char *, u_int32_t));
190
static int  ip_addr_check __P((u_int32_t, struct wordlist *));
191
 
192
static void auth_set_ip_addr __P((int));
193
 
194
/*
195
 * An Open on LCP has requested a change from Dead to Establish phase.
196
 * Do what's necessary to bring the physical layer up.
197
 */
198
void
199
link_required(unit)
200
    int unit;
201
{
202
}
203
 
204
/*
205
 * LCP has terminated the link; go to the Dead phase and take the
206
 * physical layer down.
207
 */
208
void
209
link_terminated(unit)
210
    int unit;
211
{
212
    extern      time_t  etime, stime;
213
    extern      int     minutes;
214
 
215
db_printf("%s()\n",__PRETTY_FUNCTION__);
216
    if (phase == PHASE_DEAD)
217
        return;
218
    phase = PHASE_DEAD;
219
    etime = time((time_t *) NULL);
220
    minutes = (etime-stime)/60;
221
    syslog(LOG_NOTICE, "Connection terminated, connected for %d minutes\n",
222
        minutes > 1 ? minutes : 1);
223
}
224
 
225
/*
226
 * LCP has gone down; it will either die or try to re-establish.
227
 */
228
void
229
link_down(unit)
230
    int unit;
231
{
232
    int i;
233
    struct protent *protp;
234
 
235
db_printf("%s()\n",__PRETTY_FUNCTION__);
236
    for (i = 0; (protp = protocols[i]) != NULL; ++i) {
237
        if (!protp->enabled_flag)
238
            continue;
239
        if (protp->protocol != PPP_LCP && protp->lowerdown != NULL)
240
            (*protp->lowerdown)(unit);
241
        if (protp->protocol < 0xC000 && protp->close != NULL)
242
            (*protp->close)(unit, "LCP down");
243
    }
244
    num_np_open = 0;
245
    num_np_up = 0;
246
    if (phase != PHASE_DEAD)
247
        phase = PHASE_TERMINATE;
248
}
249
 
250
/*
251
 * The link is established.
252
 * Proceed to the Dead, Authenticate or Network phase as appropriate.
253
 */
254
void
255
link_established(unit)
256
    int unit;
257
{
258
    int auth;
259
    lcp_options *wo = &lcp_wantoptions[unit];
260
    lcp_options *go = &lcp_gotoptions[unit];
261
    lcp_options *ho = &lcp_hisoptions[unit];
262
    int i;
263
    struct protent *protp;
264
 
265
    /*
266
     * Tell higher-level protocols that LCP is up.
267
     */
268
    for (i = 0; (protp = protocols[i]) != NULL; ++i)
269
        if (protp->protocol != PPP_LCP && protp->enabled_flag
270
            && protp->lowerup != NULL)
271
            (*protp->lowerup)(unit);
272
 
273
    if (auth_required && !(go->neg_chap || go->neg_upap)) {
274
        /*
275
         * We wanted the peer to authenticate itself, and it refused:
276
         * treat it as though it authenticated with PAP using a username
277
         * of "" and a password of "".  If that's not OK, boot it out.
278
         */
279
        if (!wo->neg_upap || !null_login(unit)) {
280
            syslog(LOG_WARNING, "peer refused to authenticate");
281
            lcp_close(unit, "peer refused to authenticate");
282
            cyg_ppp_stats.auth_failures++;
283
            return;
284
        }
285
    }
286
 
287
    phase = PHASE_AUTHENTICATE;
288
    auth = 0;
289
    if (go->neg_chap) {
290
        ChapAuthPeer(unit, our_name, go->chap_mdtype);
291
        auth |= CHAP_PEER;
292
    } else if (go->neg_upap) {
293
        upap_authpeer(unit);
294
        auth |= PAP_PEER;
295
    }
296
    if (ho->neg_chap) {
297
        ChapAuthWithPeer(unit, user, ho->chap_mdtype);
298
        auth |= CHAP_WITHPEER;
299
    } else if (ho->neg_upap) {
300
        if (passwd[0] == 0) {
301
            passwd_from_file = 1;
302
            if (!get_pap_passwd(passwd))
303
                syslog(LOG_ERR, "No secret found for PAP login");
304
        }
305
        upap_authwithpeer(unit, user, passwd);
306
        auth |= PAP_WITHPEER;
307
    }
308
    auth_pending[unit] = auth;
309
 
310
    if (!auth)
311
        network_phase(unit);
312
}
313
 
314
/*
315
 * Proceed to the network phase.
316
 */
317
static void
318
network_phase(unit)
319
    int unit;
320
{
321
    int i;
322
    struct protent *protp;
323
 
324
#ifdef CBCP_SUPPORT
325
    /*
326
     * If we negotiated callback, do it now.
327
     */
328
    if (go->neg_cbcp) {
329
        phase = PHASE_CALLBACK;
330
        (*cbcp_protent.open)(unit);
331
        return;
332
    }
333
#endif
334
 
335
    phase = PHASE_NETWORK;
336
    for (i = 0; (protp = protocols[i]) != NULL; ++i)
337
        if (protp->protocol < 0xC000 && protp->enabled_flag
338
            && protp->open != NULL) {
339
            (*protp->open)(unit);
340
            if (protp->protocol != PPP_CCP)
341
                ++num_np_open;
342
        }
343
 
344
    if (num_np_open == 0) {
345
        /* nothing to do */
346
        lcp_close(0, "No network protocols running");
347
        cyg_ppp_stats.no_proto++;
348
    }
349
}
350
 
351
/*
352
 * The peer has failed to authenticate himself using `protocol'.
353
 */
354
void
355
auth_peer_fail(unit, protocol)
356
    int unit, protocol;
357
{
358
    /*
359
     * Authentication failure: take the link down
360
     */
361
    lcp_close(unit, "Authentication failed");
362
    cyg_ppp_stats.auth_failures++;
363
}
364
 
365
/*
366
 * The peer has been successfully authenticated using `protocol'.
367
 */
368
void
369
auth_peer_success(unit, protocol, name, namelen)
370
    int unit, protocol;
371
    char *name;
372
    int namelen;
373
{
374
    int bit;
375
 
376
    switch (protocol) {
377
    case PPP_CHAP:
378
        bit = CHAP_PEER;
379
        break;
380
    case PPP_PAP:
381
        bit = PAP_PEER;
382
        break;
383
    default:
384
        syslog(LOG_WARNING, "auth_peer_success: unknown protocol %x",
385
               protocol);
386
        return;
387
    }
388
 
389
    /*
390
     * Save the authenticated name of the peer for later.
391
     */
392
    if (namelen > sizeof(peer_authname) - 1)
393
        namelen = sizeof(peer_authname) - 1;
394
    BCOPY(name, peer_authname, namelen);
395
    peer_authname[namelen] = 0;
396
 
397
    /*
398
     * If we have overridden addresses based on auth info
399
     * then set that information now before continuing.
400
     */
401
    auth_set_ip_addr(unit);
402
 
403
    /*
404
     * If there is no more authentication still to be done,
405
     * proceed to the network (or callback) phase.
406
     */
407
    if ((auth_pending[unit] &= ~bit) == 0)
408
        network_phase(unit);
409
}
410
 
411
/*
412
 * We have failed to authenticate ourselves to the peer using `protocol'.
413
 */
414
void
415
auth_withpeer_fail(unit, protocol)
416
    int unit, protocol;
417
{
418
    if (passwd_from_file)
419
        BZERO(passwd, MAXSECRETLEN);
420
    /*
421
     * We've failed to authenticate ourselves to our peer.
422
     * He'll probably take the link down, and there's not much
423
     * we can do except wait for that.
424
     */
425
        cyg_ppp_stats.auth_failures++;
426
}
427
 
428
/*
429
 * We have successfully authenticated ourselves with the peer using `protocol'.
430
 */
431
void
432
auth_withpeer_success(unit, protocol)
433
    int unit, protocol;
434
{
435
    int bit;
436
 
437
    switch (protocol) {
438
    case PPP_CHAP:
439
        bit = CHAP_WITHPEER;
440
        break;
441
    case PPP_PAP:
442
        if (passwd_from_file)
443
            BZERO(passwd, MAXSECRETLEN);
444
        bit = PAP_WITHPEER;
445
        break;
446
    default:
447
        syslog(LOG_WARNING, "auth_peer_success: unknown protocol %x",
448
               protocol);
449
        bit = 0;
450
    }
451
 
452
    /*
453
     * If we have overridden addresses based on auth info
454
     * then set that information now before continuing.
455
     */
456
    auth_set_ip_addr(unit);
457
 
458
    /*
459
     * If there is no more authentication still being done,
460
     * proceed to the network (or callback) phase.
461
     */
462
    if ((auth_pending[unit] &= ~bit) == 0)
463
        network_phase(unit);
464
}
465
 
466
 
467
/*
468
 * np_up - a network protocol has come up.
469
 */
470
void
471
np_up(unit, proto)
472
    int unit, proto;
473
{
474
    if (num_np_up == 0) {
475
        /*
476
         * At this point we consider that the link has come up successfully.
477
         */
478
        need_holdoff = 0;
479
 
480
        if (idle_time_limit > 0)
481
            TIMEOUT(check_idle, NULL, idle_time_limit);
482
 
483
        /*
484
         * Set a timeout to close the connection once the maximum
485
         * connect time has expired.
486
         */
487
        if (maxconnect > 0)
488
            TIMEOUT(connect_time_expired, 0, maxconnect);
489
 
490
    }
491
    ++num_np_up;
492
}
493
 
494
/*
495
 * np_down - a network protocol has gone down.
496
 */
497
void
498
np_down(unit, proto)
499
    int unit, proto;
500
{
501
    if (--num_np_up == 0 && idle_time_limit > 0) {
502
        UNTIMEOUT(check_idle, NULL);
503
    }
504
}
505
 
506
/*
507
 * np_finished - a network protocol has finished using the link.
508
 */
509
void
510
np_finished(unit, proto)
511
    int unit, proto;
512
{
513
    if (--num_np_open <= 0) {
514
        /* no further use for the link: shut up shop. */
515
        lcp_close(0, "No network protocols running");
516
        cyg_ppp_stats.no_proto++;
517
    }
518
}
519
 
520
/*
521
 * check_idle - check whether the link has been idle for long
522
 * enough that we can shut it down.
523
 */
524
static void
525
check_idle(arg)
526
     void *arg;
527
{
528
    struct ppp_idle idle;
529
    time_t itime;
530
 
531
    if (!get_idle_time(0, &idle))
532
        return;
533
    itime = MIN(idle.xmit_idle, idle.recv_idle);
534
    if (itime >= idle_time_limit) {
535
        /* link is idle: shut it down. */
536
        syslog(LOG_INFO, "Terminating connection due to lack of activity.");
537
        lcp_close(0, "Link inactive");
538
        cyg_ppp_stats.idle_timeout++;
539
    } else {
540
        TIMEOUT(check_idle, NULL, idle_time_limit - itime);
541
    }
542
}
543
 
544
/*
545
 * connect_time_expired - log a message and close the connection.
546
 */
547
static void
548
connect_time_expired(arg)
549
    void *arg;
550
{
551
    syslog(LOG_INFO, "Connect time expired");
552
    lcp_close(0, "Connect time expired");        /* Close connection */
553
    cyg_ppp_stats.connect_time_expired++;
554
}
555
 
556
/*
557
 * auth_check_options - called to check authentication options.
558
 */
559
void
560
auth_check_options()
561
{
562
    lcp_options *wo = &lcp_wantoptions[0];
563
    int can_auth;
564
    ipcp_options *ipwo = &ipcp_wantoptions[0];
565
    u_int32_t remote;
566
 
567
    /* Default our_name to hostname, and user to our_name */
568
    if (our_name[0] == 0 || usehostname)
569
        strcpy(our_name, cyg_ppp_hostname);
570
    if (user[0] == 0)
571
        strcpy(user, our_name);
572
 
573
    /* If authentication is required, ask peer for CHAP or PAP. */
574
    if (auth_required && !wo->neg_chap && !wo->neg_upap) {
575
        wo->neg_chap = 1;
576
        wo->neg_upap = 1;
577
    }
578
 
579
    /*
580
     * Check whether we have appropriate secrets to use
581
     * to authenticate the peer.
582
     */
583
    can_auth = wo->neg_upap && (uselogin || have_pap_secret());
584
    if (!can_auth && wo->neg_chap) {
585
        remote = ipwo->accept_remote? 0: ipwo->hisaddr;
586
        can_auth = have_chap_secret(remote_name, our_name, remote);
587
    }
588
 
589
    if (auth_required && !can_auth) {
590
        option_error("peer authentication required but no suitable secret(s) found\n");
591
        if (remote_name[0] == 0)
592
            option_error("for authenticating any peer to us (%s)\n", our_name);
593
        else
594
            option_error("for authenticating peer %s to us (%s)\n",
595
                         remote_name, our_name);
596
        exit(1);
597
    }
598
 
599
    /*
600
     * Check whether the user tried to override certain values
601
     * set by root.
602
     */
603
    if (!auth_required && auth_req_info.priv > 0) {
604
        if (!default_device && devnam_info.priv == 0) {
605
            option_error("can't override device name when noauth option used");
606
            exit(1);
607
        }
608
        if ((connector != NULL && connector_info.priv == 0)
609
            || (disconnector != NULL && disconnector_info.priv == 0)
610
            || (welcomer != NULL && welcomer_info.priv == 0)) {
611
            option_error("can't override connect, disconnect or welcome");
612
            option_error("option values when noauth option used");
613
            exit(1);
614
        }
615
    }
616
}
617
 
618
/*
619
 * auth_reset - called when LCP is starting negotiations to recheck
620
 * authentication options, i.e. whether we have appropriate secrets
621
 * to use for authenticating ourselves and/or the peer.
622
 */
623
void
624
auth_reset(unit)
625
    int unit;
626
{
627
    lcp_options *go = &lcp_gotoptions[unit];
628
    lcp_options *ao = &lcp_allowoptions[0];
629
    ipcp_options *ipwo = &ipcp_wantoptions[0];
630
    u_int32_t remote;
631
    ao->neg_upap = !refuse_pap && (passwd[0] != 0 || get_pap_passwd(NULL));
632
    ao->neg_chap = !refuse_chap
633
        && have_chap_secret(user, remote_name, (u_int32_t)0);
634
    if (go->neg_upap && !uselogin && !have_pap_secret())
635
        go->neg_upap = 0;
636
    if (go->neg_chap) {
637
        remote = ipwo->accept_remote? 0: ipwo->hisaddr;
638
        if (!have_chap_secret(remote_name, our_name, remote))
639
            go->neg_chap = 0;
640
    }
641
}
642
 
643
 
644
/*
645
 * check_passwd - Check the user name and passwd against the PAP secrets
646
 * file.  If requested, also check against the system password database,
647
 * and login the user if OK.
648
 *
649
 * returns:
650
 *      UPAP_AUTHNAK: Authentication failed.
651
 *      UPAP_AUTHACK: Authentication succeeded.
652
 * In either case, msg points to an appropriate message.
653
 */
654
int
655
check_passwd(unit, auser, userlen, apasswd, passwdlen, msg, msglen)
656
    int unit;
657
    char *auser;
658
    int userlen;
659
    char *apasswd;
660
    int passwdlen;
661
    char **msg;
662
    int *msglen;
663
{
664
    db_printf("%s called\n", __PRETTY_FUNCTION__);
665
    return 0;
666
}
667
 
668
/*
669
 * null_login - Check if a username of "" and a password of "" are
670
 * acceptable, and iff so, set the list of acceptable IP addresses
671
 * and return 1.
672
 */
673
static int
674
null_login(unit)
675
    int unit;
676
{
677
    db_printf("%s called\n", __PRETTY_FUNCTION__);
678
    return 0;
679
}
680
 
681
 
682
/*
683
 * get_pap_passwd - get a password for authenticating ourselves with
684
 * our peer using PAP.  Returns 1 on success, 0 if no suitable password
685
 * could be found.
686
 */
687
static int
688
get_pap_passwd(passwd)
689
    char *passwd;
690
{
691
    db_printf("%s called\n", __PRETTY_FUNCTION__);
692
    return 0;
693
}
694
 
695
 
696
/*
697
 * have_pap_secret - check whether we have a PAP file with any
698
 * secrets that we could possibly use for authenticating the peer.
699
 */
700
static int
701
have_pap_secret()
702
{
703
    db_printf("%s called\n", __PRETTY_FUNCTION__);
704
    return 0;
705
}
706
 
707
 
708
/*
709
 * have_chap_secret - check whether we have a CHAP file with a
710
 * secret that we could possibly use for authenticating `client'
711
 * on `server'.  Either can be the null string, meaning we don't
712
 * know the identity yet.
713
 */
714
static int
715
have_chap_secret(client, server, remote)
716
    char *client;
717
    char *server;
718
    u_int32_t remote;
719
{
720
//    db_printf("%s(%s,%s,%d) called\n", __PRETTY_FUNCTION__,client,server,remote);
721
    return 1;
722
}
723
 
724
 
725
/*
726
 * get_secret - open the CHAP secret file and return the secret
727
 * for authenticating the given client on the given server.
728
 * (We could be either client or server).
729
 */
730
int
731
get_secret(unit, client, server, secret, secret_len, save_addrs)
732
    int unit;
733
    char *client;
734
    char *server;
735
    char *secret;
736
    int *secret_len;
737
    int save_addrs;
738
{
739
    db_printf("%s(%d,%s,%s,%08x,%d,%d) called\n", __PRETTY_FUNCTION__,
740
                unit, client, server, secret, secret_len, save_addrs);
741
    // We use the PAP password as the CHAP secret also.
742
    strncpy( secret, passwd, MAXNAMELEN );
743
    *secret_len = strlen(secret);
744
    return 1;
745
}
746
 
747
static void
748
auth_set_ip_addr(unit)
749
    int unit;
750
{
751
    db_printf("%s called\n", __PRETTY_FUNCTION__);
752
}
753
 
754
/*
755
 * auth_ip_addr - check whether the peer is authorized to use
756
 * a given IP address.  Returns 1 if authorized, 0 otherwise.
757
 */
758
int
759
auth_ip_addr(unit, addr)
760
    int unit;
761
    u_int32_t addr;
762
{
763
    return ip_addr_check(addr, addresses[unit]);
764
}
765
 
766
static int
767
ip_addr_check(addr, addrs)
768
    u_int32_t addr;
769
    struct wordlist *addrs;
770
{
771
    int x, y;
772
//    u_int32_t a, mask, ah;
773
    u_int32_t a = -1, mask;
774
    int accept;
775
    char *ptr_word, *ptr_mask;
776
//    struct hostent *hp;
777
//    struct netent *np;
778
 
779
    /* don't allow loopback or multicast address */
780
    if (bad_ip_adrs(addr))
781
        return 0;
782
 
783
    if (addrs == NULL)
784
        return !auth_required;          /* no addresses authorized */
785
 
786
    x = y = 0;
787
    for (; addrs != NULL; addrs = addrs->next) {
788
        y++;
789
        /* "-" means no addresses authorized, "*" means any address allowed */
790
        ptr_word = addrs->word;
791
        if (strcmp(ptr_word, "-") == 0)
792
            break;
793
        if (strcmp(ptr_word, "*") == 0)
794
            return 1;
795
 
796
        /*
797
         * A colon in the string means that we wish to force a specific
798
         * local:remote address, but we ignore these for now.
799
         */
800
        if (strchr(addrs->word, ':') != NULL)
801
            x++;
802
        else {
803
 
804
        accept = 1;
805
        if (*ptr_word == '!') {
806
            accept = 0;
807
            ++ptr_word;
808
        }
809
 
810
        mask = ~ (u_int32_t) 0;
811
        ptr_mask = strchr (ptr_word, '/');
812
        if (ptr_mask != NULL) {
813
            int bit_count;
814
 
815
            bit_count = (int) strtol (ptr_mask+1, (char **) 0, 10);
816
            if (bit_count <= 0 || bit_count > 32) {
817
                syslog (LOG_WARNING,
818
                        "invalid address length %s in auth. address list",
819
                        ptr_mask);
820
                continue;
821
            }
822
            *ptr_mask = '\0';
823
            mask <<= 32 - bit_count;
824
        }
825
 
826
#ifndef __ECOS
827
        hp = gethostbyname(ptr_word);
828
        if (hp != NULL && hp->h_addrtype == AF_INET) {
829
            a = *(u_int32_t *)hp->h_addr;
830
        } else {
831
            np = getnetbyname (ptr_word);
832
            if (np != NULL && np->n_addrtype == AF_INET) {
833
                a = htonl (*(u_int32_t *)np->n_net);
834
                if (ptr_mask == NULL) {
835
                    /* calculate appropriate mask for net */
836
                    ah = ntohl(a);
837
                    if (IN_CLASSA(ah))
838
                        mask = IN_CLASSA_NET;
839
                    else if (IN_CLASSB(ah))
840
                        mask = IN_CLASSB_NET;
841
                    else if (IN_CLASSC(ah))
842
                        mask = IN_CLASSC_NET;
843
                }
844
            } else {
845
                a = inet_addr (ptr_word);
846
            }
847
        }
848
#endif
849
 
850
        if (ptr_mask != NULL)
851
            *ptr_mask = '/';
852
 
853
        if (a == (u_int32_t)-1L)
854
            syslog (LOG_WARNING,
855
                    "unknown host %s in auth. address list",
856
                    addrs->word);
857
        else
858
            /* Here a and addr are in network byte order,
859
               and mask is in host order. */
860
            if (((addr ^ a) & htonl(mask)) == 0)
861
                return accept;
862
    }   /* else */
863
    }
864
    return x == y;                      /* not in list => can't have it */
865
}
866
 
867
/*
868
 * bad_ip_adrs - return 1 if the IP address is one we don't want
869
 * to use, such as an address in the loopback net or a multicast address.
870
 * addr is in network byte order.
871
 */
872
int
873
bad_ip_adrs(addr)
874
    u_int32_t addr;
875
{
876
    addr = ntohl(addr);
877
    return (addr >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET
878
        || IN_MULTICAST(addr) || IN_BADCLASS(addr);
879
}
880
 
881
/*
882
 * check_access - complain if a secret file has too-liberal permissions.
883
 */
884
void
885
check_access(f, filename)
886
    FILE *f;
887
    char *filename;
888
{
889
    struct stat sbuf;
890
 
891
    if (fstat(fileno(f), &sbuf) < 0) {
892
        syslog(LOG_WARNING, "cannot stat secret file %s: %m", filename);
893
    } else if ((sbuf.st_mode & (S_IRWXG | S_IRWXO)) != 0) {
894
        syslog(LOG_WARNING, "Warning - secret file %s has world and/or group access", filename);
895
    }
896
}

powered by: WebSVN 2.1.0

© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.