vault-wrap: Добавлена расшифровка, генератора паролей. INF-1541
This commit is contained in:
		
							
								
								
									
										5
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,5 @@ | ||||
| *.key | ||||
| *.cert | ||||
| *.pem | ||||
| *.log | ||||
|  | ||||
							
								
								
									
										19
									
								
								Dockerfile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								Dockerfile
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,19 @@ | ||||
| FROM golang:alpine AS build | ||||
| RUN apk --no-cache add gcc g++ make git | ||||
|  | ||||
| WORKDIR /go/src/app | ||||
|  | ||||
| COPY . . | ||||
| RUN go get ./... | ||||
| RUN GOOS=linux go build -ldflags="-s -w" -o ./bin/vault-wrap ./vault.go | ||||
| FROM alpine:3.20 | ||||
| RUN apk add tzdata | ||||
| #RUN apk --no-cache add ca-certificates | ||||
| WORKDIR /usr/bin | ||||
| COPY --from=build /go/src/app/bin /go/bin | ||||
|  | ||||
| # COPY cronjobs /etc/crontabs/root | ||||
|  | ||||
| ./bin/vault-wrap -action-address "${ADDRESS}" -vault-url "${VAULT_ADDRESS}" -tls-cert "${TLS_CERT}" -tls-key "${TLS_KEY}" | ||||
| # start crond with log level 8 in foreground, output to stderr | ||||
| # CMD ["crond", "-f", "-d", "8"] | ||||
							
								
								
									
										20
									
								
								go.mod
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								go.mod
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,20 @@ | ||||
| module main | ||||
|  | ||||
| go 1.21 | ||||
|  | ||||
| toolchain go1.22.0 | ||||
|  | ||||
| require github.com/hashicorp/vault-client-go v0.4.3 | ||||
|  | ||||
| require ( | ||||
| 	github.com/gorilla/mux v1.8.1 // indirect | ||||
| 	github.com/hashicorp/go-cleanhttp v0.5.2 // indirect | ||||
| 	github.com/hashicorp/go-retryablehttp v0.7.7 // indirect | ||||
| 	github.com/hashicorp/go-rootcerts v1.0.2 // indirect | ||||
| 	github.com/hashicorp/go-secure-stdlib/strutil v0.1.2 // indirect | ||||
| 	github.com/mitchellh/go-homedir v1.1.0 // indirect | ||||
| 	github.com/ryanuber/go-glob v1.0.0 // indirect | ||||
| 	github.com/sethvargo/go-password v0.3.1 // indirect | ||||
| 	golang.org/x/sys v0.22.0 // indirect | ||||
| 	golang.org/x/time v0.5.0 // indirect | ||||
| ) | ||||
							
								
								
									
										39
									
								
								go.sum
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								go.sum
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,39 @@ | ||||
| github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= | ||||
| github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= | ||||
| github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY= | ||||
| github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ= | ||||
| github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= | ||||
| github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= | ||||
| github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= | ||||
| github.com/hashicorp/go-hclog v0.9.2 h1:CG6TE5H9/JXsFWJCfoIVpKFIkFe6ysEuHirp4DxCsHI= | ||||
| github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= | ||||
| github.com/hashicorp/go-hclog v1.6.3 h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB11/k= | ||||
| github.com/hashicorp/go-retryablehttp v0.7.1 h1:sUiuQAnLlbvmExtFQs72iFW/HXeUn8Z1aJLQ4LJJbTQ= | ||||
| github.com/hashicorp/go-retryablehttp v0.7.1/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY= | ||||
| github.com/hashicorp/go-retryablehttp v0.7.7 h1:C8hUCYzor8PIfXHa4UrZkU4VvK8o9ISHxT2Q8+VepXU= | ||||
| github.com/hashicorp/go-retryablehttp v0.7.7/go.mod h1:pkQpWZeYWskR+D1tR2O5OcBFOxfA7DoAO6xtkuQnHTk= | ||||
| github.com/hashicorp/go-rootcerts v1.0.2 h1:jzhAVGtqPKbwpyCPELlgNWhE1znq+qwJtW5Oi2viEzc= | ||||
| github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8= | ||||
| github.com/hashicorp/go-secure-stdlib/strutil v0.1.2 h1:kes8mmyCpxJsI7FTwtzRqEy9CdjCtrXrXGuOpxEA7Ts= | ||||
| github.com/hashicorp/go-secure-stdlib/strutil v0.1.2/go.mod h1:Gou2R9+il93BqX25LAKCLuM+y9U2T4hlwvT1yprcna4= | ||||
| github.com/hashicorp/vault-client-go v0.4.3 h1:zG7STGVgn/VK6rnZc0k8PGbfv2x/sJExRKHSUg3ljWc= | ||||
| github.com/hashicorp/vault-client-go v0.4.3/go.mod h1:4tDw7Uhq5XOxS1fO+oMtotHL7j4sB9cp0T7U6m4FzDY= | ||||
| github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= | ||||
| github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= | ||||
| github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= | ||||
| github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= | ||||
| github.com/ryanuber/go-glob v1.0.0 h1:iQh3xXAumdQ+4Ufa5b25cRpC5TYKlno6hsv6Cb3pkBk= | ||||
| github.com/ryanuber/go-glob v1.0.0/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc= | ||||
| github.com/sethvargo/go-password v0.3.1 h1:WqrLTjo7X6AcVYfC6R7GtSyuUQR9hGyAj/f1PYQZCJU= | ||||
| github.com/sethvargo/go-password v0.3.1/go.mod h1:rXofC1zT54N7R8K/h1WDUdkf9BOx5OptoxrMBcrXzvs= | ||||
| github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= | ||||
| github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= | ||||
| golang.org/x/sys v0.4.0 h1:Zr2JFtRQNX3BCZ8YtxRE9hNJYC8J6I1MVbMg6owUp18= | ||||
| golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | ||||
| golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= | ||||
| golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= | ||||
| golang.org/x/time v0.0.0-20220922220347-f3bd1da661af h1:Yx9k8YCG3dvF87UAn2tu2HQLf2dt/eR1bXxpLMWeH+Y= | ||||
| golang.org/x/time v0.0.0-20220922220347-f3bd1da661af/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= | ||||
| golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= | ||||
| golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= | ||||
| gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= | ||||
							
								
								
									
										32
									
								
								html-template/index.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								html-template/index.html
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,32 @@ | ||||
| <!DOCTYPE html> | ||||
| <html> | ||||
|     <head> | ||||
|         <meta charset="utf-8"> | ||||
|         <meta name="viewport" content="width=device-width, initial-scale=1.0"> | ||||
|         <title>Data Unwrap Form</title> | ||||
|         <!-- <link rel="stylesheet" href="css/normalize.css"> | ||||
|             <link href="https://fonts.googleapis.com/css?family=Lato:300,400,700" rel="stylesheet"> | ||||
|             <link rel="stylesheet" href="css/main.css"> --> | ||||
|     </head> | ||||
|     <body> | ||||
|     <table> | ||||
|       <tr><td> | ||||
|       <a href={{.URL}}/unwrap>Расшифровать</a> | | ||||
|       <a href={{.URL}}/genpassword>Сгенерировать пароль</a> | ||||
|       <tr><td><p></p></td></tr> | ||||
|       <tr><td> | ||||
|       <form method="post" action="{{.URL}}/unwrap"> | ||||
|       <table> | ||||
|           <tr><td> | ||||
|               <textarea id="wrapped_token" name="input_token" cols=50 rows=10>{{ .TEXT }}</textarea> | ||||
|           </td></tr> | ||||
|           <tr><td align=right> | ||||
|               <button type="submit">Расшифровать</button> | ||||
|           </td></tr> | ||||
|       </form> | ||||
|       </td></tr> | ||||
|       <tr><td> | ||||
|       </td></tr> | ||||
|       </table> | ||||
|     </body> | ||||
| </html> | ||||
							
								
								
									
										292
									
								
								vault.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										292
									
								
								vault.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,292 @@ | ||||
