~ubuntu-branches/ubuntu/gutsy/vnc4/gutsy

« back to all changes in this revision

Viewing changes to unix/xc/config/util/checktree.c

  • Committer: Bazaar Package Importer
  • Author(s): Ola Lundqvist
  • Date: 2006-05-15 20:35:17 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20060515203517-l4lre1ku942mn26k
Tags: 4.1.1+X4.3.0-10
* Correction of critical security issue. Thanks to Martin Kogler
  <e9925248@student.tuwien.ac.at> that informed me about the issue,
  and provided the patch.
  This flaw was originally found by Steve Wiseman of intelliadmin.com.
* Applied patch from Javier Kohen <jkohen@users.sourceforge.net> that
  inform the user that only 8 first characters of the password will
  actually be used when typing more than 8 characters, closes:
  #355619.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* $Xorg: checktree.c,v 1.4 2001/02/09 02:03:16 xorgcvs Exp $ */
 
2
 
 
3
/*
 
4
 
 
5
Copyright (c) 1993, 1998  The Open Group
 
6
 
 
7
Permission to use, copy, modify, distribute, and sell this software and its
 
8
documentation for any purpose is hereby granted without fee, provided that
 
9
the above copyright notice appear in all copies and that both that
 
10
copyright notice and this permission notice appear in supporting
 
11
documentation.
 
12
 
 
13
The above copyright notice and this permission notice shall be included in
 
14
all copies or substantial portions of the Software.
 
15
 
 
16
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 
17
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 
18
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
 
19
OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
 
20
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 
21
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
22
 
 
23
Except as contained in this notice, the name of The Open Group shall not be
 
24
used in advertising or otherwise to promote the sale, use or other dealings
 
25
in this Software without prior written authorization from The Open Group.
 
26
*/
 
27
/* $XFree86: xc/config/util/checktree.c,v 1.4 2001/12/14 19:53:22 dawes Exp $ */
 
28
 
 
29
#include <X11/Xos.h>
 
30
#include <stdio.h>
 
31
#include <sys/stat.h>
 
32
#include <sys/param.h>
 
33
#include <errno.h>
 
34
 
 
35
#ifndef X_NOT_POSIX
 
36
#include <dirent.h>
 
37
#else
 
38
#ifdef SYSV
 
39
#include <dirent.h>
 
40
#else
 
41
#ifdef USG
 
42
#include <dirent.h>
 
43
#else
 
44
#include <sys/dir.h>
 
45
#ifndef dirent
 
46
#define dirent direct
 
47
#endif
 
48
#endif
 
49
#endif
 
50
#endif
 
51
 
 
52
#ifdef S_IFLNK
 
53
#define Stat lstat
 
54
#else
 
55
#define Stat stat
 
56
#endif
 
57
 
 
58
#define CHARSALLOWED \
 
59
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_."
 
60
 
 
61
#define fmode_bits_minset 0444
 
62
#define fmode_bits_maxset 0777
 
63
#define fmode_bits_write  0222
 
64
#define dmode_bits_minset 0775
 
65
 
 
66
int dorcs = 1;                  /* check RCS file */
 
67
int do83 = 1;                   /* check for 8+3 clash */
 
68
int doro = 1;                   /* disallow writable (checked out) files */
 
69
int dodot = 1;                  /* disallow .files */
 
70
int dotwiddle = 1;              /* disallow file~ */
 
71
 
 
72
int dontcare(fn)
 
73
    char *fn;
 
74
{
 
75
    char *cp;
 
76
 
 
77
    if (fn[strlen(fn) - 1] == '~')
 
78
        return 1;
 
79
    cp = strrchr(fn, '.');
 
80
    return cp && (!strcmp(cp + 1, "Z") || !strcmp(cp + 1, "PS"));
 
81
}
 
82
 
 
83
checkfile(fullname, fn, fs)
 
84
    char *fullname, *fn;
 
85
    struct stat *fs;
 
