This bug is for tracking work on the userspace component for handling SPNEGO upcalls from CIFS. The kernel piece is being tracked in bug #334931. My guess is that we'll want to integrate this new program with samba (similar to how mount.cifs is integrated). Much of the code to do SPNEGO handling seems to already be in libsmbclient, so I'm hoping this program will be fairly small. My thinking is that the flow should be something like this: Negotiate Protocol Request (with extended security bit set) NegProt Response (with SPNEGO blob) - client sends SPNEGO blob plus some other info to userspace via request_key - client gets back new SPNEGO blob (plus maybe some state info) Session Setup Request (using new SPNEGO blob received from userspace) Session Setup Response (with new SPNEGO blob) - do we need to send this to userspace? After that, I presume we should have a signing key and we won't need to involve userspace unless we need to reconnect. Obviously this is the simple case, we'll also need to determine how to handle it if the negotiation needs to go back and forth a few times (shouldn't be too tough, but that's why we'll likely need to send state info back and forth). The mechanism I'm planning to use is simple request_key calls. The encoding I'm using for callout_data should allow for us to send large enough blobs to userspace. If it turns out not to be big enough then we can look at other options for it. I'd prefer not to do that unless we have to, and only after we have something working for smaller blobs.
Created attachment 229111 [details] sample request-key callout program This program is what I've been using to do simple testing with the current kernel work. It just attaches whatever blob was sent from the kernel to the key. It should serve as an skeleton example of what sort of program we'll need. The current kernel patch uniquely identifies the key with a description string of: uid:server_ipaddr The callout_data consists of the SPNEGO blob that came in from the Negotiate Protocol reply. So currently you have the linux_uid of the session and the server's IP address. I can easily make it so that we send more in the callout_data if needed, but we'll need to determine a format. We can also change the key description if need be (which we may want to do if there is more than one upcall per mount). I estimate that we should try to limit the amount of data sent from the kernel to ~100k. Anything more than that and we'll start bumping up against ARG_MAX (we're limited to 128k for ARG_MAX total, and that includes all program arguments + environment vars). The last thing the program does is a keyctl_instantiate, with the data that we want to send back to the kernel. For now, that's just a struct with fixed length fields that's followed by the SPNEGO blob, but we can add other fields to send back to the kernel if need be. The data restriction there is less stringent -- we have an absolute max of 1M, but we still want to keep it as small as possible. You'll probably want to have a look at the keyutils* packages since they have the docs for how to use the API. For now, my big questions are: 1) what other info do we need to send from the kernel to this program in order to get the SPNEGO blob for session setup? 2) Once the session setup reply comes back, what do we need to send to userspace? 3) how and when do we generate the session signing key?
Simo, I've been chatting with David H today and he's got some patches that allow us to send the callout data as a blob and a length rather than a string. I'm going to respin the kernel patches to take advantage of that. That will mean a lot less copying of data within the kernel and should make it so that we don't need to encode anything. Stay tuned...
Created attachment 232751 [details] sample request-key callout program This program is a request-key callout program intended for use with the latest patch in bug 315311. That patch takes advantage of some patches propsed by David Howells so that we can call request_key_with_auxdata() and pass in a binary blob as callout_info. This program also uses a different scheme for getting the callout_info. It no longer has to be passed in on the command line, so this removes the ARG_MAX limitation that the other program had. With this scheme we should be able to deal with blobs up to 1M in size, and will not need to encode/decode them before sending them off to userspace. Again, this program just attaches the callout_info as-is to the key payload, but it should serve as an example of what sort of program we'd need. The request-key.conf line for it looks like this: #OP TYPE DESCRIPTION CALLOUT INFO PROGRAM ARG1 ARG2 ARG3 ... #====== ======= =============== =============== =============================== create cifs.spnego * * /usr/local/bin/cifskey %k
Jeff, I've just sent working krb5 support patch to the linux-cifs-client mail list. Waiting for comments...
Some newer code has been posted to the linux-cifs-client mailing list. Igor posted his userspace program, and I've posted a patch to that that allows it to work with my kernel patch. At this point, this is the main blocker for getting this implemented. Igor's program basically works: 1) I think it might make sense to integrate it with the samba sources. For Fedora/RHEL that would make it easy to put it in the same package as the mount.cifs program. smbclient needs to roll up SPNEGO blobs too, so it might make sense to share some of that code with the request-key callout. 2) The program needs to deal with multiple UID's. For now I suggest we have the program get the description string via keyctl_describe and pull the key uid out of that. This will be important for multisession mounts. 3) some work needs to go into finalizing how we actually get the hostname portion of the cifs/servername principal. The kernel patch currently passes the hostname portion of the UNC to userspace in the description. Between that and the IP address, the callout will need to determine the hostname string to use. This will need to be clearly documented to save us pain later. I'm sure there's plenty of other stuff that I haven't considered as well ;-)
Update... Relevant kernel code has been committed upstream and we've got it enabled in rawhide. Latest upstream samba has a cifs.spnego program. We're hoping to have all of this in F9. The main part that's missing at this point is to make sure that Fedora's samba-client package has the cifs.spnego program.
This support is now upstream and in Fedora 9+. Closing bug.