Simple validation of the id and the authorized keys.

This commit is contained in:
Erik Brakkee 2024-08-04 23:31:12 +02:00
parent 46d4467e94
commit 02914ae40f
5 changed files with 49 additions and 8 deletions

View File

@ -29,7 +29,7 @@ func readSshPublicKeys(fileName string) ([]ssh.PublicKey, error) {
} }
defer file.Close() defer file.Close()
res := make([]ssh.PublicKey, 10) res := make([]ssh.PublicKey, 0)
scanner := bufio.NewScanner(file) scanner := bufio.NewScanner(file)
for scanner.Scan() { for scanner.Scan() {
lineText := scanner.Text() lineText := scanner.Text()
@ -37,6 +37,7 @@ func readSshPublicKeys(fileName string) ([]ssh.PublicKey, error) {
if ind >= 0 { if ind >= 0 {
lineText = lineText[:ind] lineText = lineText[:ind]
} }
log.Println("Reading public key " + lineText)
lineText = strings.Trim(lineText, "") lineText = strings.Trim(lineText, "")
if lineText == "" { if lineText == "" {
continue continue

View File

@ -3,7 +3,6 @@ package main
import ( import (
"converge/pkg/models" "converge/pkg/models"
"converge/pkg/server/converge" "converge/pkg/server/converge"
"log"
"net/http" "net/http"
"regexp" "regexp"
"strings" "strings"
@ -14,9 +13,7 @@ func getConvergeAccess(r *http.Request, sshRemoteUser string) models.ConvergeAcc
pattern := regexp.MustCompile("^(.*)/usage$") pattern := regexp.MustCompile("^(.*)/usage$")
matches := pattern.FindStringSubmatch(r.URL.Path) matches := pattern.FindStringSubmatch(r.URL.Path)
contextPath := "" contextPath := ""
if len(matches) != 2 { if len(matches) == 2 {
log.Printf("Cannot determine context path for %s, assumming it is empty", r.URL.Path)
} else {
contextPath = matches[1] contextPath = matches[1]
} }

View File

@ -2,9 +2,12 @@ package main
import ( import (
"converge/pkg/server/templates" "converge/pkg/server/templates"
"fmt"
"github.com/gliderlabs/ssh"
"math/rand" "math/rand"
"net/http" "net/http"
"os" "os"
"regexp"
"strconv" "strconv"
"strings" "strings"
) )
@ -18,11 +21,12 @@ func generateCLIExammple(w http.ResponseWriter, r *http.Request) {
ids := r.Form["rendez-vous-id"] ids := r.Form["rendez-vous-id"]
id := "" id := ""
if len(ids) > 0 { if len(ids) > 0 {
id = ids[0] id = strings.TrimSpace(ids[0])
} }
if id == "" { if id == "" {
id = strconv.Itoa(rand.Int() % 1000000) id = strconv.Itoa(rand.Int() % 1000000)
} }
remoteShells := r.Form["remote-shell"] remoteShells := r.Form["remote-shell"]
localShells := r.Form["local-shell"] localShells := r.Form["local-shell"]
keysString := r.FormValue("ssh-keys") keysString := r.FormValue("ssh-keys")
@ -36,6 +40,29 @@ func generateCLIExammple(w http.ResponseWriter, r *http.Request) {
access := getConvergeAccess(r, getAgentSshUser()) access := getConvergeAccess(r, getAgentSshUser())
usageInputs := templates.NewUsageInputs(id, sshPublicKeys, remoteShells, localShells) usageInputs := templates.NewUsageInputs(id, sshPublicKeys, remoteShells, localShells)
matched, _ := regexp.MatchString("^[a-zA-Z0-9-_]+$", id)
if !matched {
usageInputs.ErrorMessages = append(usageInputs.ErrorMessages, "ID may consist only of alphanumeric characters, '-', and '_'")
}
validPubKeys := 0
for index, pubkey := range sshPublicKeys {
_, _, _, _, err := ssh.ParseAuthorizedKey([]byte(pubkey))
if err != nil {
keysummary := pubkey
if len(pubkey) > 45 {
keysummary = keysummary[:20] + " ... " + keysummary[len(pubkey)-20:]
}
usageInputs.ErrorMessages = append(usageInputs.ErrorMessages,
fmt.Sprintf("ssh public key %d: %s: %s", index, keysummary, err.Error()))
} else {
validPubKeys++
}
}
if validPubKeys == 0 {
usageInputs.ErrorMessages = append(usageInputs.ErrorMessages,
"No valid public keys configured, password authentication will be used which is less secure.")
}
err = templates.ShellUsage(access, usageInputs).Render(r.Context(), w) err = templates.ShellUsage(access, usageInputs).Render(r.Context(), w)
if err != nil { if err != nil {
http.Error(w, err.Error(), 500) http.Error(w, err.Error(), 500)

View File

@ -5,6 +5,13 @@ import "converge/pkg/models"
templ AgentUsage(access models.ConvergeAccess, usageInputs UsageInputs) { templ AgentUsage(access models.ConvergeAccess, usageInputs UsageInputs) {
<div> <div>
for _, message := range usageInputs.ErrorMessages {
<div class="alert alert-danger" role="alert">
{message}
</div>
}
<h2>Downloading and running the agent</h2> <h2>Downloading and running the agent</h2>
<p> <p>

View File

@ -5,8 +5,10 @@ import (
) )
type UsageInputs struct { type UsageInputs struct {
Id string Id string
SshKeys []string SshKeys []string
ErrorMessages []string
RemoteShells map[string]bool RemoteShells map[string]bool
LocalShells map[string]bool LocalShells map[string]bool
} }
@ -43,3 +45,10 @@ func addSshKeys(shell string, keys []string) string {
} }
return res + " " return res + " "
} }
func formControlTextClass(message string) string {
if message == "" {
return "form-control"
}
return "form-control is-invalid"
}