Skip to content

Instantly share code, notes, and snippets.

@iamspark1e
Created September 5, 2023 11:02
Show Gist options
  • Save iamspark1e/20f709ba415ad10f00752b6ee9d840e0 to your computer and use it in GitHub Desktop.
Save iamspark1e/20f709ba415ad10f00752b6ee9d840e0 to your computer and use it in GitHub Desktop.
import (
"fmt"
"net/http"
"os"
"strings"
"github.com/gin-gonic/gin"
"caddy-http-tls-provider/bootstrap"
"caddy-http-tls-provider/utils"
)
// The URL will be augmented with the following query string parameters:
//
// server_name = SNI value,
// signature_schemes = comma-separated list of hex IDs of signature algorithms,
// and cipher_suites = comma-separated list of hex IDS of cipher suites.
type TokenizedUri struct {
Token string `uri:"token" binding:"required"`
}
func GetCertByServerName(c *gin.Context) {
// FIXME: below queries has been skipped.
// signature_schemes := c.Query("signature_schemes")
// cipher_suites := c.Query("cipher_suites")
server_name := c.Query("server_name")
// utils.Logger(fmt.Sprintf("server_name: %s, signature_schemes: %s, cipher_suites: %s", server_name, signature_schemes, cipher_suites), nil)
if server_name == "" {
c.AbortWithStatus(http.StatusBadRequest)
return
}
var tokenizedUri TokenizedUri
if err := c.ShouldBindUri(&tokenizedUri); err != nil {
c.AbortWithStatus(http.StatusBadRequest)
return
}
if bootstrap.Token != "" && tokenizedUri.Token != bootstrap.Token {
c.AbortWithStatus(http.StatusBadRequest)
return
}
// if server_name can match wildcard cert
var topDomain string = getTopDomainFromServerName(server_name)
utils.Logger(fmt.Sprintf("[Caddy TLS Request: %s] A new request from %s, wildcard should be: %s", server_name, c.ClientIP(), topDomain), nil)
var requestFilePrefix string = bootstrap.CertDir + "/" + topDomain + "/" + topDomain
var matchedFiles []string
if _, err := os.Stat(bootstrap.CertDir + "/" + topDomain); err != nil {
if os.IsNotExist(err) {
utils.Logger(fmt.Sprintf("[Caddy TLS Request: %s] Wildcard cert not found in path: %s", server_name, bootstrap.CertDir+"/"+topDomain), err)
} else {
utils.Logger(fmt.Sprintf("[Caddy TLS Request: %s] Check wildcard cert exist failed", server_name), err)
}
// else, try exact server_name cert
utils.Logger(fmt.Sprintf("[Caddy TLS Request: %s] Fallback to exact server_name", server_name), nil)
if _, err := os.Stat(bootstrap.CertDir + "/" + server_name); err != nil {
utils.Logger(fmt.Sprintf("[Caddy TLS Request: %s] Check exact server_name cert failed", server_name), err)
c.AbortWithStatus(http.StatusBadRequest)
return
}
requestFilePrefix = bootstrap.CertDir + "/" + server_name + "/" + server_name
matchedFiles = append(matchedFiles, requestFilePrefix+".pem")
} else {
matchedFiles = append(matchedFiles, bootstrap.CertDir+"/"+topDomain+"/"+"fullchain.pem")
}
matchedFiles = append(matchedFiles, requestFilePrefix+".pem")
var rBody string = ""
for _, matched := range matchedFiles {
strByte, _ := os.ReadFile(matched)
rBody += string(strByte) + "\n"
}
c.Data(200, "application/x-pem-file", []byte(rBody))
}
func getTopDomainFromServerName(server_name string) string {
if server_name == "" {
return ""
}
var topDomain string = ""
fullDomain := strings.Split(server_name, ".")
topDomain = fullDomain[len(fullDomain) - 2] + "." + fullDomain[len(fullDomain) - 1]
return topDomain
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment