Skip to content

Commit 145e04a

Browse files
committed
Now contacting metadata API using privileged source ports (fix #174)
1 parent f6f3ccb commit 145e04a

File tree

1 file changed

+43
-3
lines changed

1 file changed

+43
-3
lines changed

pkg/api/api.go

Lines changed: 43 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,15 @@ import (
1313
"encoding/json"
1414
"fmt"
1515
"io/ioutil"
16+
"net"
1617
"net/http"
1718
"net/url"
1819
"os"
1920
"sort"
2021
"strings"
2122
"text/tabwriter"
2223
"text/template"
24+
"time"
2325

2426
log "github.com/scaleway/scaleway-cli/vendor/github.com/Sirupsen/logrus"
2527
"github.com/scaleway/scaleway-cli/vendor/github.com/moul/anonuuid"
@@ -56,9 +58,11 @@ type ScalewayAPI struct {
5658
// Cache is used to quickly resolve identifiers from names
5759
Cache *ScalewayCache
5860

59-
client *http.Client
60-
anonuuid anonuuid.AnonUUID
61-
isMetadata bool
61+
client *http.Client
62+
// Used when switching from an API to another
63+
oldTransport *http.RoundTripper
64+
anonuuid anonuuid.AnonUUID
65+
isMetadata bool
6266
}
6367

6468
// ScalewayAPIError represents a Scaleway API Error
@@ -1716,18 +1720,54 @@ func (s *ScalewayAPI) DisableAccountAPI() {
17161720
s.APIUrl = s.ComputeAPI
17171721
}
17181722

1723+
func rootNetDial(network, addr string) (net.Conn, error) {
1724+
dialer := net.Dialer{
1725+
Timeout: 10 * time.Second,
1726+
KeepAlive: 10 * time.Second,
1727+
}
1728+
1729+
// bruteforce privileged ports
1730+
var localAddr net.Addr
1731+
var err error
1732+
for port := 1; port <= 1024; port++ {
1733+
localAddr, err = net.ResolveTCPAddr("tcp", fmt.Sprintf(":%d", port))
1734+
1735+
// this should never happen
1736+
if err != nil {
1737+
return nil, err
1738+
}
1739+
1740+
dialer.LocalAddr = localAddr
1741+
1742+
conn, err := dialer.Dial(network, addr)
1743+
1744+
// if err is nil, dialer.Dial succeed, so let's go
1745+
// else, err != nil, but we don't care
1746+
if err == nil {
1747+
return conn, nil
1748+
}
1749+
}
1750+
// if here, all privileged ports were tried without success
1751+
return nil, fmt.Errorf("bind: permission denied, are you root ?")
1752+
}
1753+
17191754
// EnableMetadataAPI enable metadataAPI
17201755
func (s *ScalewayAPI) EnableMetadataAPI() {
17211756
s.APIUrl = MetadataAPI
17221757
if os.Getenv("SCW_METADATA_URL") != "" {
17231758
s.APIUrl = os.Getenv("SCW_METADATA_URL")
17241759
}
1760+
s.oldTransport = &s.client.Transport
1761+
s.client.Transport = &http.Transport{
1762+
Dial: rootNetDial,
1763+
}
17251764
s.isMetadata = true
17261765
}
17271766

17281767
// DisableMetadataAPI disable metadataAPI
17291768
func (s *ScalewayAPI) DisableMetadataAPI() {
17301769
s.APIUrl = s.ComputeAPI
1770+
s.client.Transport = *s.oldTransport
17311771
s.isMetadata = false
17321772
}
17331773

0 commit comments

Comments
 (0)