| package main | ||||
|  | ||||
| import ( | ||||
| 	// "context" | ||||
| 	"log" | ||||
| 	// "time" | ||||
|     "os" | ||||
|     "fmt" | ||||
|     "flag" | ||||
|     "regexp" | ||||
|     "bytes" | ||||
|     "strconv" | ||||
|     "encoding/json" | ||||
|     "crypto/tls" | ||||
|     "net/http" | ||||
|     "html/template" | ||||
|     "path/filepath" | ||||
|   | ||||
|     "github.com/gorilla/mux" | ||||
| 	"github.com/sethvargo/go-password/password" | ||||
|     	// "io" | ||||
|     // "io/ioutil" | ||||
|      | ||||
| 	// "github.com/hashicorp/vault-client-go" | ||||
| 	// "github.com/hashicorp/vault-client-go/schema" | ||||
| ) | ||||
|  | ||||
| // { | ||||
|   // "request_id": "540486b5-80b6-4250-1ba3-ec562984c58c", | ||||
|   // "lease_id": "", | ||||
|   // "renewable": false, | ||||
|   // "lease_duration": 0, | ||||
|   // "data": { | ||||
|     // "user": "password" | ||||
|   // }, | ||||
|   // "wrap_info": null, | ||||
|   // "warnings": null, | ||||
|   // "auth": null, | ||||
|   // "mount_type": "system" | ||||
| // } | ||||
| //  | ||||
|  | ||||
| var ( | ||||
|     Debug         bool | ||||
|     TemplateDir   string | ||||
|     TemplateFile  string | ||||
|     ActionAddress string | ||||
|     VaultAddress  string | ||||
|     Data          string | ||||
|     ListenPort    string | ||||
|     TlsCertFile   string | ||||
|     TlsKeyFile    string | ||||
| ) | ||||
| type TemplateData struct { | ||||
|     URL  string | ||||
|     TEXT string | ||||
| } | ||||
| type UnwrappedData struct { | ||||
|   Rerquest_id string `json: "request_id"` | ||||
|   Lease_id string `json: "lease_id"` | ||||
|   Renewable bool `json: "renewable"` | ||||
|   Lease_daration int `json:"lease_duration"` | ||||
|   Data map[string]string `json: "data"` | ||||
|   Wrap_info string `json: "wrap_info"` | ||||
|   Warnings string `json: "warnings"` | ||||
|   Auth string `json: "auth"` | ||||
|   Mount_type string `json: "mount_type"` | ||||
|   Error string `json: "errors"` | ||||
| } | ||||
|  | ||||
| func vaultDataWrap(vaultAddr string, vaultToken string, vaultSecretName string) string { | ||||
|  | ||||
| 	customTransport := &(*http.DefaultTransport.(*http.Transport)) | ||||
| 	customTransport.TLSClientConfig = &tls.Config{InsecureSkipVerify: true} | ||||
|  | ||||
| 	client := &http.Client{Transport: customTransport} | ||||
| 	// client := &http.Client{} | ||||
|  | ||||
| 	req, _ := http.NewRequest("POST", vaultAddr, nil) | ||||
| 	req.Header.Add("Accept", "application/json") | ||||
| 	req.Header.Add("X-Vault-Token", vaultToken) | ||||
|  | ||||
| 	resp, err := client.Do(req) | ||||
|  | ||||
| 	if err != nil { | ||||
| 		log.Println("Errored when sending request to the Vault server") | ||||
| 	} | ||||
|  | ||||
| 	var result map[string]interface{} | ||||
| 	json.NewDecoder(resp.Body).Decode(&result) | ||||
| 	secret := result["data"].(map[string]interface{})["data"].(map[string]interface{})[vaultSecretName] | ||||
|     log.Println(result) | ||||
| 	return fmt.Sprint(secret) | ||||
| } | ||||
|  | ||||
| func vaultDataUnWrap(vaultAddr string, vaultWrapToken string) map[string]string { | ||||
|     log.Printf("Vault address: %s ", vaultAddr) | ||||
|  | ||||
| 	customTransport := &(*http.DefaultTransport.(*http.Transport)) | ||||
| 	customTransport.TLSClientConfig = &tls.Config{InsecureSkipVerify: true} | ||||
|  | ||||
| 	client := &http.Client{Transport: customTransport} | ||||
| 	// client := &http.Client{} | ||||
|     log.Println(vaultAddr, vaultWrapToken) | ||||
| 	req, _ := http.NewRequest("POST", vaultAddr, nil) | ||||
| 	req.Header.Add("Accept", "application/json") | ||||
| 	req.Header.Add("X-Vault-Token", vaultWrapToken) | ||||
|  | ||||
| 	resp, err := client.Do(req) | ||||
|  | ||||
| 	if err != nil { | ||||
| 		log.Println("Errored when sending request to the Vault server", err) | ||||
| 	} | ||||
|  | ||||
|     log.Println(resp) | ||||
|  | ||||
| 	var result UnwrappedData | ||||
| 	json.NewDecoder(resp.Body).Decode(&result) | ||||
| 	secret := result.Data | ||||
|     if Debug { | ||||
|         log.Println(result) | ||||
|         log.Println(secret) | ||||
|     } | ||||
|     	// fmt.Sprint(secret) | ||||
|     for v, k := range secret { | ||||
|         log.Println(k, v) | ||||
|     } | ||||
|     return secret | ||||
| } | ||||
|  | ||||
| func ParseTemplate(templateFileName string, data interface{}) (body string, err error) { | ||||
|     body = "" | ||||
| 	t, err := template.ParseFiles(templateFileName) | ||||
| 	if err != nil { | ||||
| 		log.Println("Ошибка преобразования html шаблона", templateFileName, err) | ||||
| 		return | ||||
| 	} | ||||
| 	buf := new(bytes.Buffer) | ||||
| 	if err = t.Execute(buf, data); err != nil { | ||||
| 		log.Println("Ошибка преобразования html шаблона", templateFileName, err) | ||||
|         body = "" | ||||
|     } else { | ||||
| 	    body = buf.String() | ||||
|     } | ||||
| 	return | ||||
| } | ||||
|  | ||||
| func getStaticPage(w http.ResponseWriter, r *http.Request) { | ||||
|     var ( | ||||
|         templateData TemplateData | ||||
|     ) | ||||
|  | ||||
|     template := filepath.Join(TemplateDir, TemplateFile) | ||||
|      | ||||
|     // templateData.UUID = uuid | ||||
|     templateData.URL = ActionAddress + ":" + ListenPort | ||||
|      | ||||
|     templateData.TEXT = Data | ||||
|      | ||||
|     // templateData.URL = FishingUrl + "/" + arrUsers[i].messageUUID | ||||
|     if body, err := ParseTemplate(template, templateData); err == nil { | ||||
|         w.Write([]byte(body)) | ||||
|     } | ||||
| } | ||||
|  | ||||
| // hvs.CAES - 95 | ||||
| // s.Dj7kZS - 26 | ||||
|  | ||||
| func getDataFromHtmlForm(w http.ResponseWriter, r *http.Request) { | ||||
|     r.ParseForm() | ||||
|     token := r.FormValue("input_token") | ||||
|      | ||||
|     vaultPath := VaultAddress + "/v1/sys/wrapping/unwrap" | ||||
|      | ||||
|     // fmt.Fprintln(w, r.URL.RawQuery) | ||||
|     // log.Println(w, r.URL.RawQuery) | ||||
|     if Debug { | ||||
|         log.Printf("Текст для расшифровки: %s ", token) | ||||
|         log.Printf("Адрес сервера Hashicorp Vault: %s ", vaultPath) | ||||
|     } | ||||
|     // Проверка текста на соответствие шаблону | ||||
|     re := regexp.MustCompile(`^(hvs|s)\.[\w\-\_]+`) | ||||
|     if Debug { | ||||
| 	    fmt.Println(re.Match([]byte(token))) | ||||
|     } | ||||
|     if token != "" && re.Match([]byte(token)) { | ||||
|         b := new(bytes.Buffer) | ||||
|         for key, value := range vaultDataUnWrap(vaultPath, token) { | ||||
|             fmt.Fprintf(b, "%s: %s\n", key, value) | ||||
|         } | ||||
|         Data = b.String() | ||||
|         if Debug { | ||||
|             log.Println(Data) | ||||
|         } | ||||
|     } else { | ||||
|         Data = "Введите токен" | ||||
|     } | ||||
|     getStaticPage(w, r) | ||||
|     // http.Redirect(w, r, "http://"+r.Host, http.StatusMovedPermanently) | ||||
| } | ||||
|  | ||||
| func genPassword(w http.ResponseWriter, r *http.Request) { | ||||
| 	params := mux.Vars(r) | ||||
| 	passLength := params["passLength"] | ||||
| 	// w.Write([]byte("Длина пароля " + passLength + "/n")) | ||||
| 	passwordLength, err := strconv.Atoi(passLength) | ||||
| 	if passwordLength > 1024 { | ||||
| 		log.Printf("Oversized password length") | ||||
| 		w.Write([]byte("Oversized password length")) | ||||
| 		return | ||||
| 	} | ||||
| 	if err != nil { | ||||
| 		log.Fatal(err) | ||||
| 	} | ||||
| 	res, err := password.Generate(passwordLength, 10, 5, false, true) | ||||
| 	if err != nil { | ||||
| 		log.Fatal(err) | ||||
| 	} | ||||
| 	log.Printf(res) | ||||
| 	w.Write([]byte(res)) | ||||
| } | ||||
|  | ||||
| func genPasswordDefault(w http.ResponseWriter, r *http.Request) { | ||||
| 	res, err := password.Generate(64, 10, 5, false, false) | ||||
| 	if err != nil { | ||||
| 		log.Fatal(err) | ||||
| 	} | ||||
| 	log.Printf(res) | ||||
| 	w.Write([]byte(res)) | ||||
| } | ||||
|  | ||||
| func main() { | ||||
|     var ( | ||||
|         logFile string | ||||
|     ) | ||||
|     flag.BoolVar(&Debug, "debug", false, "Вывод отладочных сообщений в консоль") | ||||
|     flag.StringVar(&logFile, "log-file", "vault-unwrap.log", "Путь до лог-файла ") | ||||
|     flag.StringVar(&TemplateDir, "template-dir", "html-template", "Каталог с шаблонами") | ||||
|     flag.StringVar(&TemplateFile, "template-file", "index.html", "Файл-шаблон для ВЭБ-странцы") | ||||
|     flag.StringVar(&VaultAddress, "vault-url", "", "Адрес сервера Hashicorp Vault (https://host.name:8200)") | ||||
|     flag.StringVar(&ActionAddress, "action-address", "", "Адрес данного сервиса (https://host.name") | ||||
|     flag.StringVar(&ListenPort, "listen-port", "8443", "Номер порта сервиса") | ||||
|     flag.StringVar(&TlsCertFile, "tls-cert", "", "TLS сертификат (файл)") | ||||
|     flag.StringVar(&TlsKeyFile, "tls-key", "", "TLS ключ (файл)") | ||||
|      | ||||
| 	flag.Parse() | ||||
|  | ||||
|     if os.Getenv("logFile") != "" { | ||||
|         logFile = os.Getenv("logFile") | ||||
|     } | ||||
|      | ||||
|     fLog, err := os.OpenFile(logFile, os.O_RDWR | os.O_CREATE | os.O_APPEND, 0666) | ||||
|     if err != nil { | ||||
|         log.Fatalf("error opening file: %v", err) | ||||
|     } | ||||
|     defer fLog.Close() | ||||
|  | ||||
|     if Debug { | ||||
|         log.SetOutput(os.Stdout) | ||||
|     } else { | ||||
|         log.SetOutput(fLog) | ||||
|     } | ||||
|      | ||||
|     if os.Getenv("VAULT_ADDRESS") == "" && VaultAddress == "" { | ||||
|       log.Println("Send error: make sure environment variables `VAULT_ADDRESS` was set") | ||||
|     } else if os.Getenv("VAULT_ADDRESS") != "" && VaultAddress == "" { | ||||
|         VaultAddress = os.Getenv("VAULT_ADDRESS") | ||||
|     } | ||||
|  | ||||
|  | ||||
|     if Debug { | ||||
|         log.Printf("Адрес сервера Hashicorp Vault: %s ", VaultAddress) | ||||
|     } | ||||
|  | ||||
|     rtr := mux.NewRouter() | ||||
|     rtr.HandleFunc("/unwrap", getDataFromHtmlForm) | ||||
|     rtr.HandleFunc("/genpassword/{passLength:[0-9]+}", genPassword) | ||||
|     rtr.HandleFunc("/genpassword", genPasswordDefault) | ||||
|      | ||||
|     rtr.HandleFunc("/", getDataFromHtmlForm) | ||||
|     rtr.PathPrefix("/").Handler(http.FileServer(http.Dir("./static"))) | ||||
|      | ||||
|     http.Handle("/", rtr) | ||||
|     if os.Getenv("LISTEN_PORT") != "" { | ||||
|         ListenPort = os.Getenv("LISTEN_PORT") | ||||
|     } | ||||
|     listenAddr := ":" + ListenPort | ||||
|      | ||||
|     log.Println("Listening...") | ||||
|     // http.ListenAndServe(":8080", nil) | ||||
|     log.Fatal(http.ListenAndServeTLS(listenAddr, TlsCertFile, TlsKeyFile, nil)) | ||||
| } | ||||
		Reference in New Issue
	
	Block a user
	 svkalinin
					svkalinin