pkg / sftp

SFTP support for the go.crypto/ssh package
BSD 2-Clause "Simplified" License
1.5k stars 379 forks source link

Add Request Packet Hook #536

Closed dmlb2000 closed 1 year ago

dmlb2000 commented 1 year ago

This adds a hook just prior to handling the request packet. The request hook takes a reference to the request and returns an error and response packet. If the error is set the response packet is processed immediately and returned to the client.

Signed-off-by: David ML Brown Jr dmlb2000@gmail.com

puellanivis commented 1 year ago

The code as provided does not actually return a response packet, and thus could only ever override a response by returning an error. The hook also only hooks if the package meets the hasPath interface, which means its use is likely going to be extremely difficult to use properly, and this defies the documentation as listed.

I’m still not sure why we would want to bring in this code, when if someone wants to implement such a hook, they’re better off using the RequestServer implementation instead.

dmlb2000 commented 1 year ago

@puellanivis Thanks for the response, I'm not familiar with Go so this is my first attempt at trying to build a service I'm working on.

I'd like an sftp server implementation that maps user permissions of incoming requests based on the path they provide, given a permission model coming from a web service (hence the path restriction on the request). I access resources from the web service that gives me users and SSH public keys that are allowed to read/write to that resource. The web path to the resource would directly map to file system path in sftp.

Looking over the RequestServer example seems a little difficult to know how to make this permissions check based on the requests coming in. I'm still looking at it but any help would be appreciated. Seems like 90% of the file is upstream ssh pkg code not sftp code...

Using a standard openssh isn't helpful as I'd need to implement a custom glibc NSS module to get the unix permissions to come from the webservice. Another option would be to implement service specific LDAP that would be accessed by OpenSSH/Glibc. This would require a couple of synchronization scripts to map the web service permissions into LDAP and secondly copy ssh public keys for users. The trick to this requirement is binding path and users public ssh keys to the permissions they have.

Accessing webservices directly at request time would be better for the users and eaiser in Go (I think).

drakkan commented 1 year ago

To use the RequestServer you have to implements the interfaces here. The example use the InMemHandler defined here, you have to write your own handler

dmlb2000 commented 1 year ago

@drakkan thanks. I think I'm getting what using the RequestServer requires. I believe my path forward is to copy request-example.go to my own module and start renaming things. Then once working start implementing one layer at a time all the various functions that need to call the web API. I think I have a path forward, thanks this can be closed.

It's a lot of code to review and implement in request-example.go. I was hoping for something a little smaller and focused to get into the code.

drakkan commented 1 year ago

@drakkan thanks. I think I'm getting what using the RequestServer requires. I believe my path forward is to copy request-example.go to my own module and start renaming things. Then once working start implementing one layer at a time all the various functions that need to call the web API. I think I have a path forward, thanks this can be closed.

It's a lot of code to review and implement in request-example.go. I was hoping for something a little smaller and focused to get into the code.

If you plan to use the local filesystem, take a look at #487 (it is a WIP)

puellanivis commented 1 year ago

Closing this as outdated, and we recommend going through request-server anyways.