86
{
 
87
    char *cp;
 
88
    int maxlen = 12;
 
89
    int len, mode;
 
90
 
 
91
    if (dodot && fn[0] == '.') {
 
92
        printf("dot file: %s\n", fullname);
 
93
        return;
 
94
    }
 
95
    for (len = 0, cp = fn; *cp; len++, cp++) {
 
96
        if (!strchr(CHARSALLOWED, *cp)) {
 
97
            if (dotwiddle || *cp != '~' || cp[1])
 
98
                printf ("bad character: %s\n", fullname);
 
99
            break;
 
100
        }
 
101
    }
 
102
    if (len > maxlen && !dontcare(fn))
 
103
        printf("too long (%d): %s\n", len, fullname);
 
104
#ifdef S_IFLNK
 
105
    if ((fs->st_mode & S_IFLNK) == S_IFLNK) {
 
106
        printf("symbolic link: %s\n", fullname);
 
107
        return;
 
108
    }
 
109
#endif
 
110
    mode = fs->st_mode & (~S_IFMT);
 
111
    if ((fs->st_mode & S_IFDIR) == S_IFDIR) {
 
112
        maxlen = 14;
 
113
        if ((mode & dmode_bits_minset) != dmode_bits_minset)
 
114
            printf("directory mode 0%o not minimum 0%o: %s\n",
 
115
                   mode, dmode_bits_minset, fullname);
 
116
    } else if ((fs->st_mode & S_IFREG) != S_IFREG)
 
117
        printf("not a regular file: %s\n", fullname);
 
118
    else {
 
119
        if ((mode & fmode_bits_minset) != fmode_bits_minset)
 
120
            printf("file mode 0%o not minimum 0%o: %s\n",
 
121
                   fs->st_mode, fmode_bits_minset, fullname);
 
122
        if (fs->st_nlink != 1)
 
123
            printf("%d links instead of 1: %s\n", fs->st_nlink, fullname);
 
124
        if (doro && (mode & fmode_bits_write) && !dontcare(fn))
 
125
            printf("writable: %s\n", fullname);
 
126
    }
 
127
    if ((mode & ~fmode_bits_maxset) != 0)
 
128
        printf("mode 0%o outside maximum set 0%o: %s\n",
 
129
               mode, fmode_bits_maxset, fullname);
 
130
}
 
131
 
 
132
void
 
133
checkrcs(dir, p)
 
134
    char *dir;
 
135
    char *p;
 
136
{
 
137
    DIR *df;
 
138
    struct dirent *dp;
 
139
    struct stat fs;
 
140
    int i;
 
141
 
 
142
    if (!(df = opendir(dir))) {
 
143
        fprintf(stderr, "cannot open: %s\n", dir);
 
144
        return;
 
145
    }
 
146
    while (dp = readdir(df)) {
 
147
        i = strlen(dp->d_name);
 
148
        if (dp->d_name[i - 1] == 'v' && dp->d_name[i - 2] == ',') {
 
149
            strcpy(p, dp->d_name);
 
150
            p[i - 2] = '\0';
 
151
            if (Stat(dir, &fs) < 0) {
 
152
                strcpy(p, "RCS/");
 
153
                strcat(p, dp->d_name);
 
154
                printf("not used: %s\n", dir);
 
155
            }
 
156
        }
 
157
    }
 
158
    closedir(df);
 
159
}
 
160
 
 
161
int
 
162
Strncmp(cp1, cp2, n)
 
163
    char *cp1, *cp2;
 
164
    int n;
 
165
{
 
166
    char c1, c2;
 
167
 
 
168
    for (; --n >= 0 && *cp1 && *cp2; cp1++, cp2++) {
 
169
        if (*cp1 != *cp2) {
 
170
            c1 = *cp1;
 
171
            c2 = *cp2;
 
172
            if (c1 >= 'A' && c1 <= 'Z')
 
173
                c1 += 'a' - 'A';
 
174
            else if (c1 == '-')
 
175
                c1 = '_';
 
176
            if (c2 >= 'A' && c2 <= 'Z')
 
177
                c2 += 'a' - 'A';
 
178
            else if (c2 == '-')
 
179
                c2 = '_';
 
180
            if (c1 != c2)
 
181
                return (int)c1 - (int)c2;
 
182
        }
 
183
    }
 
184
    if (n < 0)
 
185
        return 0;
 
186
    return (int)*cp1 - (int)*cp2;
 
187
}
 
188
 
 
189
int
 
190
fncomp(n1, n2)
 
191
    char **n1, **n2;
 
192
{
 
193
    int i, res;
 
194
    char *cp1, *cp2;
 
195
    char c1, c2;
 
196
 
 
197
    i = Strncmp(*n1, *n2, 8);
 
198
    if (!i) {
 
199
        cp1 = strrchr(*n1, '.');
 
200
        cp2 = strrchr(*n2, '.');
 
201
        if (cp1 || cp2) {
 
202
            if (!cp1)
 
203
                return -1;
 
204
            if (!cp2)
 
205
                return 1;
 
206
            i = Strncmp(cp1 + 1, cp2 + 1, 3);
 
207
        }
 
208
    }
 
209
    return i;
 
210
}
 
211
 
 
212
void
 
213
checkdir(dir)
 
214
    char *dir;
 
