pppSecretLib.c
上传用户:nvosite88
上传日期:2007-01-17
资源大小:4983k
文件大小:10k
源码类别:

VxWorks

开发平台:

C/C++

  1. /* pppSecretLib.c - PPP authentication secrets library */
  2. /* Copyright 1995 Wind River Systems, Inc. */
  3. #include "copyright_wrs.h"
  4. /*
  5. modification history
  6. --------------------
  7. 01g,14mar99,jdi  doc: removed refs to config.h and/or configAll.h (SPR 25663).
  8. 01f,20aug98,fle  doc : removed tab from func headers
  9. 01e,19dec95,vin  doc tweaks.
  10. 01d,11jul95,dzb  doc tweaks.
  11. 01c,06jul95,dzb  added doc.
  12. 01b,13jun95,dzb  cleaned up i960 compiler warning.  header file consolidation.
  13. 01a,08may95,dzb  written.
  14. */
  15. /*
  16. DESCRIPTION
  17. This library provides routines to create and manipulate a table of
  18. "secrets" for use with Point-to-Point Protocol (PPP) user authentication
  19. protocols.  The secrets in the secrets table can be searched by peers on
  20. a PPP link so that one peer (client) can send a secret word to the other
  21. peer (server).  If the client cannot find a suitable secret when
  22. required to do so, or the secret received by the server is not
  23. valid, the PPP link may be terminated.
  24. This library is automatically linked into the VxWorks system image when
  25. the configuration macro INCLUDE_PPP is defined.
  26. INCLUDE FILES: pppLib.h
  27. SEE ALSO: pppLib, pppShow,
  28. .pG "Network"
  29. */
  30. /* includes */
  31. #include "vxWorks.h"
  32. #include "string.h"
  33. #include "stdlib.h"
  34. #include "stdio.h"
  35. #include "errnoLib.h"
  36. #include "semLib.h"
  37. #include "pppLib.h"
  38. /* globals */
  39. PPP_SECRET * pppSecretHead = NULL; /* head of table linked list */
  40. /* locals */
  41. LOCAL SEM_ID  pppSemId = NULL; /* protect access to table */
  42. /*******************************************************************************
  43. *
  44. * pppSecretLibInit - initialize the PPP authentication secrets table facility
  45. *
  46. * This routine links the PPP secrets facility into the VxWorks system image.
  47. * It is called from usrNetwork.c when the configuration macro INCLUDE_PPP
  48. * is defined.
  49. *
  50. * RETURNS: N/A
  51. *
  52. * NOMANUAL
  53. */
  54. STATUS pppSecretLibInit (void)
  55.     {
  56.     if (pppSemId == NULL) /* already initialized? */
  57.         if ((pppSemId = semMCreate (SEM_Q_PRIORITY | SEM_INVERSION_SAFE))
  58.     == NULL)
  59.             return (ERROR);
  60.     return (OK);
  61.     }
  62. /*******************************************************************************
  63. *
  64. * pppSecretAdd - add a secret to the PPP authentication secrets table
  65. *
  66. * This routine adds a secret to the Point-to-Point Protocol (PPP)
  67. * authentication secrets table.  This table may be used by the
  68. * Password Authentication Protocol (PAP) and Challenge-Handshake
  69. * Authentication Protocol (CHAP) user authentication protocols.
  70. *
  71. * When a PPP link is established, a "server" may require a "client" to
  72. * authenticate itself using a "secret".  Clients and servers obtain
  73. * authentication secrets by searching secrets files, or by searching
  74. * the secrets table constructed by this routine.  Clients and servers
  75. * search the secrets table by matching client and server names with table
  76. * entries, and retrieving the associated secret.
  77. *
  78. * Client and server names in the table consisting of "*" are considered
  79. * wildcards; they serve as matches for any client and/or server name if
  80. * an exact match cannot be found.
  81. *
  82. * If <secret> starts with "@", <secret> is assumed to be the name of a file,
  83. * wherein the actual secret can be read.
  84. *
  85. * If <addrs> is not NULL, it should contain a list of acceptable client IP
  86. * addresses.   When a server is authenticating a client and the client's
  87. * IP address is not contained in the list of acceptable addresses,
  88. * the link is terminated.  Any IP address will be considered acceptable
  89. * if <addrs> is NULL.  If this parameter is "-", all IP addresses are
  90. * disallowed.
  91. * RETURNS: OK, or ERROR if the secret cannot be added to the table.
  92. *
  93. * SEE ALSO: pppSecretDelete(), pppSecretShow()
  94. */
  95. STATUS pppSecretAdd
  96.     (
  97.     char * client, /* client being authenticated */
  98.     char * server, /* server performing authentication */
  99.     char * secret, /* secret used for authentication */
  100.     char * addrs /* acceptable client IP addresses */
  101.     )
  102.     {
  103.     PPP_SECRET * pSecret; /* pointer to new secret */
  104.     if (pppSemId == NULL)
  105. {
  106.         errno = S_pppSecretLib_NOT_INITIALIZED;
  107. return (ERROR);
  108. }
  109.     if ((pSecret = (PPP_SECRET *) calloc (1, sizeof (struct ppp_secret))) ==
  110. NULL)
  111. return (ERROR);
  112.     /* copy secret information */
  113.     if (client)
  114.         strcpy (pSecret->client, client);
  115.     if (server)
  116.         strcpy (pSecret->server, server);
  117.     if (secret)
  118.         strcpy (pSecret->secret, secret);
  119.     if (addrs)
  120.         strcpy (pSecret->addrs, addrs);
  121.     /* hook into secret list */
  122.     semTake (pppSemId, WAIT_FOREVER); /* exclusive access to list */
  123.     pSecret->secretNext = pppSecretHead; /* put secret on front */
  124.     pppSecretHead = pSecret;
  125.     semGive (pppSemId); /* give up access */
  126.     return (OK);
  127.     }
  128. /*******************************************************************************
  129. *
  130. * pppSecretDelete - delete a secret from the PPP authentication secrets table
  131. *
  132. * This routine deletes a secret from the Point-to-Point Protocol (PPP)
  133. * authentication secrets table.  When searching for a secret to delete
  134. * from the table, the wildcard substitution (using "*") is not performed for
  135. * client and/or server names.  The <client>, <server>, and <secret>
  136. * strings must match the table entry exactly in order to be deleted.
  137. *
  138. * RETURNS: OK, or ERROR if the table entry being deleted is not found.
  139. *
  140. * SEE ALSO: pppSecretAdd(), pppSecretShow()
  141. */
  142. STATUS pppSecretDelete
  143.     (
  144.     char * client, /* client being authenticated */
  145.     char * server, /* server performing authentication */
  146.     char * secret /* secret used for authentication */
  147.     )
  148.     {
  149.     PPP_SECRET * pSecret;
  150.     PPP_SECRET ** ppPrev; /* list trailer */
  151.     if (pppSemId == NULL)
  152. {
  153.         errno = S_pppSecretLib_NOT_INITIALIZED;
  154. return (ERROR);
  155. }
  156.     semTake (pppSemId, WAIT_FOREVER); /* exclusive access to list */
  157.     /* find secret */
  158.     ppPrev = &pppSecretHead;
  159.     for (pSecret = pppSecretHead; pSecret != NULL; pSecret =
  160. pSecret->secretNext)
  161.         {
  162.         if ((!strcmp (client, pSecret->client)) &&
  163.            (!strcmp (server, pSecret->server)) &&
  164.            (!strcmp (secret, pSecret->secret)))
  165.     break;
  166.         ppPrev = &pSecret->secretNext; /* update list trailer */
  167.         }
  168.  
  169.     if (pSecret != NULL)
  170.         *ppPrev = pSecret->secretNext;
  171.     /* unhook from secret list */
  172.     semGive (pppSemId); /* give up access */
  173.     if (pSecret == NULL) /* secret found ? */
  174. {
  175.         errno = S_pppSecretLib_SECRET_DOES_NOT_EXIST;
  176. return (ERROR);
  177. }
  178.     free (pSecret); /* free secret */
  179.     return (OK);
  180.     }
  181. /*******************************************************************************
  182. *
  183. * pppSecretFind - find the best-fit secret in the PPP auth. secrets table
  184. *
  185. * This routine searches the PPP authentication secrets table for a suitable
  186. * secret to authenticate the given <client> and <server>.  The secret is
  187. * returned in the <secret> parameter.  The list of authorized client IP
  188. * addresses are returned in the <ppAddrs> parameter.  If the secret starts
  189. * with "@", the secret is taken to be a filename, wherein which the actual
  190. * secret is read.
  191. * RETURNS: flag determining strength of the secret, or ERROR if no
  192. * suitable secret could be found.
  193. *
  194. * NOMANUAL
  195. */
  196. int pppSecretFind
  197.     (
  198.     char * client, /* client being authenticated */
  199.     char * server, /* server performing authentication */
  200.     char * secret, /* secret used for authentication */
  201.     struct wordlist ** ppAddrs
  202.     )
  203.     {
  204.     PPP_SECRET * pSecret = NULL;
  205.     PPP_SECRET * pEntry;
  206.     char  atfile [MAXWORDLEN];
  207.     char word [MAXWORDLEN];
  208.     char * pWord;
  209.     char * separators = {" t"};
  210.     char * pAddr;
  211.     char * pLast = NULL;
  212.     FILE * sf;
  213.     int got_flag = 0;
  214.     int best_flag = -1;
  215.     int xxx;
  216.     struct wordlist * addr_list = NULL;
  217.     struct wordlist * addr_last = NULL;
  218.     struct wordlist * ap;
  219.     if (pppSemId == NULL)
  220. {
  221.         errno = S_pppSecretLib_NOT_INITIALIZED;
  222. return (ERROR);
  223. }
  224.     semTake (pppSemId, WAIT_FOREVER); /* exclusive access to list */
  225.     /* find best secret entry */
  226.     for (pEntry = pppSecretHead; pEntry != NULL; pEntry = pEntry->secretNext)
  227. {
  228.          /* check for a match */
  229. if (((client != NULL) && client[0] && strcmp (client, pEntry->client)
  230.             && !ISWILD (pEntry->client)) ||
  231.             ((server != NULL) && server[0] && strcmp (server, pEntry->server)
  232.             && !ISWILD (pEntry->server)))
  233.             continue;
  234.         if (!ISWILD (pEntry->client))
  235.             got_flag = NONWILD_CLIENT;
  236.         if (!ISWILD (pEntry->server))
  237.             got_flag |= NONWILD_SERVER;
  238.  
  239.         if (got_flag > best_flag)
  240.             {
  241.             pSecret = pEntry; /* update best entry */
  242.     best_flag = got_flag;
  243.             }
  244.         }
  245.     semGive (pppSemId); /* give up access */
  246.     if (pSecret == NULL) /* secret found ? */
  247. {
  248.         errno = S_pppSecretLib_SECRET_DOES_NOT_EXIST;
  249. return (ERROR);
  250. }
  251.     /* check for special syntax: @filename means read secret from file */
  252.     if (secret != NULL)
  253. {
  254.         if (pSecret->secret[0] == '@')
  255.             {
  256.             strcpy (atfile, pSecret->secret + 1);
  257.             if ((sf = fopen(atfile, "r")) == NULL)
  258. {
  259.                 syslog (LOG_ERR, "can't open indirect secret file %s",
  260.     atfile);
  261.                 fclose (sf);
  262.         return (ERROR);
  263. }
  264.             check_access (sf, atfile);
  265.             if (!getword (sf, word, &xxx, atfile))
  266. {
  267.                 syslog (LOG_ERR, "no secret in indirect secret file %s",
  268.     atfile);
  269.                 fclose (sf);
  270.         return (ERROR);
  271. }
  272.             fclose (sf);
  273.             strcpy (secret, word);
  274.             }
  275.         else
  276.             strcpy (secret, pSecret->secret); /* stuff secret for return */
  277.         }
  278.     /* read address authorization info and make a wordlist */
  279.     if (ppAddrs != NULL)
  280. {
  281.         *ppAddrs = NULL; /* tie off in case error */
  282.         strcpy (word, pSecret->addrs);
  283. pWord = word;
  284.         while ((pAddr = strtok_r (pWord, separators, &pLast)) != NULL)
  285.     {
  286.     pWord = NULL;
  287.             if ((ap = (struct wordlist *) malloc (sizeof (struct wordlist)
  288.                                         + strlen (pAddr))) == NULL)
  289.                 novm("authorized addresses");
  290.             ap->next = NULL;
  291.             strcpy (ap->word, pAddr); /* stuff word */
  292.             if (addr_list == NULL)
  293.                 addr_list = ap; /* first word */
  294.             else
  295.                 addr_last->next = ap; /* tie in subsequent words */
  296.             addr_last = ap; /* bump current word pointer */
  297.             }
  298.         *ppAddrs = addr_list; /* hook wordlist for return */
  299.         }
  300.  
  301.     return (best_flag);
  302.     }