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

« back to all changes in this revision

Viewing changes to unix/xc/lib/xtrans/Xtransutil.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: Xtransutil.c,v 1.4 2001/02/09 02:04:07 xorgcvs Exp $ */
 
2
/*
 
3
 
 
4
Copyright 1993, 1994, 1998  The Open Group
 
5
 
 
6
Permission to use, copy, modify, distribute, and sell this software and its
 
7
documentation for any purpose is hereby granted without fee, provided that
 
8
the above copyright notice appear in all copies and that both that
 
9
copyright notice and this permission notice appear in supporting
 
10
documentation.
 
11
 
 
12
The above copyright notice and this permission notice shall be included
 
13
in all copies or substantial portions of the Software.
 
14
 
 
15
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 
16
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 
17
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 
18
IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
 
19
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 
20
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 
21
OTHER DEALINGS IN THE SOFTWARE.
 
22
 
 
23
Except as contained in this notice, the name of The Open Group shall
 
24
not be used in advertising or otherwise to promote the sale, use or
 
25
other dealings in this Software without prior written authorization
 
26
from The Open Group.
 
27
 
 
28
*/
 
29
/* $XFree86: xc/lib/xtrans/Xtransutil.c,v 3.23 2003/02/12 15:01:38 alanh Exp $ */
 
30
 
 
31
/* Copyright 1993, 1994 NCR Corporation - Dayton, Ohio, USA
 
32
 *
 
33
 * All Rights Reserved
 
34
 *
 
35
 * Permission to use, copy, modify, and distribute this software and its
 
36
 * documentation for any purpose and without fee is hereby granted, provided
 
37
 * that the above copyright notice appear in all copies and that both that
 
38
 * copyright notice and this permission notice appear in supporting
 
39
 * documentation, and that the name NCR not be used in advertising
 
40
 * or publicity pertaining to distribution of the software without specific,
 
41
 * written prior permission.  NCR makes no representations about the
 
42
 * suitability of this software for any purpose.  It is provided "as is"
 
43
 * without express or implied warranty.
 
44
 *
 
45
 * NCRS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 
46
 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
 
47
 * NO EVENT SHALL NCR BE LIABLE FOR ANY SPECIAL, INDIRECT OR
 
48
 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
 
49
 * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
 
50
 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
 
51
 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 
52
 */
 
53
 
 
54
/*
 
55
 * These are some utility functions created for convenience or to provide
 
56
 * an interface that is similar to an existing interface. These are built
 
57
 * only using the Transport Independant API, and have no knowledge of
 
58
 * the internal implementation.
 
59
 */
 
60
 
 
61
#ifdef XTHREADS
 
62
#include <X11/Xthreads.h>
 
63
#endif
 
64
 
 
65
#ifdef X11_t
 
66
 
 
67
/*
 
68
 * These values come from X.h and Xauth.h, and MUST match them. Some
 
69
 * of these values are also defined by the ChangeHost protocol message.
 
70
 */
 
71
 
 
72
#define FamilyInternet          0
 
73
#define FamilyDECnet            1
 
74
#define FamilyChaos             2
 
75
#define FamilyAmoeba            33
 
76
#define FamilyLocalHost         252
 
77
#define FamilyKrb5Principal     253
 
78
#define FamilyNetname           254
 
79
#define FamilyLocal             256
 
80
#define FamilyWild              65535
 
81
 
 
82
/*
 
83
 * TRANS(ConvertAddress) converts a sockaddr based address to an
 
84
 * X authorization based address. Some of this is defined as part of
 
85
 * the ChangeHost protocol. The rest is just doen in a consistent manner.
 
86
 */
 
87
 
 
88
int
 
89
TRANS(ConvertAddress)(int *familyp, int *addrlenp, Xtransaddr **addrp)
 
90
 
 
91
{
 
92
 
 
93
    PRMSG(2,"ConvertAddress(%d,%d,%x)\n",*familyp,*addrlenp,*addrp);
 
94
 
 
95
    switch( *familyp )
 
96
    {
 
97
#if defined(TCPCONN) || defined(STREAMSCONN)
 
98
    case AF_INET:
 
99
    {
 
100
        /*
 
101
         * Check for the BSD hack localhost address 127.0.0.1.
 
102
         * In this case, we are really FamilyLocal.
 
103
         */
 
104
 
 
105
        struct sockaddr_in saddr;
 
106
#ifdef CRAY
 
107
#ifdef OLDTCP
 
108
        int len = sizeof(saddr.sin_addr);
 
109
#else
 
110
        int len = SIZEOF_in_addr;
 
111
#endif /* OLDTCP */
 
112
        char *cp = (char *) &saddr.sin_addr;
 
113
#else /* else not CRAY */
 
114
        int len = sizeof(saddr.sin_addr.s_addr);
 
115
        char *cp = (char *) &saddr.sin_addr.s_addr;
 
116
#endif /* CRAY */
 
117
 
 
118
        memcpy (&saddr, *addrp, sizeof (struct sockaddr_in));
 
119
 
 
120
        if ((len == 4) && (cp[0] == 127) && (cp[1] == 0) &&
 
121
            (cp[2] == 0) && (cp[3] == 1))
 
122
        {
 
123
            *familyp=FamilyLocal;
 
124
        }
 
125
        else
 
126
        {
 
127
            *familyp=FamilyInternet;
 
128
            *addrlenp=len;
 
129
            memcpy(*addrp,&saddr.sin_addr,len);
 
130
        }
 
131
        break;
 
132
    }
 
133
#endif /* defined(TCPCONN) || defined(STREAMSCONN) */
 
134
 
 
135
#if defined(DNETCONN)
 
136
    case AF_DECnet:
 
137
    {
 
138
        struct sockaddr_dn saddr;
 
139
 
 
140
        memcpy (&saddr, *addrp, sizeof (struct sockaddr_dn));
 
141
 
 
142
        *familyp=FamilyDECnet;
 
143
        *addrlenp=sizeof(struct dn_naddr);
 
144
        memcpy(*addrp,&saddr.sdn_add,*addrlenp);
 
145
 
 
146
        break;
 
147
    }
 
148
#endif /* defined(DNETCONN) */
 
149
 
 
150
#if defined(UNIXCONN) || defined(LOCALCONN)
 
151
    case AF_UNIX:
 
152
    {
 
153
        *familyp=FamilyLocal;
 
154
        break;
 
155
    }
 
156
#endif /* defined(UNIXCONN) || defined(LOCALCONN) */
 
157
 
 
158
 
 
159
    default:
 
160
        PRMSG(1,"ConvertAddress: Unknown family type %d\n",
 
161
              *familyp, 0,0 );
 
162
        return -1;
 
163
    }
 
164
 
 
165
 
 
166
    if (*familyp == FamilyLocal)
 
167
    {
 
168
        /*
 
169
         * In the case of a local connection, we need to get the
 
170
         * host name for authentication.
 
171
         */
 
172
        
 
173
        char hostnamebuf[256];
 
174
        int len = TRANS(GetHostname) (hostnamebuf, sizeof hostnamebuf);
 
175
 
 
176
        if (len > 0) {
 
177
            if (*addrp && *addrlenp < (len + 1))
 
178
            {
 
179
                xfree ((char *) *addrp);
 
180
                *addrp = NULL;
 
181
            }
 
182
            if (!*addrp)
 
183
                *addrp = (Xtransaddr *) xalloc (len + 1);
 
184
            if (*addrp) {
 
185
                strcpy ((char *) *addrp, hostnamebuf);
 
186
                *addrlenp = len;
 
187
            } else {
 
188
                *addrlenp = 0;
 
189
            }
 
190
        }
 
191
        else
 
192
        {
 
193
            if (*addrp)
 
194
                xfree ((char *) *addrp);
 
195
            *addrp = NULL;
 
196
            *addrlenp = 0;
 
197
        }
 
198
    }
 
199
 
 
200
    return 0;
 
201
}
 
202
 
 
203
#endif /* X11_t */
 
204
 
 
205
#ifdef ICE_t
 
206
 
 
207
#include <signal.h>
 
208
 
 
209
char *
 
210
TRANS(GetMyNetworkId) (XtransConnInfo ciptr)
 
