Created
September 5, 2023 11:02
-
-
Save iamspark1e/20f709ba415ad10f00752b6ee9d840e0 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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