215
{
 
216
    DIR *df;
 
217
    struct dirent *dp;
 
218
    char *p;
 
219
    struct stat fs;
 
220
    char *s, **names;
 
221
    int i, max;
 
222
 
 
223
    if (!(df = opendir(dir))) {
 
224
        fprintf(stderr, "cannot open: %s\n", dir);
 
225
        return;
 
226
    }
 
227
    p = dir + strlen(dir);
 
228
    if (p[-1] != '/')
 
229
        *p++ = '/';
 
230
    i = 0;
 
231
    max = 0;
 
232
    names = NULL;
 
233
    while (dp = readdir(df)) {
 
234
        strcpy(p, dp->d_name);
 
235
        if (Stat(dir, &fs) < 0) {
 
236
            perror(dir);
 
237
            continue;
 
238
        }
 
239
        if ((fs.st_mode & S_IFDIR) == S_IFDIR) {
 
240
            if (dp->d_name[0] == '.' &&
 
241
                (dp->d_name[1] == '\0' || (dp->d_name[1] == '.' &&
 
242
                                           dp->d_name[2] == '\0')))
 
243
                continue;
 
244
            if (!strcmp (dp->d_name, "RCS")) {
 
245
                if (dorcs)
 
246
                    checkrcs(dir, p);
 
247
                continue;
 
248
            }
 
249
            if (!strcmp (dp->d_name, "SCCS"))
 
250
                continue;
 
251
            if (!strcmp (dp->d_name, "CVS.adm"))
 
252
                continue;
 
253
            checkfile(dir, p, &fs);
 
254
            checkdir(dir);
 
255
            continue;
 
256
        }
 
257
        checkfile(dir, p, &fs);
 
258
        if (dorcs && !dontcare(dp->d_name)) {
 
259
            strcpy(p, "RCS/");
 
260
            strcat(p, dp->d_name);
 
261
            strcat(p, ",v");
 
262
            if (Stat(dir, &fs) < 0) {
 
263
                strcpy(p, dp->d_name);
 
264
                printf("no RCS: %s\n", dir);
 
265
            }
 
266
        }
 
267
        if (do83) {
 
268
            s = (char *)malloc(strlen(dp->d_name) + 1);
 
269
            strcpy(s, dp->d_name);
 
270
            if (i >= max) {
 
271
                max += 25;
 
272
                if (names)
 
273
                    names = (char **)realloc((char *)names,
 
274
                                             (max + 1) * sizeof(char *));
 
275
                else
 
276
                    names = (char **)malloc((max + 1) * sizeof(char *));
 
277
            }
 
278
            names[i++] = s;
 
279
        }
 
280
    }
 
281
    closedir(df);
 
282
    if (do83) {
 
283
        qsort((char *)names, i, sizeof(char *), fncomp);
 
284
        max = i - 1;
 
285
        *p = '\0';
 
286
        for (i = 0; i < max; i++) {
 
287
            if (!fncomp(&names[i], &names[i + 1]))
 
288
                printf("8+3 clash: %s%s and %s\n",
 
289
                       dir, names[i], names[i + 1]);
 
290
            free(names[i]);
 
291
        }
 
292
        if (names) {
 
293
            free(names[i]);
 
294
            free((char *)names);
 
295
        }
 
296
    }
 
297
}
 
298
 
 
299
main(argc, argv)
 
300
    int argc;
 
301
    char **argv;
 
302
{
 
303
    char buf[2048];
 
304
 
 
305
    argc--;
 
306
    argv++;
 
307
    while (argc > 0) {
 
308
        if (!strcmp(*argv, "-rcs")) {
 
309
            dorcs = 0;
 
310
            argc--;
 
311
            argv++;
 
312
        } else if (!strcmp(*argv, "-83")) {
 
313
            do83 = 0;
 
314
            argc--;
 
315
            argv++;
 
316
        } else if (!strcmp(*argv, "-ro")) {
 
317
            doro = 0;
 
318
            argc--;
 
319
            argv++;
 
320
        } else if (!strcmp(*argv, "-dot")) {
 
321
            dodot = 0;
 
322
            argc--;
 
323
            argv++;
 
324
        } else if (!strcmp(*argv, "-twiddle")) {
 
325
            dotwiddle = 0;
 
326
            argc--;
 
327
            argv++;
 
328
        } else
 
329
            break;
 
330
    }
 
331
    if (!argc) {
 
332
        strcpy(buf, ".");
 
333
        checkdir(buf);
 
334
    } else
 
335
        while (--argc >= 0) {
 
336
            strcpy(buf, *argv++);
 
337
            checkdir(buf);
 
338
        }
 
339
}