aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteve French <stfrench@microsoft.com>2019-09-19 05:00:55 -0400
committerSteve French <stfrench@microsoft.com>2019-09-21 07:02:26 -0400
commit7e7db86c7e1088e768438fe6c894d748b0c32abe (patch)
tree8e37feaaf0706e4a3f3547883bc59f3e2a5a3aa2
parent4d6bcba70aeb4a512ead9c9eaf9edc6bbab00b14 (diff)
smb3: allow decryption keys to be dumped by admin for debugging
In order to debug certain problems it is important to be able to decrypt network traces (e.g. wireshark) but to do this we need to be able to dump out the encryption/decryption keys. Dumping them to an ioctl is safer than dumping then to dmesg, (and better than showing all keys in a pseudofile). Restrict this to root (CAP_SYS_ADMIN), and only for a mount that this admin has access to. Sample smbinfo output: SMB3.0 encryption Session Id: 0x82d2ec52 Session Key: a5 6d 81 d0 e c1 ca e1 d8 13 aa 20 e8 f2 cc 71 Server Encryption Key: 1a c3 be ba 3d fc dc 3c e bc 93 9e 50 9e 19 c1 Server Decryption Key: e0 d4 d9 43 1b a2 1b e3 d8 76 77 49 56 f7 20 88 Reviewed-by: Aurelien Aptel <aaptel@suse.com> Pavel Shilovsky <pshilov@microsoft.com> Signed-off-by: Steve French <stfrench@microsoft.com>
-rw-r--r--fs/cifs/cifs_ioctl.h9
-rw-r--r--fs/cifs/ioctl.c29
2 files changed, 38 insertions, 0 deletions
diff --git a/fs/cifs/cifs_ioctl.h b/fs/cifs/cifs_ioctl.h
index 6c3bd07868d7..0f0dc1c1fe41 100644
--- a/fs/cifs/cifs_ioctl.h
+++ b/fs/cifs/cifs_ioctl.h
@@ -57,9 +57,18 @@ struct smb_query_info {
57 /* char buffer[]; */ 57 /* char buffer[]; */
58} __packed; 58} __packed;
59 59
60struct smb3_key_debug_info {
61 __u64 Suid;
62 __u16 cipher_type;
63 __u8 auth_key[16]; /* SMB2_NTLMV2_SESSKEY_SIZE */
64 __u8 smb3encryptionkey[SMB3_SIGN_KEY_SIZE];
65 __u8 smb3decryptionkey[SMB3_SIGN_KEY_SIZE];
66} __packed;
67
60#define CIFS_IOCTL_MAGIC 0xCF 68#define CIFS_IOCTL_MAGIC 0xCF
61#define CIFS_IOC_COPYCHUNK_FILE _IOW(CIFS_IOCTL_MAGIC, 3, int) 69#define CIFS_IOC_COPYCHUNK_FILE _IOW(CIFS_IOCTL_MAGIC, 3, int)
62#define CIFS_IOC_SET_INTEGRITY _IO(CIFS_IOCTL_MAGIC, 4) 70#define CIFS_IOC_SET_INTEGRITY _IO(CIFS_IOCTL_MAGIC, 4)
63#define CIFS_IOC_GET_MNT_INFO _IOR(CIFS_IOCTL_MAGIC, 5, struct smb_mnt_fs_info) 71#define CIFS_IOC_GET_MNT_INFO _IOR(CIFS_IOCTL_MAGIC, 5, struct smb_mnt_fs_info)
64#define CIFS_ENUMERATE_SNAPSHOTS _IOR(CIFS_IOCTL_MAGIC, 6, struct smb_snapshot_array) 72#define CIFS_ENUMERATE_SNAPSHOTS _IOR(CIFS_IOCTL_MAGIC, 6, struct smb_snapshot_array)
65#define CIFS_QUERY_INFO _IOWR(CIFS_IOCTL_MAGIC, 7, struct smb_query_info) 73#define CIFS_QUERY_INFO _IOWR(CIFS_IOCTL_MAGIC, 7, struct smb_query_info)
74#define CIFS_DUMP_KEY _IOWR(CIFS_IOCTL_MAGIC, 8, struct smb3_key_debug_info)
diff --git a/fs/cifs/ioctl.c b/fs/cifs/ioctl.c
index 76ddd98b6298..1a01e108d75e 100644
--- a/fs/cifs/ioctl.c
+++ b/fs/cifs/ioctl.c
@@ -164,6 +164,7 @@ static long smb_mnt_get_fsinfo(unsigned int xid, struct cifs_tcon *tcon,
164long cifs_ioctl(struct file *filep, unsigned int command, unsigned long arg) 164long cifs_ioctl(struct file *filep, unsigned int command, unsigned long arg)
165{ 165{
166 struct inode *inode = file_inode(filep); 166 struct inode *inode = file_inode(filep);
167 struct smb3_key_debug_info pkey_inf;
167 int rc = -ENOTTY; /* strange error - but the precedent */ 168 int rc = -ENOTTY; /* strange error - but the precedent */
168 unsigned int xid; 169 unsigned int xid;
169 struct cifsFileInfo *pSMBFile = filep->private_data; 170 struct cifsFileInfo *pSMBFile = filep->private_data;
@@ -270,6 +271,34 @@ long cifs_ioctl(struct file *filep, unsigned int command, unsigned long arg)
270 else 271 else
271 rc = -EOPNOTSUPP; 272 rc = -EOPNOTSUPP;
272 break; 273 break;
274 case CIFS_DUMP_KEY:
275 if (pSMBFile == NULL)
276 break;
277 if (!capable(CAP_SYS_ADMIN)) {
278 rc = -EACCES;
279 break;
280 }
281
282 tcon = tlink_tcon(pSMBFile->tlink);
283 if (!smb3_encryption_required(tcon)) {
284 rc = -EOPNOTSUPP;
285 break;
286 }
287 pkey_inf.cipher_type =
288 le16_to_cpu(tcon->ses->server->cipher_type);
289 pkey_inf.Suid = tcon->ses->Suid;
290 memcpy(pkey_inf.auth_key, tcon->ses->auth_key.response,
291 16 /* SMB2_NTLMV2_SESSKEY_SIZE */);
292 memcpy(pkey_inf.smb3decryptionkey,
293 tcon->ses->smb3decryptionkey, SMB3_SIGN_KEY_SIZE);
294 memcpy(pkey_inf.smb3encryptionkey,
295 tcon->ses->smb3encryptionkey, SMB3_SIGN_KEY_SIZE);
296 if (copy_to_user((void __user *)arg, &pkey_inf,
297 sizeof(struct smb3_key_debug_info)))
298 rc = -EFAULT;
299 else
300 rc = 0;
301 break;
273 default: 302 default:
274 cifs_dbg(FYI, "unsupported ioctl\n"); 303 cifs_dbg(FYI, "unsupported ioctl\n");
275 break; 304 break;