storj.io/minio@v0.0.0-20230509071714-0cbc90f649b1/pkg/bucket/policy/condition/ipaddressfunc.go (about) 1 /* 2 * MinIO Cloud Storage, (C) 2018 MinIO, Inc. 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 condition 18 19 import ( 20 "fmt" 21 "net" 22 "net/http" 23 "sort" 24 ) 25 26 func toIPAddressFuncString(n name, key Key, values []*net.IPNet) string { 27 valueStrings := []string{} 28 for _, value := range values { 29 valueStrings = append(valueStrings, value.String()) 30 } 31 sort.Strings(valueStrings) 32 33 return fmt.Sprintf("%v:%v:%v", n, key, valueStrings) 34 } 35 36 // ipAddressFunc - IP address function. It checks whether value by Key in given 37 // values is in IP network. Here Key must be AWSSourceIP. 38 // For example, 39 // - if values = [192.168.1.0/24], at evaluate() it returns whether IP address 40 // in value map for AWSSourceIP falls in the network 192.168.1.10/24. 41 type ipAddressFunc struct { 42 k Key 43 values []*net.IPNet 44 } 45 46 // evaluate() - evaluates to check whether IP address in values map for AWSSourceIP 47 // falls in one of network or not. 48 func (f ipAddressFunc) evaluate(values map[string][]string) bool { 49 IPs := []net.IP{} 50 requestValue, ok := values[http.CanonicalHeaderKey(f.k.Name())] 51 if !ok { 52 requestValue = values[f.k.Name()] 53 } 54 55 for _, s := range requestValue { 56 IP := net.ParseIP(s) 57 if IP == nil { 58 panic(fmt.Errorf("invalid IP address '%v'", s)) 59 } 60 61 IPs = append(IPs, IP) 62 } 63 64 for _, IP := range IPs { 65 for _, IPNet := range f.values { 66 if IPNet.Contains(IP) { 67 return true 68 } 69 } 70 } 71 72 return false 73 } 74 75 // key() - returns condition key which is used by this condition function. 76 // Key is always AWSSourceIP. 77 func (f ipAddressFunc) key() Key { 78 return f.k 79 } 80 81 // name() - returns "IpAddress" condition name. 82 func (f ipAddressFunc) name() name { 83 return ipAddress 84 } 85 86 func (f ipAddressFunc) String() string { 87 return toIPAddressFuncString(ipAddress, f.k, f.values) 88 } 89 90 // toMap - returns map representation of this function. 91 func (f ipAddressFunc) toMap() map[Key]ValueSet { 92 if !f.k.IsValid() { 93 return nil 94 } 95 96 values := NewValueSet() 97 for _, value := range f.values { 98 values.Add(NewStringValue(value.String())) 99 } 100 101 return map[Key]ValueSet{ 102 f.k: values, 103 } 104 } 105 106 // notIPAddressFunc - Not IP address function. It checks whether value by Key in given 107 // values is NOT in IP network. Here Key must be AWSSourceIP. 108 // For example, 109 // - if values = [192.168.1.0/24], at evaluate() it returns whether IP address 110 // in value map for AWSSourceIP does not fall in the network 192.168.1.10/24. 111 type notIPAddressFunc struct { 112 ipAddressFunc 113 } 114 115 // evaluate() - evaluates to check whether IP address in values map for AWSSourceIP 116 // does not fall in one of network. 117 func (f notIPAddressFunc) evaluate(values map[string][]string) bool { 118 return !f.ipAddressFunc.evaluate(values) 119 } 120 121 // name() - returns "NotIpAddress" condition name. 122 func (f notIPAddressFunc) name() name { 123 return notIPAddress 124 } 125 126 func (f notIPAddressFunc) String() string { 127 return toIPAddressFuncString(notIPAddress, f.ipAddressFunc.k, f.ipAddressFunc.values) 128 } 129 130 func valuesToIPNets(n name, values ValueSet) ([]*net.IPNet, error) { 131 IPNets := []*net.IPNet{} 132 for v := range values { 133 s, err := v.GetString() 134 if err != nil { 135 return nil, fmt.Errorf("value %v must be string representation of CIDR for %v condition", v, n) 136 } 137 138 var IPNet *net.IPNet 139 _, IPNet, err = net.ParseCIDR(s) 140 if err != nil { 141 return nil, fmt.Errorf("value %v must be CIDR string for %v condition", s, n) 142 } 143 144 IPNets = append(IPNets, IPNet) 145 } 146 147 return IPNets, nil 148 } 149 150 // newIPAddressFunc - returns new IP address function. 151 func newIPAddressFunc(key Key, values ValueSet) (Function, error) { 152 IPNets, err := valuesToIPNets(ipAddress, values) 153 if err != nil { 154 return nil, err 155 } 156 157 return NewIPAddressFunc(key, IPNets...) 158 } 159 160 // NewIPAddressFunc - returns new IP address function. 161 func NewIPAddressFunc(key Key, IPNets ...*net.IPNet) (Function, error) { 162 if key != AWSSourceIP { 163 return nil, fmt.Errorf("only %v key is allowed for %v condition", AWSSourceIP, ipAddress) 164 } 165 166 return &ipAddressFunc{key, IPNets}, nil 167 } 168 169 // newNotIPAddressFunc - returns new Not IP address function. 170 func newNotIPAddressFunc(key Key, values ValueSet) (Function, error) { 171 IPNets, err := valuesToIPNets(notIPAddress, values) 172 if err != nil { 173 return nil, err 174 } 175 176 return NewNotIPAddressFunc(key, IPNets...) 177 } 178 179 // NewNotIPAddressFunc - returns new Not IP address function. 180 func NewNotIPAddressFunc(key Key, IPNets ...*net.IPNet) (Function, error) { 181 if key != AWSSourceIP { 182 return nil, fmt.Errorf("only %v key is allowed for %v condition", AWSSourceIP, notIPAddress) 183 } 184 185 return ¬IPAddressFunc{ipAddressFunc{key, IPNets}}, nil 186 }