net/rxrpc/rxgk_app.c

Source file repositories/reference/linux-study-clean/net/rxrpc/rxgk_app.c

File Facts

System
Linux kernel
Corpus path
net/rxrpc/rxgk_app.c
Extension
.c
Size
7543 bytes
Lines
291
Domain
Networking Core
Bucket
Sockets, Protocols, Packet Path, And Network Policy
Inferred role
Networking Core: implementation source
Status
source implementation candidate

Why This File Exists

Networking stack implementation surface: socket APIs, protocol dispatch, packet flow, routing, filtering, and network namespaces.

Dependency Surface

Detected Declarations

Annotated Snippet

// 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)
 */

#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#include <linux/net.h>
#include <linux/skbuff.h>
#include <linux/slab.h>
#include <linux/key-type.h>
#include "ar-internal.h"
#include "rxgk_common.h"

/*
 * Decode a default-style YFS ticket in a response and turn it into an
 * rxrpc-type key.
 *
 * struct rxgk_key {
 *	afs_uint32	enctype;
 *	opaque		key<>;
 * };
 *
 * struct RXGK_AuthName {
 *	afs_int32	kind;
 *	opaque		data<AUTHDATAMAX>;
 *	opaque		display<AUTHPRINTABLEMAX>;
 * };
 *
 * struct RXGK_Token {
 *	rxgk_key		K0;
 *	RXGK_Level		level;
 *	rxgkTime		starttime;
 *	afs_int32		lifetime;
 *	afs_int32		bytelife;
 *	rxgkTime		expirationtime;
 *	struct RXGK_AuthName	identities<>;
 * };
 */
int rxgk_yfs_decode_ticket(struct rxrpc_connection *conn, struct sk_buff *skb,
			   void *buffer, unsigned int ticket_len,
			   struct key **_key)
{
	struct rxrpc_key_token *token;
	const struct cred *cred = current_cred(); // TODO - use socket creds
	struct key *key;
	size_t pre_ticket_len, payload_len;
	unsigned int klen, enctype;
	void *payload, *ticket;
	__be32 *t, *p, *q, *tmp;
	int ret;

	_enter("");

	if (ticket_len < 10 * sizeof(__be32))
		return rxrpc_abort_conn(conn, skb, RXGK_INCONSISTENCY, -EPROTO,
					rxgk_abort_resp_short_yfs_tkt);

	/* Get the session key length */
	tmp = buffer;
	enctype = ntohl(tmp[0]);
	klen = ntohl(tmp[1]);

	if (klen > ticket_len - 10 * sizeof(__be32))
		return rxrpc_abort_conn(conn, skb, RXGK_INCONSISTENCY, -EPROTO,
					rxgk_abort_resp_short_yfs_key);

	pre_ticket_len = ((5 + 14) * sizeof(__be32) +
			  xdr_round_up(klen) +
			  sizeof(__be32));
	payload_len = pre_ticket_len + xdr_round_up(ticket_len);

	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;
	memcpy(ticket, buffer, ticket_len);

	/* Fill out the form header. */
	p = payload;
	p[0] = htonl(0); /* Flags */
	p[1] = htonl(1); /* len(cellname) */
	p[2] = htonl(0x20000000); /* Cellname " " */

Annotation

Implementation Notes