211
 
 
212
{
 
213
    int         family = ciptr->family;
 
214
    char        *addr = ciptr->addr;
 
215
    char        hostnamebuf[256];
 
216
    char        *networkId = NULL;
 
217
    char        *transName = ciptr->transptr->TransName;
 
218
 
 
219
    if (gethostname (hostnamebuf, sizeof (hostnamebuf)) < 0)
 
220
    {
 
221
        return (NULL);
 
222
    }
 
223
 
 
224
    switch (family)
 
225
    {
 
226
#if defined(UNIXCONN) || defined(STREAMSCONN) || defined(LOCALCONN)
 
227
    case AF_UNIX:
 
228
    {
 
229
        struct sockaddr_un *saddr = (struct sockaddr_un *) addr;
 
230
        networkId = (char *) xalloc (3 + strlen (transName) +
 
231
            strlen (hostnamebuf) + strlen (saddr->sun_path));
 
232
        sprintf (networkId, "%s/%s:%s", transName,
 
233
            hostnamebuf, saddr->sun_path);
 
234
        break;
 
235
    }
 
236
#endif /* defined(UNIXCONN) || defined(STREAMSCONN) || defined(LOCALCONN) */
 
237
 
 
238
#if defined(TCPCONN) || defined(STREAMSCONN)
 
239
    case AF_INET:
 
240
    {
 
241
        struct sockaddr_in *saddr = (struct sockaddr_in *) addr;
 
242
        char portnumbuf[10];
 
243
 
 
244
        sprintf (portnumbuf, "%d", ntohs (saddr->sin_port));
 
245
        networkId = (char *) xalloc (3 + strlen (transName) +
 
246
            strlen (hostnamebuf) + strlen (portnumbuf));
 
247
        sprintf (networkId, "%s/%s:%s", transName, hostnamebuf, portnumbuf);
 
248
        break;
 
249
    }
 
250
#endif /* defined(TCPCONN) || defined(STREAMSCONN) */
 
251
 
 
252
#if defined(DNETCONN)
 
253
    case AF_DECnet:
 
254
    {
 
255
        struct sockaddr_dn *saddr = (struct sockaddr_dn *) addr;
 
256
 
 
257
        networkId = (char *) xalloc (
 
258
            13 + strlen (hostnamebuf) + saddr->sdn_objnamel);
 
259
        sprintf (networkId, "dnet/%s::%s",
 
260
            hostnamebuf, saddr->sdn_objname);
 
261
        break;
 
262
    }
 
263
#endif /* defined(DNETCONN) */
 
264
 
 
265
    default:
 
266
        break;
 
267
    }
 
268
 
 
269
    return (networkId);
 
270
}
 
271
 
 
272
#include <setjmp.h>
 
273
static jmp_buf env;
 
274
 
 
275
#ifdef SIGALRM
 
276
static int nameserver_timedout = 0;
 
277
 
 
278
static 
 
279
#ifdef SIGNALRETURNSINT
 
280
int
 
281
#else
 
282
void
 
283
#endif
 
284
nameserver_lost(int sig)
 
285
{
 
286
  nameserver_timedout = 1;
 
287
  longjmp (env, -1);
 
288
  /* NOTREACHED */
 
289
#ifdef SIGNALRETURNSINT
 
290
  return -1;                            /* for picky compilers */
 
291
#endif
 
292
}
 
293
#endif /* SIGALARM */
 
294
 
 
295
 
 
296
char *
 
297
TRANS(GetPeerNetworkId) (XtransConnInfo ciptr)
 
