// Get executes an external program to get the credentials from a native store. func Get(program ProgramFunc, serverURL string) (*credentials.Credentials, error) { cmd := program("get") cmd.Input(strings.NewReader(serverURL)) out, err := cmd.Output() if err != nil { t := strings.TrimSpace(string(out)) if credentials.IsErrCredentialsNotFoundMessage(t) { return nil, credentials.NewErrCredentialsNotFound() } return nil, fmt.Errorf("error getting credentials - err: %v, out: `%s`", err, t) } resp := &credentials.Credentials{ ServerURL: serverURL, } if err := json.NewDecoder(bytes.NewReader(out)).Decode(resp); err != nil { return nil, err } return resp, nil }
// Get retrieves credentials from the windows credentials manager. func (h Wincred) Get(serverURL string) (string, string, error) { g, _ := winc.GetGenericCredential(serverURL) if g == nil { return "", "", credentials.NewErrCredentialsNotFound() } return g.UserName, string(g.CredentialBlob), nil }
// Get returns the username and secret to use for a given registry server URL. func (h Osxkeychain) Get(serverURL string) (string, string, error) { s, err := splitServer(serverURL) if err != nil { return "", "", err } defer freeServer(s) var usernameLen C.uint var username *C.char var secretLen C.uint var secret *C.char defer C.free(unsafe.Pointer(username)) defer C.free(unsafe.Pointer(secret)) errMsg := C.keychain_get(s, &usernameLen, &username, &secretLen, &secret) if errMsg != nil { defer C.free(unsafe.Pointer(errMsg)) goMsg := C.GoString(errMsg) if goMsg == errCredentialsNotFound { return "", "", credentials.NewErrCredentialsNotFound() } return "", "", errors.New(goMsg) } user := C.GoStringN(username, C.int(usernameLen)) pass := C.GoStringN(secret, C.int(secretLen)) return user, pass, nil }
// Output returns responses from the remote credentials helper. // It mocks those responses based in the input in the mock. func (m *mockProgram) Output() ([]byte, error) { in, err := ioutil.ReadAll(m.input) if err != nil { return nil, err } inS := string(in) switch m.arg { case "erase": switch inS { case validServerAddress: return nil, nil default: return []byte("program failed"), errProgramExited } case "get": switch inS { case validServerAddress: return []byte(`{"Username": "******", "Secret": "bar"}`), nil case validServerAddress2: return []byte(`{"Username": "******", "Secret": "abcd1234"}`), nil case missingCredsAddress: return []byte(credentials.NewErrCredentialsNotFound().Error()), errProgramExited case invalidServerAddress: return []byte("program failed"), errProgramExited } case "store": var c credentials.Credentials err := json.NewDecoder(strings.NewReader(inS)).Decode(&c) if err != nil { return []byte("error storing credentials"), errProgramExited } switch c.ServerURL { case validServerAddress: return nil, nil case validServerAddress2: return nil, nil default: return []byte("error storing credentials"), errProgramExited } case "list": return []byte(fmt.Sprintf(`{"%s": "%s"}`, validServerAddress, validUsername)), nil } return []byte(fmt.Sprintf("unknown argument %q with %q", m.arg, inS)), errProgramExited }
func TestGet(t *testing.T) { valid := []credentials.Credentials{ {validServerAddress, "foo", "bar"}, {validServerAddress2, "<token>", "abcd1234"}, } for _, v := range valid { c, err := Get(mockProgramFn, v.ServerURL) if err != nil { t.Fatal(err) } if c.Username != v.Username { t.Fatalf("expected username `%s`, got %s", v.Username, c.Username) } if c.Secret != v.Secret { t.Fatalf("expected secret `%s`, got %s", v.Secret, c.Secret) } } invalid := []struct { serverURL string err string }{ {missingCredsAddress, credentials.NewErrCredentialsNotFound().Error()}, {invalidServerAddress, "error getting credentials - err: exited 1, out: `program failed`"}, } for _, v := range invalid { _, err := Get(mockProgramFn, v.serverURL) if err == nil { t.Fatalf("Expected error for server %s, got nil", v.serverURL) } if err.Error() != v.err { t.Fatalf("Expected error `%s`, got `%v`", v.err, err) } } }
// Get returns the username and secret to use for a given registry server URL. func (h Secretservice) Get(serverURL string) (string, string, error) { if serverURL == "" { return "", "", errors.New("missing server url") } var username *C.char defer C.free(unsafe.Pointer(username)) var secret *C.char defer C.free(unsafe.Pointer(secret)) server := C.CString(serverURL) defer C.free(unsafe.Pointer(server)) err := C.get(server, &username, &secret) if err != nil { defer C.g_error_free(err) errMsg := (*C.char)(unsafe.Pointer(err.message)) return "", "", errors.New(C.GoString(errMsg)) } user := C.GoString(username) pass := C.GoString(secret) if pass == "" { return "", "", credentials.NewErrCredentialsNotFound() } return user, pass, nil }