Created
March 31, 2021 22:11
-
-
Save nishakm/f520780bcb19ff4d33f89d4dda0d762d to your computer and use it in GitHub Desktop.
Fetch manifest from registry
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"encoding/json" | |
"io/ioutil" | |
"log" | |
"net/http" | |
"net/url" | |
"strings" | |
) | |
func main() { | |
// This is the target we want to get from | |
var target string = "https://bundle.bar/v2/u/nishakm/sboms/debian/manifests/bullseye" | |
// these are basic auth creds | |
var usrname string = "yourusername" | |
var pswd string = "yourpassword" | |
// these are accept headers the registry needs | |
accept := []string{"application/vnd.docker.distribution.manifest.v1+json", | |
"application/vnd.docker.distribution.manifest.v1+prettyjws", | |
"application/vnd.docker.distribution.manifest.v2+json", | |
"application/vnd.oci.image.manifest.v1+json", | |
"application/vnd.docker.distribution.manifest.list.v2+json", | |
"application/vnd.oci.image.index.v1+json"} | |
acceptStr := strings.Join(accept, ",") | |
// First poke the url in the normal way | |
// 1. create a get request | |
req, err := http.NewRequest("GET", target, nil) | |
printerr(err) | |
req.SetBasicAuth(usrname, pswd) | |
req.Header.Set("Accept", acceptStr) | |
// make a client for this request | |
client := &http.Client{} | |
resp, err := client.Do(req) | |
printerr(err) | |
defer resp.Body.Close() | |
// the response headers will give a 401 with information on where to get | |
// an auth token | |
for k, v := range resp.Header { | |
log.Print(k) | |
log.Print(" : ") | |
log.Println(v) | |
} | |
// we extract some of the parameters required to get a token | |
authenticate := resp.Header.Get("Www-Authenticate") | |
bearer_things := strings.Split(authenticate, " ") | |
key_val_list := strings.Split(bearer_things[1], ",") | |
key_vals := make(map[string]string) | |
for in := range key_val_list { | |
k := strings.Split(key_val_list[in], "=") | |
key_vals[k[0]] = k[1] | |
} | |
// make a request with parameters | |
params := url.Values{} | |
params.Add("service", key_vals["service"]) | |
params.Add("scope", key_vals["scope"]) | |
tokenreq, err := http.NewRequest("GET", "https://bundle.bar/auth/token", | |
strings.NewReader(params.Encode())) | |
printerr(err) | |
// make the request with the client | |
tokenresp, err := client.Do(tokenreq) | |
printerr(err) | |
defer tokenresp.Body.Close() | |
// read the access token | |
body, err := ioutil.ReadAll(tokenresp.Body) | |
printerr(err) | |
// it's a json byte string | |
// we need to decode it | |
var receiver interface{} | |
uerr := json.Unmarshal(body, &receiver) | |
printerr(uerr) | |
content := receiver.(map[string]interface{}) | |
bcont := "Bearer " + content["access_token"].(string) | |
// now you can make a request to the real endpoint with | |
// the right headers | |
req.Header.Set("Authorization", bcont) | |
resp2, err := client.Do(req) | |
printerr(err) | |
defer resp2.Body.Close() | |
result, err := ioutil.ReadAll(resp2.Body) | |
printerr(err) | |
// should be a manifest | |
log.Println(string(result)) | |
// should be a manifest | |
log.Println(string(result)) | |
log.Println(resp.Status) | |
} | |
func printerr(e error) { | |
if e != nil { | |
log.Println("Error!") | |
log.Fatalln(e) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment