func main() {
	flag.Parse()
	log.SetFlags(0)
	fs := webdav.NewMemFS()
	ls := webdav.NewMemLS()
	http.Handle("/", &webdav.Handler{
		FileSystem: fs,
		LockSystem: ls,
		PropSystem: webdav.NewMemPS(fs, ls),
		Logger: func(r *http.Request, err error) {
			litmus := r.Header.Get("X-Litmus")
			if len(litmus) > 19 {
				litmus = litmus[:16] + "..."
			}

			switch r.Method {
			case "COPY", "MOVE":
				dst := ""
				if u, err := url.Parse(r.Header.Get("Destination")); err == nil {
					dst = u.Path
				}
				o := r.Header.Get("Overwrite")
				log.Printf("%-20s%-10s%-30s%-30so=%-2s%v", litmus, r.Method, r.URL.Path, dst, o, err)
			default:
				log.Printf("%-20s%-10s%-30s%v", litmus, r.Method, r.URL.Path, err)
			}
		},
	})

	addr := fmt.Sprintf(":%d", *port)
	log.Printf("Serving %v", addr)
	log.Fatal(http.ListenAndServe(addr, nil))
}
Example #2
0
func (wd *WebDav) Init() error {
	if !(wd.Config != nil && wd.Config.WebDav.Enabled != false) {
		return fmt.Errorf("WebDav not configured")
	}

	glog.Info("[WebDav] Starting...")

	wd.mount(wd.Config.Web.Path)

	h := &webdav.Handler{
		Prefix:     wd.Config.WebDav.Mount,
		FileSystem: wd.fs,
		LockSystem: webdav.NewMemLS(),
		Logger: func(r *http.Request, err error) {
			glog.Infof("[dav] %-10s%-30s%v", r.Method, r.URL.Path, err)
		},
	}

	wd.HandlerFunc = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		u, p, ok := r.BasicAuth()
		if !(ok == true && u == wd.Config.WebDav.Username && p == wd.Config.WebDav.Password) {
			w.Header().Set("WWW-Authenticate", `Basic realm="davfs"`)
			http.Error(w, "Unauthorized", http.StatusUnauthorized)
			return
		}
		h.ServeHTTP(w, r)
	})

	return nil
}
Example #3
0
func main() {
	h := &webdav.Handler{
		// 在内存中的文件系统,重启应用后就消失
		// FileSystem: webdav.NewMemFS(),
		// 挂载本地文件系统
		FileSystem: webdav.Dir("."),
		LockSystem: webdav.NewMemLS(),
		// 设置log
		Logger: func(r *http.Request, err error) {
			log.Printf("[dav] %-10s%-30s%v", r.Method, r.URL.Path, err)
		},
	}
	// 挂载webdav服务:net use P: http://localhost:5555
	// 取消挂载:net use P: /del /y
	http.HandleFunc("/", h.ServeHTTP)
	http.ListenAndServe(":5555", nil)
}
Example #4
0
func Fuzz(data []byte) int {
	score := 0
	buf := bufio.NewReader(bytes.NewReader(data))
	for {
		r, err := http.ReadRequest(buf)
		if err != nil {
			break
		}
		h := &webdav.Handler{
			FileSystem: webdav.NewMemFS(),
			LockSystem: webdav.NewMemLS(),
		}
		w := &NilWriter{hdr: make(http.Header)}
		h.ServeHTTP(w, r)
		score = 1
	}
	return score
}
Example #5
0
func main() {
	authenticator := auth.NewBasicAuthenticator("webdav", GetSecret)

	h := new(webdav.Handler)
	root, err := os.Getwd()
	if err != nil {
		log.Fatal(err)
	}
	h.FileSystem = webdav.Dir(root)
	h.LockSystem = webdav.NewMemLS()
	h.Prefix = "/dav/"
	h.Logger = func(r *http.Request, e error) {
		log.Printf("%s(%s): %s", r.Method, r.RemoteAddr, r.RequestURI)
		if err != nil {
			log.Println("[ERROR] ", err)
		}
	}

	//then use the Handler.ServeHTTP Method as the http.HandleFunc
	http.HandleFunc("/dav/", func(w http.ResponseWriter, r *http.Request) {
		switch r.Method {
		default:
			if username := authenticator.CheckAuth(r); username == "" {
				authenticator.RequireAuth(w, r)
				return
			} else {
			}
		case http.MethodGet, http.MethodOptions, "PROPFIND":
			// No need auth
		}
		h.ServeHTTP(w, r)
		log.Print("...done")
	})

	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("content-type", "text/html; charset=UTF-8")
		w.Write([]byte(fmt.Sprintf(`Time: %s`, time.Now().String())))
	})

	log.Println("Listen at :5555")
	http.ListenAndServe(":5555", nil)
}
Example #6
0
// NewServer is used to create a new Server instance
func NewServer(config *ServerConfig) *Server {
	s := &Server{
		Config:     config,
		cookie:     securecookie.New(securecookie.GenerateRandomKey(64), securecookie.GenerateRandomKey(32)),
		cookieSalt: securecookie.GenerateRandomKey(32),
		webdav: &webdav.Handler{
			FileSystem: webdav.Dir(config.DataRoot),
			LockSystem: webdav.NewMemLS(),
		},
	}
	AddRDFExtension(s.Config.ACLSuffix)
	AddRDFExtension(s.Config.MetaSuffix)
	if config.Debug {
		s.debug = log.New(os.Stderr, debugPrefix, debugFlags)
	} else {
		s.debug = log.New(ioutil.Discard, "", 0)
	}
	s.debug.Println("---- starting server ----")
	s.debug.Printf("config: %#v\n", s.Config)
	return s
}
Example #7
0
func (wd *WebDav) Init() error {
	if !(wd.Config != nil && wd.Config.WebDav.Enabled != false) {
		return fmt.Errorf("WebDav not configured")
	}

	log.WithFields(log.Fields{
		"service": "webdav",
	}).Info("Init")

	wd.mount(wd.Config.Web.Path)

	h := &webdav.Handler{
		Prefix:     wd.Config.WebDav.Mount,
		FileSystem: wd.fs,
		LockSystem: webdav.NewMemLS(),
		Logger: func(r *http.Request, err error) {
			log.WithFields(log.Fields{
				"service": "webdav",
				"method":  r.Method,
				"path":    r.URL.Path,
				"error":   err,
			}).Info("Request")
		},
	}

	wd.HandlerFunc = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		u, p, ok := r.BasicAuth()
		if !(ok == true && u == wd.Config.WebDav.Username && p == wd.Config.WebDav.Password) {
			w.Header().Set("WWW-Authenticate", `Basic realm="davfs"`)
			http.Error(w, "Unauthorized", http.StatusUnauthorized)
			return
		}
		h.ServeHTTP(w, r)
	})

	return nil
}
func main() {
	uri := flag.String("docker", "unix:///var/run/docker.sock", "Daemon socket to connect to")
	image := flag.String("image", "", "Docker image to inspect")
	path := flag.String("path", "", "Destination path for the image files")
	serve := flag.String("serve", "", "Host and port where to serve the image with webdav")

	flag.Parse()

	if *uri == "" {
		log.Fatalf("Docker socket connection must be specified")
	}
	if *image == "" {
		log.Fatalf("Docker image to inspect must be specified")
	}

	client, err := docker.NewClient(*uri)
	if err != nil {
		log.Fatalf("Unable to connect to docker daemon: %v\n", err)
	}

	if _, err := client.InspectImage(*image); err != nil {
		log.Printf("Pulling image %s", *image)
		imagePullOption := docker.PullImageOptions{Repository: *image}
		imagePullAuth := docker.AuthConfiguration{} // TODO: support authentication
		if err := client.PullImage(imagePullOption, imagePullAuth); err != nil {
			log.Fatalf("Unable to pull docker image: %v\n", err)
		}
	} else {
		log.Printf("Image %s is available, skipping image pull", *image)
	}

	// For security purpose we don't define any entrypoint and command
	container, err := client.CreateContainer(docker.CreateContainerOptions{
		Name: generateRandomName(),
		Config: &docker.Config{
			Image:      *image,
			Entrypoint: []string{""},
			Cmd:        []string{""},
		},
	})
	if err != nil {
		log.Fatalf("Unable to create docker container: %v\n", err)
	}

	containerMetadata, err := client.InspectContainer(container.ID)
	if err != nil {
		log.Fatalf("Unable to get docker container information: %v\n", err)
	}

	imageMetadata, err := client.InspectImage(containerMetadata.Image)
	if err != nil {
		log.Fatalf("Unable to get docker image information: %v\n", err)
	}

	if path != nil && *path != "" {
		err = os.Mkdir(*path, 0755)
		if err != nil {
			if !os.IsExist(err) {
				log.Fatalf("Unable to create destination path: %v\n", err)
			}
		}
	} else {
		// forcing to use /var/tmp because often it's not an in-memory tmpfs
		*path, err = ioutil.TempDir("/var/tmp", "image-inspector-")
		if err != nil {
			log.Fatalf("Unable to create temporary path: %v\n", err)
		}
	}

	reader, writer := io.Pipe()
	go handleTarStream(reader, *path)

	log.Printf("Extracting image %s to %s", *image, *path)
	err = client.CopyFromContainer(docker.CopyFromContainerOptions{
		Container:    container.ID,
		OutputStream: writer,
		Resource:     "/",
	})
	if err != nil {
		log.Fatalf("Unable to extract container: %v\n", err)
	}

	_ = client.RemoveContainer(docker.RemoveContainerOptions{
		ID: container.ID,
	})

	supportedVersions := APIVersions{Versions: []string{VERSION_TAG}}

	if serve != nil && *serve != "" {
		log.Printf("Serving image content %s on webdav://%s%s", *path, *serve, CONTENT_URL_PREFIX)

		http.HandleFunc(HEALTHZ_URL_PATH, func(w http.ResponseWriter, r *http.Request) {
			w.Write([]byte("ok\n"))
		})

		http.HandleFunc(API_URL_PREFIX, func(w http.ResponseWriter, r *http.Request) {
			body, err := json.MarshalIndent(supportedVersions, "", "  ")
			if err != nil {
				http.Error(w, err.Error(), http.StatusInternalServerError)
				return
			}
			w.Write(body)
		})

		http.HandleFunc(METADATA_URL_PATH, func(w http.ResponseWriter, r *http.Request) {
			body, err := json.MarshalIndent(imageMetadata, "", "  ")
			if err != nil {
				http.Error(w, err.Error(), http.StatusInternalServerError)
				return
			}
			w.Write(body)
		})

		http.Handle(CONTENT_URL_PREFIX, &webdav.Handler{
			Prefix:     CONTENT_URL_PREFIX,
			FileSystem: webdav.Dir(*path),
			LockSystem: webdav.NewMemLS(),
		})

		log.Fatal(http.ListenAndServe(*serve, nil))
	}
}
Example #9
0
func main() {
	flag.Parse()
	log.SetFlags(0)
	h := &webdav.Handler{
		FileSystem: webdav.NewMemFS(),
		LockSystem: webdav.NewMemLS(),
		Logger: func(r *http.Request, err error) {
			litmus := r.Header.Get("X-Litmus")
			if len(litmus) > 19 {
				litmus = litmus[:16] + "..."
			}

			switch r.Method {
			case "COPY", "MOVE":
				dst := ""
				if u, err := url.Parse(r.Header.Get("Destination")); err == nil {
					dst = u.Path
				}
				o := r.Header.Get("Overwrite")
				log.Printf("%-20s%-10s%-30s%-30so=%-2s%v", litmus, r.Method, r.URL.Path, dst, o, err)
			default:
				log.Printf("%-20s%-10s%-30s%v", litmus, r.Method, r.URL.Path, err)
			}
		},
	}

	// The next line would normally be:
	//	http.Handle("/", h)
	// but we wrap that HTTP handler h to cater for a special case.
	//
	// The propfind_invalid2 litmus test case expects an empty namespace prefix
	// declaration to be an error. The FAQ in the webdav litmus test says:
	//
	// "What does the "propfind_invalid2" test check for?...
	//
	// If a request was sent with an XML body which included an empty namespace
	// prefix declaration (xmlns:ns1=""), then the server must reject that with
	// a "400 Bad Request" response, as it is invalid according to the XML
	// Namespace specification."
	//
	// On the other hand, the Go standard library's encoding/xml package
	// accepts an empty xmlns namespace, as per the discussion at
	// https://github.com/golang/go/issues/8068
	//
	// Empty namespaces seem disallowed in the second (2006) edition of the XML
	// standard, but allowed in a later edition. The grammar differs between
	// http://www.w3.org/TR/2006/REC-xml-names-20060816/#ns-decl and
	// http://www.w3.org/TR/REC-xml-names/#dt-prefix
	//
	// Thus, we assume that the propfind_invalid2 test is obsolete, and
	// hard-code the 400 Bad Request response that the test expects.
	http.Handle("/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		if r.Header.Get("X-Litmus") == "props: 3 (propfind_invalid2)" {
			http.Error(w, "400 Bad Request", http.StatusBadRequest)
			return
		}
		h.ServeHTTP(w, r)
	}))

	addr := fmt.Sprintf(":%d", *port)
	log.Printf("Serving %v", addr)
	log.Fatal(http.ListenAndServe(addr, nil))
}
// Inspect inspects and serves the image based on the ImageInspectorOptions.
func (i *defaultImageInspector) Inspect() error {
	client, err := docker.NewClient(i.opts.URI)
	if err != nil {
		return fmt.Errorf("Unable to connect to docker daemon: %v\n", err)
	}

	if _, err := client.InspectImage(i.opts.Image); err != nil {
		log.Printf("Pulling image %s", i.opts.Image)
		imagePullOption := docker.PullImageOptions{Repository: i.opts.Image}

		var imagePullAuths *docker.AuthConfigurations
		var authCfgErr error
		if imagePullAuths, authCfgErr = i.getAuthConfigs(); authCfgErr != nil {
			return authCfgErr
		}

		// Try all the possible auth's from the config file
		var authErr error
		for _, auth := range imagePullAuths.Configs {
			if authErr = client.PullImage(imagePullOption, auth); authErr == nil {
				break
			}
		}
		if authErr != nil {
			return fmt.Errorf("Unable to pull docker image: %v\n", authErr)
		}
	} else {
		log.Printf("Image %s is available, skipping image pull", i.opts.Image)
	}

	randomName, err := generateRandomName()
	if err != nil {
		return err
	}

	imageMetadata, err := i.createAndExtractImage(client, randomName)
	if err != nil {
		return err
	}
	i.meta.Image = *imageMetadata

	supportedVersions := APIVersions{Versions: []string{VERSION_TAG}}

	var scanReport []byte
	if i.opts.ScanType == "openscap" {
		if i.opts.ScanResultsDir, err = createOutputDir(i.opts.ScanResultsDir, "image-inspector-scan-results-"); err != nil {
			return err
		}
		scanner := openscap.NewDefaultScanner(OSCAP_CVE_DIR, i.opts.ScanResultsDir)
		scanReport, err = i.scanImage(scanner)
		if err != nil {
			i.meta.OpenSCAP.SetError(err)
			log.Printf("Unable to scan image: %v", err)
		} else {
			i.meta.OpenSCAP.Status = StatusSuccess
		}
	}

	if len(i.opts.Serve) > 0 {
		servePath := i.opts.DstPath
		if i.opts.Chroot {
			if err := syscall.Chroot(i.opts.DstPath); err != nil {
				return fmt.Errorf("Unable to chroot into %s: %v\n", i.opts.DstPath, err)
			}
			servePath = CHROOT_SERVE_PATH
		} else {
			log.Printf("!!!WARNING!!! It is insecure to serve the image content without changing")
			log.Printf("root (--chroot). Absolute-path symlinks in the image can lead to disclose")
			log.Printf("information of the hosting system.")
		}

		log.Printf("Serving image content %s on webdav://%s%s", i.opts.DstPath, i.opts.Serve, CONTENT_URL_PREFIX)

		http.HandleFunc(HEALTHZ_URL_PATH, func(w http.ResponseWriter, r *http.Request) {
			w.Write([]byte("ok\n"))
		})

		http.HandleFunc(API_URL_PREFIX, func(w http.ResponseWriter, r *http.Request) {
			body, err := json.MarshalIndent(supportedVersions, "", "  ")
			if err != nil {
				http.Error(w, err.Error(), http.StatusInternalServerError)
				return
			}
			w.Write(body)
		})

		http.HandleFunc(METADATA_URL_PATH, func(w http.ResponseWriter, r *http.Request) {
			body, err := json.MarshalIndent(i.meta, "", "  ")
			if err != nil {
				http.Error(w, err.Error(), http.StatusInternalServerError)
				return
			}
			w.Write(body)
		})

		http.HandleFunc(OPENSCAP_URL_PATH, func(w http.ResponseWriter, r *http.Request) {
			if i.opts.ScanType == "openscap" && i.meta.OpenSCAP.Status == StatusSuccess {
				w.Write(scanReport)
			} else {
				if i.meta.OpenSCAP.Status == StatusError {
					http.Error(w, fmt.Sprintf("OpenSCAP Error: %s", i.meta.OpenSCAP.ErrorMessage),
						http.StatusInternalServerError)
				} else {
					http.Error(w, "OpenSCAP option was not chosen", http.StatusNotFound)
				}
			}
		})

		http.Handle(CONTENT_URL_PREFIX, &webdav.Handler{
			Prefix:     CONTENT_URL_PREFIX,
			FileSystem: webdav.Dir(servePath),
			LockSystem: webdav.NewMemLS(),
		})

		return http.ListenAndServe(i.opts.Serve, nil)
	}
	return nil
}