1 /*
2  * Copyright (c) 2006-2021, RT-Thread Development Team
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Change Logs:
7  * Date           Author       Notes
8  */
9 
10 #include <rpc/types.h>
11 #include <rpc/xdr.h>
12 #include <rpc/auth.h>
13 
14 #define MAX_MARSHEL_SIZE 64
15 
16 struct nfs_credentia
17 {
18     rt_uint32_t stamp;
19     char *name;
20     rt_uint32_t uid;
21     rt_uint32_t gid;
22     rt_uint32_t *auxi;
23     rt_uint32_t auxi_count;
24 };
25 
26 static void authnone_verf(AUTH *);
27 static bool_t authnone_validate(AUTH *, struct opaque_auth *);
28 static bool_t authnone_refresh(AUTH *);
29 static void authnone_destroy(AUTH *);
30 static bool_t authnone_marshal(AUTH *client, XDR *xdrs);
31 
32 static struct nfs_credentia _credentia = {
33     .stamp = 0,
34     .name = "rt-thread",
35     .uid = 0,
36     .gid = 0,
37     .auxi = NULL,
38     .auxi_count = 0,
39 };
40 
41 struct opaque_auth _null_auth;
42 
43 static struct auth_ops ops =
44 {
45     authnone_verf,
46     authnone_marshal,
47     authnone_validate,
48     authnone_refresh,
49     authnone_destroy
50 };
51 
52 static struct authnone_private
53 {
54     AUTH no_client;
55     char marshalled_client[MAX_MARSHEL_SIZE];
56     unsigned int mcnt;
57 } *authnone_private;
58 
authnone_create(void)59 AUTH *authnone_create(void)
60 {
61     register struct authnone_private *ap = authnone_private;
62     XDR xdr_stream;
63     register XDR *xdrs;
64     extern bool_t xdr_opaque_auth(XDR * xdrs, struct opaque_auth * ap);
65     struct opaque_auth auth;
66     rt_uint32_t *auth_buf, *auth_base;
67     int buf_len = 0, str_len = 0;
68 
69     if (_credentia.name)
70     {
71         str_len = strlen(_credentia.name);
72     }
73     if (str_len == 0)
74     {
75         _credentia.name = "unknown";
76         str_len = strlen(_credentia.name);
77     }
78     buf_len = ((str_len) + (sizeof(rt_uint32_t)) - 1) & ~((sizeof(rt_uint32_t)) - 1);
79     buf_len += sizeof(struct nfs_credentia);
80     if (_credentia.auxi && _credentia.auxi_count)
81     {
82         buf_len += sizeof(rt_uint32_t) * _credentia.auxi_count;
83     }
84     auth_buf = auth_base = rt_malloc(buf_len);
85     if (auth_buf == NULL)
86     {
87         return NULL;
88     }
89     memset(auth_buf, 0, buf_len);
90     *auth_buf++ = htonl(rt_tick_get());
91     *auth_buf++ = htonl(str_len);
92     memcpy(auth_buf, _credentia.name, str_len);
93     auth_buf += (str_len + sizeof(rt_uint32_t) - 1) >> 2;
94     *auth_buf++ = htonl(_credentia.uid);
95     *auth_buf++ = htonl(_credentia.gid);
96     if (_credentia.auxi && _credentia.auxi_count)
97     {
98         rt_uint32_t tmp_cnt = 0;
99         *auth_buf++ = htonl(_credentia.auxi_count);
100         while (tmp_cnt < _credentia.auxi_count)
101         {
102             *auth_buf++ = htonl(_credentia.auxi[tmp_cnt]);
103         }
104     }
105     else
106     {
107         *auth_buf++ = htonl(0);
108     }
109 
110     if (ap == 0)
111     {
112         ap = (struct authnone_private *) rt_malloc(sizeof(*ap));
113         if (ap == 0)
114         {
115             rt_free(auth_base);
116             return NULL;
117         }
118         memset(ap, 0, sizeof(*ap));
119         authnone_private = ap;
120     }
121 
122     if (!ap->mcnt)
123     {
124         memset(&auth, 0, sizeof(auth));
125         auth.oa_flavor = 1;
126         auth.oa_base = (char *)auth_base;
127         auth.oa_length = (auth_buf - auth_base) * sizeof(rt_uint32_t);
128         ap->no_client.ah_cred = auth;
129         ap->no_client.ah_verf = _null_auth;
130         ap->no_client.ah_ops = &ops;
131         xdrs = &xdr_stream;
132         xdrmem_create(xdrs, ap->marshalled_client,
133                       (unsigned int) MAX_MARSHEL_SIZE, XDR_ENCODE);
134         (void) xdr_opaque_auth(xdrs, &ap->no_client.ah_cred);
135         (void) xdr_opaque_auth(xdrs, &ap->no_client.ah_verf);
136         ap->mcnt = XDR_GETPOS(xdrs);
137         XDR_DESTROY(xdrs);
138     }
139     rt_free(auth_base);
140     return (&ap->no_client);
141 }
142 
143 /*ARGSUSED*/
authnone_marshal(AUTH * client,XDR * xdrs)144 static bool_t authnone_marshal(AUTH *client, XDR *xdrs)
145 {
146     register struct authnone_private *ap = authnone_private;
147 
148     if (ap == 0)
149         return (0);
150     return ((*xdrs->x_ops->x_putbytes)(xdrs,
151                                        ap->marshalled_client, ap->mcnt));
152 }
153 
authnone_verf(AUTH * x)154 static void authnone_verf(AUTH *x)
155 {
156 }
157 
authnone_validate(AUTH * x,struct opaque_auth * x1)158 static bool_t authnone_validate(AUTH *x, struct opaque_auth *x1)
159 {
160 
161     return (TRUE);
162 }
163 
authnone_refresh(AUTH * x)164 static bool_t authnone_refresh(AUTH *x)
165 {
166 
167     return (FALSE);
168 }
169 
authnone_destroy(AUTH * x)170 static void authnone_destroy(AUTH *x)
171 {
172 }
173