| 
									
										
										
										
											2022-11-30 13:50:59 +08:00
										 |  |  | package setting | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							| 
									
										
										
										
											2024-03-22 20:52:24 +08:00
										 |  |  | 	"encoding/pem" | 
					
						
							| 
									
										
										
										
											2022-11-30 13:50:59 +08:00
										 |  |  | 	"errors" | 
					
						
							| 
									
										
										
										
											2024-03-22 20:52:24 +08:00
										 |  |  | 	"os" | 
					
						
							| 
									
										
										
										
											2022-11-30 13:50:59 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	"gopkg.in/ini.v1" | 
					
						
							|  |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | type SecureSocksDSProxySettings struct { | 
					
						
							| 
									
										
										
										
											2024-03-22 20:52:24 +08:00
										 |  |  | 	Enabled            bool | 
					
						
							|  |  |  | 	ShowUI             bool | 
					
						
							|  |  |  | 	AllowInsecure      bool | 
					
						
							|  |  |  | 	ClientCert         string | 
					
						
							|  |  |  | 	ClientCertFilePath string | 
					
						
							|  |  |  | 	ClientKey          string | 
					
						
							|  |  |  | 	ClientKeyFilePath  string | 
					
						
							|  |  |  | 	RootCAs            []string | 
					
						
							|  |  |  | 	RootCAFilePaths    []string | 
					
						
							|  |  |  | 	ProxyAddress       string | 
					
						
							|  |  |  | 	ServerName         string | 
					
						
							| 
									
										
										
										
											2022-11-30 13:50:59 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func readSecureSocksDSProxySettings(iniFile *ini.File) (SecureSocksDSProxySettings, error) { | 
					
						
							| 
									
										
										
										
											2024-03-22 20:52:24 +08:00
										 |  |  | 	s := SecureSocksDSProxySettings{ | 
					
						
							|  |  |  | 		RootCAs:         []string{}, | 
					
						
							|  |  |  | 		RootCAFilePaths: []string{}, | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2022-11-30 13:50:59 +08:00
										 |  |  | 	secureSocksProxySection := iniFile.Section("secure_socks_datasource_proxy") | 
					
						
							|  |  |  | 	s.Enabled = secureSocksProxySection.Key("enabled").MustBool(false) | 
					
						
							|  |  |  | 	s.ProxyAddress = secureSocksProxySection.Key("proxy_address").MustString("") | 
					
						
							|  |  |  | 	s.ServerName = secureSocksProxySection.Key("server_name").MustString("") | 
					
						
							| 
									
										
										
										
											2023-06-02 02:58:51 +08:00
										 |  |  | 	s.ShowUI = secureSocksProxySection.Key("show_ui").MustBool(true) | 
					
						
							| 
									
										
										
										
											2023-12-14 23:16:32 +08:00
										 |  |  | 	s.AllowInsecure = secureSocksProxySection.Key("allow_insecure").MustBool(false) | 
					
						
							| 
									
										
										
										
											2024-03-22 20:52:24 +08:00
										 |  |  | 	s.ClientCertFilePath = secureSocksProxySection.Key("client_cert").MustString("") | 
					
						
							|  |  |  | 	s.ClientKeyFilePath = secureSocksProxySection.Key("client_key").MustString("") | 
					
						
							|  |  |  | 	s.RootCAFilePaths = secureSocksProxySection.Key("root_ca_cert").Strings(" ") | 
					
						
							| 
									
										
										
										
											2022-11-30 13:50:59 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if !s.Enabled { | 
					
						
							|  |  |  | 		return s, nil | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-14 23:16:32 +08:00
										 |  |  | 	if s.ProxyAddress == "" { | 
					
						
							| 
									
										
										
										
											2022-11-30 13:50:59 +08:00
										 |  |  | 		return s, errors.New("proxy address required") | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-14 23:16:32 +08:00
										 |  |  | 	// If the proxy is going to use TLS.
 | 
					
						
							|  |  |  | 	if !s.AllowInsecure { | 
					
						
							|  |  |  | 		// all fields must be specified to use the proxy
 | 
					
						
							| 
									
										
										
										
											2024-03-22 20:52:24 +08:00
										 |  |  | 		if len(s.RootCAFilePaths) == 0 { | 
					
						
							|  |  |  | 			return s, errors.New("one or more rootCA required") | 
					
						
							|  |  |  | 		} else if s.ClientCertFilePath == "" || s.ClientKeyFilePath == "" { | 
					
						
							| 
									
										
										
										
											2023-12-14 23:16:32 +08:00
										 |  |  | 			return s, errors.New("client key pair required") | 
					
						
							|  |  |  | 		} else if s.ServerName == "" { | 
					
						
							|  |  |  | 			return s, errors.New("server name required") | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2024-03-22 20:52:24 +08:00
										 |  |  | 	} else { | 
					
						
							|  |  |  | 		return s, nil | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if s.ClientCertFilePath != "" { | 
					
						
							|  |  |  | 		certPEMBlock, err := os.ReadFile(s.ClientCertFilePath) | 
					
						
							|  |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			return s, err | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		s.ClientCert = string(certPEMBlock) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if s.ClientKeyFilePath != "" { | 
					
						
							|  |  |  | 		keyPEMBlock, err := os.ReadFile(s.ClientKeyFilePath) | 
					
						
							|  |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			return s, err | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		s.ClientKey = string(keyPEMBlock) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	var rootCAs []string | 
					
						
							|  |  |  | 	for _, rootCAFile := range s.RootCAFilePaths { | 
					
						
							|  |  |  | 		// nolint:gosec
 | 
					
						
							|  |  |  | 		// The gosec G304 warning can be ignored because `rootCAFile` comes from config ini, and we check below if
 | 
					
						
							|  |  |  | 		// it's the right file type.
 | 
					
						
							|  |  |  | 		pemBytes, err := os.ReadFile(rootCAFile) | 
					
						
							|  |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			return s, err | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		pemDecoded, _ := pem.Decode(pemBytes) | 
					
						
							|  |  |  | 		if pemDecoded == nil || pemDecoded.Type != "CERTIFICATE" { | 
					
						
							|  |  |  | 			return s, errors.New("root ca is invalid") | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		rootCAs = append(rootCAs, string(pemBytes)) | 
					
						
							| 
									
										
										
										
											2023-12-14 23:16:32 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2024-03-22 20:52:24 +08:00
										 |  |  | 	s.RootCAs = rootCAs | 
					
						
							| 
									
										
										
										
											2023-12-14 23:16:32 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-30 13:50:59 +08:00
										 |  |  | 	return s, nil | 
					
						
							|  |  |  | } |