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