sockd_util.c
上传用户:zm130024
上传日期:2007-01-04
资源大小:432k
文件大小:8k
源码类别:

代理服务器

开发平台:

Unix_Linux

  1. /*
  2.  * Copyright (c) 1997, 1998, 1999
  3.  *      Inferno Nettverk A/S, Norway.  All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  * 1. The above copyright notice, this list of conditions and the following
  9.  *    disclaimer must appear in all copies of the software, derivative works
  10.  *    or modified versions, and any portions thereof, aswell as in all
  11.  *    supporting documentation.
  12.  * 2. All advertising materials mentioning features or use of this software
  13.  *    must display the following acknowledgement:
  14.  *      This product includes software developed by
  15.  *      Inferno Nettverk A/S, Norway.
  16.  * 3. The name of the author may not be used to endorse or promote products
  17.  *    derived from this software without specific prior written permission.
  18.  *
  19.  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  20.  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  21.  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  22.  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  23.  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  24.  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  25.  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  26.  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  27.  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  28.  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  29.  *
  30.  * Inferno Nettverk A/S requests users of this software to return to
  31.  *
  32.  *  Software Distribution Coordinator  or  sdc@inet.no
  33.  *  Inferno Nettverk A/S
  34.  *  Oslo Research Park
  35.  *  Gaustadal閑n 21
  36.  *  N-0349 Oslo
  37.  *  Norway
  38.  *
  39.  * any improvements or extensions that they make and grant Inferno Nettverk A/S
  40.  * the rights to redistribute these changes.
  41.  *
  42.  */
  43. #include "common.h"
  44. static const char rcsid[] =
  45. "$Id: sockd_util.c,v 1.59 1999/12/22 09:29:27 karls Exp $";
  46. #define CM2IM(charmethodv, methodc, intmethodv) 
  47. do { 
  48. int cm2im = methodc; 
  49. while (--cm2im >= 0) 
  50. intmethodv[cm2im] = charmethodv[cm2im]; 
  51. } while (lintnoloop_sockd_h) 
  52. int
  53. selectmethod(methodv, methodc)
  54. const unsigned char *methodv;
  55. size_t methodc;
  56. {
  57. const char stdmethodv[] = {AUTHMETHOD_NONE, AUTHMETHOD_UNAME};
  58. int i;
  59. for (i = 0; i < config.methodc; ++i) {
  60. if (config.methodv[i] > AUTHMETHOD_NOACCEPT) { /* pseudo method */
  61. int intmethodv[AUTHMETHOD_MAX];
  62. CM2IM(methodv, methodc, intmethodv);
  63. switch (config.methodv[i]) {
  64. case AUTHMETHOD_RFC931: {
  65. /* can select any standard method. */
  66. size_t ii;
  67. for (ii = 0; ii < ELEMENTS(stdmethodv); ++i)
  68. if (methodisset(stdmethodv[i], intmethodv, methodc))
  69. return stdmethodv[i];
  70. break;
  71. }
  72. default:
  73. SERRX(config.methodv[i]);
  74. }
  75. }
  76. if (memchr(methodv, (unsigned char)config.methodv[i], (size_t)methodc)
  77. != NULL)
  78. return config.methodv[i];
  79. }
  80. return AUTHMETHOD_NOACCEPT;
  81. }
  82. void
  83. setsockoptions(s)
  84. int s;
  85. {
  86. const char *function = "setsockoptions()";
  87. socklen_t len;
  88. int type, val, bufsize;
  89. #ifdef SO_BSDCOMPAT
  90. val = 1;
  91. if (setsockopt(s, SOL_SOCKET, SO_BSDCOMPAT, &val, sizeof(val)) != 0)
  92. swarn("%s: setsockopt(SO_BSDCOMPAT)", function);
  93. #endif /* SO_BSDCOMPAT */
  94. len = sizeof(type);
  95. if (getsockopt(s, SOL_SOCKET, SO_TYPE, &type, &len) != 0) {
  96. swarn("%s: getsockopt(SO_TYPE)", function);
  97. return;
  98. }
  99. switch (type) {
  100. case SOCK_STREAM:
  101. bufsize = SOCKD_BUFSIZETCP;
  102. val = 1;
  103. if (setsockopt(s, SOL_SOCKET, SO_OOBINLINE, &val, sizeof(val)) != 0)
  104. swarn("%s: setsockopt(SO_OOBINLINE)", function);
  105. if (config.option.keepalive) {
  106. val = 1;
  107. if (setsockopt(s, SOL_SOCKET, SO_KEEPALIVE, &val, sizeof(val)) != 0)
  108. swarn("%s: setsockopt(SO_KEEPALIVE)", function);
  109. }
  110. break;
  111. case SOCK_DGRAM:
  112. bufsize = SOCKD_BUFSIZEUDP;
  113. val = 1;
  114. if (setsockopt(s, SOL_SOCKET, SO_BROADCAST, &val, sizeof(val)) != 0)
  115. if (errno != ENOPROTOOPT)
  116. swarn("%s: setsockopt(SO_BROADCAST)", function);
  117. break;
  118. default:
  119. SERRX(type);
  120. }
  121. val = bufsize;
  122. if (setsockopt(s, SOL_SOCKET, SO_SNDBUF, &val, sizeof(val)) != 0
  123. ||  setsockopt(s, SOL_SOCKET, SO_RCVBUF, &val, sizeof(val)) != 0)
  124. swarn("%s: setsockopt(SO_SNDBUF/SO_RCVBUF)", function);
  125. #if HAVE_LIBWRAP
  126. if ((val = fcntl(s, F_GETFD, 0)) == -1
  127. || fcntl(s, F_SETFD, val | FD_CLOEXEC) == -1)
  128. swarn("%s: fcntl(F_GETFD/F_SETFD)", function);
  129. #endif
  130. }
  131. void
  132. sockdexit(sig)
  133. int sig;
  134. {
  135. const char *function = "sockdexit()";
  136. int i;
  137. if (pidismother(config.state.pid)) {
  138. if (*config.state.motherpidv == config.state.pid) /* main mother. */
  139. if (sig > 0)
  140. slog(LOG_ALERT, "%s: terminating on signal %d", function, sig);
  141. else
  142. slog(LOG_ALERT, "%s: terminating", function, sig);
  143. /* don't want this while cleaning up, which is all that's left. */
  144. if (signal(SIGCHLD, SIG_IGN) == SIG_ERR)
  145. swarn("%s: signal(SIGCHLD, SIG_IGN)", function);
  146. }
  147. #if HAVE_PROFILING
  148. if (chdir(SOCKS_PROFILEDIR) != 0)
  149. swarn("%s: chdir(%s)", function, SOCKS_PROFILEDIR);
  150. else {
  151. char dir[80];
  152. snprintf(dir, sizeof(dir), "%s.%d",
  153. childtype2string(config.state.type), getpid());
  154. if (mkdir(dir, S_IRWXU) != 0)
  155. swarn("%s: mkdir(%s)", function, dir);
  156. else
  157. if (chdir(dir) != 0)
  158. swarn("%s: chdir(%s)", function, dir);
  159. }
  160. #endif /* HAVE_PROFILING */
  161. for (i = 0;  i < config.log.fpc; ++i) {
  162. fclose(config.log.fpv[i]);
  163. close(config.log.fplockv[i]);
  164. }
  165. if (sig > 0)
  166. switch (sig) {
  167. /* ok signals. */
  168. case SIGINT:
  169. case SIGQUIT:
  170. case SIGTERM:
  171. break;
  172. /* bad signals. */
  173. default:
  174. abort();
  175. }
  176. if (*config.state.motherpidv == config.state.pid) /* main mother. */
  177. exit(sig > 0 ? EXIT_FAILURE : -sig);
  178. else
  179. #if HAVE_PROFILING
  180. exit(sig > 0 ? EXIT_FAILURE : -sig);
  181. #else
  182. _exit(sig > 0 ? EXIT_FAILURE : -sig);
  183. #endif /* HAVE_PROFILING */
  184. }
  185. void
  186. socks_seteuid(old, new)
  187. uid_t *old;
  188. uid_t new;
  189. {
  190. const char *function = "socks_seteuid()";
  191. uid_t oldmem;
  192. if (old == NULL)
  193. old = &oldmem;
  194. *old = geteuid();
  195. slog(LOG_DEBUG, "%s: old: %lu, new: %lu", function, *old, new);
  196. if (*old == new)
  197. return;
  198. if (*old != config.state.euid)
  199. /* need to revert back to original (presumably 0) euid before changing. */
  200. if (seteuid(config.state.euid) != 0) {
  201. slog(LOG_ERR, "running linux are we?");
  202. SERR(config.state.euid);
  203. }
  204. if (seteuid(new) != 0)
  205. serr(EXIT_FAILURE, "%s: seteuid(%d)", function, new);
  206. }
  207. void
  208. socks_reseteuid(current, new)
  209. uid_t current;
  210. uid_t new;
  211. {
  212. const char *function = "socks_reseteuid()";
  213. slog(LOG_DEBUG, "%s: current: %lu, new: %lu", function, current, new);
  214. #if DIAGNOSTIC
  215. SASSERTX(current == geteuid());
  216. #endif
  217. if (current == new)
  218. return;
  219. if (new != config.state.euid)
  220. /* need to revert back to original (presumably 0) euid before changing. */
  221. if (seteuid(config.state.euid) != 0)
  222. SERR(config.state.euid);
  223. if (seteuid(new) != 0)
  224. SERR(new);
  225. }
  226. int
  227. passwordcheck(name, clearpassword)
  228. const char *name;
  229. const char *clearpassword;
  230. {
  231. /* const char *function = "passwordcheck()"; */
  232. struct passwd *pw;
  233. char *salt, *password;
  234. uid_t euid;
  235. int ok;
  236. socks_seteuid(&euid, config.uid.privileged);
  237. if ((pw = getpwnam(name)) == NULL) {
  238. salt = "*";
  239. password = "*";
  240. ok = 0;
  241. }
  242. else {
  243. salt = pw->pw_passwd;
  244. password = pw->pw_passwd;
  245. ok = 1;
  246. }
  247. socks_reseteuid(config.uid.privileged, euid);
  248. if (clearpassword != NULL) /* XXX waste cycles correctly? */
  249. if (strcmp(crypt(clearpassword, salt), password) == 0)
  250. ok = 1;
  251. else
  252. ok = 0;
  253. if (ok)
  254. return 0;
  255. if (pw == NULL)
  256. return 1;
  257. else
  258. return 2;
  259. }