summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog3
-rw-r--r--Makefile.in2
-rw-r--r--acconfig.h3
-rw-r--r--bsd-getcwd.c237
-rw-r--r--bsd-getcwd.h10
-rw-r--r--bsd-realpath.c163
-rw-r--r--bsd-realpath.h11
-rw-r--r--configure.in3
-rw-r--r--openbsd-compat.h2
9 files changed, 432 insertions, 2 deletions
diff --git a/ChangeLog b/ChangeLog
index bbd97b950..9b37a5fcd 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,7 @@
120001014 120001014
2 - (bal) Add support for realpath and getcwd for platforms with broken
3 or missing realpath implementations for sftp-server.
4 - (bal) Corrected mistake in INSTALL in regards to GNU rx library
2 - (bal) Add support for GNU rx library for those lacking regexp support 5 - (bal) Add support for GNU rx library for those lacking regexp support
3 - (djm) Don't accept PAM_PROMPT_ECHO_ON messages during initial auth 6 - (djm) Don't accept PAM_PROMPT_ECHO_ON messages during initial auth
4 - (djm) Revert SSH2 serverloop hack, will find a better way. 7 - (djm) Revert SSH2 serverloop hack, will find a better way.
diff --git a/Makefile.in b/Makefile.in
index 9969a5216..a08b3731b 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -37,7 +37,7 @@ TARGETS=ssh$(EXEEXT) sshd$(EXEEXT) ssh-add$(EXEEXT) ssh-keygen$(EXEEXT) ssh-agen
37 37
38LIBSSH_OBJS=atomicio.o authfd.o authfile.o bufaux.o buffer.o canohost.o channels.o cipher.o cli.o compat.o compress.o crc32.o cygwin_util.o deattack.o dispatch.o dsa.o hmac.o hostfile.o key.o kex.o log.o match.o mpaux.o nchan.o packet.o radix.o rijndael.o entropy.o readpass.o rsa.o tildexpand.o ttymodes.o uidswap.o util.o uuencode.o xmalloc.o 38LIBSSH_OBJS=atomicio.o authfd.o authfile.o bufaux.o buffer.o canohost.o channels.o cipher.o cli.o compat.o compress.o crc32.o cygwin_util.o deattack.o dispatch.o dsa.o hmac.o hostfile.o key.o kex.o log.o match.o mpaux.o nchan.o packet.o radix.o rijndael.o entropy.o readpass.o rsa.o tildexpand.o ttymodes.o uidswap.o util.o uuencode.o xmalloc.o
39 39
40LIBOPENBSD_COMPAT_OBJS=bsd-arc4random.o bsd-base64.o bsd-bindresvport.o bsd-daemon.o bsd-inet_aton.o bsd-inet_ntoa.o bsd-misc.o bsd-mktemp.o bsd-rresvport.o bsd-setenv.o bsd-sigaction.o bsd-snprintf.o bsd-strlcat.o bsd-strlcpy.o bsd-strsep.o bsd-strtok.o bsd-vis.o fake-getaddrinfo.o fake-getnameinfo.o next-posix.o 40LIBOPENBSD_COMPAT_OBJS=bsd-arc4random.o bsd-base64.o bsd-bindresvport.o bsd-daemon.o bsd-getcwd.o bsd-inet_aton.o bsd-inet_ntoa.o bsd-misc.o bsd-mktemp.o bsd-realpath.o bsd-rresvport.o bsd-setenv.o bsd-sigaction.o bsd-snprintf.o bsd-strlcat.o bsd-strlcpy.o bsd-strsep.o bsd-strtok.o bsd-vis.o fake-getaddrinfo.o fake-getnameinfo.o next-posix.o
41 41
42SSHOBJS= ssh.o sshconnect.o sshconnect1.o sshconnect2.o log-client.o readconf.o clientloop.o 42SSHOBJS= ssh.o sshconnect.o sshconnect1.o sshconnect2.o log-client.o readconf.o clientloop.o
43 43
diff --git a/acconfig.h b/acconfig.h
index 3bf61ec92..d212b90f7 100644
--- a/acconfig.h
+++ b/acconfig.h
@@ -55,6 +55,9 @@
55/* Define if you lack native POSIX regex and you are using GNU rx library */ 55/* Define if you lack native POSIX regex and you are using GNU rx library */
56#undef HAVE_LIBRX 56#undef HAVE_LIBRX
57 57
58/* Define if you have a broken realpath. */
59#undef BROKEN_REALPATH
60
58/* Define if you are on NeXT */ 61/* Define if you are on NeXT */
59#undef HAVE_NEXT 62#undef HAVE_NEXT
60 63
diff --git a/bsd-getcwd.c b/bsd-getcwd.c
new file mode 100644
index 000000000..cca417787
--- /dev/null
+++ b/bsd-getcwd.c
@@ -0,0 +1,237 @@
1/*
2 * Copyright (c) 1989, 1991, 1993
3 * The Regents of the University of California. 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. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 */
26
27#include "config.h"
28
29#if !defined(HAVE_GETCWD)
30
31#if defined(LIBC_SCCS) && !defined(lint)
32static char rcsid[] = "$OpenBSD: getcwd.c,v 1.6 2000/07/19 15:25:13 deraadt Exp $";
33#endif /* LIBC_SCCS and not lint */
34
35#include <sys/param.h>
36#include <sys/stat.h>
37#include <errno.h>
38#include <dirent.h>
39#include <sys/dir.h>
40#include <stdio.h>
41#include <stdlib.h>
42#include <string.h>
43#include "includes.h"
44
45#define ISDOT(dp) \
46 (dp->d_name[0] == '.' && (dp->d_name[1] == '\0' || \
47 (dp->d_name[1] == '.' && dp->d_name[2] == '\0')))
48
49char *
50getcwd(char *pt,size_t size)
51{
52 register struct dirent *dp;
53 register DIR *dir = NULL;
54 register dev_t dev;
55 register ino_t ino;
56 register int first;
57 register char *bpt, *bup;
58 struct stat s;
59 dev_t root_dev;
60 ino_t root_ino;
61 size_t ptsize, upsize;
62 int save_errno;
63 char *ept, *eup, *up;
64
65 /*
66 * If no buffer specified by the user, allocate one as necessary.
67 * If a buffer is specified, the size has to be non-zero. The path
68 * is built from the end of the buffer backwards.
69 */
70 if (pt) {
71 ptsize = 0;
72 if (!size) {
73 errno = EINVAL;
74 return (NULL);
75 }
76 ept = pt + size;
77 } else {
78 if ((pt = malloc(ptsize = 1024 - 4)) == NULL)
79 return (NULL);
80 ept = pt + ptsize;
81 }
82 bpt = ept - 1;
83 *bpt = '\0';
84
85 /*
86 * Allocate bytes (1024 - malloc space) for the string of "../"'s.
87 * Should always be enough (it's 340 levels). If it's not, allocate
88 * as necessary. Special * case the first stat, it's ".", not "..".
89 */
90 if ((up = malloc(upsize = 1024 - 4)) == NULL)
91 goto err;
92 eup = up + MAXPATHLEN;
93 bup = up;
94 up[0] = '.';
95 up[1] = '\0';
96
97 /* Save root values, so know when to stop. */
98 if (stat("/", &s))
99 goto err;
100 root_dev = s.st_dev;
101 root_ino = s.st_ino;
102
103 errno = 0; /* XXX readdir has no error return. */
104
105 for (first = 1;; first = 0) {
106 /* Stat the current level. */
107 if (lstat(up, &s))
108 goto err;
109
110 /* Save current node values. */
111 ino = s.st_ino;
112 dev = s.st_dev;
113
114 /* Check for reaching root. */
115 if (root_dev == dev && root_ino == ino) {
116 *--bpt = '/';
117 /*
118 * It's unclear that it's a requirement to copy the
119 * path to the beginning of the buffer, but it's always
120 * been that way and stuff would probably break.
121 */
122 bcopy(bpt, pt, ept - bpt);
123 free(up);
124 return (pt);
125 }
126
127 /*
128 * Build pointer to the parent directory, allocating memory
129 * as necessary. Max length is 3 for "../", the largest
130 * possible component name, plus a trailing NULL.
131 */
132 if (bup + 3 + MAXNAMLEN + 1 >= eup) {
133 char *nup;
134
135 if ((nup = realloc(up, upsize *= 2)) == NULL)
136 goto err;
137 up = nup;
138 bup = up;
139 eup = up + upsize;
140 }
141 *bup++ = '.';
142 *bup++ = '.';
143 *bup = '\0';
144
145 /* Open and stat parent directory.
146 * RACE?? - replaced fstat(dirfd(dir), &s) w/ lstat(up,&s)
147 */
148 if (!(dir = opendir(up)) || lstat(up,&s))
149 goto err;
150
151 /* Add trailing slash for next directory. */
152 *bup++ = '/';
153
154 /*
155 * If it's a mount point, have to stat each element because
156 * the inode number in the directory is for the entry in the
157 * parent directory, not the inode number of the mounted file.
158 */
159 save_errno = 0;
160 if (s.st_dev == dev) {
161 for (;;) {
162 if (!(dp = readdir(dir)))
163 goto notfound;
164 if (dp->d_fileno == ino)
165 break;
166 }
167 } else
168 for (;;) {
169 if (!(dp = readdir(dir)))
170 goto notfound;
171 if (ISDOT(dp))
172 continue;
173 bcopy(dp->d_name, bup, dp->d_namlen + 1);
174
175 /* Save the first error for later. */
176 if (lstat(up, &s)) {
177 if (!save_errno)
178 save_errno = errno;
179 errno = 0;
180 continue;
181 }
182 if (s.st_dev == dev && s.st_ino == ino)
183 break;
184 }
185
186 /*
187 * Check for length of the current name, preceding slash,
188 * leading slash.
189 */
190 if (bpt - pt < dp->d_namlen + (first ? 1 : 2)) {
191 size_t len, off;
192 char *npt;
193
194 if (!ptsize) {
195 errno = ERANGE;
196 goto err;
197 }
198 off = bpt - pt;
199 len = ept - bpt;
200 if ((npt = realloc(pt, ptsize *= 2)) == NULL)
201 goto err;
202 pt = npt;
203 bpt = pt + off;
204 ept = pt + ptsize;
205 bcopy(bpt, ept - len, len);
206 bpt = ept - len;
207 }
208 if (!first)
209 *--bpt = '/';
210 bpt -= dp->d_namlen;
211 bcopy(dp->d_name, bpt, dp->d_namlen);
212 (void)closedir(dir);
213
214 /* Truncate any file name. */
215 *bup = '\0';
216 }
217
218notfound:
219 /*
220 * If readdir set errno, use it, not any saved error; otherwise,
221 * didn't find the current directory in its parent directory, set
222 * errno to ENOENT.
223 */
224 if (!errno)
225 errno = save_errno ? save_errno : ENOENT;
226 /* FALLTHROUGH */
227err:
228 if (ptsize)
229 free(pt);
230 if (up)
231 free(up);
232 if (dir)
233 (void)closedir(dir);
234 return (NULL);
235}
236
237#endif /* !defined(HAVE_GETCWD) */
diff --git a/bsd-getcwd.h b/bsd-getcwd.h
new file mode 100644
index 000000000..bee738657
--- /dev/null
+++ b/bsd-getcwd.h
@@ -0,0 +1,10 @@
1#ifndef _BSD_GETCWD_H
2#define _BSD_GETCWD_H
3#include "config.h"
4
5#if !defined(HAVE_GETCWD)
6
7char *getcwd(char *pt, size_t size);
8
9#endif /* !defined(HAVE_GETCWD) */
10#endif /* _BSD_GETCWD_H */
diff --git a/bsd-realpath.c b/bsd-realpath.c
new file mode 100644
index 000000000..103dcc256
--- /dev/null
+++ b/bsd-realpath.c
@@ -0,0 +1,163 @@
1/*
2 * Copyright (c) 1994
3 * The Regents of the University of California. All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Jan-Simon Pendry.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 */
29
30#include "includes.h"
31
32#if !defined(HAVE_REALPATH) || defined(BROKEN_REALPATH)
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char *rcsid = "$OpenBSD: realpath..c,v 1.4 1998/05/18 09:55:19 deraadt Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <sys/param.h>
39#include <sys/stat.h>
40
41#include <errno.h>
42#include <fcntl.h>
43#include <stdlib.h>
44#include <string.h>
45#include <unistd.h>
46
47/*
48 * S_ISLNK compatibility
49 */
50#ifndef S_ISLNK
51#define S_ISLNK(m) ((m & 0170000) == 0120000)
52#endif
53
54/*
55 * char *realpath(const char *path, char resolved_path[MAXPATHLEN]);
56 *
57 * Find the real name of path, by removing all ".", ".." and symlink
58 * components. Returns (resolved) on success, or (NULL) on failure,
59 * in which case the path which caused trouble is left in (resolved).
60 */
61char *
62realpath(const char *path, char *resolved)
63{
64 struct stat sb;
65 int fd, n, rootd, serrno = 0;
66 char *p, *q, wbuf[MAXPATHLEN], start[MAXPATHLEN];
67 int symlinks = 0;
68
69 /* Save the starting point. */
70 getcwd(start,MAXPATHLEN);
71 if ((fd = open(".", O_RDONLY)) < 0) {
72 (void)strcpy(resolved, ".");
73 return (NULL);
74 }
75 close(fd);
76
77 /*
78 * Find the dirname and basename from the path to be resolved.
79 * Change directory to the dirname component.
80 * lstat the basename part.
81 * if it is a symlink, read in the value and loop.
82 * if it is a directory, then change to that directory.
83 * get the current directory name and append the basename.
84 */
85 (void)strncpy(resolved, path, MAXPATHLEN - 1);
86 resolved[MAXPATHLEN - 1] = '\0';
87loop:
88 q = strrchr(resolved, '/');
89 if (q != NULL) {
90 p = q + 1;
91 if (q == resolved)
92 q = "/";
93 else {
94 do {
95 --q;
96 } while (q > resolved && *q == '/');
97 q[1] = '\0';
98 q = resolved;
99 }
100 if (chdir(q) < 0)
101 goto err1;
102 } else
103 p = resolved;
104
105 /* Deal with the last component. */
106 if (lstat(p, &sb) == 0) {
107 if (S_ISLNK(sb.st_mode)) {
108 if (++symlinks > MAXSYMLINKS) {
109 serrno = ELOOP;
110 goto err1;
111 }
112 n = readlink(p, resolved, MAXPATHLEN-1);
113 if (n < 0)
114 goto err1;
115 resolved[n] = '\0';
116 goto loop;
117 }
118 if (S_ISDIR(sb.st_mode)) {
119 if (chdir(p) < 0)
120 goto err1;
121 p = "";
122 }
123 }
124
125 /*
126 * Save the last component name and get the full pathname of
127 * the current directory.
128 */
129 (void)strcpy(wbuf, p);
130 if (getcwd(resolved, MAXPATHLEN) == 0)
131 goto err1;
132
133 /*
134 * Join the two strings together, ensuring that the right thing
135 * happens if the last component is empty, or the dirname is root.
136 */
137 if (resolved[0] == '/' && resolved[1] == '\0')
138 rootd = 1;
139 else
140 rootd = 0;
141
142 if (*wbuf) {
143 if (strlen(resolved) + strlen(wbuf) + rootd + 1 > MAXPATHLEN) {
144 serrno = ENAMETOOLONG;
145 goto err1;
146 }
147 if (rootd == 0)
148 (void)strcat(resolved, "/");
149 (void)strcat(resolved, wbuf);
150 }
151
152 /* Go back to where we came from. */
153 if (chdir(start) < 0) {
154 serrno = errno;
155 goto err2;
156 }
157 return (resolved);
158
159err1: chdir(start);
160err2: errno = serrno;
161 return (NULL);
162}
163#endif /* !defined(HAVE_REALPATH) || defined(BROKEN_REALPATH) */
diff --git a/bsd-realpath.h b/bsd-realpath.h
new file mode 100644
index 000000000..dc3579dd3
--- /dev/null
+++ b/bsd-realpath.h
@@ -0,0 +1,11 @@
1#ifndef _BSD_REALPATH_H
2#define _BSD_REALPATH_H
3
4#include "config.h"
5
6#if !defined(HAVE_REALPATH) || defined(BROKEN_REALPATH)
7
8char *realpath(const char *path, char *resolved);
9
10#endif /* !defined(HAVE_REALPATH) || defined(BROKEN_REALPATH) */
11#endif /* _BSD_REALPATH_H */
diff --git a/configure.in b/configure.in
index a6bed7508..7cd7467f9 100644
--- a/configure.in
+++ b/configure.in
@@ -128,6 +128,7 @@ case "$host" in
128 conf_wtmp_location=/usr/adm/wtmp 128 conf_wtmp_location=/usr/adm/wtmp
129 MAIL=/usr/spool/mail 129 MAIL=/usr/spool/mail
130 AC_DEFINE(HAVE_NEXT) 130 AC_DEFINE(HAVE_NEXT)
131 AC_DEFINE(BROKEN_REALPATH)
131 CFLAGS="$CFLAGS -I/usr/local/include" 132 CFLAGS="$CFLAGS -I/usr/local/include"
132 ;; 133 ;;
133*-*-solaris*) 134*-*-solaris*)
@@ -269,7 +270,7 @@ fi
269AC_CHECK_HEADERS(bstring.h endian.h floatingpoint.h getopt.h lastlog.h limits.h login.h login_cap.h maillock.h netdb.h netgroup.h netinet/in_systm.h paths.h poll.h pty.h shadow.h security/pam_appl.h sys/bitypes.h sys/bsdtty.h sys/cdefs.h sys/poll.h sys/select.h sys/stat.h sys/stropts.h sys/sysmacros.h sys/time.h sys/ttcompat.h sys/un.h stddef.h time.h ttyent.h usersec.h util.h utmp.h utmpx.h vis.h) 270AC_CHECK_HEADERS(bstring.h endian.h floatingpoint.h getopt.h lastlog.h limits.h login.h login_cap.h maillock.h netdb.h netgroup.h netinet/in_systm.h paths.h poll.h pty.h shadow.h security/pam_appl.h sys/bitypes.h sys/bsdtty.h sys/cdefs.h sys/poll.h sys/select.h sys/stat.h sys/stropts.h sys/sysmacros.h sys/time.h sys/ttcompat.h sys/un.h stddef.h time.h ttyent.h usersec.h util.h utmp.h utmpx.h vis.h)
270 271
271dnl Checks for library functions. 272dnl Checks for library functions.
272AC_CHECK_FUNCS(arc4random atexit b64_ntop bcopy bindresvport_af clock fchmod freeaddrinfo futimes gai_strerror getaddrinfo getnameinfo getrusage getttyent inet_aton inet_ntoa innetgr login_getcapbool md5_crypt memmove mkdtemp on_exit openpty rresvport_af setenv seteuid setlogin setproctitle setreuid setrlimit sigaction sigvec snprintf strerror strlcat strlcpy strsep strtok_r vsnprintf vhangup vis _getpty __b64_ntop) 273AC_CHECK_FUNCS(arc4random atexit b64_ntop bcopy bindresvport_af clock fchmod freeaddrinfo futimes gai_strerror getcwd getaddrinfo getnameinfo getrusage getttyent inet_aton inet_ntoa innetgr login_getcapbool md5_crypt memmove mkdtemp on_exit openpty realpath rresvport_af setenv seteuid setlogin setproctitle setreuid setrlimit sigaction sigvec snprintf strerror strlcat strlcpy strsep strtok_r vsnprintf vhangup vis _getpty __b64_ntop)
273dnl Checks for time functions 274dnl Checks for time functions
274AC_CHECK_FUNCS(gettimeofday time) 275AC_CHECK_FUNCS(gettimeofday time)
275dnl Checks for libutil functions 276dnl Checks for libutil functions
diff --git a/openbsd-compat.h b/openbsd-compat.h
index f3ae2f3ff..18c67f088 100644
--- a/openbsd-compat.h
+++ b/openbsd-compat.h
@@ -6,6 +6,8 @@
6/* BSD function replacements */ 6/* BSD function replacements */
7#include "bsd-arc4random.h" 7#include "bsd-arc4random.h"
8#include "bsd-bindresvport.h" 8#include "bsd-bindresvport.h"
9#include "bsd-getcwd.h"
10#include "bsd-realpath.h"
9#include "bsd-rresvport.h" 11#include "bsd-rresvport.h"
10#include "bsd-misc.h" 12#include "bsd-misc.h"
11#include "bsd-strlcpy.h" 13#include "bsd-strlcpy.h"