golisten

package module
v0.0.0-...-f2c7a6b Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 21, 2015 License: MIT Imports: 9 Imported by: 0

README

golisten

Privilege de-escalation listen in Go.

Overview

golisten expects to be root. If it is not, it will error. As root, perform a net.Listen(). Once this is done, we can perform the privilege de-escalation. Because of the Go thread model, it is not safe to do so with a "simple" syscall.Setuid(). In order to ensure that the whole process (all threads) are de-escalated, golsiten will fork itself as the requested user while inheriting the privileged listened file descriptor.

golisten.ListenAndServe works just like http.ListenAndServe but expect the target user to be run as.

Example

ListenAndServe
package main

import (
	"fmt"
	"log"
	"net/http"
	"os/user"

	"github.com/creack/golisten"
)

func handler(w http.ResponseWriter, req *http.Request) {
	u, err := user.Current()
	if err != nil {
		log.Printf("Error getting user: %s", err)
		return
	}
	fmt.Fprintf(w, "%s\n", u.Uid)
}

func main() {
	http.HandleFunc("/", handler)
	log.Fatal(golisten.ListenAndServe("guillaume", ":80", nil))
}
Listen
package main

import (
	"fmt"
	"log"
	"net/http"
	"os/user"

	"github.com/creack/golisten"
)

func handler(w http.ResponseWriter, req *http.Request) {
	u, err := user.Current()
	if err != nil {
		log.Printf("Error getting user: %s", err)
		return
	}
	fmt.Fprintf(w, "%s\n", u.Uid)
}

func ExampleListenAndServe() {
	ln, err := golisten.Listen("guillaume", "tcp", ":80")
	if err != nil {
		log.Fatal(err)
	}
	http.HandleFunc("/", handler)
	log.Fatal(http.Serve(ln, nil))
}

TODO

  • ListenAndServeTLS
  • Benchmarks
  • Tests
  • Use environment instead of command-line flag for fd passing

Documentation

Overview

Package golisten allows a user to user http.ListenAndServe with any port as root and effectively accept the incomming connection as an other un-privileged user.

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func Listen

func Listen(targetUser, network, addr string) (net.Listener, error)

Listen listens to the requested port and de-escalate the privilege to `targetUser`.

func ListenAndServe

func ListenAndServe(targetUser, addr string, handler http.Handler) error

ListenAndServe wraps `http.ListenAndServe`. Listen as root and accept as `targetUser`.

Example
package main

import (
	"fmt"
	"log"
	"net/http"
	"os/user"
)

func handler(w http.ResponseWriter, req *http.Request) {
	u, err := user.Current()
	if err != nil {
		log.Printf("Error getting user: %s", err)
		return
	}
	fmt.Fprintf(w, "%s\n", u.Uid)
}

func main() {
	ln, err := Listen("guillaume", "tcp", ":80")
	if err != nil {
		log.Fatal(err)
	}
	http.HandleFunc("/", handler)
	log.Fatal(http.Serve(ln, nil))
}
Output:

Example
package main

import (
	"fmt"
	"log"
	"net/http"
	"os/user"
)

func handler(w http.ResponseWriter, req *http.Request) {
	u, err := user.Current()
	if err != nil {
		log.Printf("Error getting user: %s", err)
		return
	}
	fmt.Fprintf(w, "%s\n", u.Uid)
}

func main() {
	http.HandleFunc("/", handler)
	log.Fatal(ListenAndServe("guillaume", ":80", nil))
}
Output:

Types

This section is empty.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL