forked from toolshed/abra
		
	
		
			
				
	
	
		
			55 lines
		
	
	
		
			1.6 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			55 lines
		
	
	
		
			1.6 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| //go:build !windows
 | |
| 
 | |
| package sockets
 | |
| 
 | |
| import (
 | |
| 	"net"
 | |
| 	"os"
 | |
| 	"syscall"
 | |
| )
 | |
| 
 | |
| // WithChown modifies the socket file's uid and gid
 | |
| func WithChown(uid, gid int) SockOption {
 | |
| 	return func(path string) error {
 | |
| 		if err := os.Chown(path, uid, gid); err != nil {
 | |
| 			return err
 | |
| 		}
 | |
| 		return nil
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // WithChmod modifies socket file's access mode.
 | |
| func WithChmod(mask os.FileMode) SockOption {
 | |
| 	return func(path string) error {
 | |
| 		if err := os.Chmod(path, mask); err != nil {
 | |
| 			return err
 | |
| 		}
 | |
| 		return nil
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // NewUnixSocket creates a unix socket with the specified path and group.
 | |
| func NewUnixSocket(path string, gid int) (net.Listener, error) {
 | |
| 	return NewUnixSocketWithOpts(path, WithChown(0, gid), WithChmod(0o660))
 | |
| }
 | |
| 
 | |
| func listenUnix(path string) (net.Listener, error) {
 | |
| 	// net.Listen does not allow for permissions to be set. As a result, when
 | |
| 	// specifying custom permissions ("WithChmod()"), there is a short time
 | |
| 	// between creating the socket and applying the permissions, during which
 | |
| 	// the socket permissions are Less restrictive than desired.
 | |
| 	//
 | |
| 	// To work around this limitation of net.Listen(), we temporarily set the
 | |
| 	// umask to 0777, which forces the socket to be created with 000 permissions
 | |
| 	// (i.e.: no access for anyone). After that, WithChmod() must be used to set
 | |
| 	// the desired permissions.
 | |
| 	//
 | |
| 	// We don't use "defer" here, to reset the umask to its original value as soon
 | |
| 	// as possible. Ideally we'd be able to detect if WithChmod() was passed as
 | |
| 	// an option, and skip changing umask if default permissions are used.
 | |
| 	origUmask := syscall.Umask(0o777)
 | |
| 	l, err := net.Listen("unix", path)
 | |
| 	syscall.Umask(origUmask)
 | |
| 	return l, err
 | |
| }
 |