298
 
 
299
{
 
300
    int         family = ciptr->family;
 
301
    char        *peer_addr = ciptr->peeraddr;
 
302
    char        *hostname;
 
303
    char        addrbuf[256];
 
304
    char        *addr = NULL;
 
305
 
 
306
    switch (family)
 
307
    {
 
308
    case AF_UNSPEC:
 
309
#if defined(UNIXCONN) || defined(STREAMSCONN) || defined(LOCALCONN)
 
310
    case AF_UNIX:
 
311
    {
 
312
        if (gethostname (addrbuf, sizeof (addrbuf)) == 0)
 
313
            addr = addrbuf;
 
314
        break;
 
315
    }
 
316
#endif /* defined(UNIXCONN) || defined(STREAMSCONN) || defined(LOCALCONN) */
 
317
 
 
318
#if defined(TCPCONN) || defined(STREAMSCONN)
 
319
    case AF_INET:
 
320
    {
 
321
        struct sockaddr_in *saddr = (struct sockaddr_in *) peer_addr;
 
322
#ifdef XTHREADS_NEEDS_BYNAMEPARAMS
 
323
        _Xgethostbynameparams hparams;
 
324
#endif
 
325
        struct hostent * volatile hostp = NULL;
 
326
 
 
327
#ifdef SIGALRM
 
328
        /*
 
329
         * gethostbyaddr can take a LONG time if the host does not exist.
 
330
         * Assume that if it does not respond in NAMESERVER_TIMEOUT seconds
 
331
         * that something is wrong and do not make the user wait.
 
332
         * gethostbyaddr will continue after a signal, so we have to
 
333
         * jump out of it. 
 
334
         */
 
335
 
 
336
        nameserver_timedout = 0;
 
337
        signal (SIGALRM, nameserver_lost);
 
338
        alarm (4);
 
339
        if (setjmp(env) == 0) {
 
340
#endif
 
341
            hostp = _XGethostbyaddr ((char *) &saddr->sin_addr,
 
342
                sizeof (saddr->sin_addr), AF_INET, hparams);
 
343
#ifdef SIGALRM
 
344
        }
 
345
        alarm (0);
 
346
#endif
 
347
        if (hostp != NULL)
 
348
          addr = hostp->h_name;
 
349
        else
 
350
          addr = inet_ntoa (saddr->sin_addr);
 
351
        break;
 
352
    }
 
353
 
 
354
#endif /* defined(TCPCONN) || defined(STREAMSCONN) */
 
355
 
 
356
#if defined(DNETCONN)
 
357
    case AF_DECnet:
 
358
    {
 
359
        struct sockaddr_dn *saddr = (struct sockaddr_dn *) peer_addr;
 
360
        struct nodeent *np;
 
361
 
 
362
        if (np = getnodebyaddr(saddr->sdn_add.a_addr,
 
363
            saddr->sdn_add.a_len, AF_DECnet)) {
 
364
            sprintf(addrbuf, "%s:", np->n_name);
 
365
        } else {
 
366
            sprintf(addrbuf, "%s:", dnet_htoa(&saddr->sdn_add));
 
367
        }
 
368
        addr = addrbuf;
 
369
        break;
 
370
    }
 
371
#endif /* defined(DNETCONN) */
 
372
 
 
373
    default:
 
374
        return (NULL);
 
375
    }
 
376
 
 
377
 
 
378
    hostname = (char *) xalloc (
 
379
        strlen (ciptr->transptr->TransName) + strlen (addr) + 2);
 
380
    strcpy (hostname, ciptr->transptr->TransName);
 
381
    strcat (hostname, "/");
 
382
    if (addr)
 
383
        strcat (hostname, addr);
 
384
 
 
385
    return (hostname);
 
386
}
 
387
 
 
388
#endif /* ICE_t */
 
389
 
 
390
 
 
391
#if defined(WIN32) && (defined(TCPCONN) || defined(DNETCONN))
 
392
int
 
393
TRANS(WSAStartup) (void)
 
394
{
 
395
    static WSADATA wsadata;
 
396
 
 
397
    PRMSG (2,"WSAStartup()\n", 0, 0, 0);
 
398
 
 
399
    if (!wsadata.wVersion && WSAStartup(MAKEWORD(1,1), &wsadata))
 
400
        return 1;
 
401
    return 0;
 
402
}
 
403
#endif
 
404
 
 
405
 
 
406
static int
 
407
is_numeric (char *str)
 
408
 
 
409
{
 
410
    int i;
 
411
 
 
412
    for (i = 0; i < (int) strlen (str); i++)
 
413
        if (!isdigit (str[i]))
 
414
            return (0);
 
415
 
 
416
    return (1);
 
417
}
 
418
 
 
419
#ifdef TRANS_SERVER
 
