fea: support get openvpn file from user

This commit is contained in:
Daniel Ding
2023-12-27 21:24:02 +08:00
parent dd05f95017
commit 9909380092
8 changed files with 82 additions and 38 deletions

View File

@@ -5,7 +5,7 @@ SHELL := /bin/bash
## version ## version
LSB = $(shell lsb_release -i -s)$(shell lsb_release -r -s) LSB = $(shell lsb_release -i -s)$(shell lsb_release -r -s)
VER = $(shell cat VERSION) VER = $(shell ./dist/version.sh)
ARCH = $(shell uname -m) ARCH = $(shell uname -m)
## declare directory ## declare directory
@@ -185,4 +185,4 @@ cover: env ## execute unit test and output coverage
go tool cover -html=coverage.out -o coverage.html go tool cover -html=coverage.out -o coverage.html
clean: ## clean cache clean: ## clean cache
rm -rvf ./build rm -rvf ./build

View File

@@ -1 +0,0 @@
23.09.18

14
dist/version.sh vendored Executable file
View File

@@ -0,0 +1,14 @@
#!/bin/bash
if [ -e "VERSION" ]; then
cat VERSION
exit 0
fi
ver=$(git describe --tags --abbrev=0 --match 'v*')
if [ $? -eq 0 ]; then
echo $ver
exit 0
fi
date +%y%m%d

View File

