Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Publish API: "json: cannot unmarshal array into Go struct field .Signing of type api.SigningOptions" #1266

Open
mkasimd opened this issue Apr 11, 2024 · 3 comments

Comments

@mkasimd
Copy link

mkasimd commented Apr 11, 2024

When using an encrypted PGP key and delivering the passphrase, publishing fails with HTTP status code 400 and the response body {"error":"json: cannot unmarshal array into Go struct field .Signing of type api.SigningOptions"}

Detailed Description

When using a GPG key that was generated with a passphrase, publishing a repo via API fails (cropped output):

$ curl -X POST -H 'Content-Type: application/json' --data '{"SourceKind": "local", "Sources": [{"Name": "test-repo"}], "Architectures": ["i386", "amd64"], "Signing": [{"Skip": false, "Passphrase": "123456"}], "Distribution": "bookworm"}' http://localhost:8080/api/publish/:. -v
* Connected to localhost (127.0.0.1) port 8080
> POST /api/publish/:. HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/8.6.0
> Accept: */*
> Content-Type: application/json
> Content-Length: 176
> 
< HTTP/1.1 400 Bad Request
< Date: Thu, 11 Apr 2024 14:08:36 GMT
< Content-Length: 97
< Content-Type: text/plain; charset=utf-8
< 
* Connection #0 to host localhost left intact
{"error":"json: cannot unmarshal array into Go struct field .Signing of type api.SigningOptions"}

This seems to be related to: json - cannot unmarshal array into Go struct when decoding array| StackOverflow

Context

Storing private keys in an encrypted manner is a security feature, I'd like to keep. As the aptly API can be made accessible TLS-encrypted behind a reverse proxy, delivering the passphrase in cleartext to the aptly API endpoint isn't a security risk either.

Possible Implementation

In api/publish.go:102, changing Signing SigningOptions to Signing []SigningOptions could solve it, if it's related to above mentioned StackOverflow issue (I haven't tested it)

Your Environment

Docker with Dockerfile (excerpt):

FROM debian:bookworm

RUN apt-get update && \
    apt-get install -y\
      ca-certificates \
      gnupg2 curl procps \
      graphviz && \
    curl -fSSL https://www.aptly.info/pubkey.txt | gpg --dearmor -o /usr/share/keyrings/aptly.gpg && \
    echo "deb [arch=amd64,arm64 signed-by=/usr/share/keyrings/aptly.gpg] http://repo.aptly.info/ squeeze main" | tee /etc/apt/sources.list.d/aptly.list && \ 
    apt-get update && apt-get install -y aptly
$ curl http://localhost:8080/api/version                                                                                                                                 ✔ 
{"Version":"1.5.0+ds1-1+b4"}
@neolynx
Copy link
Member

neolynx commented Apr 17, 2024

what is the reason for adding the array ?

in our api calls we just pass a dict:
$ curl -X POST -H 'Content-Type: application/json' --data '{"SourceKind": "local", "Sources": [{"Name": "test-repo"}], "Architectures": ["i386", "amd64"], "Signing": {"Skip": false, "Passphrase": "123456"}, "Distribution": "bookworm"}' http://localhost:8080/api/publish/:. -v

could you try this ?

@mkasimd
Copy link
Author

mkasimd commented Apr 18, 2024

That one didn't work for me either unfortunately. Up until now, I have succeeded with unencrypted PGP keys. It's also unusual that it returns 202 Accepted for almost any input. So I'd have to list items through a GET request to see if it was actually successful or not

$ curl http://localhost:8080/api/repos
[{"Name":"test-repo","Comment":"","DefaultDistribution":"","DefaultComponent":""}]

$ curl -X POST -H 'Content-Type: application/json' --data '{"SourceKind": "local", "Sources": [{"Name": "test-repo"}], "Architectures": ["i386", "amd64"], "Signing": {"Skip": false, "Passphrase": "hello"}, "Distribution": "bookworm"}' http://localhost:8080/api/publish/:. -v
* Connected to localhost (127.0.0.1) port 8080
> POST /api/publish/:. HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/8.6.0
> Accept: */*
> Content-Type: application/json
> Content-Length: 174
> 
< HTTP/1.1 202 Accepted
< Content-Type: application/json; charset=utf-8
< Date: Thu, 18 Apr 2024 07:28:52 GMT
< Content-Length: 52
< 
* Connection #0 to host localhost left intact
{"Name":"Publish local: test-repo","ID":1,"State":0}

$ curl http://localhost:8080/api/publish 
[]

In the Logs of aptly:

[GIN] 2024/04/18 - 07:28:52 | 202 |    9.624038ms |      172.17.0.1 | POST     "/api/publish/:."
Signing file 'Release' with gpg, please enter your passphrase when prompted:
gpg: signing failed: No such file or directory
gpg: signing failed: No such file or directory

@neolynx
Copy link
Member

neolynx commented Apr 20, 2024

looks like the keyring is not found. where is it stored ?

we are using something similar to this:

curl -fsS -X PUT -H 'Content-Type: application/json' --data \
        '{"AcquireByHash": true, "Snapshots": [{"Component": "main", "Name": "snapshot1"}],
          "Signing": {"Batch": true, "Keyring": "trustedkeys.gpg", "Passphrase": "hello"}}' \
        http://localhost:8080/api/publish/pub1

this uses ~/.gnupg/trustedkeys.gpg, also the batch argument is important for running gpg.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants