JSON-RPC over TLS socket

930 views
Skip to first unread message

sma...@swiftlayer.com

unread,
Jul 28, 2010, 4:14:39 PM7/28/10
to golang-nuts
Hello,

I am new to GO, we wanted to implement JSON-RPC over a TLS socket so
authentication can be securely transmitted, this could be for many
applications remote server control etc.

We examined the JSON-RPC server/client but did not see any TLS
mechanism in place, we also found the TLS Package which we thought we
could combine for this purpose. I wanted to get your thoughts on
whether this is the right approach for remote systems administration,
or if there is better already implemented solutions for this type of
thing.



--Stephen

Cory Mainwaring

unread,
Jul 28, 2010, 4:26:59 PM7/28/10
to sma...@swiftlayer.com, golang-nuts
Nope, I'm pretty sure TLS + JSON-RPC packages are the way for you to go. TLS has had some issues that you may want to look into (just search "tls" on the mailing list)

sma...@swiftlayer.com

unread,
Jul 29, 2010, 8:55:44 PM7/29/10
to golang-nuts
I got this working... Does anyone know who to contact or what I have
to do to have this function implemented into the trunk as
jsonrpc.ListenTLS() and below is the client for jsonrpc.DialTLS()

Server:

config := &tls.Config{
Rand: rand.Reader,
Time: time.Nanoseconds,
}

var err os.Error
config.Certificates = make([]tls.Certificate, 1)
config.Certificates[0], err = tls.LoadX509KeyPair(SERVER_CERT,
SERVER_KEY)
if err != nil {
fmt.Printf("Certificates: ", err.String())
}

l, e := tls.Listen("tcp", ":" + SERVER_PORT, config);
if e != nil {
fmt.Printf("Listen error : ", e);
}
defer l.Close()

for {
conn, _ := l.Accept()
jsonrpc.ServeConn(conn)
}



Client jsonrpc.DialTLS :

conn, err := tls.Dial("tcp", "", SERVER_IP + ":" + RPC_PORT)
if err != nil {
log.Exit("dialing:", err)
}

defer conn.Close()
client := jsonrpc.NewClient(conn)

sma...@swiftlayer.com

unread,
Jul 29, 2010, 8:57:51 PM7/29/10
to golang-nuts
Here is the non TLS version of it as well jsonrpc.Listen()

l, e := net.Listen("tcp", ":" + SERVER_PORT);

Alexander Surma

unread,
Jul 30, 2010, 7:03:21 AM7/30/10
to golan...@googlegroups.com
> for {
> conn, _ := l.Accept()
> jsonrpc.ServeConn(conn)
> }
>
I couldn't help but notice that you copied that passage verbatim. This
loop *never* exits. Even if there is some error. So maybe you should
catch the error (right now that's the _) and use it as a condition for
the loop. And if this is going to be in a library, I don't think putting
the loop in there is very go-like (though I don't really know). The rpc
package doesn't even have rpc.Listen(), just rpc.HandleHTTP().

Surma

PS: Sorry I couldn't help with the actual problem

Stephen Major

unread,
Jul 30, 2010, 3:27:13 PM7/30/10
to Alexander Surma, golan...@googlegroups.com
Hmm,


I guess you are right, I had followed suit with the http package... they
have built in Listen and serve calls for TLS which is essentially what I was
working on.

Is there another way to bind to this without a loop? I guess this is why I
got stuck here is I don't fully grasp how or why we need to use ServeConn in
this manner.

Alexander Surma

unread,
Jul 30, 2010, 3:42:09 PM7/30/10
to Stephen Major, Alexander Surma, golan...@googlegroups.com
In my book, the looping is the programmer's concern, not the library's.

Surma

Stephen Major

unread,
Jul 30, 2010, 4:50:04 PM7/30/10
to Alexander Surma, golan...@googlegroups.com
I did find in the base rpc package that the rpc.Accept does handle the
looping but this same implementation is not found in the jsonrpc package:

// Accept accepts connections on the listener and serves requests
// for each incoming connection. Accept blocks; the caller typically
// invokes it in a go statement.
func Accept(lis net.Listener) { server.accept(lis) }


func (server *serverType) accept(lis net.Listener) {
for {
conn, err := lis.Accept()
if err != nil {
log.Exit("rpc.Serve: accept:", err.String()) // TODO(r): exit?
}
go ServeConn(conn)
}
}

-----Original Message-----
From: Alexander Surma [mailto:alexand...@googlemail.com]
Sent: Friday, July 30, 2010 12:42 PM
To: Stephen Major
Cc: 'Alexander Surma'; golan...@googlegroups.com
Subject: Re: [go-nuts] Re: JSON-RPC over TLS socket

Alexander Surma

unread,
Jul 30, 2010, 4:53:20 PM7/30/10
to Stephen Major, golang-nuts
The loop is there, so that more than one client can connect. You could
leave it out, but than only one (i.e. the first) client could connect.

You don't have to loop with the standard rpc because the rpc package has
a *convenience function*. That is, it does the looping, the accepting of
the connection request, creating the codec (gob) and handling the rpc
request. jsonrpc does not have those convenience functions, which is why
you have to do all that on your on.
Maybe take a look at the rpc package source code in $GOROOT/src/pkg/rpc

Surma

On 7/30/10 22:35 , Stephen Major wrote:
> I didn't mean the looping being the libraries concern...
>
>
> The concern that I was addressing is an easy way for developers to implement
> a json-rpc server that is listening on a TLS socket, much like the http
> package has ListenandServeTLS
>
>
> I am still confused as to why we have to loop there to bind jsonrpc to the
> connection, we don't have to loop to bind standard rpc to the connection.
>
> Forgive me I come from a php shell scripting background and this is my first
> GO project, I am just having trouble understanding how the jsonrpc.ServeConn
> works and as to why we have to loop to bind it to the connection.
>
>
> --Stephen


>
> -----Original Message-----
> From: Alexander Surma [mailto:alexand...@googlemail.com]
> Sent: Friday, July 30, 2010 12:42 PM
> To: Stephen Major

> Cc: 'Alexander Surma'; golan...@googlegroups.com
> Subject: Re: [go-nuts] Re: JSON-RPC over TLS socket
>

Reply all
Reply to author
Forward
0 new messages