15 #include <linux/module.h>
16 #include <linux/net.h>
20 #include <linux/ctype.h>
21 #include <linux/slab.h>
28 static int rxrpc_vet_description_s(
const char *);
29 static int rxrpc_instantiate(
struct key *,
struct key_preparsed_payload *);
30 static int rxrpc_instantiate_s(
struct key *,
struct key_preparsed_payload *);
31 static void rxrpc_destroy(
struct key *);
32 static void rxrpc_destroy_s(
struct key *);
33 static void rxrpc_describe(
const struct key *,
struct seq_file *);
34 static long rxrpc_read(
const struct key *,
char __user *,
size_t);
42 .instantiate = rxrpc_instantiate,
44 .destroy = rxrpc_destroy,
45 .describe = rxrpc_describe,
56 .vet_description = rxrpc_vet_description_s,
57 .instantiate = rxrpc_instantiate_s,
59 .destroy = rxrpc_destroy_s,
60 .describe = rxrpc_describe,
66 static int rxrpc_vet_description_s(
const char *
desc)
72 if (*p !=
':' || num > 65535)
75 if (*p || num < 1 || num > 255)
84 static int rxrpc_instantiate_xdr_rxkad(
struct key *
key,
const __be32 *xdr,
92 _enter(
",{%x,%x,%x,%x},%u",
98 tktlen =
ntohl(xdr[7]);
99 _debug(
"tktlen: %x", tktlen);
102 if (8 * 4 + tktlen != toklen)
105 plen =
sizeof(*token) +
sizeof(*token->
kad) + tktlen;
110 plen -=
sizeof(*token);
122 token->
kad->ticket_len = tktlen;
123 token->
kad->vice_id =
ntohl(xdr[0]);
127 token->
kad->primary_flag =
ntohl(xdr[6]);
128 memcpy(&token->
kad->session_key, &xdr[2], 8);
129 memcpy(&token->
kad->ticket, &xdr[8], tktlen);
132 _debug(
"TLEN: %u", token->
kad->ticket_len);
135 _debug(
"PRIM: %u", token->
kad->primary_flag);
136 _debug(
"SKEY: %02x%02x%02x%02x%02x%02x%02x%02x",
137 token->
kad->session_key[0], token->
kad->session_key[1],
138 token->
kad->session_key[2], token->
kad->session_key[3],
139 token->
kad->session_key[4], token->
kad->session_key[5],
140 token->
kad->session_key[6], token->
kad->session_key[7]);
141 if (token->
kad->ticket_len >= 8)
142 _debug(
"TCKT: %02x%02x%02x%02x%02x%02x%02x%02x",
143 token->
kad->ticket[0], token->
kad->ticket[1],
144 token->
kad->ticket[2], token->
kad->ticket[3],
145 token->
kad->ticket[4], token->
kad->ticket[5],
146 token->
kad->ticket[6], token->
kad->ticket[7]);
149 key->type_data.x[0]++;
154 pptoken = &(*pptoken)->
next)
157 if (token->
kad->expiry < key->expiry)
158 key->expiry = token->
kad->expiry;
164 static void rxrpc_free_krb5_principal(
struct krb5_principal *princ)
184 static void rxrpc_rxk5_free(
struct rxk5_key *rxk5)
188 rxrpc_free_krb5_principal(&rxk5->
client);
189 rxrpc_free_krb5_principal(&rxk5->
server);
190 rxrpc_free_krb5_tagged(&rxk5->
session);
193 for (loop = rxk5->
n_addresses - 1; loop >= 0; loop--)
194 rxrpc_free_krb5_tagged(&rxk5->
addresses[loop]);
198 for (loop = rxk5->
n_authdata - 1; loop >= 0; loop--)
199 rxrpc_free_krb5_tagged(&rxk5->
authdata[loop]);
211 static int rxrpc_krb5_decode_principal(
struct krb5_principal *princ,
213 unsigned int *_toklen)
215 const __be32 *xdr = *_xdr;
216 unsigned int toklen = *_toklen, n_parts, loop,
tmp;
226 n_parts =
ntohl(*xdr++);
232 if (toklen <= (n_parts + 1) * 4)
239 for (loop = 0; loop < n_parts; loop++) {
253 tmp = (tmp + 3) & ~3;
271 tmp = (tmp + 3) & ~3;
279 _leave(
" = 0 [toklen=%u]", toklen);
287 size_t max_data_size,
289 unsigned int *_toklen)
291 const __be32 *xdr = *_xdr;
292 unsigned int toklen = *_toklen,
len;
299 max_data_size,
ntohl(xdr[0]),
ntohl(xdr[1]), toklen);
304 if (len > max_data_size)
312 len = (len + 3) & ~3;
321 _leave(
" = 0 [toklen=%u]", toklen);
331 size_t max_elem_size,
333 unsigned int *_toklen)
336 const __be32 *xdr = *_xdr;
337 unsigned int toklen = *_toklen, n_elem, loop;
344 _enter(
",,%u,%zu,{%x},%u",
345 max_n_elem, max_elem_size,
ntohl(xdr[0]), toklen);
347 n_elem =
ntohl(*xdr++);
349 if (n_elem < 0 || n_elem > max_n_elem)
353 if (toklen <= (n_elem + 1) * 4)
356 _debug(
"n_elem %d", n_elem);
364 for (loop = 0; loop < n_elem; loop++) {
365 ret = rxrpc_krb5_decode_tagged_data(&td[loop],
375 _leave(
" = 0 [toklen=%u]", toklen);
382 static int rxrpc_krb5_decode_ticket(
u8 **_ticket,
u16 *_tktlen,
383 const __be32 **_xdr,
unsigned int *_toklen)
385 const __be32 *xdr = *_xdr;
386 unsigned int toklen = *_toklen, len;
400 _debug(
"ticket len %u", len);
406 len = (len + 3) & ~3;
413 _leave(
" = 0 [toklen=%u]", toklen);
421 static int rxrpc_instantiate_xdr_rxk5(
struct key *key,
const __be32 *xdr,
426 const __be32 *end_xdr = xdr + (toklen >> 2);
429 _enter(
",{%x,%x,%x,%x},%u",
453 ret = rxrpc_krb5_decode_principal(&rxk5->
client, &xdr, &toklen);
456 ret = rxrpc_krb5_decode_principal(&rxk5->
server, &xdr, &toklen);
467 if (toklen < 4 * 8 + 2 * 4)
479 toklen -= 4 * 8 + 2 * 4;
481 _debug(
"times: a=%llx s=%llx e=%llx rt=%llx",
487 ret = rxrpc_krb5_decode_tagged_array(&rxk5->
addresses,
495 ASSERTCMP((end_xdr - xdr) << 2, ==, toklen);
507 ASSERTCMP((end_xdr - xdr) << 2, ==, toklen);
510 ret = rxrpc_krb5_decode_tagged_array(&rxk5->
authdata,
518 ASSERTCMP((end_xdr - xdr) << 2, ==, toklen);
526 pptoken = &(*pptoken)->
next)
529 if (token->
kad->expiry < key->expiry)
530 key->expiry = token->
kad->expiry;
538 rxrpc_rxk5_free(rxk5);
548 static int rxrpc_instantiate_xdr(
struct key *key,
const void *
data,
size_t datalen)
552 unsigned int len,
tmp, loop, ntoken, toklen, sec_ix;
555 _enter(
",{%x,%x,%x,%x},%zu",
568 if (
ntohl(*xdr++) != 0)
577 tmp = (len + 3) & ~3;
581 cp = (
const char *) xdr;
582 for (loop = 0; loop < len; loop++)
586 for (; loop <
tmp; loop++)
589 _debug(
"cellname: [%u/%u] '%*.*s'",
590 len, tmp, len, len, (
const char *) xdr);
597 ntoken =
ntohl(*xdr++);
599 _debug(
"ntoken: %x", ntoken);
609 toklen =
ntohl(*xdr++);
610 sec_ix =
ntohl(*xdr);
612 _debug(
"token: [%x/%zx] %x", toklen, datalen, sec_ix);
613 if (toklen < 20 || toklen > datalen)
615 datalen -= (toklen + 3) & ~3;
616 xdr += (toklen + 3) >> 2;
618 }
while (--loop > 0);
620 _debug(
"remainder: %zu", datalen);
629 toklen =
ntohl(*xdr++);
630 token = xdr + ((toklen + 3) >> 2);
631 sec_ix =
ntohl(*xdr++);
634 _debug(
"TOKEN type=%u [%p-%p]", sec_ix, xdr, token);
638 ret = rxrpc_instantiate_xdr_rxkad(key, xdr, toklen);
644 ret = rxrpc_instantiate_xdr_rxk5(key, xdr, toklen);
654 }
while (--ntoken > 0);
681 static int rxrpc_instantiate(
struct key *key,
struct key_preparsed_payload *prep)
689 _enter(
"{%x},,%zu", key_serial(key), prep->datalen);
692 if (!prep->data && prep->datalen == 0)
696 if (prep->datalen > 7 * 4) {
697 ret = rxrpc_instantiate_xdr(key, prep->data, prep->datalen);
704 if (prep->datalen <= 4 || !prep->data)
706 memcpy(&kver, prep->data,
sizeof(kver));
707 prep->data +=
sizeof(kver);
708 prep->datalen -=
sizeof(kver);
710 _debug(
"KEY I/F VERSION: %u", kver);
718 if (prep->datalen <
sizeof(*v1))
729 _debug(
"SKEY: %02x%02x%02x%02x%02x%02x%02x%02x",
735 _debug(
"TCKT: %02x%02x%02x%02x%02x%02x%02x%02x",
766 key->type_data.x[0]++;
772 if (token->
kad->expiry < key->expiry)
773 key->expiry = token->
kad->expiry;
787 static int rxrpc_instantiate_s(
struct key *key,
788 struct key_preparsed_payload *prep)
792 _enter(
"{%x},,%zu", key_serial(key), prep->datalen);
794 if (prep->datalen != 8)
797 memcpy(&key->type_data, prep->data, 8);
801 _leave(
" = %ld", PTR_ERR(ci));
805 if (crypto_blkcipher_setkey(ci, prep->data, 8) < 0)
808 key->payload.data = ci;
816 static void rxrpc_destroy(
struct key *key)
820 while ((token = key->payload.data)) {
821 key->payload.data = token->
next;
828 rxrpc_rxk5_free(token->
k5);
843 static void rxrpc_destroy_s(
struct key *key)
845 if (key->payload.data) {
846 crypto_free_blkcipher(key->payload.data);
847 key->payload.data =
NULL;
854 static void rxrpc_describe(
const struct key *key,
struct seq_file *
m)
869 if (optlen <= 0 || optlen >
PAGE_SIZE - 1)
880 description[optlen] = 0;
885 _leave(
" = %ld", PTR_ERR(key));
891 _leave(
" = 0 [key %x]", key->serial);
906 if (optlen <= 0 || optlen >
PAGE_SIZE - 1)
917 description[optlen] = 0;
922 _leave(
" = %ld", PTR_ERR(key));
928 _leave(
" = 0 [key %x]", key->serial);
953 KEY_ALLOC_NOT_IN_QUOTA);
955 _leave(
" = -ENOMEM [alloc %ld]", PTR_ERR(key));
959 _debug(
"key %d", key_serial(key));
963 data.v1.ticket_length = 0;
967 memcpy(&data.v1.session_key, session_key,
sizeof(data.v1.session_key));
974 _leave(
" = 0 [%d]", key_serial(key));
980 _leave(
" = -ENOMEM [ins %d]", ret);
1000 KEY_POS_SEARCH, KEY_ALLOC_NOT_IN_QUOTA);
1008 return ERR_PTR(ret);
1019 static long rxrpc_read(
const struct key *key,
1026 u32 cnlen, toksize, ntoks, tok,
zero;
1033 if (
memcmp(key->description,
"afs@", 4) != 0)
1035 cnlen =
strlen(key->description + 4);
1037 #define RND(X) (((X) + 3) & ~3)
1046 for (token = key->payload.data; token; token = token->
next) {
1053 toksize +=
RND(token->
kad->ticket_len);
1057 princ = &token->
k5->client;
1063 princ = &token->
k5->server;
1069 toksize += 8 +
RND(token->
k5->session.data_len);
1071 toksize += 4 * 8 + 2 * 4;
1073 toksize += 4 + token->
k5->n_addresses * 8;
1074 for (loop = 0; loop < token->
k5->n_addresses; loop++)
1075 toksize +=
RND(token->
k5->addresses[loop].data_len);
1077 toksize += 4 +
RND(token->
k5->ticket_len);
1078 toksize += 4 +
RND(token->
k5->ticket2_len);
1080 toksize += 4 + token->
k5->n_authdata * 8;
1081 for (loop = 0; loop < token->
k5->n_authdata; loop++)
1082 toksize +=
RND(token->
k5->authdata[loop].data_len);
1090 _debug(
"token[%u]: toksize=%u", ntoks, toksize);
1093 toksizes[ntoks++] = toksize;
1094 size += toksize + 4;
1099 if (!buffer || buflen < size)
1106 __be32 y = htonl(x); \
1107 if (put_user(y, xdr++) < 0) \
1110 #define ENCODE_DATA(l, s) \
1114 if (copy_to_user(xdr, (s), _l) != 0) \
1117 copy_to_user((u8 *)xdr + _l, &zero, 4 - (_l & 3)) != 0) \
1119 xdr += (_l + 3) >> 2; \
1121 #define ENCODE64(x) \
1123 __be64 y = cpu_to_be64(x); \
1124 if (copy_to_user(xdr, &y, 8) != 0) \
1128 #define ENCODE_STR(s) \
1130 const char *_s = (s); \
1131 ENCODE_DATA(strlen(_s), _s); \
1139 for (token = key->payload.data; token; token = token->
next) {
1140 toksize = toksizes[tok++];
1157 princ = &token->
k5->client;
1163 princ = &token->
k5->server;
1171 token->
k5->session.data);
1181 for (loop = 0; loop < token->
k5->n_addresses; loop++) {
1182 ENCODE(token->
k5->addresses[loop].tag);
1184 token->
k5->addresses[loop].data);
1191 for (loop = 0; loop < token->
k5->n_authdata; loop++) {
1192 ENCODE(token->
k5->authdata[loop].tag);
1194 token->
k5->authdata[loop].data);
1203 ASSERTCMP((
unsigned long)xdr - (
unsigned long)oldxdr, ==,
1213 ASSERTCMP((
char __user *) xdr - buffer, ==, size);