-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcwmpd
executable file
·178 lines (157 loc) · 6.25 KB
/
cwmpd
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
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
#!/usr/bin/env python
# Copyright 2011 Google Inc. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# TR-069 has mandatory attribute names that don't comply with policy
# pylint:disable=invalid-name
#
"""The main server process for our TR-069 CPE device."""
__author__ = '[email protected] (Avery Pennarun)'
# this needs to be first, before any tornado imports
import tr.epoll_fix # pylint:disable=g-bad-import-order
import errno
import os.path
import sys
import google3
import bup.options
import diagui.main
import dm_root
import factory
import tr.acs_config
import tr.api
import tr.cwmptypes
import tr.filenotifier
import tr.handle
import tr.http
import tr.mainloop
import tr.rcommand
optspec = """
cwmpd [options]
--
r,rcmd-port= TCP port to listen for rcommands on; 0 to disable [12999]
u,unix-path= Unix socket to listen on [/tmp/cwmpd.sock]
i,ip= IP address to report to ACS. (default=finds interface IP address)
l,listenip= IP address to listen on [::1]
p,port= TCP port to listen for TR-069 on [7547]
ping-path= Force CPE ping listener to this URL path (default=random)
acs-url= URL of the TR-069 ACS server to connect to
fake-acs Run a fake ACS (and auto-set --acs-url to that)
no-cpe Don't run a CPE (and thus never connect to ACS)
cpe-listener Let CPE listen for http requests (not TR-069 compliant)
platform= Activate the platform-specific device tree (see platform/ dir)
ext-dir= Activate any extension modules in this dir [%(ext_dir)s]
close-stdio Close stdout after listeners are running; exit when stdin closes
ca-certs= SSL ca_certificates.crt file to use
client-cert= SSL client certificate to use
client-key= SSL client private key to use
restrict-acs-hosts= Domain names allowed for ACS URL. Default=unrestricted. Example: 'google.com gfsvc.com'
diagui Listen for diagui requests on diagui-port
diagui-port= Port to listen on (0=random) [80]
techui Also handle TechUI requests on the diagui-port
licenseui Listen for license requests on the diagui-port
factory Listen for factory requests on factory-port
factory-port= Port to listen on (0=random) [8883]
"""
def _GotData(loop, fd, unused_flags):
if not os.read(fd, 1024):
loop.ioloop.stop()
def main():
try:
os.mkdir(tr.acs_config.CWMP_TMP_DIR)
except OSError, e:
if e.errno == errno.EEXIST:
pass
else:
raise
cwmpdir = os.path.dirname(os.path.abspath(sys.argv[0]))
defargs = dict(ext_dir=os.environ.get('CWMPD_EXT_DIR', cwmpdir + '/ext'))
o = bup.options.Options(optspec % defargs)
(opt, unused_flags, unused_extra) = o.parse(sys.argv[1:])
if not opt.platform:
o.fatal('You must specify a --platform')
loop = tr.mainloop.MainLoop()
root = dm_root.DeviceModelRoot(loop, opt.platform, opt.ext_dir)
root.add_cwmp_extensions()
handle = root.handle
notifier = tr.filenotifier.FileNotifier(loop)
tr.cwmptypes.SetFileBackedNotifier(notifier)
acs = cpe = None
if opt.fake_acs:
if not opt.port:
o.fatal("Can't use --fake-acs without --port")
acs = tr.api.ACS()
if not opt.acs_url:
opt.acs_url = 'http://localhost:%d/acs' % opt.port
if opt.cpe:
cpe = tr.api.CPE(handle)
if not opt.cpe_listener:
print 'CPE API is client mode only.'
if cpe:
# Arguments to pass to Tornado HTTPClient.fetch
fetch_args = {'user_agent': 'catawampus-tr69'}
if opt.ca_certs:
fetch_args['ca_certs'] = opt.ca_certs
fetch_args['validate_cert'] = True
if opt.client_cert and opt.client_key:
fetch_args['client_cert'] = opt.client_cert
fetch_args['client_key'] = opt.client_key
pc = root.get_platform_config(ioloop=loop.ioloop)
cpe.download_manager.SetDirectories(config_dir=pc.ConfigDir(),
download_dir=pc.DownloadDir())
cpe_machine = tr.http.Listen(ip=opt.ip, port=opt.port,
ping_path=opt.ping_path,
acs=acs, cpe=cpe,
restrict_acs_hosts=opt.restrict_acs_hosts,
cpe_listener=opt.cpe_listener,
acs_config=tr.acs_config.AcsConfig(),
acs_url=opt.acs_url,
fetch_args=fetch_args)
ms = cpe_machine.GetManagementServer()
root.add_management_server(ms)
root.configure_tr157(cpe_machine)
else:
cpe_machine = None
if opt.rcmd_port:
loop.ListenInet((opt.listenip, opt.rcmd_port),
tr.rcommand.MakeRemoteCommandStreamer(handle, cpe_machine))
if opt.unix_path:
loop.ListenUnix(opt.unix_path,
tr.rcommand.MakeRemoteCommandStreamer(handle, cpe_machine))
if opt.diagui or opt.licenseui:
inst = diagui.main.MainApplication(root, cpe_machine,
run_diagui=opt.diagui,
run_techui=opt.techui,
run_licenseui=opt.licenseui)
print 'Listening for diagui on port %d' % (opt.diagui_port,)
inst.listen(opt.diagui_port)
if opt.factory:
print 'Listening for factoryui on port %d' % (opt.factory_port,)
inst = factory.FactoryFactory()
inst.listen(opt.factory_port)
if cpe_machine:
cpe_machine.Startup()
if opt.close_stdio:
nullf = open('/dev/null', 'w+')
os.dup2(nullf.fileno(), 1)
nullf.close()
loop.ioloop.add_handler(sys.stdin.fileno(),
lambda *args: _GotData(loop, *args),
loop.ioloop.READ)
loop.Start()
if __name__ == '__main__':
sys.stdout.flush()
sys.stdout = os.fdopen(1, 'w', 1) # force line buffering even if redirected
sys.stderr.flush()
sys.stderr = os.fdopen(2, 'w', 1) # force line buffering even if redirected
print
main()