@@ -1,12 +1,13 @@
package api package api
import ( import (
"net/http"
"strings"
"github.com/gorilla/mux" "github.com/gorilla/mux"
"github.com/luscis/openlan/pkg/cache" "github.com/luscis/openlan/pkg/cache"
"github.com/luscis/openlan/pkg/models" "github.com/luscis/openlan/pkg/models"
"github.com/luscis/openlan/pkg/schema" "github.com/luscis/openlan/pkg/schema"
"net/http"
"strings"
) )
type Network struct { type Network struct {
@@ -15,7 +16,7 @@ type Network struct {
func (h Network) Router(router *mux.Router) { func (h Network) Router(router *mux.Router) {
router.HandleFunc("/api/network", h.List).Methods("GET") router.HandleFunc("/api/network", h.List).Methods("GET")
router.HandleFunc("/api/network/{id}", h.Get).Methods("GET") router.HandleFunc("/api/network/{id}", h.Get).Methods("GET")
router.HandleFunc("/get/network/{id}/{ie}.ovpn", h.Profile).Methods("GET") router.HandleFunc("/get/network/{id}/ovpn", h.Profile).Methods("GET")
} }
func (h Network) List(w http.ResponseWriter, r *http.Request) { func (h Network) List(w http.ResponseWriter, r *http.Request) {
@@ -42,7 +43,7 @@ func (h Network) Get(w http.ResponseWriter, r *http.Request) {
func (h Network) Profile(w http.ResponseWriter, r *http.Request) { func (h Network) Profile(w http.ResponseWriter, r *http.Request) {
server := strings.SplitN(r.Host, ":", 2)[0] server := strings.SplitN(r.Host, ":", 2)[0]
vars := mux.Vars(r) vars := mux.Vars(r)
data, err := cache.VPNClient.GetClientProfile(vars["id"], vars["ie"], server) data, err := cache.VPNClient.GetClientProfile(vars["id"], server)
if err == nil { if err == nil {
_, _ = w.Write([]byte(data)) _, _ = w.Write([]byte(data))
} else { } else {

View File

@@ -72,14 +72,25 @@ func (h User) Del(w http.ResponseWriter, r *http.Request) {
ResponseMsg(w, 0, "") ResponseMsg(w, 0, "")
} }
func UserCheck(user, pass string) error {
model := &models.User{
Name: user,
Password: pass,
}
if _, err := cache.User.Check(model); err == nil {
return nil
} else {
return err
}
}
func (h User) Check(w http.ResponseWriter, r *http.Request) { func (h User) Check(w http.ResponseWriter, r *http.Request) {
user := &schema.User{} user := &schema.User{}
if err := GetData(r, user); err != nil { if err := GetData(r, user); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError) http.Error(w, err.Error(), http.StatusInternalServerError)
return return
} }
model := models.SchemaToUserModel(user) if err := UserCheck(user.Name, user.Password); err == nil {
if _, err := cache.User.Check(model); err == nil {
ResponseMsg(w, 0, "success") ResponseMsg(w, 0, "success")
} else { } else {
http.Error(w, err.Error(), http.StatusUnauthorized) http.Error(w, err.Error(), http.StatusUnauthorized)

24
pkg/cache/openvpn.go vendored
View File

@@ -2,9 +2,6 @@ package cache
import ( import (
"bufio" "bufio"
"github.com/luscis/openlan/pkg/config"
"github.com/luscis/openlan/pkg/libol"
"github.com/luscis/openlan/pkg/schema"
"io" "io"
"os" "os"
"path/filepath" "path/filepath"
@@ -12,6 +9,10 @@ import (
"strings" "strings"
"time" "time"
"unicode" "unicode"
"github.com/luscis/openlan/pkg/config"
"github.com/luscis/openlan/pkg/libol"
"github.com/luscis/openlan/pkg/schema"
) )
type vpnClient struct { type vpnClient struct {
@@ -156,9 +157,15 @@ func (o *vpnClient) List(name string) <-chan *schema.VPNClient {
return c return c
} }
func (o *vpnClient) GetClientProfile(network, client, remote string) (string, error) { func (o *vpnClient) clientFile(name string) string {
file := o.Dir(network, client+"client.ovpn") files, _ := filepath.Glob(o.Dir(name, "*client.ovpn"))
reader, err := os.Open(file) if len(files) > 0 {
return files[0]
}
return ""
}
func (o *vpnClient) GetClientProfile(network, remote string) (string, error) {
reader, err := os.Open(o.clientFile(network))
if err != nil { if err != nil {
return "", err return "", err
} }
@@ -166,8 +173,9 @@ func (o *vpnClient) GetClientProfile(network, client, remote string) (string, er
scanner := bufio.NewScanner(reader) scanner := bufio.NewScanner(reader)
for scanner.Scan() { for scanner.Scan() {
line := scanner.Text() line := scanner.Text()
if strings.HasPrefix(line, "remote 0.0.0.0") { elements := strings.SplitN(line, " ", 3)
profile += strings.Replace(line, "0.0.0.0", remote, 1) if len(elements) == 3 && elements[0] == "remote" {
profile += "remote " + remote + " " + elements[2]
} else { } else {
profile += line profile += line
} }

View File

@@ -2,10 +2,11 @@ package models
import ( import (
"fmt" "fmt"
"github.com/luscis/openlan/pkg/libol"
"runtime" "runtime"
"strings" "strings"
"time" "time"
"github.com/luscis/openlan/pkg/libol"
) )
type User struct { type User struct {
@@ -56,5 +57,8 @@ func (u *User) Update() {
} }
func (u *User) Id() string { func (u *User) Id() string {
if u.Network == "" {
return u.Name
}
return u.Name + "@" + u.Network return u.Name + "@" + u.Network
} }

View File

@@ -2,16 +2,7 @@ package _switch
import ( import (
"context" "context"
"crypto/md5"
"encoding/hex"
"fmt" "fmt"
"github.com/gorilla/mux"
"github.com/luscis/openlan/pkg/api"
"github.com/luscis/openlan/pkg/cache"
co "github.com/luscis/openlan/pkg/config"
"github.com/luscis/openlan/pkg/libol"
"github.com/luscis/openlan/pkg/models"
"github.com/luscis/openlan/pkg/schema"
"io/ioutil" "io/ioutil"
"net/http" "net/http"
"net/http/pprof" "net/http/pprof"
@@ -21,13 +12,20 @@ import (
"strings" "strings"
"text/template" "text/template"
"time" "time"
"github.com/gorilla/mux"
"github.com/luscis/openlan/pkg/api"
"github.com/luscis/openlan/pkg/cache"
co "github.com/luscis/openlan/pkg/config"
"github.com/luscis/openlan/pkg/libol"
"github.com/luscis/openlan/pkg/models"
"github.com/luscis/openlan/pkg/schema"
) )
type Http struct { type Http struct {
switcher api.Switcher switcher api.Switcher
listen string listen string
adminToken string adminToken string
guestToken string
adminFile string adminFile string
server *http.Server server *http.Server
crtFile string crtFile string
@@ -141,9 +139,7 @@ func (h *Http) LoadToken() {
} }
func (h *Http) SetToken(value string) { func (h *Http) SetToken(value string) {
sum := md5.Sum([]byte(value))
h.adminToken = value h.adminToken = value
h.guestToken = hex.EncodeToString(sum[:16])[:12]
} }
func (h *Http) Start() { func (h *Http) Start() {
@@ -182,16 +178,27 @@ func (h *Http) Shutdown() {
func (h *Http) IsAuth(w http.ResponseWriter, r *http.Request) bool { func (h *Http) IsAuth(w http.ResponseWriter, r *http.Request) bool {
token, pass, ok := r.BasicAuth() token, pass, ok := r.BasicAuth()
libol.Debug("Http.IsAuth token: %s, pass: %s", token, pass) libol.Debug("Http.IsAuth token: %s, pass: %s", token, pass)
if strings.HasPrefix(r.URL.Path, "/api/") { if !ok {
if !ok || token != h.adminToken { return false
return false }
} if token == h.adminToken {
} else if strings.HasPrefix(r.URL.Path, "/get/") { return true
if !ok || token != h.guestToken { }
return false
elements := strings.SplitN(r.URL.Path, "/", 8)
if len(elements) > 3 {
if elements[2] == "network" {
zone := elements[3]
if !strings.HasSuffix(token, "@"+zone) {
return false
}
if api.UserCheck(token, pass) == nil {
return true
}
} }
} }
return true
return false
} }
func (h *Http) getFile(name string) string { func (h *Http) getFile(name string) string {