From 8d21674ced97124bed8af6d58c766ceb62bdba8a Mon Sep 17 00:00:00 2001 From: Jarrod Johnson Date: Mon, 14 Oct 2013 09:21:55 -0400 Subject: [PATCH] Implement unix domain socket in socket api --- bin/confetty | 13 ++++++++++++- confluent/sockapi.py | 31 +++++++++++++++++++++++++++---- 2 files changed, 39 insertions(+), 5 deletions(-) diff --git a/bin/confetty b/bin/confetty index 69c05e37..ff796ca3 100755 --- a/bin/confetty +++ b/bin/confetty @@ -34,6 +34,7 @@ import sys import termios import tty +SO_PASSCRED = 16 conserversequence = '\x05c' # ctrl-e, c oldtcattr = termios.tcgetattr(sys.stdin.fileno()) @@ -90,9 +91,17 @@ def check_escape_seq(input, fh): return input +def connect_unix_server(sockpath): + server = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) + server.setsockopt(socket.SOL_SOCKET, SO_PASSCRED, 1) + server.connect(sockpath) + return server + + def connect_tls_server(serverstring): host, port = parseservervalue(serverstring) - for res in socket.getaddrinfo(host, port, socket.AF_UNSPEC, socket.SOCK_STREAM): + for res in socket.getaddrinfo(host, port, socket.AF_UNSPEC, + socket.SOCK_STREAM): af, socktype, proto, cononname, sa = res try: server = socket.socket(af, socktype, proto) @@ -121,6 +130,8 @@ parser.add_option("-u", "--unixsocket", dest="unixsock", opts, args = parser.parse_args() if opts.server: # going over a TLS network server = connect_tls_server(opts.server) +elif opts.unixsock: + server = connect_unix_server(opts.unixsock) #Next stop, reading and writing from whichever of stdin and server goes first. #see pyghmi code for solconnect.py diff --git a/confluent/sockapi.py b/confluent/sockapi.py index 0411ae3c..134ec6b6 100644 --- a/confluent/sockapi.py +++ b/confluent/sockapi.py @@ -10,22 +10,26 @@ import confluent.config as config import eventlet.green.socket as socket import eventlet.green.ssl as ssl import eventlet +import os +import struct + +SO_PEERCRED = 17 def sessionhdl(connection): #TODO: authenticate and authorize peer # For now, trying to test the console stuff, so let's just do n1. cfm = config.ConfigManager(tenant=0) consession = console.ConsoleSession(node='n1', configmanager=cfm, - datacallback=connection.write) + datacallback=connection.sendall) while (1): - data = connection.read() + data = connection.recv(4096) if not data: consession.destroy() return consession.write(data) -def _handler(): +def _tlshandler(): plainsocket = socket.socket() plainsocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) srv = ssl.wrap_socket(plainsocket, keyfile="/etc/confluent/privkey.pem", @@ -38,6 +42,25 @@ def _handler(): cnn, addr = srv.accept() eventlet.spawn_n(sessionhdl, cnn) + +def _unixdomainhandler(): + unixsocket = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) + try: + os.remove("/var/run/confluent/api.sock") + except OSError: # if file does not exist, no big deal + pass + unixsocket.bind("/var/run/confluent/api.sock") + unixsocket.listen(5) + while (1): + cnn, addr = unixsocket.accept() + creds = cnn.getsockopt(socket.SOL_SOCKET, SO_PEERCRED, + struct.calcsize('3i')) + print struct.unpack('3i',creds) + eventlet.spawn_n(sessionhdl, cnn) + + + class SockApi(object): def start(self): - self.server = eventlet.spawn(_handler) + self.tlsserver = eventlet.spawn(_tlshandler) + self.unixdomainserver = eventlet.spawn(_unixdomainhandler)