Mercurial > dropbear
comparison dbutil.c @ 4:fe6bca95afa7
Makefile.in contains updated files required
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Tue, 01 Jun 2004 02:46:09 +0000 |
parents | |
children | f76c9389e9e0 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 4:fe6bca95afa7 |
---|---|
1 /* | |
2 * Dropbear - a SSH2 server | |
3 * | |
4 * Copyright (c) 2002,2003 Matt Johnston | |
5 * All rights reserved. | |
6 * | |
7 * Permission is hereby granted, free of charge, to any person obtaining a copy | |
8 * of this software and associated documentation files (the "Software"), to deal | |
9 * in the Software without restriction, including without limitation the rights | |
10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
11 * copies of the Software, and to permit persons to whom the Software is | |
12 * furnished to do so, subject to the following conditions: | |
13 * | |
14 * The above copyright notice and this permission notice shall be included in | |
15 * all copies or substantial portions of the Software. | |
16 * | |
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
20 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |
23 * SOFTWARE. | |
24 * | |
25 * strlcat() is copyright as follows: | |
26 * Copyright (c) 1998 Todd C. Miller <[email protected]> | |
27 * All rights reserved. | |
28 * | |
29 * Redistribution and use in source and binary forms, with or without | |
30 * modification, are permitted provided that the following conditions | |
31 * are met: | |
32 * 1. Redistributions of source code must retain the above copyright | |
33 * notice, this list of conditions and the following disclaimer. | |
34 * 2. Redistributions in binary form must reproduce the above copyright | |
35 * notice, this list of conditions and the following disclaimer in the | |
36 * documentation and/or other materials provided with the distribution. | |
37 * 3. The name of the author may not be used to endorse or promote products | |
38 * derived from this software without specific prior written permission. | |
39 * | |
40 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, | |
41 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY | |
42 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL | |
43 * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |
44 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |
45 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; | |
46 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, | |
47 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR | |
48 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF | |
49 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ | |
50 | |
51 #include "includes.h" | |
52 #include "dbutil.h" | |
53 #include "buffer.h" | |
54 #include "session.h" | |
55 #include "atomicio.h" | |
56 | |
57 #define MAX_FMT 100 | |
58 | |
59 void (*_dropbear_exit)(int exitcode, const char* format, va_list param) = NULL; | |
60 void (*_dropbear_log)(int priority, const char* format, va_list param) = NULL; | |
61 | |
62 int usingsyslog = 0; /* set by runopts, but required externally to sessions */ | |
63 #ifndef DISABLE_SYSLOG | |
64 void startsyslog() { | |
65 | |
66 openlog(PROGNAME, LOG_PID, LOG_AUTHPRIV); | |
67 | |
68 } | |
69 #endif /* DISABLE_SYSLOG */ | |
70 | |
71 /* the "format" string must be <= 100 characters */ | |
72 void dropbear_close(const char* format, ...) { | |
73 | |
74 va_list param; | |
75 | |
76 va_start(param, format); | |
77 _dropbear_exit(EXIT_SUCCESS, format, param); | |
78 va_end(param); | |
79 | |
80 } | |
81 | |
82 void dropbear_exit(const char* format, ...) { | |
83 | |
84 va_list param; | |
85 | |
86 va_start(param, format); | |
87 _dropbear_exit(EXIT_FAILURE, format, param); | |
88 va_end(param); | |
89 } | |
90 | |
91 | |
92 /* this is what can be called to write arbitrary log messages */ | |
93 void dropbear_log(int priority, const char* format, ...) { | |
94 | |
95 va_list param; | |
96 | |
97 va_start(param, format); | |
98 _dropbear_log(priority, format, param); | |
99 va_end(param); | |
100 } | |
101 | |
102 | |
103 #ifdef DEBUG_TRACE | |
104 void dropbear_trace(const char* format, ...) { | |
105 | |
106 va_list param; | |
107 | |
108 va_start(param, format); | |
109 fprintf(stderr, "TRACE: "); | |
110 vfprintf(stderr, format, param); | |
111 fprintf(stderr, "\n"); | |
112 va_end(param); | |
113 } | |
114 #endif /* DEBUG_TRACE */ | |
115 | |
116 /* Return a string representation of the socket address passed. The return | |
117 * value is allocated with malloc() */ | |
118 unsigned char * getaddrstring(struct sockaddr * addr) { | |
119 | |
120 char *retstring; | |
121 | |
122 /* space for "255.255.255.255:65535\0" = 22 */ | |
123 retstring = m_malloc(22); | |
124 | |
125 switch (addr->sa_family) { | |
126 case PF_INET: | |
127 snprintf(retstring, 22, "%s:%hu", | |
128 inet_ntoa(((struct sockaddr_in *)addr)->sin_addr), | |
129 ((struct sockaddr_in *)addr)->sin_port); | |
130 break; | |
131 | |
132 default: | |
133 /* XXX ipv6 */ | |
134 strcpy(retstring, "Bad protocol"); | |
135 | |
136 } | |
137 return retstring; | |
138 | |
139 } | |
140 | |
141 /* Get the hostname corresponding to the address addr. On failure, the IP | |
142 * address is returned. The return value is allocated with strdup() */ | |
143 char* getaddrhostname(struct sockaddr * addr) { | |
144 | |
145 struct hostent *host = NULL; | |
146 char * retstring; | |
147 | |
148 #ifdef DO_HOST_LOOKUP | |
149 host = gethostbyaddr((char*)&((struct sockaddr_in*)addr)->sin_addr, | |
150 sizeof(struct in_addr), AF_INET); | |
151 #endif | |
152 | |
153 if (host == NULL) { | |
154 /* return the address */ | |
155 retstring = inet_ntoa(((struct sockaddr_in *)addr)->sin_addr); | |
156 } else { | |
157 /* return the hostname */ | |
158 retstring = host->h_name; | |
159 } | |
160 | |
161 return strdup(retstring); | |
162 } | |
163 #ifdef DEBUG_TRACE | |
164 void printhex(unsigned char* buf, int len) { | |
165 | |
166 int i; | |
167 | |
168 for (i = 0; i < len; i++) { | |
169 fprintf(stderr, "%02x", buf[i]); | |
170 if (i % 16 == 15) { | |
171 fprintf(stderr, "\n"); | |
172 } | |
173 else if (i % 2 == 1) { | |
174 fprintf(stderr, " "); | |
175 } | |
176 } | |
177 fprintf(stderr, "\n"); | |
178 } | |
179 #endif | |
180 | |
181 /* Strip all control characters from text (a null-terminated string), except | |
182 * for '\n', '\r' and '\t'. | |
183 * The result returned is a newly allocated string, this must be free()d after | |
184 * use */ | |
185 char * stripcontrol(const char * text) { | |
186 | |
187 char * ret; | |
188 int len, pos; | |
189 int i; | |
190 | |
191 len = strlen(text); | |
192 ret = m_malloc(len+1); | |
193 | |
194 pos = 0; | |
195 for (i = 0; i < len; i++) { | |
196 if ((text[i] <= '~' && text[i] >= ' ') /* normal printable range */ | |
197 || text[i] == '\n' || text[i] == '\r' || text[i] == '\t') { | |
198 ret[pos] = text[i]; | |
199 pos++; | |
200 } | |
201 } | |
202 ret[pos] = 0x0; | |
203 return ret; | |
204 } | |
205 | |
206 | |
207 /* reads the contents of filename into the buffer buf, from the current | |
208 * position, either to the end of the file, or the buffer being full. | |
209 * Returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE */ | |
210 int buf_readfile(buffer* buf, const char* filename) { | |
211 | |
212 int fd; | |
213 int len; | |
214 int maxlen; | |
215 | |
216 fd = open(filename, O_RDONLY); | |
217 | |
218 if (fd < 0) { | |
219 close(fd); | |
220 return DROPBEAR_FAILURE; | |
221 } | |
222 | |
223 do { | |
224 maxlen = buf->size - buf->pos; | |
225 len = read(fd, buf_getwriteptr(buf, maxlen), | |
226 maxlen); | |
227 buf_incrwritepos(buf, len); | |
228 } while (len < maxlen && len > 0); | |
229 | |
230 close(fd); | |
231 return DROPBEAR_SUCCESS; | |
232 } | |
233 | |
234 /* loop until the socket is closed (in case of EINTR) or | |
235 * we get and error. | |
236 * Returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE */ | |
237 int m_close(int fd) { | |
238 | |
239 int val; | |
240 do { | |
241 val = close(fd); | |
242 } while (val < 0 && errno == EINTR); | |
243 | |
244 if (val == 0 || errno == EBADF) { | |
245 return DROPBEAR_SUCCESS; | |
246 } else { | |
247 return DROPBEAR_FAILURE; | |
248 } | |
249 } | |
250 | |
251 void * m_malloc(size_t size) { | |
252 | |
253 void* ret; | |
254 | |
255 if (size == 0) { | |
256 dropbear_exit("m_malloc failed"); | |
257 } | |
258 ret = malloc(size); | |
259 if (ret == NULL) { | |
260 dropbear_exit("m_malloc failed"); | |
261 } | |
262 return ret; | |
263 | |
264 } | |
265 | |
266 void __m_free(void* ptr) { | |
267 if (ptr != NULL) { | |
268 free(ptr); | |
269 } | |
270 } | |
271 | |
272 void * m_realloc(void* ptr, size_t size) { | |
273 | |
274 void *ret; | |
275 | |
276 if (size == 0) { | |
277 dropbear_exit("m_realloc failed"); | |
278 } | |
279 ret = realloc(ptr, size); | |
280 if (ret == NULL) { | |
281 dropbear_exit("m_realloc failed"); | |
282 } | |
283 return ret; | |
284 } | |
285 | |
286 /* Clear the data, based on the method in David Wheeler's | |
287 * "Secure Programming for Linux and Unix HOWTO" */ | |
288 void m_burn(void *data, unsigned int len) { | |
289 volatile char *p = data; | |
290 | |
291 if (data == NULL) | |
292 return; | |
293 while (len--) { | |
294 *p++ = 0x66; | |
295 } | |
296 } |