Whamcloud - gitweb
LU-16356 hsm: add running ref to the coordinator
[fs/lustre-release.git] / lustre / include / uapi / linux / lustre / lgss.h
1 /*
2  * GPL HEADER START
3  *
4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 only,
8  * as published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * General Public License version 2 for more details (a copy is included
14  * in the LICENSE file that accompanied this code).
15  *
16  * You should have received a copy of the GNU General Public License
17  * version 2 along with this program; If not, see
18  * http://www.gnu.org/licenses/gpl-2.0.html
19  *
20  * GPL HEADER END
21  */
22 /*
23  * Copyright (c) 2022, Whamcloud.
24  */
25 /*
26  * This file is part of Lustre, http://www.lustre.org/
27  */
28
29 #ifndef _LGSS_H
30 #define _LGSS_H
31
32 #ifndef __KERNEL__
33 # define __USE_ISOC99   1
34 # include <stdio.h> /* snprintf() */
35 # include <stdlib.h> /* abs() */
36 # include <inttypes.h> /* PRIu64 */
37 # include <ctype.h> /* isascii() */
38 # define __USE_GNU      1
39 # define __USE_XOPEN2K8  1
40 #else
41 #include <linux/ctype.h>
42 #define PRIu64 "llu"
43 #define PRIx64 "llx"
44 #endif /* !__KERNEL__ */
45
46 #include <linux/types.h>
47 #include <linux/string.h>
48 #include <linux/unistd.h>
49
50 /*
51  * sparse kernel source annotations
52  */
53 #ifndef __user
54 #define __user
55 #endif
56
57 struct lgssd_ioctl_param {
58         /* in */
59         __u32 version;
60         __u32 secid;
61         char __user *uuid;
62         __u32 lustre_svc;
63         __kernel_uid_t uid;
64         __kernel_gid_t gid;
65         __u64 send_token_size;
66         char __user *send_token;
67         __u64 reply_buf_size;
68         char __user *reply_buf;
69         /* out */
70         __u64 status;
71         __u64 reply_length;
72 };
73
74 #define GSS_SOCKET_PATH "/tmp/svcgssd.socket"
75 #define RSI_DOWNCALL_MAGIC      0x6d6dd62a
76 #define RSI_DOWNCALL_PATH       "sptlrpc/gss/rsi_info"
77 #define RSI_CACHE_NAME          "rsicache"
78
79 struct rsi_downcall_data {
80         __u32     sid_magic;
81         __u32     sid_err;
82         __u32     sid_hash;
83         __u32     sid_maj_stat;
84         __u32     sid_min_stat;
85         __u32     sid_len;
86         __s64     sid_offset;
87         /* sid_val contains in_handle, in_token,
88          * out_handle, out_token
89          */
90         char      sid_val[0];
91 };
92
93 /*
94  * gss_string_write() - write some string
95  *
96  * If string is empty, write single digit 0.
97  * Pad with a trailing space.
98  */
99 static inline void gss_string_write(char **dst, int *dstlen, const char *src)
100 {
101         char *cp = *dst;
102         int ret;
103
104         if (*dstlen < 0)
105                 return;
106
107         if (!strlen(src))
108                 ret = snprintf(cp, *dstlen, "0");
109         else
110                 ret = snprintf(cp, *dstlen, "%s", src);
111         if (ret >= *dstlen) {
112                 cp += *dstlen;
113                 *dstlen = -1;
114         } else {
115                 cp[ret] = ' ';
116                 cp += ret + 1;
117                 *dstlen -= ret + 1;
118         }
119         *dst = cp;
120 }
121
122 /*
123  * gss_u64_write() - write some u64
124  */
125 static inline void gss_u64_write_string(char **dst, int *dstlen, uint64_t n)
126 {
127         char *cp = *dst;
128         int ret;
129
130         if (*dstlen < 0)
131                 return;
132
133         ret = snprintf(cp, *dstlen, "%"PRIu64, n);
134         if (ret >= *dstlen) {
135                 cp += *dstlen;
136                 *dstlen = -1;
137         } else {
138                 cp[ret] = ' ';
139                 cp += ret + 1;
140                 *dstlen -= ret + 1;
141         }
142         *dst = cp;
143 }
144
145 /*
146  * gss_u64_write_hex() - write some u64 in hex
147  */
148 static inline void gss_u64_write_hex_string(char **dst, int *dstlen, uint64_t n)
149 {
150         char *cp = *dst;
151         int ret;
152
153         if (*dstlen < 0)
154                 return;
155
156         ret = snprintf(cp, *dstlen, "0x%"PRIx64, n);
157         if (ret >= *dstlen) {
158                 cp += *dstlen;
159                 *dstlen = -1;
160         } else {
161                 cp[ret] = ' ';
162                 cp += ret + 1;
163                 *dstlen -= ret + 1;
164         }
165         *dst = cp;
166 }
167
168 /*
169  * gss_buffer_write() - write some buffer
170  */
171 static inline void gss_buffer_write(char **dst, int *dstlen,
172                                     const __u8 *src, int srclen)
173 {
174         char *cp = *dst;
175         int len = *dstlen;
176         __u32 *p;
177
178         if (len < 0)
179                 return;
180
181         if (len < sizeof(__u32)) {
182                 len = -1;
183                 goto out;
184         }
185
186         /* write size of data */
187         p = (__u32 *)cp;
188         *p = srclen;
189         cp += sizeof(__u32);
190         len -= sizeof(__u32);
191
192         if (!srclen)
193                 goto out;
194
195         /* write data itself */
196         while (srclen && len) {
197                 *cp++ = *src++;
198                 len--;
199                 srclen--;
200         }
201         if (!len && srclen)
202                 len = -1;
203
204 out:
205         *dst = cp;
206         *dstlen = len;
207 }
208
209 /*
210  * gss_u32_write() - write some u32
211  */
212 static inline void gss_u32_write(char **dst, int *dstlen, __u32 val)
213 {
214         char *cp = *dst;
215         int len = *dstlen;
216         __u32 *p;
217
218         if (len < 0)
219                 return;
220
221         if (len < sizeof(__u32)) {
222                 len = -1;
223                 goto out;
224         }
225
226         p = (__u32 *)cp;
227         *p = val;
228         cp += sizeof(__u32);
229         len -= sizeof(__u32);
230
231 out:
232         *dst = cp;
233         *dstlen = len;
234 }
235
236 static const char base64url_table[] =
237         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
238
239 #define BASE64URL_CHARS(nbytes) ((((nbytes) * 4) + 3 - 1) / 3)
240
241 /*
242  * gss_base64url_encode() - base64url-encode some binary data
243  *
244  * Encode data using base64url encoding, i.e. the "Base 64 Encoding with URL
245  * and Filename Safe Alphabet" specified by RFC 4648.  '='-padding isn't used,
246  * as it's unneeded and not required by the RFC.
247  * Pad with a trailing space.
248  */
249 static inline void gss_base64url_encode(char **dst, int *dstlen,
250                                         const __u8 *src, int srclen)
251 {
252         char *cp = *dst;
253         int len = *dstlen;
254         __u32 ac = 0;
255         int bits = 0;
256         int i;
257
258         if (len < 0)
259                 return;
260
261         if (!srclen)
262                 return gss_string_write(dst, dstlen, "");
263
264         for (i = 0; i < srclen; i++) {
265                 if (!len)
266                         break;
267                 ac = (ac << 8) | src[i];
268                 bits += 8;
269                 do {
270                         bits -= 6;
271                         *cp++ = base64url_table[(ac >> bits) & 0x3f];
272                         len--;
273                 } while (bits >= 6 && len > 0);
274         }
275         if (i < srclen) {
276                 len = -1;
277                 goto out;
278         }
279
280         if (bits) {
281                 *cp++ = base64url_table[(ac << (6 - bits)) & 0x3f];
282                 len--;
283         }
284
285         if (!len) {
286                 len = -1;
287                 goto out;
288         }
289         *cp++ = ' ';
290         len--;
291
292 out:
293         *dst = cp;
294         *dstlen = len;
295 }
296
297 /*
298  * gss_base64url_decode() - base64url-decode a string
299  *
300  * Decode a string using base64url encoding, i.e. the "Base 64 Encoding with
301  * URL and Filename Safe Alphabet" specified by RFC 4648.  '='-padding isn't
302  * accepted, nor are non-encoding characters such as whitespace.
303  * String end is marked with a trailing space or '\n' or '\0'.
304  */
305 static inline int gss_base64url_decode(char **src, char *dst, int destsize)
306 {
307         int bits = 0, len = 0;
308         char *cp = *src, *p;
309         char *bp = dst;
310         __u32 ac = 0;
311
312         while (*cp == ' ')
313                 cp++;
314
315         /* the single digit 0 is inserted if field is empty */
316         if (*cp == '0' &&
317             (*(cp + 1) == ' ' || *(cp + 1) == '\n' || *(cp + 1) == '\0')) {
318                 cp++;
319                 goto fini;
320         }
321
322         while (isascii(*cp)) {
323                 if (*cp == ' ' || *cp == '\n' || *cp == '\0')
324                         break;
325
326                 p = strchr(base64url_table, *cp);
327                 if (len > destsize || p == NULL || *cp == '\0') {
328                         len = -1;
329                         goto out;
330                 }
331
332                 cp++;
333                 ac = (ac << 6) | (p - base64url_table);
334                 bits += 6;
335                 if (bits >= 8) {
336                         bits -= 8;
337                         *bp++ = (__u8)(ac >> bits);
338                         len++;
339                 }
340         }
341
342         if (!isascii(*cp) || (ac & ((1 << bits) - 1))) {
343                 len = -1;
344                 goto out;
345         }
346
347 fini:
348         *src = cp;
349 out:
350         return len;
351 }
352
353 /*
354  * gss_string_read() - read some string
355  *
356  * An empty string is represented with the single digit 0.
357  * String end is marked with a trailing space or '\n' or '\0'.
358  */
359 static inline int gss_string_read(char **src, char *dst, int destsize,
360                                   int allowzero)
361 {
362         char *cp = *src;
363         char *bp = dst;
364         int len = 0;
365
366         while (*cp == ' ')
367                 cp++;
368
369         /* the single digit 0 is inserted if field is empty */
370         if (!allowzero && *cp == '0' &&
371             (*(cp + 1) == ' ' || *(cp + 1) == '\n')) {
372                 cp++;
373                 goto out;
374         }
375
376         while (isascii(*cp)) {
377                 if (*cp == ' ' || *cp == '\n')
378                         break;
379
380                 if (len >= destsize || *cp == '\0') {
381                         len = -1;
382                         goto out;
383                 }
384
385                 *(bp++) = *(cp++);
386                 len++;
387         }
388
389         if (!isascii(*cp)) {
390                 len = -1;
391                 goto out;
392         }
393
394         *src = cp;
395
396 out:
397         return len;
398 }
399
400 #ifndef __KERNEL__
401 /*
402  * gss_u64_read() - read some u64
403  */
404 static inline int gss_u64_read_string(char **src, __u64 *n)
405 {
406         char buf[24];
407         char *ep;
408         int ret;
409
410         ret = gss_string_read(src, buf, sizeof(buf), 1);
411         if (ret < 0)
412                 return ret;
413
414         buf[ret] = '\0';
415         *n = strtoull(buf, &ep, 0);
416         if (*ep)
417                 return -1;
418
419         return 0;
420 }
421 #endif
422
423 /*
424  * gss_buffer_read() - read some buffer
425  */
426 static inline int gss_buffer_read(char **src, char *dst, int destsize)
427 {
428         char *cp = *src;
429         char *bp = dst;
430         __u32 *p;
431         int len, size;
432
433         /* read data size */
434         p = (__u32 *)cp;
435         len = *p;
436         cp += sizeof(__u32);
437
438         if (len > destsize) {
439                 len = -1;
440                 goto out;
441         }
442
443         if (!len)
444                 goto fini;
445
446         /* read data itself */
447         size = len;
448         while (size && destsize) {
449                 *(bp++) = *(cp++);
450                 destsize--;
451                 size--;
452         }
453         if (!destsize && size)
454                 len = -1;
455
456 fini:
457         *src = cp;
458 out:
459         return len;
460 }
461
462 /*
463  * gss_buffer_get() - get reference to gss buffer
464  */
465 static inline int gss_buffer_get(char **src, __u32 *len, __u8 **data)
466 {
467         char *cp = *src;
468         __u32 *p;
469
470         /* read data size */
471         p = (__u32 *)cp;
472         *len = *p;
473         cp += sizeof(__u32);
474
475         /* point to data buf */
476         if (!*len)
477                 *data = NULL;
478         else
479                 *data = (__u8 *)cp;
480
481         /* move forward */
482         cp += *len;
483
484         *src = cp;
485         return *len;
486 }
487
488 /*
489  * gss_u32_read() - read some u32
490  */
491 static inline int gss_u32_read(char **src, __u32 *val)
492 {
493         char *cp = *src;
494         __u32 *p;
495
496         p = (__u32 *)cp;
497         *val = *p;
498         cp += sizeof(__u32);
499
500         *src = cp;
501         return 0;
502 }
503
504 #endif /* _LGSS_H */