]> git.sesse.net Git - rdpsrv/blob - Xserver/programs/Xserver/dix/extension.c
Support RDP5 logon packets.
[rdpsrv] / Xserver / programs / Xserver / dix / extension.c
1 /***********************************************************
2
3 Copyright (c) 1987  X Consortium
4
5 Permission is hereby granted, free of charge, to any person obtaining a copy
6 of this software and associated documentation files (the "Software"), to deal
7 in the Software without restriction, including without limitation the rights
8 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 copies of the Software, and to permit persons to whom the Software is
10 furnished to do so, subject to the following conditions:
11
12 The above copyright notice and this permission notice shall be included in
13 all copies or substantial portions of the Software.
14
15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
18 X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
19 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
22 Except as contained in this notice, the name of the X Consortium shall not be
23 used in advertising or otherwise to promote the sale, use or other dealings
24 in this Software without prior written authorization from the X Consortium.
25
26
27 Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
28
29                         All Rights Reserved
30
31 Permission to use, copy, modify, and distribute this software and its 
32 documentation for any purpose and without fee is hereby granted, 
33 provided that the above copyright notice appear in all copies and that
34 both that copyright notice and this permission notice appear in 
35 supporting documentation, and that the name of Digital not be
36 used in advertising or publicity pertaining to distribution of the
37 software without specific, written prior permission.  
38
39 DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
40 ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
41 DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
42 ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
43 WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
44 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
45 SOFTWARE.
46
47 ******************************************************************/
48 /* $XConsortium: extension.c /main/36 1996/09/28 11:23:27 rws $ */
49 /* $XFree86: xc/programs/Xserver/dix/extension.c,v 3.5 1996/12/23 06:29:44 dawes Exp $ */
50
51 #include "X.h"
52 #define NEED_EVENTS
53 #define NEED_REPLIES
54 #include "Xproto.h"
55 #include "misc.h"
56 #include "dixstruct.h"
57 #include "extnsionst.h"
58 #include "gcstruct.h"
59 #include "scrnintstr.h"
60 #include "dispatch.h"
61 #ifdef XCSECURITY
62 #define _SECURITY_SERVER
63 #include "extensions/security.h"
64 #endif
65
66 #define EXTENSION_BASE  128
67 #define EXTENSION_EVENT_BASE  64
68 #define LAST_EVENT  128
69 #define LAST_ERROR 255
70
71 ScreenProcEntry AuxillaryScreenProcs[MAXSCREENS];
72
73 static ExtensionEntry **extensions = (ExtensionEntry **)NULL;
74
75 int lastEvent = EXTENSION_EVENT_BASE;
76 static int lastError = FirstExtensionError;
77 static unsigned int NumExtensions = 0;
78
79 ExtensionEntry *AddExtension(name, NumEvents, NumErrors, MainProc, 
80                               SwappedMainProc, CloseDownProc, MinorOpcodeProc)
81     char *name;
82     int NumEvents;
83     int NumErrors;
84     int (* MainProc)();
85     int (* SwappedMainProc)();
86     void (* CloseDownProc)();
87     unsigned short (* MinorOpcodeProc)();
88 {
89     int i;
90     register ExtensionEntry *ext, **newexts;
91
92     if (!MainProc || !SwappedMainProc || !CloseDownProc || !MinorOpcodeProc)
93         return((ExtensionEntry *) NULL);
94     if ((lastEvent + NumEvents > LAST_EVENT) || 
95                 (unsigned)(lastError + NumErrors > LAST_ERROR))
96         return((ExtensionEntry *) NULL);
97
98     ext = (ExtensionEntry *) xalloc(sizeof(ExtensionEntry));
99     if (!ext)
100         return((ExtensionEntry *) NULL);
101     ext->name = (char *)xalloc(strlen(name) + 1);
102     ext->num_aliases = 0;
103     ext->aliases = (char **)NULL;
104     if (!ext->name)
105     {
106         xfree(ext);
107         return((ExtensionEntry *) NULL);
108     }
109     strcpy(ext->name,  name);
110     i = NumExtensions;
111     newexts = (ExtensionEntry **) xrealloc(extensions,
112                                            (i + 1) * sizeof(ExtensionEntry *));
113     if (!newexts)
114     {
115         xfree(ext->name);
116         xfree(ext);
117         return((ExtensionEntry *) NULL);
118     }
119     NumExtensions++;
120     extensions = newexts;
121     extensions[i] = ext;
122     ext->index = i;
123     ext->base = i + EXTENSION_BASE;
124     ext->CloseDown = CloseDownProc;
125     ext->MinorOpcode = MinorOpcodeProc;
126     ProcVector[i + EXTENSION_BASE] = MainProc;
127     SwappedProcVector[i + EXTENSION_BASE] = SwappedMainProc;
128     if (NumEvents)
129     {
130         ext->eventBase = lastEvent;
131         ext->eventLast = lastEvent + NumEvents;
132         lastEvent += NumEvents;
133     }
134     else
135     {
136         ext->eventBase = 0;
137         ext->eventLast = 0;
138     }
139     if (NumErrors)
140     {
141         ext->errorBase = lastError;
142         ext->errorLast = lastError + NumErrors;
143         lastError += NumErrors;
144     }
145     else
146     {
147         ext->errorBase = 0;
148         ext->errorLast = 0;
149     }
150 #ifdef XCSECURITY
151     ext->secure = FALSE;
152 #endif
153
154 #ifdef LBX
155     (void) LbxAddExtension(name, ext->base, ext->eventBase, ext->errorBase);
156 #endif
157     return(ext);
158 }
159
160 Bool AddExtensionAlias(alias, ext)
161     char *alias;
162     ExtensionEntry *ext;
163 {
164     char *name;
165     char **aliases;
166
167     aliases = (char **)xrealloc(ext->aliases,
168                                 (ext->num_aliases + 1) * sizeof(char *));
169     if (!aliases)
170         return FALSE;
171     ext->aliases = aliases;
172     name = (char *)xalloc(strlen(alias) + 1);
173     if (!name)
174         return FALSE;
175     strcpy(name,  alias);
176     ext->aliases[ext->num_aliases] = name;
177     ext->num_aliases++;
178 #ifdef LBX
179     return LbxAddExtensionAlias(ext->index, alias);
180 #else
181     return TRUE;
182 #endif
183 }
184
185 static int
186 FindExtension(extname, len)
187     char *extname;
188     int len;
189 {
190     int i, j;
191
192     for (i=0; i<NumExtensions; i++)
193     {
194         if ((strlen(extensions[i]->name) == len) &&
195             !strncmp(extname, extensions[i]->name, len))
196             break;
197         for (j = extensions[i]->num_aliases; --j >= 0;)
198         {
199             if ((strlen(extensions[i]->aliases[j]) == len) &&
200                 !strncmp(extname, extensions[i]->aliases[j], len))
201                 break;
202         }
203         if (j >= 0) break;
204     }
205     return ((i == NumExtensions) ? -1 : i);
206 }
207
208 void
209 DeclareExtensionSecurity(extname, secure)
210     char *extname;
211     Bool secure;
212 {
213 #ifdef XCSECURITY
214     int i = FindExtension(extname, strlen(extname));
215     if (i >= 0)
216     {
217         int majorop = extensions[i]->base;
218         extensions[i]->secure = secure;
219         if (secure)
220         {
221             UntrustedProcVector[majorop] = ProcVector[majorop];
222             SwappedUntrustedProcVector[majorop] = SwappedProcVector[majorop];
223         }
224         else
225         {
226             UntrustedProcVector[majorop]        = ProcBadRequest;
227             SwappedUntrustedProcVector[majorop] = ProcBadRequest;
228         }
229     }
230 #endif
231 #ifdef LBX
232     LbxDeclareExtensionSecurity(extname, secure);
233 #endif
234 }
235
236 unsigned short
237 StandardMinorOpcode(client)
238     ClientPtr client;
239 {
240     return ((xReq *)client->requestBuffer)->data;
241 }
242
243 unsigned short
244 MinorOpcodeOfRequest(client)
245     ClientPtr client;
246 {
247     unsigned char major;
248
249     major = ((xReq *)client->requestBuffer)->reqType;
250     if (major < EXTENSION_BASE)
251         return 0;
252     major -= EXTENSION_BASE;
253     if (major >= NumExtensions)
254         return 0;
255     return (*extensions[major]->MinorOpcode)(client);
256 }
257
258 void
259 CloseDownExtensions()
260 {
261     register int i,j;
262
263 #ifdef LBX
264     LbxCloseDownExtensions();
265 #endif
266
267     for (i = NumExtensions - 1; i >= 0; i--)
268     {
269         (* extensions[i]->CloseDown)(extensions[i]);
270         NumExtensions = i;
271         xfree(extensions[i]->name);
272         for (j = extensions[i]->num_aliases; --j >= 0;)
273             xfree(extensions[i]->aliases[j]);
274         xfree(extensions[i]->aliases);
275         xfree(extensions[i]);
276     }
277     xfree(extensions);
278     extensions = (ExtensionEntry **)NULL;
279     lastEvent = EXTENSION_EVENT_BASE;
280     lastError = FirstExtensionError;
281     for (i=0; i<MAXSCREENS; i++)
282     {
283         register ScreenProcEntry *spentry = &AuxillaryScreenProcs[i];
284
285         while (spentry->num)
286         {
287             spentry->num--;
288             xfree(spentry->procList[spentry->num].name);
289         }
290         xfree(spentry->procList);
291         spentry->procList = (ProcEntryPtr)NULL;
292     }
293 }
294
295
296 int
297 ProcQueryExtension(client)
298     ClientPtr client;
299 {
300     xQueryExtensionReply reply;
301     int i;
302     REQUEST(xQueryExtensionReq);
303
304     REQUEST_FIXED_SIZE(xQueryExtensionReq, stuff->nbytes);
305     
306     reply.type = X_Reply;
307     reply.length = 0;
308     reply.major_opcode = 0;
309     reply.sequenceNumber = client->sequence;
310
311     if ( ! NumExtensions )
312         reply.present = xFalse;
313     else
314     {
315         i = FindExtension((char *)&stuff[1], stuff->nbytes);
316         if (i < 0
317 #ifdef XCSECURITY
318             /* don't show insecure extensions to untrusted clients */
319             || (client->trustLevel == XSecurityClientUntrusted &&
320                 !extensions[i]->secure)
321 #endif
322             )
323             reply.present = xFalse;
324         else
325         {            
326             reply.present = xTrue;
327             reply.major_opcode = extensions[i]->base;
328             reply.first_event = extensions[i]->eventBase;
329             reply.first_error = extensions[i]->errorBase;
330         }
331     }
332     WriteReplyToClient(client, sizeof(xQueryExtensionReply), &reply);
333     return(client->noClientException);
334 }
335
336 int
337 ProcListExtensions(client)
338     ClientPtr client;
339 {
340     xListExtensionsReply reply;
341     char *bufptr, *buffer;
342     int total_length = 0;
343
344     REQUEST_SIZE_MATCH(xReq);
345
346     reply.type = X_Reply;
347     reply.nExtensions = 0;
348     reply.length = 0;
349     reply.sequenceNumber = client->sequence;
350     buffer = NULL;
351
352     if ( NumExtensions )
353     {
354         register int i, j;
355
356         for (i=0;  i<NumExtensions; i++)
357         {
358 #ifdef XCSECURITY
359             /* don't show insecure extensions to untrusted clients */
360             if (client->trustLevel == XSecurityClientUntrusted &&
361                 !extensions[i]->secure)
362                 continue;
363 #endif
364             total_length += strlen(extensions[i]->name) + 1;
365             reply.nExtensions += 1 + extensions[i]->num_aliases;
366             for (j = extensions[i]->num_aliases; --j >= 0;)
367                 total_length += strlen(extensions[i]->aliases[j]) + 1;
368         }
369         reply.length = (total_length + 3) >> 2;
370         buffer = bufptr = (char *)ALLOCATE_LOCAL(total_length);
371         if (!buffer)
372             return(BadAlloc);
373         for (i=0;  i<NumExtensions; i++)
374         {
375             int len;
376 #ifdef XCSECURITY
377             if (client->trustLevel == XSecurityClientUntrusted &&
378                 !extensions[i]->secure)
379                 continue;
380 #endif
381             *bufptr++ = len = strlen(extensions[i]->name);
382             memmove(bufptr, extensions[i]->name,  len);
383             bufptr += len;
384             for (j = extensions[i]->num_aliases; --j >= 0;)
385             {
386                 *bufptr++ = len = strlen(extensions[i]->aliases[j]);
387                 memmove(bufptr, extensions[i]->aliases[j],  len);
388                 bufptr += len;
389             }
390         }
391     }
392     WriteReplyToClient(client, sizeof(xListExtensionsReply), &reply);
393     if (reply.length)
394     {
395         WriteToClient(client, total_length, buffer);
396         DEALLOCATE_LOCAL(buffer);
397     }
398     return(client->noClientException);
399 }
400
401
402 ExtensionLookupProc 
403 LookupProc(name, pGC)
404     char *name;
405     GCPtr pGC;
406 {
407     register int i;
408     register ScreenProcEntry *spentry;
409     spentry  = &AuxillaryScreenProcs[pGC->pScreen->myNum];
410     if (spentry->num)    
411     {
412         for (i = 0; i < spentry->num; i++)
413             if (strcmp(name, spentry->procList[i].name) == 0)
414                 return(spentry->procList[i].proc);
415     }
416     return (ExtensionLookupProc)NULL;
417 }
418
419 Bool
420 RegisterProc(name, pGC, proc)
421     char *name;
422     GC *pGC;
423     ExtensionLookupProc proc;
424 {
425     return RegisterScreenProc(name, pGC->pScreen, proc);
426 }
427
428 Bool
429 RegisterScreenProc(name, pScreen, proc)
430     char *name;
431     ScreenPtr pScreen;
432     ExtensionLookupProc proc;
433 {
434     register ScreenProcEntry *spentry;
435     register ProcEntryPtr procEntry = (ProcEntryPtr)NULL;
436     char *newname;
437     int i;
438
439     spentry = &AuxillaryScreenProcs[pScreen->myNum];
440     /* first replace duplicates */
441     if (spentry->num)
442     {
443         for (i = 0; i < spentry->num; i++)
444             if (strcmp(name, spentry->procList[i].name) == 0)
445             {
446                 procEntry = &spentry->procList[i];
447                 break;
448             }
449     }
450     if (procEntry)
451         procEntry->proc = proc;
452     else
453     {
454         newname = (char *)xalloc(strlen(name)+1);
455         if (!newname)
456             return FALSE;
457         procEntry = (ProcEntryPtr)
458                             xrealloc(spentry->procList,
459                                      sizeof(ProcEntryRec) * (spentry->num+1));
460         if (!procEntry)
461         {
462             xfree(newname);
463             return FALSE;
464         }
465         spentry->procList = procEntry;
466         procEntry += spentry->num;
467         procEntry->name = newname;
468         strcpy(newname, name);
469         procEntry->proc = proc;
470         spentry->num++;        
471     }
472     return TRUE;
473 }