1 /*
2 * Copyright (c) 1997, 1998, 1999, 2000, 2001, 2008, 2009, 2010, 2011, 2012
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 * Gaustadall�en 21
36 * NO-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
44 #include "common.h"
45
46 static const char rcsid[] =
47 "$Id: userio.c,v 1.60 2012/11/01 23:57:57 michaels Exp $";
48
49 /* ARGSUSED */
50 char *
socks_getusername(host,buf,buflen)51 socks_getusername(host, buf, buflen)
52 const sockshost_t *host;
53 char *buf;
54 size_t buflen;
55 {
56 const char *function = "socks_getusername()";
57 char *name;
58
59 if ((name = socks_getenv(ENV_SOCKS_USERNAME, dontcare)) != NULL
60 || (name = socks_getenv(ENV_SOCKS_USER, dontcare)) != NULL
61 || (name = socks_getenv(ENV_SOCKS5_USER, dontcare)) != NULL)
62 slog(LOG_NEGOTIATE,
63 "%s: using socks username from environment: \"%s\"", function, name);
64 #if SOCKS_CLIENT
65 else {
66 struct passwd *pw;
67
68 if ((pw = getpwuid(getuid())) != NULL)
69 name = pw->pw_name;
70 else
71 name = getlogin();
72 }
73 #endif /* SOCKS_CLIENT */
74
75 if (name == NULL)
76 return NULL;
77
78 if (strlen(name) >= buflen) {
79 swarnx("%s: socks username %lu characters too long, truncated",
80 function, (unsigned long)((strlen(name) + 1) - buflen));
81 name[buflen - 1] = NUL;
82 }
83
84 strcpy(buf, name);
85 return buf;
86 }
87
88 char *
socks_getpassword(host,user,buf,buflen)89 socks_getpassword(host, user, buf, buflen)
90 const sockshost_t *host;
91 const char *user;
92 char *buf;
93 size_t buflen;
94 {
95 const char *function = "socks_getpassword()";
96 char *password;
97 int password_is_from_env;
98
99 if ((password = socks_getenv(ENV_SOCKS_PASSWORD, dontcare)) != NULL
100 || (password = socks_getenv(ENV_SOCKS_PASSWD, dontcare)) != NULL
101 || (password = socks_getenv(ENV_SOCKS5_PASSWD, dontcare)) != NULL)
102 password_is_from_env = 1;
103 else {
104 #if SOCKS_CLIENT && HAVE_GETPASS
105 char prompt[256 + MAXSOCKSHOSTSTRING];
106 char hstring[MAXSOCKSHOSTSTRING];
107
108 snprintf(prompt, sizeof(prompt), "%s@%s socks password: ",
109 user, sockshost2string(host, hstring, sizeof(hstring)));
110
111 password = getpass(prompt);
112
113 #else /* !SOCKS_CLIENT && HAVE_GETPASS */
114
115 password = NULL;
116 #endif /* !SOCKS_CLIENT && HAVE_GETPASS */
117
118 password_is_from_env = 0;
119 }
120
121 if (password == NULL)
122 return NULL;
123
124 if (strlen(password) >= buflen) {
125 swarnx("%s: socks password is %lu characters too long; truncated",
126 function, (unsigned long)((strlen(password) + 1) - buflen));
127
128 password[buflen - 1] = NUL;
129 }
130
131 strcpy(buf, password);
132
133 if (!password_is_from_env) /* don't zero environment. */
134 bzero(password, strlen(password));
135
136 return buf;
137 }
138
139 char *
socks_getenv(name,value)140 socks_getenv(name, value)
141 const char *name;
142 value_t value;
143 {
144 char *p = NULL;
145
146 #if SOCKS_CLIENT
147 #if HAVE_CONFENV_DISABLE
148 const char *safenames[] = { ENV_SOCKS_BINDLOCALONLY,
149 ENV_SOCKS_DEBUG,
150 ENV_SOCKS_DISABLE_THREADLOCK,
151 ENV_SOCKS_DIRECTROUTE_FALLBACK,
152 ENV_SOCKS_PASSWORD,
153 ENV_SOCKS_PASSWD,
154 ENV_SOCKS5_PASSWD,
155 ENV_SOCKS_USERNAME,
156 ENV_SOCKS_USER,
157 ENV_SOCKS5_USER,
158 };
159 size_t i;
160 #endif /* HAVE_CONFENV_DISABLE */
161
162 if (strcmp(name, ENV_SOCKS_CONF) == 0
163 || strcmp(name, ENV_SOCKS_LOGOUTPUT) == 0
164 || strcmp(name, ENV_SOCKS_ERRLOGOUTPUT) == 0
165 || strcmp(name, ENV_TMPDIR) == 0) {
166 /*
167 * Even if getenv() is not disabled, we don't want to return
168 * anything for this if the program may be running setuid,
169 * as it could allow reading/writing of arbitrary files.
170 */
171 if (issetugid())
172 return NULL;
173 else
174 return getenv(name);
175 }
176
177 #if HAVE_CONFENV_DISABLE
178 /*
179 * If the name is safe, get it regardless of confenv being disabled.
180 */
181 for (i = 0; i < ELEMENTS(safenames); ++i)
182 if (strcmp(name, safenames[i]) == 0) {
183 p = getenv(name);
184 break;
185 }
186
187 #else /* !HAVE_CONFENV_DISABLE */
188 p = getenv(name);
189 #endif /* !HAVE_CONFENV_DISABLE */
190
191 #else /* !SOCKS_CLIENT */
192 p = getenv(name);
193 #endif /* !SOCKS_CLIENT */
194
195 if (p == NULL || value == dontcare) {
196 /*
197 * Some variables have a default based on configure/define.
198 */
199 if (strcmp(name, ENV_SOCKS_DIRECTROUTE_FALLBACK) == 0)
200 p = (SOCKS_DIRECTROUTE_FALLBACK ? "yes" : "no");
201 else
202 return p;
203 }
204
205 switch (value) {
206 case istrue:
207 if (strcasecmp(p, "yes") == 0
208 || strcasecmp(p, "true") == 0
209 || strcasecmp(p, "1") == 0)
210 return p;
211 return NULL;
212
213 case isfalse:
214 if (strcasecmp(p, "no") == 0
215 || strcasecmp(p, "false") == 0
216 || strcasecmp(p, "0") == 0)
217 return p;
218 return NULL;
219
220 default:
221 SERRX(value);
222 }
223
224 /* NOTREACHED */
225 }
226