1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
|
# Copyright (c) 2001-2004 Twisted Matrix Laboratories.
# See LICENSE for details.
#
"""
Twisted inetd TAP support
Maintainer: U{Andrew Bennetts<mailto:spiv@twistedmatrix.com>}
Future Plans: more configurability.
"""
import os, pwd, grp, socket
from twisted.runner import inetd, inetdconf
from twisted.python import log, usage
from twisted.internet.protocol import ServerFactory
from twisted.application import internet, service as appservice
try:
import portmap
rpcOk = 1
except ImportError:
rpcOk = 0
# Protocol map
protocolDict = {'tcp': socket.IPPROTO_TCP, 'udp': socket.IPPROTO_UDP}
class Options(usage.Options):
optParameters = [
['rpc', 'r', '/etc/rpc', 'RPC procedure table file'],
['file', 'f', '/etc/inetd.conf', 'Service configuration file']
]
optFlags = [['nointernal', 'i', "Don't run internal services"]]
zsh_actions = {"file" : "_files -g '*.conf'"}
class RPCServer(internet.TCPServer):
def __init__(self, rpcVersions, rpcConf, proto, service):
internet.TCPServer.__init__(0, ServerFactory())
self.rpcConf = rpcConf
self.proto = proto
self.service = service
def startService(self):
internet.TCPServer.startService(self)
import portmap
portNo = self._port.getHost()[2]
service = self.service
for version in rpcVersions:
portmap.set(self.rpcConf.services[name], version, self.proto,
portNo)
inetd.forkPassingFD(service.program, service.programArgs,
os.environ, service.user, service.group, p)
def makeService(config):
s = appservice.MultiService()
conf = inetdconf.InetdConf()
conf.parseFile(open(config['file']))
rpcConf = inetdconf.RPCServicesConf()
try:
rpcConf.parseFile(open(config['rpc']))
except:
# We'll survive even if we can't read /etc/rpc
log.deferr()
for service in conf.services:
rpc = service.protocol.startswith('rpc/')
protocol = service.protocol
if rpc and not rpcOk:
log.msg('Skipping rpc service due to lack of rpc support')
continue
if rpc:
# RPC has extra options, so extract that
protocol = protocol[4:] # trim 'rpc/'
if not protocolDict.has_key(protocol):
log.msg('Bad protocol: ' + protocol)
continue
try:
name, rpcVersions = service.name.split('/')
except ValueError:
log.msg('Bad RPC service/version: ' + service.name)
continue
if not rpcConf.services.has_key(name):
log.msg('Unknown RPC service: ' + repr(service.name))
continue
try:
if '-' in rpcVersions:
start, end = map(int, rpcVersions.split('-'))
rpcVersions = range(start, end+1)
else:
rpcVersions = [int(rpcVersions)]
except ValueError:
log.msg('Bad RPC versions: ' + str(rpcVersions))
continue
if (protocol, service.socketType) not in [('tcp', 'stream'),
('udp', 'dgram')]:
log.msg('Skipping unsupported type/protocol: %s/%s'
% (service.socketType, service.protocol))
continue
# Convert the username into a uid (if necessary)
try:
service.user = int(service.user)
except ValueError:
try:
service.user = pwd.getpwnam(service.user)[2]
except KeyError:
log.msg('Unknown user: ' + service.user)
continue
# Convert the group name into a gid (if necessary)
if service.group is None:
# If no group was specified, use the user's primary group
service.group = pwd.getpwuid(service.user)[3]
else:
try:
service.group = int(service.group)
except ValueError:
try:
service.group = grp.getgrnam(service.group)[2]
except KeyError:
log.msg('Unknown group: ' + service.group)
continue
if service.program == 'internal':
if config['nointernal']:
continue
# Internal services can use a standard ServerFactory
if not inetd.internalProtocols.has_key(service.name):
log.msg('Unknown internal service: ' + service.name)
continue
factory = ServerFactory()
factory.protocol = inetd.internalProtocols[service.name]
elif rpc:
i = RPCServer(rpcVersions, rpcConf, proto, service)
i.setServiceParent(s)
continue
else:
# Non-internal non-rpc services use InetdFactory
factory = inetd.InetdFactory(service)
if protocol == 'tcp':
internet.TCPServer(service.port, factory).setServiceParent(s)
elif protocol == 'udp':
raise RuntimeError("not supporting UDP")
return s
|