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

« back to all changes in this revision

Viewing changes to unix/xc/lib/dps/csstartNX.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
/*
 
2
  csstartNX.c
 
3
 
 
4
 * (c) Copyright 1992-1994 Adobe Systems Incorporated.
 
5
 * All rights reserved.
 
6
 * 
 
7
 * Permission to use, copy, modify, distribute, and sublicense this software
 
8
 * and its documentation for any purpose and without fee is hereby granted,
 
9
 * provided that the above copyright notices appear in all copies and that
 
10
 * both those copyright notices and this permission notice appear in
 
11
 * supporting documentation and that the name of Adobe Systems Incorporated
 
12
 * not be used in advertising or publicity pertaining to distribution of the
 
13
 * software without specific, written prior permission.  No trademark license
 
14
 * to use the Adobe trademarks is hereby granted.  If the Adobe trademark
 
15
 * "Display PostScript"(tm) is used to describe this software, its
 
16
 * functionality or for any other purpose, such use shall be limited to a
 
17
 * statement that this software works in conjunction with the Display
 
18
 * PostScript system.  Proper trademark attribution to reflect Adobe's
 
19
 * ownership of the trademark shall be given whenever any such reference to
 
20
 * the Display PostScript system is made.
 
21
 * 
 
22
 * ADOBE MAKES NO REPRESENTATIONS ABOUT THE SUITABILITY OF THE SOFTWARE FOR
 
23
 * ANY PURPOSE.  IT IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY.
 
24
 * ADOBE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
 
25
 * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 
26
 * NON- INFRINGEMENT OF THIRD PARTY RIGHTS.  IN NO EVENT SHALL ADOBE BE LIABLE
 
27
 * TO YOU OR ANY OTHER PARTY FOR ANY SPECIAL, INDIRECT, OR CONSEQUENTIAL
 
28
 * DAMAGES OR ANY DAMAGES WHATSOEVER WHETHER IN AN ACTION OF CONTRACT,
 
29
 * NEGLIGENCE, STRICT LIABILITY OR ANY OTHER ACTION ARISING OUT OF OR IN
 
30
 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.  ADOBE WILL NOT
 
31
 * PROVIDE ANY TRAINING OR OTHER SUPPORT FOR THE SOFTWARE.
 
32
 * 
 
33
 * Adobe, PostScript, and Display PostScript are trademarks of Adobe Systems
 
34
 * Incorporated which may be registered in certain jurisdictions
 
35
 * 
 
36
 * Author:  Adobe Systems Incorporated
 
37
 */
 
38
/* $XFree86: xc/lib/dps/csstartNX.c,v 1.7 2002/05/31 18:45:48 dawes Exp $ */
 
39
 
 
40
#include <sys/param.h>
 
41
#include <X11/X.h>
 
42
#include <X11/Xlibint.h>
 
43
#include <sys/wait.h>
 
44
#include <DPS/dpsNXargs.h>
 
45
#include <sys/socket.h>
 
46
#include <errno.h>
 
47
#include <X11/Xos.h>
 
48
 
 
49
#include "DPSCAPproto.h"
 
50
#include "Xlibnet.h"            /* New for R5, delete for R4 */
 
51
#include "dpsassert.h"
 
52
#include "csfindNX.h"
 
53
#include "csstartNX.h"
 
54
 
 
55
/* ---Defines--- */
 
56
 
 
57
#include <stddef.h>
 
58
  
 
59
#define DOZETIME 1              /* time to wait for agent to start up (sec) */
 
60
 
 
61
#define BASE_TCP_PORT CSDPSPORT
 
62
 
 
63
#ifndef CSDPSMAXPORT
 
64
#define CSDPSMAXPORT 16
 
65
#endif
 
66
 
 
67
#ifndef SO_REUSEADDR
 
68
#define SO_REUSEADDR 1
 
69
#endif
 
70
 
 
71
/* ---Globals--- */
 
72
 
 
73
pid_t gSecretAgentPID = 0;      /* PID of launched agent *Shh!* Not public! */
 
74
 
 
75
/* ---Private Functions--- */
 
76
 
 
77
static int
 
78
TryTCP(void)
 
79
{
 
80
    struct sockaddr_in insock;
 
81
    int request;
 
82
    unsigned short port, startPort = 0;
 
83
    struct servent *serventInfo;
 
84
    int okay;
 
85
 
 
86
#ifndef ultrix
 
87
    /* Ultrix has a nasty bug in getservbyname().  If the name passed
 
88
       to it doesn't exist in the services list it will seg. fault...
 
89
       * sigh *  */
 
90
    if ((serventInfo = getservbyname(DPS_NX_SERV_NAME,
 
91
                                        (char *) 0)) != 0)
 
92
        if (strcmp("tcp", serventInfo->s_proto) == 0) {
 
93
          startPort = ntohs(serventInfo->s_port);
 
94
        }
 
95
    /* So, for Ultrix we just default to the default default port :-) */ 
 
96
#endif /* ultrix */
 
97
    if (startPort == 0) startPort = BASE_TCP_PORT;
 
98
    if ((request = socket (AF_INET, SOCK_STREAM, 0)) < 0) 
 
99
    {
 
100
        DPSWarnProc(NULL, "Creating TCP socket while recommending port\n");
 
101
        return -1;
 
102
    } 
 
103
#ifdef SO_REUSEADDR
 
104
    /* Necesary to restart the server without a reboot */
 
105
    {
 
106
        int one = 1;
 
107
        setsockopt(request, SOL_SOCKET, SO_REUSEADDR, (char *)&one, sizeof(int));
 
108
    }
 
109
    /* What the hell is all this?  I'll tell you.  We don't know
 
110
       a prioi what port is free, so we try to bind to each
 
111
       in sequence and return the one that works. */
 
112
#if !defined(AIXV3)
 
113
    {
 
114
      struct linger lingere;
 
115
      
 
116
      lingere.l_onoff = 0;              /* off */
 
117
      lingere.l_linger = 0;             /* don't */
 
118
      if(setsockopt(request, SOL_SOCKET, SO_LINGER, (char *)&lingere,
 
119
        sizeof(struct linger)) != 0)
 
120
      DPSWarnProc(NULL,
 
121
                  "Couldn't set TCP SO_DONTLINGER while recommending port.");
 
122
    }
 
123
#endif /* AIXV3 */
 
124
#endif /* SO_REUSEADDR */
 
125
    bzero((char *)&insock, sizeof (insock));
 
126
    insock.sin_family = AF_INET;
 
127
    insock.sin_addr.s_addr = htonl(INADDR_ANY);
 
128
    okay = 0;
 
129
    
 
130
    for (port = startPort; (int) port < (int) startPort + CSDPSMAXPORT; port++)
 
131
    {
 
132
    int result;
 
133
    insock.sin_port = htons(port);
 
134
    
 
135
    errno = 0;
 
136
    result = bind(request, (struct sockaddr *) &insock, sizeof (insock));
 
137
    if (result < 0)
 
138
        {
 
139
        if (errno != EADDRINUSE)
 
140
            {
 
141
            DPSWarnProc(NULL, "Binding TCP socket while recommending port.\n");
 
142
            close(request);
 
143
            return -1;
 
144
            }
 
145
        continue;
 
146
        }
 
147
    else
 
148
        {
 
149
        /* We have a good port number */
 
150
        okay = 1;
 
151
        break;
 
152
        }
 
153
    }
 
154
    close(request);
 
155
    return (okay) ? port : -1;
 
156
}
 
157
 
 
158
/* ---Functions--- */
 
159
 
 
160
int
 
161
XDPSNXRecommendPort(int transport)
 
162
{
 
163
    int ret;
 
164
    
 
165
    switch (transport)
 
166
        {
 
167
        case XDPSNX_TRANS_UNIX:
 
168
            /* If the TCP socket exists, we just assume the UNIX one
 
169
               is there too.  FALL THRU! */
 
170
        case XDPSNX_TRANS_TCP: /* TCP */
 
171
            ret = TryTCP();
 
172
            break;
 
173
        default: ret = -1;
 
174
        }
 
175
    return(ret);
 
176
}
 
177
 
 
178
int
 
179
StartXDPSNX(char **additionalArgs)
 
180
{
 
181
  char **args, **cpp;
 
182
  pid_t childPid;
 
183
  int argc = 1;                 /* 1, args[0]:=path, args[1]:=null */
 
184
  int i = 0;
 
185
  int status = Success;         /* assume we'll succeed */
 
186
  char *execObj, **execArgs;
 
187
 
 
188
  (void) XDPSGetNXArg(XDPSNX_EXEC_FILE, (void **) &execObj);
 
189
  if (execObj == 0) return (!Success);
 
190
 
 
191
  /* Create the argv list for the execl() call */
 
192
  (void) XDPSGetNXArg(XDPSNX_EXEC_ARGS, (void **) &execArgs);
 
193
  if (execArgs != 0)
 
194
    for(cpp = execArgs; *cpp != 0; cpp++, argc++); /* count args. */
 
195
  if (additionalArgs != 0)      /* add on the add-on args. */
 
196
    for(cpp = additionalArgs; *cpp != 0; cpp++, argc++); 
 
197
 
 
198
  args = (char **) Xmalloc(sizeof(char *) * (argc+1));
 
199
  if (args == 0)
 
200
    return(!Success);
 
201
  args[argc] = 0;               /* cap end of args */
 
202
  args[i++] = execObj;
 
203
  if (additionalArgs != 0)
 
204
    for(cpp = additionalArgs; *cpp != 0; cpp++, i++) args[i] = *cpp;
 
205
  if (execArgs != 0)
 
206
    for(cpp = execArgs; *cpp != 0; cpp++, i++) args[i] = *cpp;
 
207
 
 
208
  /* now try to start up the agent... */
 
209
  if ((childPid = fork()) != -1) {
 
210
    if (childPid == 0) {        /* Child process */
 
211
#ifndef __UNIXOS2__
 
212
      if (setsid() < 0)
 
213
        DPSWarnProc(NULL, "Agent unable to create session.  Continuing...\n");
 
214
#endif
 
215
 
 
216
      /* Try to start the agent */
 
217
      if (execvp(args[0], args) < 0) { /* Error!! */
 
218
        exit(1);                /* This is OKAY, we're the child here */
 
219
      }
 
220
      /* SHOULD NEVER REACH HERE */
 
221
    } else {                    /* Parent (NX Client) */
 
222
      (void) sleep(DOZETIME);
 
223
      /* if decmips, pray that we hesitate long enough for the child... */
 
224
      /* Check on child (NX Agent) */
 
225
      if (waitpid(childPid, NULL, WNOHANG) != 0) {
 
226
        /* Server terminated or stopped; don't care, result is same... */
 
227
        status = !Success;
 
228
      } else {                  /* we think the agent started okay */
 
229
        gSecretAgentPID = childPid; /* set secret global */
 
230
      }
 
231
    }
 
232
  } else {                      /* Error in fork */
 
233
    status = !Success;
 
234
  }
 
235
  if (args != 0) (void) XFree(args);
 
236
  return(status);
 
237
}