TACACS.cpp
上传用户:woshihumen
上传日期:2013-07-18
资源大小:484k
文件大小:9k
源码类别:

Email服务器

开发平台:

Visual C++

  1. /*
  2.  *  XMail by Davide Libenzi ( Intranet and Internet mail server )
  3.  *  Copyright (C) 1999,..,2004  Davide Libenzi
  4.  *
  5.  *  This program is free software; you can redistribute it and/or modify
  6.  *  it under the terms of the GNU General Public License as published by
  7.  *  the Free Software Foundation; either version 2 of the License, or
  8.  *  (at your option) any later version.
  9.  *
  10.  *  This program is distributed in the hope that it will be useful,
  11.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.  *  GNU General Public License for more details.
  14.  *
  15.  *  You should have received a copy of the GNU General Public License
  16.  *  along with this program; if not, write to the Free Software
  17.  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  18.  *
  19.  *  Davide Libenzi <davidel@xmailserver.org>
  20.  *
  21.  */
  22. #include "SysInclude.h"
  23. #include "SysDep.h"
  24. #include "SvrDefines.h"
  25. #include "ShBlocks.h"
  26. #include "StrUtils.h"
  27. #include "SList.h"
  28. #include "MailConfig.h"
  29. #include "MailSvr.h"
  30. #include "MiscUtils.h"
  31. #include "TACACS.h"
  32. /*
  33. #define ERR_TACACS_AUTH_FAILED      (-???)
  34. #define ERR_TACACS_AUTH_UNAVAILABLE (-???)
  35. #define ERR_TACACS_FILE_NOT_FOUND   (-???)
  36. #define ERR_TACACS_SERVER_NOT_FOUND (-???)
  37. {ERR_TACACS_AUTH_FAILED, "TACACS authentication failed", NULL},
  38. {ERR_TACACS_AUTH_UNAVAILABLE, "TACACS authentication server unavailable", NULL},
  39. {ERR_TACACS_FILE_NOT_FOUND, "TACACS configuration file not found", NULL},
  40. {ERR_TACACS_SERVER_NOT_FOUND, "TACACS server for domain not found", NULL},
  41.     */
  42. #define TACACS_TIMEOUT          15
  43. #define TACACS_SEND_RETRIES     3
  44. #define TACACS_DPORT            110
  45. #define TACACS_LPORT            0
  46. #define TACS_CONFIG_FILE        "tacacsservers.tab"
  47. #define TACS_ALIAS_LINE_MAX     1024
  48. #define TACACS_SVC_NAME         "tacacs"
  49. #define TACACS_PORT             49
  50. #define XTA_VERSION             0x80
  51. #define TA_QUERY                1
  52. #define TA_ANSWER               2
  53. #define TA_CHANGE               3
  54. #define TA_FOLLOW               4
  55. #define TA_A_ACCEPTED           1
  56. #define TA_A_REJECTED           2
  57. #define TA_A_NONE               0
  58. #define TA_A_EXPIRING           1
  59. #define TA_A_PASSWORD           2
  60. #define TA_A_DENIED             3
  61. #define TA_A_NOROUTE            8 /* Dialup routing not allowed           */
  62. #define TA_A_LOGINREQ           9 /* Login required for requested action  */
  63. #define XTACACSSIZE             sizeof(xtacacstype)
  64. #define XTA_LOGIN               1
  65. #define XTA_ANSWER              2
  66. #define XTA_CHANGE              3
  67. #define XTA_FOLLOW              4
  68. #define XTA_CONNECT             5
  69. #define XTA_ENABLE              6
  70. #define XTA_LOGOUT              7
  71. #define XTA_RELOAD              8
  72. #define XTA_SLIPON              9
  73. #define XTA_SLIPOFF             10
  74. #define XTA_SLIPADDR            11
  75. #define XTA_ARAP_AUTH           12
  76. #define XTA_CHAP_AUTH           13
  77. #define XTA_A_ACCEPTED          1
  78. #define XTA_A_REJECTED          2
  79. #define XTA_A_NONE              0
  80. #define XTA_A_EXPIRING          1 /* Account expiring                     */
  81. #define XTA_A_PASSWORD          2 /* Wrong password                       */
  82. #define XTA_A_DENIED            3 /* Permission denied                    */
  83. #define XTA_A_NOROUTE           8 /* Dialup routing not permitted         */
  84. #define XTA_A_LOGINREQ          9 /* Login required for requested action  */
  85. enum TacsFields {
  86. tacsDomain = 0,
  87. tacsServer,
  88. tacsPort,
  89. tacsMax
  90. };
  91. struct xtacacstype {
  92. SYS_UINT8 version; /* version of protocol      */
  93. SYS_UINT8 type; /* Type of query/response   */
  94. SYS_UINT16 trans; /* transaction ID           */
  95. SYS_UINT8 namelen; /* length of name           */
  96. SYS_UINT8 pwlen; /* length of password       */
  97. SYS_UINT8 response; /* response code            */
  98. SYS_UINT8 reason; /* reason for response      */
  99. SYS_UINT32 uuid; /* user id code assigned    */
  100. SYS_UINT32 dhost; /* destination host         */
  101. SYS_UINT16 dport; /* destination port         */
  102. SYS_UINT16 lport; /* local line number        */
  103. SYS_UINT32 flags; /* misc flags               */
  104. SYS_UINT16 accesslist; /* access list for user     */
  105. /*                  user name[]                             */
  106. /*                  password[]                              */
  107. };
  108. static char *TacsGetConfigFilePath(char *pszTacsFile);
  109. static int TacsGetServerName(char const *pszDomain, char *pszTacsServer, int &iPortNo);
  110. static char *TacsGetConfigFilePath(char *pszTacsFile)
  111. {
  112. CfgGetRootPath(pszTacsFile);
  113. strcat(pszTacsFile, TACS_CONFIG_FILE);
  114. return (pszTacsFile);
  115. }
  116. static int TacsGetServerName(char const *pszDomain, char *pszTacsServer, int &iPortNo)
  117. {
  118. char szTacsFile[SYS_MAX_PATH] = "";
  119. TacsGetConfigFilePath(szTacsFile);
  120. FILE *pTacsFile = fopen(szTacsFile, "rt");
  121. if (pTacsFile == NULL) {
  122. ErrSetErrorCode(ERR_TACACS_FILE_NOT_FOUND);
  123. return (ERR_TACACS_FILE_NOT_FOUND);
  124. }
  125. char szTacsLine[TACS_ALIAS_LINE_MAX] = "";
  126. while (MscGetConfigLine(szTacsLine, sizeof(szTacsLine) - 1, pTacsFile) != NULL) {
  127. char **ppszStrings = StrGetTabLineStrings(szTacsLine);
  128. if (ppszStrings == NULL)
  129. continue;
  130. int iFieldsCount = StrStringsCount(ppszStrings);
  131. if ((iFieldsCount >= tacsMax) &&
  132.     StrIWildMatch(pszDomain, ppszStrings[tacsDomain])) {
  133. strcpy(pszTacsServer, ppszStrings[tacsServer]);
  134. iPortNo = atoi(ppszStrings[tacsPort]);
  135. StrFreeStrings(ppszStrings);
  136. fclose(pTacsFile);
  137. return (0);
  138. }
  139. StrFreeStrings(ppszStrings);
  140. }
  141. fclose(pTacsFile);
  142. ErrSetErrorCode(ERR_TACACS_SERVER_NOT_FOUND);
  143. return (ERR_TACACS_SERVER_NOT_FOUND);
  144. }
  145. int TacsAuthenticate(char const *pszDomain, char const *pszUsername,
  146.      char const *pszPassword, int iServicePort)
  147. {
  148. ///////////////////////////////////////////////////////////////////////////////
  149. //  Get TACACS server coordinates
  150. ///////////////////////////////////////////////////////////////////////////////
  151. int iPortNo = TACACS_PORT;
  152. char szTacsServer[MAX_HOST_NAME] = "";
  153. if (TacsGetServerName(pszDomain, szTacsServer, iPortNo) < 0)
  154. return (ErrGetErrorCode());
  155. ///////////////////////////////////////////////////////////////////////////////
  156. //  If not specified use POP3 port ( TACACS_DPORT )
  157. ///////////////////////////////////////////////////////////////////////////////
  158. if (iServicePort < 0)
  159. iServicePort = TACACS_DPORT;
  160. ///////////////////////////////////////////////////////////////////////////////
  161. //  Open TACACS server socket
  162. ///////////////////////////////////////////////////////////////////////////////
  163. SYS_SOCKET SockFD;
  164. SYS_INET_ADDR SvrAddr;
  165. SYS_INET_ADDR SockAddr;
  166. if (MscCreateClientSocket(szTacsServer, iPortNo, SOCK_DGRAM, &SockFD, &SvrAddr,
  167.   &SockAddr, TACACS_TIMEOUT) < 0)
  168. return (ErrGetErrorCode());
  169. ///////////////////////////////////////////////////////////////////////////////
  170. //  Build TACACS request packet
  171. ///////////////////////////////////////////////////////////////////////////////
  172. char szBuffer[1024] = "";
  173. xtacacstype *pTacs = (xtacacstype *) szBuffer;
  174. ZeroData(szBuffer);
  175. pTacs->type = XTA_LOGIN;
  176. pTacs->version = XTA_VERSION;
  177. pTacs->trans = htons((unsigned short) SysGetCurrentThreadId());
  178. pTacs->reason = XTA_A_NONE;
  179. pTacs->dhost = (SYS_UINT32) SysGetAddrAddress(SockAddr);
  180. pTacs->dport = htons((unsigned short) iServicePort);
  181. pTacs->lport = htons(TACACS_LPORT);
  182. pTacs->namelen = (SYS_UINT8) strlen(pszUsername);
  183. pTacs->pwlen = (SYS_UINT8) strlen(pszPassword);
  184. int iQueryLenght = XTACACSSIZE + pTacs->namelen + pTacs->pwlen;
  185. memcpy(&szBuffer[XTACACSSIZE], pszUsername, pTacs->namelen);
  186. memcpy(&szBuffer[XTACACSSIZE + pTacs->namelen], pszPassword, pTacs->pwlen);
  187. for (int iSendLoops = 0; iSendLoops < TACACS_SEND_RETRIES; iSendLoops++) {
  188. ///////////////////////////////////////////////////////////////////////////////
  189. //  Send packet
  190. ///////////////////////////////////////////////////////////////////////////////
  191. if (SysSendDataTo(SockFD, (const struct sockaddr *) &SvrAddr, sizeof(SvrAddr),
  192.   szBuffer, iQueryLenght, TACACS_TIMEOUT) != iQueryLenght)
  193. continue;
  194. ///////////////////////////////////////////////////////////////////////////////
  195. //  Receive packet lenght
  196. ///////////////////////////////////////////////////////////////////////////////
  197. SYS_INET_ADDR RecvAddr;
  198. SYS_UINT8 RespBuffer[1024];
  199. ZeroData(RecvAddr);
  200. ZeroData(RespBuffer);
  201. int iPacketLenght =
  202.     SysRecvDataFrom(SockFD, (struct sockaddr *) &RecvAddr, sizeof(RecvAddr),
  203.     (char *) RespBuffer, sizeof(RespBuffer), TACACS_TIMEOUT);
  204. if (iPacketLenght < XTACACSSIZE)
  205. continue;
  206. xtacacstype *pRespTacs = (xtacacstype *) RespBuffer;
  207. if (pRespTacs->response != 1) {
  208. SysCloseSocket(SockFD);
  209. ErrSetErrorCode(ERR_TACACS_AUTH_FAILED);
  210. return (ERR_TACACS_AUTH_FAILED);
  211. }
  212. SysCloseSocket(SockFD);
  213. return (0);
  214. }
  215. SysCloseSocket(SockFD);
  216. ErrSetErrorCode(ERR_TACACS_AUTH_UNAVAILABLE);
  217. return (ERR_TACACS_AUTH_UNAVAILABLE);
  218. }