Annotation of researchv9/X11/src/X.V11R1/server/os/4.2bsd/access.c, revision 1.1.1.1

1.1       root        1: /***********************************************************
                      2: Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts,
                      3: and the Massachusetts Institute of Technology, Cambridge, Massachusetts.
                      4: 
                      5:                         All Rights Reserved
                      6: 
                      7: Permission to use, copy, modify, and distribute this software and its 
                      8: documentation for any purpose and without fee is hereby granted, 
                      9: provided that the above copyright notice appear in all copies and that
                     10: both that copyright notice and this permission notice appear in 
                     11: supporting documentation, and that the names of Digital or MIT not be
                     12: used in advertising or publicity pertaining to distribution of the
                     13: software without specific, written prior permission.  
                     14: 
                     15: DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
                     16: ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
                     17: DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
                     18: ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
                     19: WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
                     20: ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
                     21: SOFTWARE.
                     22: 
                     23: ******************************************************************/
                     24: 
                     25: /* $Header: access.c,v 1.18 87/09/03 14:24:02 toddb Exp $ */
                     26: 
                     27: #include "X.h"
                     28: #include "Xproto.h"
                     29: #include "misc.h"
                     30: #include <errno.h>
                     31: #include <sys/types.h>
                     32: #include <sys/socket.h>
                     33: #include <sys/ioctl.h>
                     34: #include <net/if.h>
                     35: #include <netdb.h>
                     36: #ifdef TCPCONN
                     37: #include <netinet/in.h>
                     38: #endif /* TCPCONN */
                     39: #ifdef DNETCONN
                     40: #include <netdnet/dn.h>
                     41: #include <netdnet/dnetdb.h>
                     42: #endif
                     43: #undef NULL
                     44: #include <stdio.h>
                     45: #include "dixstruct.h"
                     46: #include "osdep.h"
                     47: 
                     48: 
                     49: #define DONT_CHECK -1
                     50: extern char    *index();
                     51: 
                     52: typedef struct _host {
                     53:        short           family;
                     54:        short           len;
                     55:        unsigned char   addr[4];        /* will need to be bigger eventually */
                     56:        struct _host *next;
                     57: } HOST;
                     58: 
                     59: static HOST *selfhosts = NULL;
                     60: static HOST *validhosts = NULL;
                     61: static int AccessEnabled = TRUE;
                     62: 
                     63: typedef struct {
                     64:     int af, xf;
                     65: } FamilyMap;
                     66: 
                     67: static FamilyMap familyMap[] = {
                     68: #ifdef     AF_DECnet
                     69:     {AF_DECnet, FamilyDECnet},
                     70: #endif /* AF_DECnet */
                     71: #ifdef     AF_CHAOS
                     72:     {AF_CHAOS, FamilyChaos},
                     73: #endif /* AF_CHAOS */
                     74: #ifdef    AF_INET
                     75:     {AF_INET, FamilyInternet}
                     76: #endif
                     77: };
                     78: 
                     79: #define FAMILIES ((sizeof familyMap)/(sizeof familyMap[0]))
                     80: 
                     81: /* Define this host for access control.  Find all the hosts the OS knows about 
                     82:  * for this fd and add them to the selfhosts list.
                     83:  */
                     84: DefineSelf (fd)
                     85:     int fd;
                     86: {
                     87:     char               buf[2048];
                     88:     struct ifconf      ifc;
                     89:     register int       n;
                     90:     int                len;
                     91:     pointer            addr;
                     92:     short              family;
                     93:     register HOST      *host;
                     94:     register struct ifreq *ifr;
                     95:     
                     96:     ifc.ifc_len = sizeof (buf);
                     97:     ifc.ifc_buf = buf;
                     98:     if (ioctl (fd, (int) SIOCGIFCONF, (pointer) &ifc) < 0)
                     99:         Error ("Getting interface configuration");
                    100:     for (ifr = ifc.ifc_req, n = ifc.ifc_len / sizeof (struct ifreq); --n >= 0;
                    101:      ifr++)
                    102:     {
                    103: #ifdef DNETCONN
                    104:        /*
                    105:         * this is ugly but SIOCGIFCONF returns decnet addresses in
                    106:         * a different form from other decnet calls
                    107:         */
                    108:        if (ifr->ifr_addr.sa_family == AF_DECnet) {
                    109:                len = sizeof (struct dn_naddr);
                    110:                addr = (pointer)ifr->ifr_addr.sa_data;
                    111:                family = AF_DECnet;
                    112:        } else
                    113: #endif /* DNETCONN */
                    114:         if ((family = ConvertAddr (&ifr->ifr_addr, &len, &addr)) <= 0)
                    115:            continue;
                    116:         for (host = selfhosts; host && (family != host->family ||
                    117:          bcmp (addr, host->addr, len)); host = host->next)
                    118:            ;
                    119:         if (host)
                    120:            continue;
                    121:         host = (HOST *) Xalloc (sizeof (HOST));
                    122:         host->family = family;
                    123:         host->len = len;
                    124:         bcopy(addr, host->addr, len);
                    125:         host->next = selfhosts;
                    126:         selfhosts = host;
                    127:     }
                    128: }
                    129: 
                    130: /* Reset access control list to initial hosts */
                    131: ResetHosts (display)
                    132:     char *display;
                    133: {
                    134:     register HOST      *host, *self;
                    135:     char               hostname[120];
                    136:     char               fname[32];
                    137:     FILE               *fd;
                    138:     char               *ptr;
                    139:     union {
                    140:         struct sockaddr        sa;
                    141: #ifdef TCPCONN
                    142:         struct sockaddr_in in;
                    143: #endif /* TCPCONN */
                    144: #ifdef DNETCONN
                    145:         struct sockaddr_dn dn;
                    146: #endif
                    147:     }                  saddr;
                    148: #ifdef DNETCONN
                    149:     struct nodeent     *np;
                    150:     struct dn_naddr    dnaddr, *dnaddrp, *dnet_addr();
                    151: #endif
                    152:     short              family;
                    153:     int                        len;
                    154:     pointer            addr;
                    155:     register struct hostent *hp;
                    156: 
                    157:     while (host = validhosts)
                    158:     {
                    159:         validhosts = host->next;
                    160:         Xfree ((pointer) host);
                    161:     }
                    162:     for (self = selfhosts; self; self = self->next)
                    163:     {
                    164:         host = (HOST *) Xalloc (sizeof (HOST));
                    165:         *host = *self;
                    166:         host->next = validhosts;
                    167:         validhosts = host;
                    168:     }
                    169:     strcpy (fname, "/etc/X");
                    170:     strcat (fname, display);
                    171:     strcat (fname, ".hosts");
                    172:     if (fd = fopen (fname, "r")) 
                    173:     {
                    174:         while (fgets (hostname, sizeof (hostname), fd))
                    175:        {
                    176:        if (ptr = index (hostname, '\n'))
                    177:            *ptr = 0;
                    178: #ifdef DNETCONN
                    179:        if ((ptr = index (hostname, ':')) && (*(ptr + 1) == ':'))
                    180:        {
                    181:            /* node name (DECnet names end in "::") */
                    182:            *ptr = 0;
                    183:            if (dnaddrp = dnet_addr(hostname))
                    184:            {
                    185:                    /* allow nodes to be specified by address */
                    186:                    NewHost (AF_DECnet, (pointer) dnaddrp);
                    187:            }
                    188:            else
                    189:            {
                    190:                if (np = getnodebyname (hostname))
                    191:                {
                    192:                    /* node was specified by name */
                    193:                    saddr.sa.sa_family = np->n_addrtype;
                    194:                    if ((family = ConvertAddr (&saddr.sa, &len, &addr)) ==
                    195:                      AF_DECnet)
                    196:                    {
                    197:                        bzero ((pointer) &dnaddr, sizeof (dnaddr));
                    198:                        dnaddr.a_len = np->n_length;
                    199:                        bcopy (np->n_addr, (pointer) dnaddr.a_addr,
                    200:                          np->n_length);
                    201:                        NewHost (family, (pointer) &dnaddr);
                    202:                    }
                    203:                }
                    204:            }
                    205:        }
                    206:        else
                    207:        {
                    208: #endif /* DNETCONN */
                    209: #ifdef TCPCONN
                    210:            /* host name */
                    211:            if (hp = gethostbyname (hostname))
                    212:            {
                    213:                saddr.sa.sa_family = hp->h_addrtype;
                    214:                if ((family = ConvertAddr (&saddr.sa, &len, &addr)) > 0)
                    215: #ifdef NEW_HEADER_WITH_OLD_LIBRARY
                    216:                    NewHost (family, hp->h_addr_list);
                    217: #else
                    218:                    NewHost (family, hp->h_addr);
                    219: #endif
                    220: 
                    221:            }
                    222: #endif /* TCPCONN */
                    223: #ifdef DNETCONN
                    224:        }       
                    225: #endif /* DNETCONN */
                    226:         }
                    227:         fclose (fd);
                    228:     }
                    229: }
                    230: 
                    231: /* Add a host to the access control list.  This is the external interface
                    232:  * called from the dispatcher */
                    233: 
                    234: int
                    235: AddHost (client, family, length, pAddr)
                    236:     int                        client;
                    237:     int                 family;
                    238:     int                 length;        /* of bytes in pAddr */
                    239:     pointer             pAddr;
                    240: {
                    241:     int                        len;
                    242:     register HOST      *host;
                    243:     int                 unixFamily;
                    244: 
                    245:     unixFamily = UnixFamily(family);
                    246:     if ((len = CheckFamily (DONT_CHECK, unixFamily)) < 0)
                    247:         return BadMatch;
                    248: 
                    249:     if (len != length)
                    250:         return BadMatch;
                    251:     for (host = validhosts; host; host = host->next)
                    252:     {
                    253:         if (unixFamily == host->family && !bcmp (pAddr, host->addr, len))
                    254:            return Success;
                    255:     }
                    256:     host = (HOST *) Xalloc (sizeof (HOST));
                    257:     host->family = unixFamily;
                    258:     host->len = len;
                    259:     bcopy(pAddr, host->addr, len);
                    260:     host->next = validhosts;
                    261:     validhosts = host;
                    262:     return Success;
                    263: }
                    264: 
                    265: /* Add a host to the access control list. This is the internal interface 
                    266:  * called when starting or resetting the server */
                    267: NewHost (family, addr)
                    268:     short      family;
                    269:     pointer    addr;
                    270: {
                    271:     int                len;
                    272:     register HOST *host;
                    273: 
                    274:     if ((len = CheckFamily (DONT_CHECK, family)) < 0)
                    275:         return;
                    276:     for (host = validhosts; host; host = host->next)
                    277:     {
                    278:         if (family == host->family && !bcmp (addr, host->addr, len))
                    279:        return;
                    280:     }
                    281:     host = (HOST *) Xalloc (sizeof (HOST));
                    282:     host->family = family;
                    283:     host->len = len;
                    284:     bcopy(addr, host->addr, len);
                    285:     host->next = validhosts;
                    286:     validhosts = host;
                    287: }
                    288: 
                    289: /* Remove a host from the access control list */
                    290: 
                    291: int
                    292: RemoveHost (client, family, length, pAddr)
                    293:     int                        client;
                    294:     int                 family;
                    295:     int                 length;        /* of bytes in pAddr */
                    296:     pointer             pAddr;
                    297: {
                    298:     int                        len,
                    299:                         unixFamily;
                    300:     register HOST      *host, **prev;
                    301: 
                    302:     unixFamily = UnixFamily(family);
                    303:     if ((len = CheckFamily (DONT_CHECK, unixFamily)) < 0)
                    304:         return BadMatch;
                    305:     if (len != length)
                    306:         return BadMatch;
                    307:     for (prev = &validhosts;
                    308:          (host = *prev) && (unixFamily != host->family ||
                    309:                            bcmp (pAddr, host->addr, len));
                    310:          prev = &host->next)
                    311:         ;
                    312:     if (host)
                    313:     {
                    314:         *prev = host->next;
                    315:         Xfree ((pointer) host);
                    316:     }
                    317:     return Success;
                    318: }
                    319: 
                    320: /* Get all hosts in the access control list */
                    321: int
                    322: GetHosts (data, pnHosts, pEnabled)
                    323:     pointer            *data;
                    324:     int                        *pnHosts;
                    325:     BOOL               *pEnabled;
                    326: {
                    327:     int                        len;
                    328:     register int       n = 0;
                    329:     register pointer   ptr;
                    330:     register HOST      *host;
                    331:     int                        nHosts = 0;
                    332:     int                        *lengths = (int *) NULL;
                    333: 
                    334:     *pEnabled = AccessEnabled ? EnableAccess : DisableAccess;
                    335:     for (host = validhosts; host; host = host->next)
                    336:     {
                    337:         if ((len = CheckFamily (DONT_CHECK, host->family)) < 0)
                    338:             return (-1);
                    339:        lengths = (int *) Xrealloc(lengths, (nHosts + 1) * sizeof(int));
                    340:        lengths[nHosts++] = len;
                    341:        n += (((len + 3) >> 2) << 2) + sizeof(xHostEntry);
                    342:     }
                    343:     if (n)
                    344:     {
                    345:         *data = ptr = (pointer) Xalloc (n);
                    346:        nHosts = 0;
                    347:         for (host = validhosts; host; host = host->next)
                    348:        {
                    349: 
                    350:            len = lengths[nHosts++];
                    351:            ((xHostEntry *)ptr)->family = XFamily(host->family);
                    352:            ((xHostEntry *)ptr)->length = len;
                    353:            ptr += sizeof(xHostEntry);
                    354:            bcopy (host->addr, ptr, len);
                    355:            ptr += ((len + 3) >> 2) << 2;
                    356:         }
                    357:     }
                    358:     *pnHosts = nHosts;
                    359:     Xfree(lengths);
                    360:     return (n);
                    361: }
                    362: 
                    363: /* Check for valid address family, and for local host if client modification.
                    364:  * Return address length.
                    365:  */
                    366: 
                    367: CheckFamily (connection, family)
                    368:     int                        connection;
                    369:     short              family;
                    370: {
                    371:     struct sockaddr    from;
                    372:     int                        alen;
                    373:     pointer            addr;
                    374:     register HOST      *host;
                    375:     int                len;
                    376: 
                    377:     switch (family)
                    378:     {
                    379: #ifdef TCPCONN
                    380:       case AF_INET:
                    381:         len = sizeof (struct in_addr);
                    382:         break;
                    383: #endif 
                    384: #ifdef DNETCONN
                    385:       case AF_DECnet:
                    386:         len = sizeof (struct dn_naddr);
                    387:         break;
                    388: #endif
                    389:       default:
                    390:         /* BadValue */
                    391:         return (-1);
                    392:     }
                    393:     if (connection == DONT_CHECK)
                    394:         return (len);
                    395:     alen = sizeof (from);
                    396:     if (!getpeername (connection, &from, &alen))
                    397:     {
                    398:         if ((family = ConvertAddr (&from, &alen, &addr)) >= 0)
                    399:        {
                    400:            if (family == 0)
                    401:                return (len);
                    402:            for (host = selfhosts; host; host = host->next)
                    403:            {
                    404:                if (family == host->family &&
                    405:                    !bcmp (addr, host->addr, alen))
                    406:                    return (len);
                    407:            }
                    408:        }
                    409:     }
                    410:     /* Bad Access */
                    411:     return (-1);
                    412: }
                    413: 
                    414: /* Check if a host is not in the access control list. 
                    415:  * Returns 1 if host is invalid, 0 if we've found it. */
                    416: 
                    417: InvalidHost (saddr, len)
                    418:     register struct sockaddr   *saddr;
                    419:     int                                len;
                    420: {
                    421:     short                      family;
                    422:     pointer                    addr;
                    423:     register HOST              *host;
                    424:     if ((family = ConvertAddr (saddr, len ? &len : 0, &addr)) < 0)
                    425:         return (1);
                    426:     if (family == 0)
                    427:         return (0);
                    428:     if (!AccessEnabled)   /* just let them in */
                    429:         return(0);    
                    430:     for (host = validhosts; host; host = host->next)
                    431:     {
                    432:         if (family == host->family && !bcmp (addr, host->addr, len))
                    433:            return (0);
                    434:     }
                    435:     return (1);
                    436: }
                    437: 
                    438: ConvertAddr (saddr, len, addr)
                    439:     register struct sockaddr   *saddr;
                    440:     int                                *len;
                    441:     pointer                    *addr;
                    442: {
                    443:     if (len == 0)
                    444:         return (0);
                    445:     switch (saddr->sa_family)
                    446:     {
                    447:       case AF_UNSPEC:
                    448:       case AF_UNIX:
                    449:         return (0);
                    450:       case AF_INET:
                    451: #ifdef TCPCONN
                    452:         *len = sizeof (struct in_addr);
                    453:         *addr = (pointer) &(((struct sockaddr_in *) saddr)->sin_addr);
                    454:         return (AF_INET);
                    455: #else TCPCONN
                    456:         break;
                    457: #endif TCPCONN
                    458: 
                    459: #ifdef DNETCONN
                    460:       case AF_DECnet:
                    461:         *len = sizeof (struct dn_naddr);
                    462:         *addr = (pointer) &(((struct sockaddr_dn *) saddr)->sdn_add);
                    463:         return (AF_DECnet);
                    464: #else DNETCONN
                    465:         break;
                    466: #endif DNETCONN
                    467: 
                    468:       default:
                    469:         break;
                    470:     }
                    471:     return (-1);
                    472: }
                    473: 
                    474: ChangeAccessControl(client, fEnabled)
                    475:     ClientPtr client;
                    476:     int fEnabled;
                    477: {
                    478:     int                alen, family;
                    479:     struct sockaddr    from;
                    480:     pointer            addr;
                    481:     register HOST      *host;
                    482: 
                    483:     alen = sizeof (from);
                    484:     if (!getpeername (((osPrivPtr)client->osPrivate)->fd, &from, &alen))
                    485:     {
                    486:         if ((family = ConvertAddr (&from, &alen, &addr)) >= 0)
                    487:        {
                    488:            if (family == 0)
                    489:                AccessEnabled = fEnabled;
                    490:            for (host = selfhosts; host; host = host->next)
                    491:            {
                    492:                if (family == host->family &&
                    493:                    !bcmp (addr, host->addr, alen))
                    494:                    AccessEnabled = fEnabled;
                    495:            }
                    496:        }
                    497:     }
                    498: }
                    499: 
                    500: static int XFamily(af)
                    501:     int af;
                    502: {
                    503:     int i;
                    504:     for (i = 0; i < FAMILIES; i++)
                    505:         if (familyMap[i].af == af)
                    506:             return familyMap[i].xf;
                    507:     return -1;
                    508: }
                    509: 
                    510: static int UnixFamily(xf)
                    511:     int xf;
                    512: {
                    513:     int i;
                    514:     for (i = 0; i < FAMILIES; i++)
                    515:         if (familyMap[i].xf == xf)
                    516:             return familyMap[i].af;
                    517:     return -1;
                    518: }
                    519: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.