1/* 2 * This program is free software; you can redistribute it and/or 3 * modify it under the terms of the GNU General Public License as 4 * published by the Free Software Foundation; either version 2 of 5 * the License, or (at your option) any later version. 6 * 7 * This program is distributed in the hope that it will be useful, 8 * but WITHOUT ANY WARRANTY; without even the implied warranty of 9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 * GNU General Public License for more details. 11 * 12 * You should have received a copy of the GNU General Public License 13 * along with this program; if not, write to the Free Software 14 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 15 * MA 02111-1307 USA 16 * 17 * Copyright 2004, ASUSTeK Inc. 18 * All Rights Reserved. 19 * 20 * THIS SOFTWARE IS OFFERED "AS IS", AND ASUS GRANTS NO WARRANTIES OF ANY 21 * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM 22 * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS 23 * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. 24 * 25 */ 26#include "rc.h" 27 28#include <stdio.h> 29#include <stdlib.h> 30#include <errno.h> 31#include <string.h> 32#include <unistd.h> 33 34#if defined(RTCONFIG_JFFS2) || defined(RTCONFIG_BRCM_NAND_JFFS2) 35#define JFFS_TR_FOLDER "/jffs/tr" 36#endif 37#define TR_FOLDER "/tmp/tr" 38#define DEFAULT_TR_XML "/usr/tr/tr.xml" 39#define TR_XML_FILE "tr.xml" 40#define TR_XML_BAK_FILE "tr.xml.bak" 41#define TR_XML_TAR_FILE "tr.xml.tz" 42#define TR_XML_BAK_TAR_FILE "tr.xml.bak.tz" 43#define DHCPC_LEASE_LIST "/tmp/dhcpc_lease_list" 44#define TR_CONFIG_FILE TR_FOLDER"/tr.conf" 45#define TR_LOG_FILE TR_FOLDER"/tr.log" 46#define CA_CERT_FILE TR_FOLDER"/ca.pem" 47#define CLIENT_CERT_FILE TR_FOLDER"/client.crt" 48#define CLIENT_KEY_FILE TR_FOLDER"/client.key" 49//#define IPDRDOC_FOLDER TR_FOLDER"/IPDRDoc" 50 51int generate_tr_config() 52{ 53 FILE *fp; 54 55 /* Generate tr configuration file */ 56 if (!(fp = fopen(TR_CONFIG_FILE, "w"))) { 57 perror(TR_CONFIG_FILE); 58 return -1; 59 } 60 61 fprintf(fp, "#TCPAddress = 0.0.0.0\n"); 62 fprintf(fp, "TCPAddress = :: #or IPv6_Addr\n"); 63 fprintf(fp, "TCPChallenge = Basic\n"); 64 fprintf(fp, "TCPNotifyInterval = 0\n"); 65 fprintf(fp, "UDPAddress = 0.0.0.0\n"); 66 fprintf(fp, "UDPPort = 7547\n"); 67 fprintf(fp, "UDPNotifyInterval = 20\n"); 68 fprintf(fp, "#CLIAddress = 0.0.0.0\n"); 69 fprintf(fp, "CLIAddress = ::\n"); 70 fprintf(fp, "CLIPort = 1234\n"); 71 fprintf(fp, "CLITimeout = 10\n"); 72 fprintf(fp, "CLIDocRoot = /usr/tr/doc/html\n"); 73 fprintf(fp, "CLIIndex = index.html\n"); 74 fprintf(fp, "MaxListener = 3\n"); 75 fprintf(fp, "CACert = %s\n", CA_CERT_FILE); 76 fprintf(fp, "ClientCert = %s\n", CLIENT_CERT_FILE); 77 fprintf(fp, "ClientKey = %s\n", CLIENT_KEY_FILE); 78 fprintf(fp, "SSLPassword= password\n"); 79 fprintf(fp, "Init = tr.xml\n"); 80 //fprintf(fp, "#At the moment, all statis inform parameter MUST be constant value parameter\n"); 81#ifdef RTCONFIG_TR181 82 fprintf(fp, "InformParameter = Device.DeviceInfo.SpecVersion\n"); 83 fprintf(fp, "InformParameter = Device.DeviceInfo.HardwareVersion\n"); 84 fprintf(fp, "InformParameter = Device.DeviceInfo.SoftwareVersion\n"); 85 fprintf(fp, "InformParameter = Device.DeviceInfo.ProvisioningCode\n"); 86 fprintf(fp, "InformParameter = Device.ManagementServer.ConnectionRequestURL\n"); 87 fprintf(fp, "InformParameter = Device.ManagementServer.ParameterKey\n"); 88 //fprintf(fp, "#InformParameter = Device.WANDevice.1.WANConnectionDevice.1.WANPPPConnection.1.ExternalIPAddress\n"); 89#else /* TR098 */ 90 fprintf(fp, "InformParameter = InternetGatewayDevice.DeviceSummary\n"); 91 fprintf(fp, "InformParameter = InternetGatewayDevice.DeviceInfo.SpecVersion\n"); 92 fprintf(fp, "InformParameter = InternetGatewayDevice.DeviceInfo.HardwareVersion\n"); 93 fprintf(fp, "InformParameter = InternetGatewayDevice.DeviceInfo.SoftwareVersion\n"); 94 fprintf(fp, "InformParameter = InternetGatewayDevice.DeviceInfo.ProvisioningCode\n"); 95 fprintf(fp, "InformParameter = InternetGatewayDevice.ManagementServer.ConnectionRequestURL\n"); 96 fprintf(fp, "InformParameter = InternetGatewayDevice.ManagementServer.ParameterKey\n"); 97 //fprintf(fp, "#InformParameter = InternetGatewayDevice.WANDevice.1.WANConnectionDevice.1.WANPPPConnection.1.ExternalIPAddress\n"); 98#endif 99 fprintf(fp, "LogFileName = %s\n", TR_LOG_FILE); 100 fprintf(fp, "LogAutoRotate = true\n"); 101 fprintf(fp, "LogBackup = 5\n"); 102 fprintf(fp, "LogLevel = DEBUG\n"); 103 if(nvram_get_int("TR_debug") == 1) 104 fprintf(fp, "LogMode = BOTH\n"); 105 else 106 fprintf(fp, "LogMode = NONE\n"); 107 fprintf(fp, "LogLimit = 1MB\n"); 108 fprintf(fp, "TaskQueueLenLimit = 64\n"); 109 fprintf(fp, "Upload = 1:1 Vendor Configuration File:/tmp/Settings_%s.CFG\n", nvram_safe_get("productid")); 110 fprintf(fp, "Upload = 0:2 Vendor Log File:/tmp/syslog.log\n"); 111 //fprintf(fp, "Upload = 0:X 00256D 3GPP Performance File:pm.xml\n"); 112 fprintf(fp, "Download = 1 Firmware Upgrade Image:/tmp/firmware.trx\n"); 113 fprintf(fp, "Download = 2 Web Content:web.html\n"); 114 fprintf(fp, "Download = 3 Vendor Configuration File:/tmp/settings_u.prf\n"); 115#ifdef RTCONFIG_SFEXPRESS 116 fprintf(fp, "Download = 4 Openvpn Client1 File:/tmp/openvpn_file\n"); 117 fprintf(fp, "Download = 5 Openvpn Client2 File:/tmp/openvpn_file\n"); 118 fprintf(fp, "Download = 6 Openvpn Client3 File:/tmp/openvpn_file\n"); 119#endif 120 //fprintf(fp, "Download = 4 Tone File:tone.file\n"); 121 //fprintf(fp, "Download = 5 Ringer File:ringer.file\n"); 122 //fprintf(fp, "Download = X Worksys DUInstallDownload: duin.pkg\n"); 123 //fprintf(fp, "Download = X Worksys DUUpdateDownload: duup.pkg\n"); 124 //fprintf(fp, "Download = X 00256D 3GPP Configuration File:cm.xml\n"); 125 fprintf(fp, "TrustTargetFileName = false\n"); 126 fprintf(fp, "CheckIdleInterval = 2\n"); 127 fprintf(fp, "DownloadRetryInterval = 5\n"); 128 fprintf(fp, "DownloadMaxRetries = 3\n"); 129#if 0 130 fprintf(fp, "#CustomedEvent = 1:X 123456 Event1\n"); 131 fprintf(fp, "CustomedEvent = 1: X 00256D 3GPP Reprovision Required: SecGW\n"); 132 fprintf(fp, "CustomedEvent = 2: X 00256D 3GPP Reprovision Required: FAPGW\n"); 133#endif 134 fprintf(fp, "SessionTimeout = 10\n"); 135 fprintf(fp, "Expect100Continue = false\n"); 136 fprintf(fp, "HTTPChunk = true\n"); 137 fprintf(fp, "KAISpan=5\n"); 138 fprintf(fp, "StunRepeat = 2\n"); 139#if 0 140 fprintf(fp, "WIBRepeat = 5\n"); 141 fprintf(fp, "WIBSpan = 5\n"); 142 fprintf(fp, "WIBReInterval = 10\n"); 143 fprintf(fp, "ResponseStatus1 = Device.DeviceInfo.SoftwareVersion\n"); 144 fprintf(fp, "ResponseStatus1 = Device.MultiInstanceSample\n"); 145#endif 146 //fprintf(fp, "IPDRDoc = %s\n", IPDRDOC_FOLDER); 147 148 fclose(fp); 149 150 return 0; 151} 152 153int check_xml_file_version(char *def_file, char *run_file) 154{ 155 FILE *fp_def, *fp_run; 156 int res = 0; 157 char buf[128]; 158 char def_ver_info[16] = "", run_ver_info[16] = ""; 159 char *p; 160 161 /* get version info from the xml file of default */ 162 if ((fp_def = fopen(def_file, "r")) == NULL) { 163 _dprintf("*** can't open file(%s)\n", def_file); 164 return res; 165 } 166 167 memset(buf, 0, sizeof(buf)); 168 while(fgets(buf, sizeof(buf), fp_def) != NULL) { 169#ifdef RTCONFIG_TR181 170 if(strstr(buf, "'Device'")) { 171#else /* TR098 */ 172 if(strstr(buf, "'InternetGatewayDevice'")) { 173#endif 174 if((p =strstr(buf, "arg="))) { 175 sscanf(p, "arg='%[^']", def_ver_info); 176 //logmessage("TR-069 agent", "def_ver_info: %s, len: %d", def_ver_info, strlen(def_ver_info)); 177 break; 178 } 179 } 180 } 181 fclose(fp_def); 182 183 /* get version info from the xml file of runtime */ 184 if ((fp_run = fopen(run_file, "r")) == NULL) { 185 _dprintf("*** can't open file(%s)\n", run_file); 186 return res; 187 } 188 189 memset(buf, 0, sizeof(buf)); 190 while(fgets(buf, sizeof(buf), fp_run) != NULL) { 191#ifdef RTCONFIG_TR181 192 if(strstr(buf, "'Device'")) { 193#else /* TR098 */ 194 if(strstr(buf, "'InternetGatewayDevice'")) { 195#endif 196 if((p =strstr(buf, "arg="))) { 197 sscanf(p, "arg='%[^']", run_ver_info); 198 //logmessage("TR-069 agent", "def_ver_info: %s, len: %d", run_ver_info, strlen(run_ver_info)); 199 break; 200 } 201 } 202 } 203 fclose(fp_run); 204 205 //logmessage("TR-069 agent", "def_ver_info: %s, run_ver_info: %s", def_ver_info, run_ver_info); 206 207 if (!strcmp(def_ver_info, run_ver_info)) { 208 res = 1; 209 logmessage("TR-069 agent", "version match"); 210 } 211 else 212 logmessage("TR-069 agent", "version dismatch"); 213 214 return res; 215} 216 217char *convert_cert(const char *name, char *buf) 218{ 219 char *value; 220 int len, i; 221 222 value = nvram_safe_get(name); 223 224 len = strlen(value); 225 226 for (i=0; (i < len); i++) { 227 if (value[i] == '>') 228 buf[i] = '\n'; 229 else 230 buf[i] = value[i]; 231 } 232 233 buf[i] = '\0'; 234 235 return buf; 236} 237 238void save_cert_from_nvram() 239{ 240 char buf[3000]; 241 FILE *fp = NULL; 242 243 /* write ca cert from nvram */ 244 if (check_if_file_exist(CA_CERT_FILE)) 245 unlink(CA_CERT_FILE); 246 247 if(!nvram_is_empty("tr_ca_cert")) { 248 fp = fopen(CA_CERT_FILE, "w"); 249 chmod(CA_CERT_FILE, S_IRUSR|S_IWUSR); 250 fprintf(fp, "%s", convert_cert("tr_ca_cert", buf)); 251 fclose(fp); 252 } 253 254 /* write client cert from nvram */ 255 if (check_if_file_exist(CLIENT_CERT_FILE)) 256 unlink(CLIENT_CERT_FILE); 257 258 if(!nvram_is_empty("tr_client_cert")) { 259 fp = fopen(CLIENT_CERT_FILE, "w"); 260 chmod(CLIENT_CERT_FILE, S_IRUSR|S_IWUSR); 261 fprintf(fp, "%s", convert_cert("tr_client_cert", buf)); 262 fclose(fp); 263 } 264 265 /* write client key from nvram */ 266 if (check_if_file_exist(CLIENT_KEY_FILE)) 267 unlink(CLIENT_KEY_FILE); 268 269 if(!nvram_is_empty("tr_client_key")) { 270 fp = fopen(CLIENT_KEY_FILE, "w"); 271 chmod(CLIENT_KEY_FILE, S_IRUSR|S_IWUSR); 272 fprintf(fp, "%s", convert_cert("tr_client_key", buf)); 273 fclose(fp); 274 } 275} 276 277void 278stop_tr(void) 279{ 280 killall_tk("tr069"); 281} 282 283int 284start_tr(void) 285{ 286 char *tr_argv[] = { "/sbin/tr069", "-d", TR_FOLDER, NULL}; 287 char tr_xml_path[64]; 288 pid_t pid; 289 int ret; 290 291 if (!nvram_match("tr_enable", "1") || nvram_match("tr_acs_url", "")) { 292 return 0; 293 } 294 295 if (getpid() != 1) { 296 notify_rc_after_wait("start_tr"); 297 return 0; 298 } 299 300 /* Shut down previous instance if any */ 301 stop_tr(); 302 303 /* Check tr folder whether exists or not */ 304 if (!check_if_dir_exist(TR_FOLDER)) 305 mkdir(TR_FOLDER, 0744); 306 307#if defined(RTCONFIG_JFFS2) || defined(RTCONFIG_BRCM_NAND_JFFS2) 308 /* Check tr folder on jffs whether exists or not */ 309 if (!check_if_dir_exist(JFFS_TR_FOLDER)) 310 mkdir(JFFS_TR_FOLDER, 0744); 311 312 /* copy /jffs/tr/tr.xml to /tmp/tr and then delete it */ 313 if (check_if_file_exist(JFFS_TR_FOLDER"/"TR_XML_FILE)) { 314 eval("cp", JFFS_TR_FOLDER"/"TR_XML_FILE, TR_FOLDER); 315 unlink(JFFS_TR_FOLDER"/"TR_XML_FILE); 316 } 317 318 /* copy /jffs/tr/tr.xml.bak to /tmp/tr and then delete it */ 319 if (check_if_file_exist(JFFS_TR_FOLDER"/"TR_XML_BAK_FILE)) { 320 eval("cp", JFFS_TR_FOLDER"/"TR_XML_BAK_FILE, TR_FOLDER); 321 unlink(JFFS_TR_FOLDER"/"TR_XML_BAK_FILE); 322 } 323 324 /* untar /jffs/tr/tr.xml.tz to /tmp/tr */ 325 if (check_if_file_exist(JFFS_TR_FOLDER"/"TR_XML_TAR_FILE)) 326 eval("tar", "-zxf", JFFS_TR_FOLDER"/"TR_XML_TAR_FILE); 327 328 /* untar /jffs/tr/tr.xml.bak.tz to /tmp/tr */ 329 if (check_if_file_exist(JFFS_TR_FOLDER"/"TR_XML_BAK_TAR_FILE)) 330 eval("tar", "-zxf", JFFS_TR_FOLDER"/"TR_XML_BAK_TAR_FILE); 331#endif 332 333 /* Check IPDRDoc folder whether exists or not */ 334 //if (!check_if_dir_exist(IPDRDOC_FOLDER)); 335 // mkdir(IPDRDOC_FOLDER, 0744); 336 337 /* Check tr.xml whether exists or not */ 338 sprintf(tr_xml_path, "%s/%s", TR_FOLDER, TR_XML_FILE); 339 if (!check_if_file_exist(tr_xml_path)) 340 eval("cp", DEFAULT_TR_XML, tr_xml_path); 341 else 342 { 343 if (!check_xml_file_version(DEFAULT_TR_XML, tr_xml_path)) 344 eval("cp", DEFAULT_TR_XML, tr_xml_path); 345 } 346 347 /* Generate tr configuration file */ 348 ret = generate_tr_config(); 349 if (ret < 0) 350 return ret; 351 352 /* write cert and key to file */ 353 save_cert_from_nvram(); 354 355 /* Execute tr agent */ 356 ret = _eval(tr_argv, NULL, 0, &pid); 357 358 if (pids("tr069")) 359 logmessage("TR-069 agent", "daemon is started"); 360 361 return ret; 362} 363 364int check_udhcpc_lease_exist(char *check_str) 365{ 366 FILE *fp; 367 char buf[128]; 368 int res = 0; 369 370 if (!(fp = fopen(DHCPC_LEASE_LIST, "r"))) 371 return 0; 372 373 while(fgets(buf, sizeof(buf), fp) != NULL) { 374 if(strstr(buf, check_str) != NULL) 375 res = 1; 376 } 377 378 fclose(fp); 379 380 return res; 381} 382 383int 384dhcpc_lease_main(int argc, char **argv) 385{ 386 char *oui = safe_getenv("DNSMASQ_CPEWAN_OUI"); 387 char *serial = safe_getenv("DNSMASQ_CPEWAN_SERIAL"); 388 char *class = safe_getenv("DNSMASQ_CPEWAN_CLASS"); 389 int hn_exist = 1; 390 391 if(argc != 5 && argc != 4) 392 return -1; 393 394 if(argc == 4) 395 hn_exist = 0; 396 else if(argc == 5) 397 hn_exist = 1; 398 else 399 return -1; 400 401 _dprintf("%s():: %s, %s, %s, %s\n", __FUNCTION__, argv[1], argv[2], argv[3], hn_exist ? argv[4]: "No hostname"); 402 403// if((oui && *oui) && (serial && *serial)) { 404 if(!pids("tr069")) { /* write the info of manageable device into the file */ 405 if(!strcmp(argv[1], "add") || !strcmp(argv[1], "old")) { 406 if((oui && *oui) && (serial && *serial)) { 407 char check_str[128]; 408 409 snprintf(check_str, sizeof(check_str), "%s,%s,%s,%s", oui, serial, class, argv[2]); 410 411 if(!check_udhcpc_lease_exist(check_str)) { 412 FILE *fp; 413 414 if (!(fp = fopen(DHCPC_LEASE_LIST, "a"))) 415 return -1; 416 417 /* write oui, serial, class */ 418 _dprintf("%s():: %s %s %s %s\n", __FUNCTION__, argv[1], oui, serial, class); 419 fprintf(fp, "%s,%s,%s,%s\n", oui, serial, class, argv[2]); 420 421 fclose(fp); 422 } 423 } 424 } 425 } 426 else /* send the info of manageable device to tr069 agent */ 427 { 428 char cmd[256]; 429 char cmdhost[256]; 430 431 memset(cmd, 0 ,sizeof(cmd)); 432 memset(cmdhost, 0 ,sizeof(cmdhost)); 433 434 if(!strcmp(argv[1], "add") || !strcmp(argv[1], "old")) { 435 snprintf(cmdhost, sizeof(cmdhost), "/sbin/sendtocli http://127.0.0.1:1234/hostshost/device \"action=add&ipaddr=%s&hostname=%s\"", argv[3], hn_exist ? argv[4] : ""); 436 437 438 if((oui && *oui) && (serial && *serial)) { 439 char check_str[128]; 440 441 snprintf(check_str, sizeof(check_str), "%s,%s,%s,%s", oui, serial, class, argv[2]); 442 443 if(!check_udhcpc_lease_exist(check_str)) { 444 FILE *fp; 445 446 if (!(fp = fopen(DHCPC_LEASE_LIST, "a"))) 447 return -1; 448 449 /* write oui, serial, class */ 450 _dprintf("%s():: %s %s %s %s\n", __FUNCTION__, argv[1], oui, serial, class); 451 fprintf(fp, "%s,%s,%s,%s\n", oui, serial, class, argv[2]); 452 453 fclose(fp); 454 } 455 456 _dprintf("%s():: %s %s %s %s\n", __FUNCTION__, oui, serial, class, argv[2]); 457 snprintf(cmd, sizeof(cmd), "/sbin/sendtocli http://127.0.0.1:1234/manageable/device \"action=add&oui=%s&serial=%s&class=%s\"", oui, serial, class); 458 } 459 } 460 else if(!strcmp(argv[1], "del")) { 461 snprintf(cmdhost, sizeof(cmdhost), "/sbin/sendtocli http://127.0.0.1:1234/hostshost/device \"action=del&ipaddr=%s&hostname=%s\"", argv[3], hn_exist ? argv[4] : ""); 462 463 FILE *fp; 464 char buf[128]; 465 char *oui_str = NULL, *serial_str = NULL, *class_str = NULL, *hwaddr_str = NULL; 466 467 if (!(fp = fopen(DHCPC_LEASE_LIST, "r"))) 468 return -1; 469 470 while(fgets(buf, sizeof(buf), fp) != NULL) { 471 if(strstr(buf, argv[2]) != NULL) { 472 if ((vstrsep(buf, ",", &oui_str, &serial_str, &class_str, &hwaddr_str) != 4)) 473 continue; 474 _dprintf("%s():: oui: %s, serial: %s, class: %s, hwaddr: %s\n", oui_str, serial_str, class_str, hwaddr_str); 475 snprintf(cmd, sizeof(cmd), "/sbin/sendtocli http://127.0.0.1:1234/manageable/device \"action=del&oui=%s&serial=%s&class=%s\"", oui_str, serial_str, class_str); 476 break; 477 } 478 } 479 480 fclose(fp); 481 } 482 483 if(strlen(cmd)) { 484 _dprintf("%s():: %s\n", __FUNCTION__, cmd); 485 system(cmd); 486 } 487 488 } 489 490 _dprintf("%s:: done\n", __FUNCTION__); 491 return 0; 492} 493