420
#include <sys/types.h>
 
421
#include <sys/stat.h>
 
422
#include <errno.h>
 
423
 
 
424
#if !defined(S_IFLNK) && !defined(S_ISLNK)
 
425
#define lstat(a,b) stat(a,b)
 
426
#endif
 
427
 
 
428
static int 
 
429
trans_mkdir(char *path, int mode)
 
430
{
 
431
    struct stat buf;
 
432
 
 
433
    if (mkdir(path, mode) == 0) {
 
434
        chmod(path, mode);
 
435
        return 0;
 
436
    }
 
437
    /* If mkdir failed with EEXIST, test if it is a directory with 
 
438
       the right modes, else fail */
 
439
    if (errno == EEXIST) {
 
440
        if (lstat(path, &buf) != 0) {
 
441
            PRMSG(1, "mkdir: (l)stat failed for %s (%d)\n",
 
442
                  path, errno, 0);
 
443
            return -1;
 
444
        }
 
445
        if (S_ISDIR(buf.st_mode)) {
 
446
            int updateOwner = 0;
 
447
            int updateMode = 0;
 
448
            int updatedOwner = 0;
 
449
            int updatedMode = 0;
 
450
            /* Check if the directory's ownership is OK. */
 
451
            if (buf.st_uid != 0)
 
452
                updateOwner = 1;
 
453
            /*
 
454
             * Check if the directory's mode is OK.  An exact match isn't
 
455
             * required, just a mode that isn't more permissive than the
 
456
             * one requested.
 
457
             */
 
458
            if ((~mode) & 0077 & buf.st_mode)
 
459
                updateMode = 1;
 
460
            if ((mode & 01000) &&
 
461
                (buf.st_mode & 0002) && !(buf.st_mode & 01000))
 
462
                updateMode = 1;
 
463
#ifdef HAS_FCHOWN
 
464
            /*
 
465
             * If fchown(2) and fchmod(2) are available, try to correct the
 
466
             * directory's owner and mode.  Otherwise it isn't safe to attempt
 
467
             * to do this.
 
468
             */
 
469
            if (updateMode || updateOwner) {
 
470
                int fd = -1;
 
471
                struct stat fbuf;
 
472
                if ((fd = open(path, O_RDONLY)) != -1) {
 
473
                    if (fstat(fd, &fbuf) == -1) {
 
474
                        PRMSG(1, "mkdir: fstat failed for %s (%d)\n",
 
475
                              path, errno, 0);
 
476
                        return -1;
 
477
                    }
 
478
                    /*
 
479
                     * Verify that we've opened the same directory as was
 
480
                     * checked above.
 
481
                     */
 
482
                    if (!S_ISDIR(fbuf.st_mode) ||
 
483
                        buf.st_dev != fbuf.st_dev ||
 
484
                        buf.st_ino != fbuf.st_ino) {
 
485
                        PRMSG(1, "mkdir: inode for %s changed\n",
 
486
                              path, 0, 0);
 
487
                        return -1;
 
488
                    }
 
489
                    if (updateOwner && fchown(fd, 0, 0) == 0)
 
490
                        updatedOwner = 1;
 
491
                    if (updateMode && fchmod(fd, mode) == 0)
 
492
                        updatedMode = 1;
 
493
                    close(fd);
 
494
                }
 
495
            }
 
496
#endif
 
497
            if (updateOwner && !updatedOwner) {
 
498
                PRMSG(1, "mkdir: Owner of %s should be set to root\n",
 
499
                      path, 0, 0);
 
500
#if !defined(__CYGWIN__)
 
501
                sleep(5);
 
502
#endif
 
503
            }
 
504
            if (updateMode && !updatedMode) {
 
505
                PRMSG(1, "mkdir: Mode of %s should be set to %04o\n",
 
506
                      path, mode, 0);
 
507
#if !defined(__CYGWIN__)
 
508
                sleep(5);
 
509
#endif
 
510
            }
 
511
            return 0;
 
512
        }
 
513
    }
 
514
    /* In all other cases, fail */
 
515
    return -1;
 
516
}
 
517
 
 
518
#endif /* TRANS_SERVER */