1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* Cache manager security. 3 * 4 * Copyright (C) 2025 Red Hat, Inc. All Rights Reserved. 5 * Written by David Howells (dhowells@redhat.com) 6 */ 7 8 #include <linux/slab.h> 9 #include <crypto/krb5.h> 10 #include "internal.h" 11 #include "afs_fs.h" 12 #include "protocol_yfs.h" 13 #define RXRPC_TRACE_ONLY_DEFINE_ENUMS 14 #include <trace/events/rxrpc.h> 15 16 /* 17 * Respond to an RxGK challenge, adding appdata. 18 */ 19 static int afs_respond_to_challenge(struct sk_buff *challenge) 20 { 21 #ifdef CONFIG_RXGK 22 struct krb5_buffer appdata = {}; 23 #endif 24 struct rxrpc_peer *peer; 25 unsigned long peer_data; 26 u16 service_id; 27 u8 security_index; 28 29 rxrpc_kernel_query_challenge(challenge, &peer, &peer_data, 30 &service_id, &security_index); 31 32 _enter("%u,%u", service_id, security_index); 33 34 switch (service_id) { 35 /* We don't send CM_SERVICE RPCs, so don't expect a challenge 36 * therefrom. 37 */ 38 case FS_SERVICE: 39 case VL_SERVICE: 40 case YFS_FS_SERVICE: 41 case YFS_VL_SERVICE: 42 break; 43 default: 44 pr_warn("Can't respond to unknown challenge %u:%u", 45 service_id, security_index); 46 return rxrpc_kernel_reject_challenge(challenge, RX_USER_ABORT, -EPROTO, 47 afs_abort_unsupported_sec_class); 48 } 49 50 switch (security_index) { 51 #ifdef CONFIG_RXKAD 52 case RXRPC_SECURITY_RXKAD: 53 return rxkad_kernel_respond_to_challenge(challenge); 54 #endif 55 56 #ifdef CONFIG_RXGK 57 case RXRPC_SECURITY_RXGK: 58 case RXRPC_SECURITY_YFS_RXGK: 59 return rxgk_kernel_respond_to_challenge(challenge, &appdata); 60 #endif 61 62 default: 63 return rxrpc_kernel_reject_challenge(challenge, RX_USER_ABORT, -EPROTO, 64 afs_abort_unsupported_sec_class); 65 } 66 } 67 68 /* 69 * Process the OOB message queue, processing challenge packets. 70 */ 71 void afs_process_oob_queue(struct work_struct *work) 72 { 73 struct afs_net *net = container_of(work, struct afs_net, rx_oob_work); 74 struct sk_buff *oob; 75 enum rxrpc_oob_type type; 76 77 while ((oob = rxrpc_kernel_dequeue_oob(net->socket, &type))) { 78 switch (type) { 79 case RXRPC_OOB_CHALLENGE: 80 afs_respond_to_challenge(oob); 81 break; 82 } 83 rxrpc_kernel_free_oob(oob); 84 } 85 } 86