Пример #1
0
func (si *SSLInterceptor) GetHostKeyPair(cn string) (*tls.Certificate, error) {
	si.mu.Lock()
	defer si.mu.Unlock()
	keypair, found := si.keyPairCache[cn]
	if found {
		return keypair, nil
	}
	keypair, err := cert.GetOrGenerateKeyPair(path.Join(si.HostCertFolder, cn+"_cert.pem"), path.Join(si.HostCertFolder, cn+"_key.pem"), cn, []string{"Sniffy"}, false, si.caParentCert)
	if err == nil {
		si.keyPairCache[cn] = keypair
	}
	return keypair, err
}
Пример #2
0
func NewSSLInterceptor(handler InterceptHandler, caCertFile, caKeyFile string) (*SSLInterceptor, error) {
	si := SSLInterceptor{
		Handler:           handler,
		GenerateHostCerts: true,               // TODO: TEMP
		HostCertFolder:    "cert/interceptor", // TODO: TEMP
		keyPairCache:      map[string]*tls.Certificate{},
		mu:                &sync.Mutex{},
	}
	_, err := cert.GetOrGenerateKeyPair(caCertFile, caKeyFile, "interceptor.sniffy.local", []string{"Sniffy"}, true, nil)
	if err != nil {
		return nil, fmt.Errorf("Couldn't get or generate interceptor CA key pair: %s", err)
	}
	caKeyPair, err := tls.LoadX509KeyPair(caCertFile, caKeyFile)
	if err != nil {
		return nil, fmt.Errorf("Couldn't load interceptor CA key pair: %s", err)
	}
	si.caKeyPair = &caKeyPair
	si.caParentCert, err = x509.ParseCertificate(caKeyPair.Certificate[0])
	if err != nil {
		return nil, fmt.Errorf("Couldn't parse interceptor CA key pair: %s", err)
	}
	return &si, nil
}
Пример #3
0
func boot() {
	var err error
	initLogger(logBoot)

	config, err = loadConfig()
	if err != nil {
		setup()
		return
	}
	err = connectDB()
	if err != nil {
		log.Fatal("Couldn't open database:", err)
	}
	err = initDB()
	if err != nil {
		log.Fatalln("Failed to initialize database:", err, "\r\nIf the database settings have changed, please delete "+configFile+", then re-run\r\nSniffy to define new database connection settings. (Existing information in\r\nthe database, if it exists, will not be removed.)")
	}
	err = loadSettings()
	if err != nil {
		log.Fatalln("Failed to load settings from database:", err)
	}
	debug.Println("Settings loaded")

	os.Mkdir(config.certFolder, 0755)
	_, err = cert.GetOrGenerateKeyPair(config.webCertFile, config.webKeyFile, "web.sniffy.local", []string{"Sniffy"}, false, nil)
	if err != nil {
		log.Fatalln("Couldn't generate web interface RSA key pair:", err)
	}

	loadTemplates()

	pss, err := getProxyServers("")
	if err != nil {
		log.Println("Error starting proxy servers:", err)
	} else {
		for _, v := range pss {
			proxyServers = append(proxyServers, v)

			go func(ps *proxyServer) {
				var err error
				if ps.CertFile != "" && ps.KeyFile != "" {
					err = ps.ps.ListenAndServeTLS(v.CertFile, v.KeyFile)
				} else {
					err = ps.ps.ListenAndServe()
				}
				if err != nil {
					log.Println("Proxy server", ps.Name, "stopped:", err)
				}
			}(v)
		}
	}

	dss, err := getDummyServers("")
	if err != nil {
		log.Println("Error starting dummy servers:", err)
	} else {
		for _, v := range dss {
			dummyServers = append(dummyServers, v)
			if v.CertFile != "" && v.KeyFile != "" {
				_, err = cert.GetOrGenerateKeyPair(v.CertFile, v.KeyFile, "dummy.sniffy.local", []string{"Sniffy"}, false, nil)
			}
			go v.ds.Run()
		}
	}

	os.Mkdir(config.interceptorCertFolder, 0755)
	sslInterceptor, err = sniff.NewSSLInterceptor(proxyServers[0], config.interceptorCACertFile, config.interceptorCAKeyFile)
	if err != nil {
		log.Fatalln("Couldn't create SSL interceptor:", err)
	}
	if config.preloadInterceptorCerts {
		rows, err := db.Query("SELECT cn FROM certs")
		if err == nil {
			for rows.Next() {
				var cn string
				rows.Scan(&cn)
				if cn != "web.sniffy.local" && cn != "interceptor.sniffy.local" {
					go func() {
						_, err := sslInterceptor.GetHostKeyPair(cn)
						if err != nil {
							log.Println("Couldn't preload RSA key pair for", cn+":", err)
						}
					}()
				}
			}
		}
	}

	// BEGIN TESTING!
	test := false
	if test {
		http.HandleFunc("/", testfunc)
		testkp, _ := sslInterceptor.GetHostKeyPair("sheeped.com")
		// testkp.Certificate = append(testkp.Certificate, si.caKeyPair.Certificate...)
		config := &tls.Config{
			Rand:       rand.Reader,
			NextProtos: []string{"http/1.1"},
			Certificates: []tls.Certificate{
				*testkp,
				// si.caKeyPair,
			},
		}
		log.Println("LAUNCHING TEST SSL SERVER :20010")
		l, _ := tls.Listen("tcp", ":20010", config)
		srv := http.Server{}
		srv.Serve(l)
		// END TESTING!
	}

	wsHost, err := getSetting("WebServerHost")
	if err != nil {
		wsHost = "127.0.0.1"
	}
	wsPort, err := getIntSetting("WebServerPort")
	if err != nil || wsPort < 1 || wsPort > 65535 {
		wsPort = defaultWebServerPort
	}
	// log.Println("Logging to", logFile)
	initLogger(logToFile)
	fmt.Println("")
	fmt.Printf("Sniffy interface running on https://%s:%d\n", wsHost, wsPort)
	ws := NewWebServer(wsHost, uint16(wsPort))
	go ws.Run()
	fmt.Println("")
	fmt.Print("For recovery, enter administrator password: ")
	prompt(stateLogin)
}