58 lines
1.4 KiB
Go
58 lines
1.4 KiB
Go
package utils
|
|
|
|
import (
|
|
"fmt"
|
|
"net/http"
|
|
"strings"
|
|
|
|
"github.com/fiskerinc/cloud-services/pkg/logger"
|
|
"github.com/fiskerinc/cloud-services/pkg/validator"
|
|
)
|
|
|
|
// ParseVINFromRequest retrieves VIN from "Ssl-Client-Subject-Dn"
|
|
//
|
|
// which is generated by NGINX through a cert on websocket request
|
|
func ParseVINFromRequest(r *http.Request) (vin string, err error) {
|
|
// Try SDK 1.2 format first: Ssl-Client-Subject-Dn header
|
|
vin = retrieveCommonNameFromHeaderSSLClientSubject(r)
|
|
|
|
if vin == "" {
|
|
// Try SDK 1.4 format: Ssl header
|
|
vin = retrieveCommonNameFromHeaderSSL(r)
|
|
}
|
|
|
|
ok := validator.ValidateVINSimple(vin)
|
|
if ok {
|
|
return vin, nil
|
|
}
|
|
// If neither header format contains a VIN, return error
|
|
return "", fmt.Errorf("VIN not found in request headers: '%s' bad value", vin)
|
|
}
|
|
|
|
func retrieveCommonNameFromHeaderSSL(r *http.Request) (vin string) {
|
|
sslHeader := r.Header.Get("Ssl")
|
|
logger.Info().Str("SSL Header Value", sslHeader).Msg("CSDK 1.2 VIN Format Failed, trying 1.4")
|
|
if sslHeader != "" {
|
|
// Extract VIN from "CN=VIN_HERE" format
|
|
if strings.HasPrefix(sslHeader, "CN=") {
|
|
vin = strings.TrimPrefix(sslHeader, "CN=")
|
|
}
|
|
}
|
|
return
|
|
}
|
|
|
|
func retrieveCommonNameFromHeaderSSLClientSubject(r *http.Request) string {
|
|
dn := r.Header.Values("Ssl-Client-Subject-Dn")
|
|
|
|
for _, d := range dn {
|
|
fields := strings.Split(d, ",")
|
|
for _, field := range fields {
|
|
if len(field) > 3 && field[:3] == "CN=" {
|
|
return field[3:]
|
|
}
|
|
}
|
|
}
|
|
|
|
return ""
|
|
}
|