1/*
2
3Copyright 1991, 1998  The Open Group
4
5Permission to use, copy, modify, distribute, and sell this software and its
6documentation for any purpose is hereby granted without fee, provided that
7the above copyright notice appear in all copies and that both that
8copyright notice and this permission notice appear in supporting
9documentation.
10
11The above copyright notice and this permission notice shall be included
12in all copies or substantial portions of the Software.
13
14THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
18OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20OTHER DEALINGS IN THE SOFTWARE.
21
22Except as contained in this notice, the name of The Open Group shall
23not be used in advertising or otherwise to promote the sale, use or
24other dealings in this Software without prior written authorization
25from The Open Group.
26
27*/
28
29/*
30 * SUN-DES-1 authentication mechanism
31 * Author:  Mayank Choudhary, Sun Microsystems
32 */
33
34
35#ifdef HAVE_DIX_CONFIG_H
36#include <dix-config.h>
37#endif
38
39#ifdef SECURE_RPC
40
41#include <X11/X.h>
42#include <X11/Xauth.h>
43#include "misc.h"
44#include "os.h"
45#include "osdep.h"
46#include "dixstruct.h"
47
48#include <rpc/rpc.h>
49
50#ifdef sun
51/* <rpc/auth.h> only includes this if _KERNEL is #defined... */
52extern bool_t xdr_opaque_auth(XDR *, struct opaque_auth *);
53#endif
54
55static enum auth_stat why;
56
57static char *
58authdes_ezdecode(const char *inmsg, int len)
59{
60    struct rpc_msg  msg;
61    char            cred_area[MAX_AUTH_BYTES];
62    char            verf_area[MAX_AUTH_BYTES];
63    char            *temp_inmsg;
64    struct svc_req  r;
65    bool_t          res0, res1;
66    XDR             xdr;
67    SVCXPRT         xprt;
68
69    temp_inmsg = malloc(len);
70    if (temp_inmsg == NULL) {
71        why = AUTH_FAILED; /* generic error, since there is no AUTH_BADALLOC */
72        return NULL;
73    }
74    memmove(temp_inmsg, inmsg, len);
75
76    memset((char *)&msg, 0, sizeof(msg));
77    memset((char *)&r, 0, sizeof(r));
78    memset(cred_area, 0, sizeof(cred_area));
79    memset(verf_area, 0, sizeof(verf_area));
80
81    msg.rm_call.cb_cred.oa_base = cred_area;
82    msg.rm_call.cb_verf.oa_base = verf_area;
83    why = AUTH_FAILED;
84    xdrmem_create(&xdr, temp_inmsg, len, XDR_DECODE);
85
86    if ((r.rq_clntcred = malloc(MAX_AUTH_BYTES)) == NULL)
87        goto bad1;
88    r.rq_xprt = &xprt;
89
90    /* decode into msg */
91    res0 = xdr_opaque_auth(&xdr, &(msg.rm_call.cb_cred));
92    res1 = xdr_opaque_auth(&xdr, &(msg.rm_call.cb_verf));
93    if ( ! (res0 && res1) )
94         goto bad2;
95
96    /* do the authentication */
97
98    r.rq_cred = msg.rm_call.cb_cred;        /* read by opaque stuff */
99    if (r.rq_cred.oa_flavor != AUTH_DES) {
100        why = AUTH_TOOWEAK;
101        goto bad2;
102    }
103#ifdef SVR4
104    if ((why = __authenticate(&r, &msg)) != AUTH_OK) {
105#else
106    if ((why = _authenticate(&r, &msg)) != AUTH_OK) {
107#endif
108            goto bad2;
109    }
110    return (((struct authdes_cred *) r.rq_clntcred)->adc_fullname.name);
111
112bad2:
113    free(r.rq_clntcred);
114bad1:
115    return ((char *)0); /* ((struct authdes_cred *) NULL); */
116}
117
118static XID  rpc_id = (XID) ~0L;
119
120static Bool
121CheckNetName (
122    unsigned char    *addr,
123    short	    len,
124    pointer	    closure
125)
126{
127    return (len == strlen ((char *) closure) &&
128	    strncmp ((char *) addr, (char *) closure, len) == 0);
129}
130
131static char rpc_error[MAXNETNAMELEN+50];
132
133_X_HIDDEN XID
134SecureRPCCheck (unsigned short data_length, const char *data,
135    ClientPtr client, char **reason)
136{
137    char *fullname;
138
139    if (rpc_id == (XID) ~0L) {
140	*reason = "Secure RPC authorization not initialized";
141    } else {
142	fullname = authdes_ezdecode(data, data_length);
143	if (fullname == (char *)0) {
144	    sprintf(rpc_error, "Unable to authenticate secure RPC client (why=%d)", why);
145	    *reason = rpc_error;
146	} else {
147	    if (ForEachHostInFamily (FamilyNetname, CheckNetName, fullname))
148		return rpc_id;
149	    sprintf(rpc_error, "Principal \"%s\" is not authorized to connect",
150			fullname);
151	    *reason = rpc_error;
152	}
153    }
154    return (XID) ~0L;
155}
156
157_X_HIDDEN void
158SecureRPCInit (void)
159{
160    if (rpc_id == ~0L)
161	AddAuthorization (9, "SUN-DES-1", 0, (char *) 0);
162}
163
164_X_HIDDEN int
165SecureRPCAdd (unsigned short data_length, const char *data, XID id)
166{
167    if (data_length)
168	AddHost ((pointer) 0, FamilyNetname, data_length, data);
169    rpc_id = id;
170    return 1;
171}
172
173_X_HIDDEN int
174SecureRPCReset (void)
175{
176    rpc_id = (XID) ~0L;
177    return 1;
178}
179
180_X_HIDDEN int
181SecureRPCFromID (XID id, unsigned short *data_lenp, char **datap)
182{
183    return 0;
184}
185
186_X_HIDDEN int
187SecureRPCRemove (unsigned short data_length, const char *data)
188{
189    return 0;
190}
191#endif /* SECURE_RPC */
192