13
#include <arpa/inet.h>
14
#include <vdr/tools.h>
15
#include <vdr/menuitems.h>
16
#include <vdr/plugin.h>
27
m_serverSslPort( 8443 ),
31
m_screenshotInterval( 1000 ),
33
m_adminLogin("admin"),
35
m_lastwhatsonlistmode("detail"),
36
m_tntnetloglevel("INFO"),
41
m_streamdevPort(3000),
45
m_adminPasswordMD5 = "4:" + MD5Hash("live");
46
liveplugin = cPluginManager::GetPlugin("live");
49
bool Setup::ParseCommandLine( int argc, char* argv[] )
51
static struct option opts[] = {
52
{ "port", required_argument, NULL, 'p' },
53
{ "ip", required_argument, NULL, 'i' },
54
{ "log", required_argument, NULL, 'l' },
55
{ "epgimages", required_argument, NULL, 'e' },
57
{ "sslport", required_argument, NULL, 's' },
58
{ "cert", required_argument, NULL, 'c' },
63
int optchar, optind = 0;
64
while ( ( optchar = getopt_long( argc, argv, "p:i:l:e:s:c:", opts, &optind ) ) != -1 ) {
66
case 'p': m_serverPort = atoi( optarg ); break;
67
case 'i': m_serverIps.push_back( optarg ); break;
68
case 'l': m_tntnetloglevel = optarg; break;
69
case 'e': m_epgimagedir = optarg; break;
71
case 's': m_serverSslPort = atoi( optarg ); break;
72
case 'c': m_serverSslCert = optarg; break;
74
default: return false;
78
return CheckServerPort() &&
80
CheckServerSslPort() &&
85
char const* Setup::CommandLineHelp() const
87
if ( m_helpString.empty() ) {
88
ostringstream builder;
89
builder << " -p PORT, --port=PORT use PORT to listen for incoming connections\n"
90
" (default: " << m_serverPort << ")\n"
91
<< " -i IP, --ip=IP bind server only to specified IP, may appear\n"
93
" (default: 0.0.0.0)\n"
95
<< " -s PORT, --sslport=PORT use PORT to listen for incoming ssl connections\n"
96
" (default: " << m_serverSslPort << ")\n"
97
<< " -c CERT, --cert=CERT full path to a custom ssl certificate file\n"
99
<< " -l level, --log=level log level for tntnet (values: INFO, DEBUG,...)\n"
100
<< " -e <dir>, --epgimages=<dir> directory for epgimages\n";
101
m_helpString = builder.str();
103
return m_helpString.c_str();
106
bool Setup::ParseSetupEntry( char const* name, char const* value )
108
if ( strcmp( name, "LastChannel" ) == 0 ) m_lastChannel = atoi( value );
109
else if ( strcmp( name, "ScreenshotInterval" ) == 0 ) m_screenshotInterval = atoi( value );
110
else if ( strcmp( name, "UseAuth" ) == 0 ) m_useAuth = atoi( value );
111
else if ( strcmp( name, "AdminLogin" ) == 0 ) m_adminLogin = value;
112
else if ( strcmp( name, "AdminPasswordMD5" ) == 0 ) m_adminPasswordMD5 = value;
113
else if ( strcmp( name, "UserdefTimes" ) == 0 ) m_times = value;
114
else if ( strcmp( name, "StartPage" ) == 0 ) m_startscreen = value;
115
else if ( strcmp( name, "Theme" ) == 0 ) m_theme = value;
116
else if ( strcmp( name, "LocalNetMask" ) == 0 ) { m_localnetmask = value; }
117
else if ( strcmp( name, "LastWhatsOnListMode" ) == 0 ) { m_lastwhatsonlistmode = value; }
118
else if ( strcmp( name, "ShowLogo" ) == 0 ) { m_showLogo = atoi(value); }
119
else if ( strcmp( name, "UseAjax" ) == 0 ) { m_useAjax = atoi(value); }
120
else if ( strcmp( name, "ShowInfoBox" ) == 0 ) { m_showInfoBox = atoi(value); }
121
else if ( strcmp( name, "UseStreamdev" ) == 0 ) { m_useStreamdev = atoi(value); }
122
else if ( strcmp( name, "StreamdevPort" ) == 0 ) { m_streamdevPort = atoi(value); }
123
else if ( strcmp( name, "StreamdevType" ) == 0 ) { m_streamdevType = value; }
124
else if ( strcmp( name, "ScreenShotInterval" ) == 0 ) { m_screenshotInterval = atoi(value); }
125
else if ( strcmp( name, "ShowIMDb" ) == 0 ) { m_showIMDb = atoi(value); }
130
bool Setup::CheckServerPort()
132
if ( m_serverPort <= 0 || m_serverPort > numeric_limits< uint16_t >::max() ) {
133
esyslog( "ERROR: live server port %d is not a valid port number", m_serverPort );
134
cerr << "ERROR: live server port " << m_serverPort << " is not a valid port number" << endl;
141
bool Setup::CheckServerSslPort()
143
if ( m_serverSslPort <= 0 || m_serverSslPort > numeric_limits< uint16_t >::max() ) {
144
esyslog( "ERROR: live server ssl port %d is not a valid port number", m_serverSslPort );
145
cerr << "ERROR: live server ssl port " << m_serverSslPort << " is not a valid port number" << endl;
152
bool Setup::CheckServerIps()
154
if ( m_serverIps.empty() ) {
155
m_serverIps.push_back( "0.0.0.0" );
159
for ( IpList::const_iterator ip = m_serverIps.begin(); ip != m_serverIps.end(); ++ip ) {
160
if ( inet_addr( ip->c_str() ) == static_cast< in_addr_t >( -1 ) ) {
161
esyslog( "ERROR: live server ip %s is not a valid ip address", ip->c_str() );
162
cerr << "ERROR: live server ip " << *ip << " is not a valid ip address" << endl;
169
std::string const Setup::GetMD5HashAdminPassword() const
171
// format is <length>:<md5-hash of password>
172
vector< string > parts = StringSplit( m_adminPasswordMD5, ':' );
173
return (parts.size() > 1) ? parts[1] : "";
176
int Setup::GetAdminPasswordLength() const
178
// format is <length>:<md5-hash of password>
179
vector< string > parts = StringSplit( m_adminPasswordMD5, ':' );
180
return (parts.size() > 0) ? lexical_cast< int >( parts[0] ) : 0;
183
std::string Setup::SetAdminPassword(std::string password)
185
ostringstream passwordStr;
186
passwordStr << password.size() << ":" << MD5Hash(password);
187
m_adminPasswordMD5 = passwordStr.str();
188
return m_adminPasswordMD5;
191
std::string const Setup::GetStartScreenLink() const
193
if (m_startscreen == "whatsonnext")
194
return "whats_on.html?type=next";
195
else if (m_startscreen == "schedule")
196
return "schedule.html";
197
else if (m_startscreen == "timers")
198
return "timers.html";
199
else if (m_startscreen == "recordings")
200
return "recordings.html";
202
return "whats_on.html?type=now";
205
bool Setup::UseAuth() const
207
return m_useAuth && !GetIsLocalNet();
210
bool Setup::CheckLocalNet(const std::string& ip)
212
// split local net mask in net and range
213
vector< string > parts = StringSplit( m_localnetmask, '/' );
214
if (parts.size() != 2) return false;
215
string net = parts[0];
217
int range = lexical_cast< int >(parts[1]);
218
// split net and ip addr in its 4 subcomponents
219
vector< string > netparts = StringSplit( net, '.' );
220
vector< string > addrparts = StringSplit( ip, '.' );
221
if (netparts.size() != 4 || addrparts.size() != 4) return false;
223
// to binary representation
224
ostringstream bin_netstream;
225
bin_netstream << bitset<8>(lexical_cast<long>(netparts[0]))
226
<< bitset<8>(lexical_cast<long>(netparts[1]))
227
<< bitset<8>(lexical_cast<long>(netparts[2]))
228
<< bitset<8>(lexical_cast<long>(netparts[3]));
230
ostringstream bin_addrstream;
231
bin_addrstream << bitset<8>(lexical_cast<long>(addrparts[0]))
232
<< bitset<8>(lexical_cast<long>(addrparts[1]))
233
<< bitset<8>(lexical_cast<long>(addrparts[2]))
234
<< bitset<8>(lexical_cast<long>(addrparts[3]));
237
string bin_net = bin_netstream.str();
238
string bin_addr = bin_addrstream.str();
239
string bin_net_range(bin_net.begin(), bin_net.begin() + range);
240
string addr_net_range(bin_addr.begin(), bin_addr.begin() + range);
241
m_islocalnet = (bin_net_range == addr_net_range);
246
bool Setup::SaveSetup()
248
if (!liveplugin) return false;
249
liveplugin->SetupStore("LastChannel", m_lastChannel);
250
liveplugin->SetupStore("UseAuth", m_useAuth);
253
liveplugin->SetupStore("AdminLogin", m_adminLogin.c_str());
254
liveplugin->SetupStore("AdminPasswordMD5", m_adminPasswordMD5.c_str());
255
liveplugin->SetupStore("LocalNetMask", m_localnetmask.c_str());
257
liveplugin->SetupStore("UserdefTimes", m_times.c_str());
258
liveplugin->SetupStore("StartPage", m_startscreen.c_str());
259
liveplugin->SetupStore("Theme", m_theme.c_str());
260
liveplugin->SetupStore("LastWhatsOnListMode", m_lastwhatsonlistmode.c_str());
261
liveplugin->SetupStore("ShowLogo", m_showLogo);
262
liveplugin->SetupStore("UseAjax", m_useAjax);
263
liveplugin->SetupStore("ShowInfoBox", m_showInfoBox);
264
liveplugin->SetupStore("UseStreamdev", m_useStreamdev);
265
liveplugin->SetupStore("StreamdevPort", m_streamdevPort);
266
liveplugin->SetupStore("StreamdevType", m_streamdevType.c_str());
267
liveplugin->SetupStore("ScreenShotInterval", m_screenshotInterval);
268
liveplugin->SetupStore("ShowIMDb", m_showIMDb);
275
static Setup instance;
279
cMenuSetupLive::cMenuSetupLive():
282
m_lastChannel = vdrlive::LiveSetup().GetLastChannel();
283
m_useAuth = vdrlive::LiveSetup().UseAuth();
284
strcpy(m_adminLogin, vdrlive::LiveSetup().GetAdminLogin().c_str());
286
m_oldpasswordMD5 = m_newpasswordMD5 = vdrlive::LiveSetup().GetMD5HashAdminPassword();
288
string strHidden(vdrlive::LiveSetup().GetAdminPasswordLength(), '*');
289
strn0cpy(m_tmpPassword, strHidden.c_str(), sizeof(m_tmpPassword));
290
strcpy(m_adminPassword, "");
294
void cMenuSetupLive::Set(void)
296
int current = Current();
298
//Add(new cMenuEditIntItem(tr("Last channel to display"), &m_lastChannel, 0, 65536));
299
Add(new cMenuEditChanItem(tr("Last channel to display"), &m_lastChannel, tr("No limit")));
300
//Add(new cMenuEditIntItem(tr("Screenshot interval"), &m_lastChannel, 0, 65536));
301
Add(new cMenuEditBoolItem(tr("Use authentication"), &m_useAuth, tr("No"), tr("Yes")));
302
Add(new cMenuEditStrItem( tr("Admin login"), m_adminLogin, sizeof(m_adminLogin), tr(FileNameChars)));
303
Add(new cMenuEditStrItem( tr("Admin password"), m_tmpPassword, sizeof(m_tmpPassword), tr(FileNameChars)));
304
SetCurrent(Get(current));
308
void cMenuSetupLive::Store(void)
310
vdrlive::LiveSetup().SetLastChannel(m_lastChannel);
311
vdrlive::LiveSetup().SetUseAuth(m_useAuth);
312
vdrlive::LiveSetup().SetAdminLogin(m_adminLogin);
313
if (m_oldpasswordMD5 != m_newpasswordMD5) // only save the password if needed
314
vdrlive::LiveSetup().SetAdminPassword(m_adminPassword);
315
LiveSetup().SaveSetup();
318
bool cMenuSetupLive::InEditMode(const char* ItemText, const char* ItemName, const char* ItemValue)
320
bool bEditMode = true;
321
// ugly solution to detect, if in edit mode
322
char* value = strdup(ItemText);
323
strreplace(value, ItemName, "");
324
strreplace(value, ":\t", "");
326
strreplace(value, "\t", "");
327
if (strlen(value) == strlen(ItemValue))
333
eOSState cMenuSetupLive::ProcessKey(eKeys Key)
335
const char* ItemText = Get(Current())->Text();
336
bool bPassWasInEditMode = false;
337
if (ItemText && strlen(ItemText) > 0 && strstr(ItemText, tr("Admin password")) == ItemText)
338
bPassWasInEditMode = InEditMode(ItemText, tr("Admin password"), m_tmpPassword);
340
eOSState state = cMenuSetupPage::ProcessKey(Key);
342
ItemText = Get(Current())->Text();
343
bool bPassIsInEditMode = false;
344
if (ItemText && strlen(ItemText) > 0 && strstr(ItemText, tr("Admin password")) == ItemText)
345
bPassIsInEditMode = InEditMode(ItemText, tr("Admin password"), m_tmpPassword);
347
if (bPassWasInEditMode && !bPassIsInEditMode)
349
strcpy(m_adminPassword, m_tmpPassword);
350
m_newpasswordMD5 = MD5Hash(m_tmpPassword);
351
string strHidden(strlen(m_adminPassword), '*');
352
strcpy(m_tmpPassword, strHidden.c_str());
356
if (!bPassWasInEditMode && bPassIsInEditMode)
358
strcpy(m_tmpPassword, "");
361
state = cMenuSetupPage::ProcessKey(Key);
367
} // namespace vdrlive