// SPDX-License-Identifier: GPL-2.0-or-later /* Application-specific bits for GSSAPI-based RxRPC security * * Copyright (C) 2025 Red Hat, Inc. All Rights Reserved. * Written by David Howells (dhowells@redhat.com)
*/
payload = kzalloc(payload_len, GFP_NOFS); if (!payload) return -ENOMEM;
/* We need to fill out the XDR form for a key payload that we can pass * to add_key(). Start by copying in the ticket so that we can parse * it.
*/
ticket = payload + pre_ticket_len;
ret = skb_copy_bits(skb, ticket_offset, ticket, ticket_len); if (ret < 0) {
ret = rxrpc_abort_conn(conn, skb, RXGK_INCONSISTENCY, -EPROTO,
rxgk_abort_resp_short_yfs_tkt); goto error;
}
/* Fill out the form header. */
p = payload;
p[0] = htonl(0); /* Flags */
p[1] = htonl(1); /* len(cellname) */
p[2] = htonl(0x20000000); /* Cellname " " */
p[3] = htonl(1); /* #tokens */
p[4] = htonl(15 * sizeof(__be32) + xdr_round_up(klen) +
xdr_round_up(ticket_len)); /* Token len */
if (token_len < sizeof(container)) goto short_packet;
/* Decode the RXGK_TokenContainer object. This tells us which server * key we should be using. We can then fetch the key, get the secret * and set up the crypto to extract the token.
*/ if (skb_copy_bits(skb, token_offset, &container, sizeof(container)) < 0) goto short_packet;
server_key = rxrpc_look_up_server_security(conn, skb, kvno, enctype); if (IS_ERR(server_key)) goto cant_get_server_key;
down_read(&server_key->sem);
server_secret = (constvoid *)&server_key->payload.data[2];
ret = rxgk_set_up_token_cipher(server_secret, &token_enc, enctype, &krb5, GFP_NOFS);
up_read(&server_key->sem);
key_put(server_key); if (ret < 0) goto cant_get_token;
/* We can now decrypt and parse the token/ticket. This allows us to * gain access to K0, from which we can derive the transport key and * thence decode the authenticator.
*/
ret = rxgk_decrypt_skb(krb5, token_enc, skb,
&ticket_offset, &ticket_len, &ec);
crypto_free_aead(token_enc);
token_enc = NULL; if (ret < 0) { if (ret != -ENOMEM) return rxrpc_abort_conn(conn, skb, ec, ret,
rxgk_abort_resp_tok_dec);
}
ret = conn->security->default_decode_ticket(conn, skb, ticket_offset,
ticket_len, _key); if (ret < 0) goto cant_get_token;
_leave(" = 0"); return ret;
cant_get_server_key:
ret = PTR_ERR(server_key); switch (ret) { case -ENOMEM: goto temporary_error; case -ENOKEY: case -EKEYREJECTED: case -EKEYEXPIRED: case -EKEYREVOKED: case -EPERM: return rxrpc_abort_conn(conn, skb, RXGK_BADKEYNO, -EKEYREJECTED,
rxgk_abort_resp_tok_nokey); default: return rxrpc_abort_conn(conn, skb, RXGK_NOTAUTH, -EKEYREJECTED,
rxgk_abort_resp_tok_keyerr);
}
cant_get_token: switch (ret) { case -ENOMEM: goto temporary_error; case -EINVAL: return rxrpc_abort_conn(conn, skb, RXGK_NOTAUTH, -EKEYREJECTED,
rxgk_abort_resp_tok_internal_error); case -ENOPKG: return rxrpc_abort_conn(conn, skb, KRB5_PROG_KEYTYPE_NOSUPP,
-EKEYREJECTED, rxgk_abort_resp_tok_nopkg);
}
temporary_error: /* Ignore the response packet if we got a temporary error such as * ENOMEM. We just want to send the challenge again. Note that we * also come out this way if the ticket decryption fails.
*/ return ret;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.