goczmq icon indicating copy to clipboard operation
goczmq copied to clipboard

Can't get encrypted PUB/SUB working

Open miska opened this issue 4 years ago • 1 comments

Hi,

decided to play with ZeroMQ after some time and try Go at the same time, so probably doing something obviously wrong, but can't see it. I'm trying to get encrypted PUB/SUB working. I wrote basically two little bit extended examples. Code bellow. What is happening is that I'm not receiving messages. If I disable encryption (don't provide any cert) it works. If I change the socket type to PUSH/PULL while keeping encryption, it also works. I was hoping that I was not doing encryption properly (but PUSH/PULL works with it) or that I'm incorrectly subscribing (but works without encryption), but since I ruled both out, I'm lost now. Any ideas what might be wrong?

server

package main

import (
    "github.com/zeromq/goczmq"

    "log"
    "flag"
    "fmt"
    "runtime"
    "time"
)

func main() {
    var cert string
    var endpoint string
    var err error

    flag.StringVar(&cert, "cert", "", "Certificate to use")
    flag.StringVar(&endpoint, "endpoint", "tcp://127.0.0.1:7087", "Where to listen")
    flag.Parse()

    server := goczmq.NewSock(goczmq.Pub)
    monitor := goczmq.NewMonitor(server)
    monitor.Verbose()
    monitor.Listen("ALL")
    monitor.Start()

    //  Start authentication engine
    if(cert != "") {
        auth := goczmq.NewAuth()
        auth.Verbose()
        auth.Curve(goczmq.CurveAllowAny)

        //  Apply certificates
        serverKey, err := goczmq.NewCertFromFile(cert)
        checkErr(err)
        serverKey.Apply(server)
        server.SetOption(goczmq.SockSetCurveServer(1))
    }

    //  Create and connect client socket
    _, err = server.Bind(endpoint)
    checkErr(err)

    //  Start sending
    fmt.Println("Listening...")
    for {
        err := server.SendFrame([]byte("hello"), goczmq.FlagMore)
        checkErr(err)
        err = server.SendFrame([]byte("hello"), goczmq.FlagNone)
        checkErr(err)
        fmt.Print(">")
        time.Sleep(time.Second)
    }
}

func checkErr(err error) {
    if err != nil {
        log.SetFlags(0)
        _, filename, lineno, ok := runtime.Caller(1)
        if ok {
            log.Fatalf("%v:%v: %v", filename, lineno, err)
        } else {
            log.Fatalln(err)
        }
    }
}

client

package main

import (
    "github.com/zeromq/goczmq"

    "log"
    "fmt"
    "runtime"
    "flag"
    "time"
)

func main() {
    var cert string
    var endpoint string

    flag.StringVar(&cert, "cert", "", "Certificate to use")
    flag.StringVar(&endpoint, "endpoint", "tcp://127.0.0.1:7087", "Where to listen")
    flag.Parse()

    client := goczmq.NewSock(goczmq.Sub)
    monitor := goczmq.NewMonitor(client)
    monitor.Verbose()
    monitor.Listen("ALL")
    monitor.Start()

    //  Start authentication engine
    if(cert != "") {
        auth := goczmq.NewAuth()
        auth.Verbose()
        auth.Curve(goczmq.CurveAllowAny)


        //  Apply certificates
        serverKey, err := goczmq.NewCertFromFile(cert)
        checkErr(err)
        clientCert := goczmq.NewCert()
        clientCert.Apply(client)
        client.SetOption(goczmq.SockSetCurveServerkey(serverKey.PublicText()))
    }

    client.SetOption(goczmq.SockSetSubscribe(""))

    //  Connect client socket
    client.Connect(endpoint)

    //  Wait for a message
    for {
        msg, err := client.RecvMessage()
        if(err == nil) {
            fmt.Println("Got one")
            fmt.Println(msg[0])
        } else {
            fmt.Print("<")
            time.Sleep(time.Second)
        }
    }
}

func checkErr(err error) {
    if err != nil {
        log.SetFlags(0)
        _, filename, lineno, ok := runtime.Caller(1)
        if ok {
            log.Fatalf("%v:%v: %v", filename, lineno, err)
        } else {
            log.Fatalln(err)
        }
    }
}

Server logs

I: 20-03-29 17:47:51 zmonitor: API command=LISTEN
I: 20-03-29 17:47:51 zmonitor: - listening to event=ALL
I: 20-03-29 17:47:51 zmonitor: API command=START
I: 20-03-29 17:47:51 zauth: API command=CURVE
Listening...
>I: 20-03-29 17:47:51 zmonitor: LISTENING - tcp://127.0.0.1:7087
>>>>>>>>>>I: 20-03-29 17:48:01 zmonitor: ACCEPTED - tcp://127.0.0.1:7087
I: 20-03-29 17:48:01 zauth: ZAP request mechanism=CURVE ipaddress=127.0.0.1
I: 20-03-29 17:48:01 zauth: - allowed (CURVE allow any client)
I: 20-03-29 17:48:01 zauth: - ZAP reply status_code=200 status_text=OK
I: 20-03-29 17:48:01 zmonitor: HANDSHAKE_SUCCEEDED - tcp://127.0.0.1:7087
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

Client logs

I: 20-03-29 17:48:01 zmonitor: API command=LISTEN
I: 20-03-29 17:48:01 zmonitor: - listening to event=ALL
I: 20-03-29 17:48:01 zmonitor: API command=START
I: 20-03-29 17:48:01 zauth: API command=CURVE
I: 20-03-29 17:48:01 zmonitor: CONNECT_DELAYED - tcp://127.0.0.1:7087
I: 20-03-29 17:48:01 zmonitor: CONNECTED - tcp://127.0.0.1:7087
I: 20-03-29 17:48:01 zmonitor: HANDSHAKE_SUCCEEDED - tcp://127.0.0.1:7087

miska avatar Mar 29 '20 15:03 miska

I just tried your example scripts (removed the Monitor parts) and everything seems to work. Are you passing cert_secret to the server and cert to the client?

I'm on libzmq 4.3.2 and libsodium 1.0.18

erkki avatar May 29 '20 04:05 erkki