1d40c406bdc6798323559b1307efb58e982a3c85
[ealt-edge.git] / mep / mepagent / pkg / service / request.go
1 /*
2  *  Copyright 2020 Huawei Technologies Co., Ltd.
3  *
4  *  Licensed under the Apache License, Version 2.0 (the "License");
5  *  you may not use this file except in compliance with the License.
6  *  You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  *  Unless required by applicable law or agreed to in writing, software
11  *  distributed under the License is distributed on an "AS IS" BASIS,
12  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  *  See the License for the specific language governing permissions and
14  *  limitations under the License.
15  */
16
17 package service
18
19 import (
20         "crypto/tls"
21         "crypto/x509"
22         "errors"
23         "io/ioutil"
24         "log"
25         "net/http"
26         "os"
27         "strconv"
28         "strings"
29 )
30
31 // const
32 var cipherSuiteMap = map[string]uint16{
33         "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256": tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
34         "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384": tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
35 }
36
37 // register to mep
38 func RegisterToMep(param string, url string) (string, error) {
39         response, errPost := DoPost(param, url)
40         if errPost != nil {
41                 log.Println("Failed to send request")
42                 return "", errPost
43         }
44         defer response.Body.Close()
45
46         if response.StatusCode != http.StatusCreated {
47                 return "", errors.New("request failed, status is " + strconv.Itoa(response.StatusCode))
48         }
49         body, err := ioutil.ReadAll(response.Body)
50         if err != nil {
51                 log.Println("Failed to read response")
52                 return "", err
53         }
54
55         return string(body), nil
56 }
57
58 func DoPost(param string, url string) (*http.Response, error) {
59         sslMode := os.Getenv("APP_SSL_MODE")
60
61         //if ssl mode is enabled, then config tls
62         if sslMode == "0" {
63                 response, errPost := http.Post(url, "application/json", strings.NewReader(param))
64                 if errPost != nil {
65                         log.Println("Failed to create http request")
66                         return nil, errPost
67                 }
68                 return response, nil
69         } else {
70                 req, errReq := http.NewRequest("POST", url, strings.NewReader(param))
71                 if errReq != nil {
72                         log.Println("Failed to create https request")
73                         return nil, errReq
74                 }
75                 response, errDo := DoRegister(req)
76                 if errDo != nil {
77                         log.Println("Failed to post https request %s", errDo)
78                         return nil, errDo
79                 }
80                 return response, nil
81         }
82 }
83
84 func DoRegister(req *http.Request) (*http.Response, error) {
85         config, err := TlsConfig()
86         if err != nil {
87                 log.Println("Failed to config HTTPS")
88                 return nil, err
89         }
90
91         trans := &http.Transport{
92                 TLSClientConfig: config,
93         }
94
95         client := &http.Client{Transport: trans}
96
97         return client.Do(req)
98 }
99
100 func TlsConfig() (*tls.Config, error) {
101         caCert, err := ioutil.ReadFile(os.Getenv("SSL_ROOT"))
102         if err != nil {
103                 log.Println("Failed to read  cert from file")
104                 return nil, err
105         }
106
107         CACERT := x509.NewCertPool()
108         CACERT.AppendCertsFromPEM(caCert)
109
110         appconf, err1 := GetAppConf("./conf/app_info.yaml")
111         if err1 != nil {
112                 log.Println("Failed to read  cipher from file")
113                 return nil, err1
114         }
115
116         cipherslist := appconf.SslCipherSuite
117         if cipherslist == "" {
118                 log.Println("no cipher provided in conf")
119                 return nil, err
120         }
121
122     ciphermap := getcipher(cipherslist)
123     if ciphermap == nil {
124                 return nil, err
125         }
126
127         return &tls.Config{
128                 RootCAs: CACERT,
129                 ServerName:   os.Getenv("CA_CERT_DOMAIN_NAME"),
130                 CipherSuites: ciphermap,
131                 MinVersion: tls.VersionTLS12,
132         }, nil
133 }
134
135 func getcipher(ciphers string) []uint16 {
136         ciphersmap := make([]uint16, 0)
137         cipherlist := strings.Split(ciphers, ",")
138         for _, ciphername := range cipherlist {
139                 ciphernametrim := strings.TrimSpace(ciphername)
140                 if len(ciphernametrim) == 0 {
141                         continue
142                 }
143
144                 ciphervalue, ok := cipherSuiteMap[ciphernametrim]
145                 if !ok {
146                         log.Println("not recommended cipher")
147                         return nil
148                 }
149                 ciphersmap = append(ciphersmap, ciphervalue)
150         }
151
152         if len(ciphersmap) <= 0 {
153                 log.Println("no cipher in list")
154                 return nil
155         }
156
157         return ciphersmap
158 }