1#include <ctype.h> 2#include <stdio.h> 3#include <string.h> 4#include <strings.h> 5 6#define IF_LOOKUP 1 7#include <sys/ioctl.h> 8#include <net/if.h> 9#include <sys/types.h> 10#include <sys/socket.h> 11#include <netinet/in.h> 12#include <stdlib.h> 13 14#include "md5.h" 15#include "asus_ddns.h" 16#if 0 17#include <nvram_linux.h> 18#else //2007.03.14 Yau add for WL500gp2 19#include <bcmnvram.h> 20#endif 21#include <syslog.h> 22#include <shared.h> 23 24#define MAX_DOMAIN_LEN 50 // hostname len (32) + "asuscomm.com" ~~ 45, reserve 5 char 25 26//#define DUMP_KEY 27#ifdef DUMP_KEY 28#define DUMP(k) dump (k, sizeof (k)) 29#else 30#define DUMP(k) 31#endif // DUMP_KEY 32 33enum { 34 REGISTERES_OK = 0, 35 REGISTERES_ERROR, 36 REGISTERES_SHUTDOWN, 37}; 38 39/**************************************** Copy from ez-ipupdate.c * start ********************************/ 40#ifdef DEBUG 41# define BUFFER_SIZE (16*1024) 42#else 43# define BUFFER_SIZE (4*1024-1) 44#endif 45 46#define OPT_DEBUG 0x0001 47#define OPT_DAEMON 0x0004 48#define OPT_QUIET 0x0008 49#define OPT_FOREGROUND 0x0010 50#define OPT_OFFLINE 0x0020 51 52enum { 53 UPDATERES_OK = 0, 54 UPDATERES_ERROR, 55 UPDATERES_SHUTDOWN, 56}; 57/**************************************** Copy from ez-ipupdate.c * end **********************************/ 58 59 60#ifdef DEBUG 61# define PRINT(fmt,args...) fprintf (stderr, fmt, ## args); 62# define DBG(fmt,args...) fprintf (stderr, fmt, ## args); 63#else 64# define PRINT(fmt,args...) show_message(fmt,args...); 65//# define PRINT(fmt,args...) syslog (LOG_NOTICE, fmt, ## args); 66# define DBG(fmt,args...) 67#endif 68 69int g_asus_ddns_mode = 0; /* 0: disable; 1: register domain; 2: update ip */ 70 71 72static void hm(text, text_len, key, key_len, digest) 73unsigned char *text; /* pointer to data stream */ 74int text_len; /* length of data stream */ 75unsigned char *key; /* pointer to authentication key */ 76int key_len; /* length of authentication key */ 77unsigned char *digest; /* caller digest to be filled in */ 78 79{ 80 struct md5_ctx context; 81 unsigned char k_ipad[65]; /* inner padding - 82 * key XORd with ipad 83 */ 84 unsigned char k_opad[65]; /* outer padding - 85 * key XORd with opad 86 */ 87 unsigned char tk[16]; 88 int i; 89 /* if key is longer than 64 bytes reset it to key=MD5(key) */ 90 if (key_len > 64) { 91 struct md5_ctx tctx; 92 md5_init_ctx(&tctx); 93 md5_process_bytes(key, key_len, &tctx); 94 md5_finish_ctx(&tctx, tk); 95 96 key = tk; 97 key_len = 16; 98 } 99 100 /* 101 * the HMAC_MD5 transform looks like: 102 * 103 * MD5(K XOR opad, MD5(K XOR ipad, text)) 104 * 105 * where K is an n byte key 106 * ipad is the byte 0x36 repeated 64 times 107 * opad is the byte 0x5c repeated 64 times 108 * and text is the data being protected 109 */ 110 111 /* start out by storing key in pads */ 112 bzero(k_ipad, sizeof k_ipad); 113 bzero(k_opad, sizeof k_opad); 114 bcopy(key, k_ipad, key_len); 115 bcopy(key, k_opad, key_len); 116 117 /* XOR key with ipad and opad values */ 118 for (i = 0; i < 64; i++) { 119 k_ipad[i] ^= 0x36; 120 k_opad[i] ^= 0x5c; 121 } 122 /* 123 * perform inner MD5 124 */ 125 md5_init_ctx(&context); /* init context for 1st * pass */ 126 md5_process_bytes(k_ipad, 64, &context); /* start with inner pad */ 127 md5_process_bytes(text, text_len, &context);/* then text of datagram */ 128 md5_finish_ctx(&context, digest); /* finish up 1st pass */ 129 /* 130 * perform outer MD5 131 */ 132 md5_init_ctx(&context); /* init context for 2nd * pass */ 133 md5_process_bytes(k_opad, 64, &context); /* start with outer pad */ 134 md5_process_bytes(digest, 16, &context); /* then results of 1st * hash */ 135 md5_finish_ctx(&context, digest); /* finish up 2nd pass */ 136} 137 138 139#ifdef TEST_HMAC_MD5 140/* 141HMAC-MD5 Test Vectors (Trailing '\0' of a character string not included in test): 142 143 key = 0x0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b 144 key_len = 16 bytes 145 data = "Hi There" 146 data_len = 8 bytes 147 digest = 0x9294727a3638bb1c13f48ef8158bfc9d 148 149 key = "Jefe" 150 data = "what do ya want for nothing?" 151 data_len = 28 bytes 152 digest = 0x750c783e6ab0b503eaa86e310a5db738 153 154 key = 0xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 155 key_len 16 bytes 156 data = 0xDDDDDDDDDDDDDDDDDDDD... 157 ..DDDDDDDDDDDDDDDDDDDD... 158 ..DDDDDDDDDDDDDDDDDDDD... 159 ..DDDDDDDDDDDDDDDDDDDD... 160 ..DDDDDDDDDDDDDDDDDDDD 161 data_len = 50 bytes 162 digest = 0x56be34521d144c88dbb8c733f0e8b3f6 163 164 ------------------------------------------------ 165 HOW TO COMPILE TEST VECTORS? 166 gcc -Wall -c -o test_hmac_md5.o -DTEST_HMAC_MD5 -DDEBUG -DUSE_MD5 asus_ddns.c 167 gcc -Wall -c -o md5_x86.o -DTEST_HMAC_MD5 -DDEBUG -DUSE_MD5 md5.c 168 gcc -Wall -o test_hmac_md5 test_hmac_md5.o md5_x86.o 169 170 ------------------------------------------------ 171 NOTES: If your device is big-endian platform, you have to define WORDS_BIGENDIAN as 1. 172 173 The test_hmac_md5 is test program. It will print three hash values and match with above. 174*/ 175static void dump (unsigned char *p, unsigned int l) 176{ 177 unsigned int i; 178 if (p == NULL || l == 0) 179 return; 180 181 printf ("0x"); 182 for (i = 0; i < l; ++i) 183 printf ("%02x", p[i]); 184 printf ("\n\n"); 185} 186 187int main(void) 188{ 189 unsigned char key[16], data[256], digest[16]; 190 191 // case 1 192 memset (key, 0, sizeof (key)); 193 memset (key, 0x0b, 16); 194 memset (data, 0, sizeof (data)); 195 strcpy ((char*)data, "Hi There"); 196 hm(data, 8, key, 16, digest); 197 printf ("case 1:"); dump (digest, 16); 198 199 // case 2 200 memset (key, 0, sizeof (key)); 201 strcpy ((char*)key, "Jefe"); 202 memset (data, 0, sizeof (data)); 203 strcpy ((char*)data, "what do ya want for nothing?"); 204 hm(data, 28, key, 4, digest); 205 printf ("case 2:"); dump (digest, 16); 206 207 // case 3 208 memset (key, 0, sizeof (key)); 209 memset (key, 0xAA, 16); 210 memset (data, 0, sizeof (data)); 211 memset (data, 0xDD, 50); 212 hm(data, 50, key, 16, digest); 213 printf ("case 3:"); dump (digest, 16); 214 215 216 return 0; 217} 218#else // !TEST_HMAC_MD5 219 220#define MULTICAST_BIT 0x0001 221#define UNIQUE_OUI_BIT 0x0002 222int TransferMacAddr(const char* mac, char* transfer_mac) 223{ 224 int sec_byte; 225 int i = 0, s = 0; 226 char *p_mac; 227 p_mac = transfer_mac; 228 229 if( strlen(mac)!=17 || !strcmp("00:00:00:00:00:00", mac) ) 230 return 0; 231 232 while( *mac && i<12 ) { 233 if( isxdigit(*mac) ) { 234 if(i==1) { 235 sec_byte= strtol(mac, NULL, 16); 236 if((sec_byte & MULTICAST_BIT)||(sec_byte & UNIQUE_OUI_BIT)) 237 break; 238 } 239 i++; 240 memcpy(p_mac, mac, 1); 241 p_mac++; 242 } 243 else if( *mac==':') { 244 if( i==0 || i/2-1!=s ) 245 break; 246 ++s; 247 } 248 ++mac; 249 } 250 return( i==12 && s==5 ); 251} 252 253int asus_reg_domain (void) 254{ 255 char buf[BUFFER_SIZE + 1]; 256 char *p, *bp = buf; 257 char ret_buf[64]; 258 char sug_name[MAX_DOMAIN_LEN], old_name[MAX_DOMAIN_LEN]; 259 int bytes; 260 int btot; 261 int ret; 262 int retval = REGISTERES_OK; 263 264 buf[BUFFER_SIZE] = '\0'; 265 266 if (do_connect((int *) &client_sockfd, server, port) != 0) { 267 PRINT ("error connecting to %s:%s\n", server, port); 268 show_message("error connecting to %s:%s\n", server, port); 269 nvram_set ("ddns_return_code", "connect_fail"); 270 nvram_set ("ddns_return_code_chk", "connect_fail"); 271 return (REGISTERES_ERROR); 272 } 273 274 char *ddns_transfer; 275 char old_mac[13]; 276 memset(old_mac, 0, 13); 277 if(TransferMacAddr(nvram_safe_get("ddns_transfer"), old_mac)) { 278 snprintf(buf, BUFFER_SIZE, "GET /ddns/register.jsp?hostname=%s&myip=%s&oldmac=%s HTTP/1.0\015\012", 279 host, address, old_mac); 280 } 281 else { 282 snprintf(buf, BUFFER_SIZE, "GET /ddns/register.jsp?hostname=%s&myip=%s HTTP/1.0\015\012", host, address); 283 } 284 output(buf); 285 snprintf(buf, BUFFER_SIZE, "Authorization: Basic %s\015\012", auth); 286 output(buf); 287 snprintf(buf, BUFFER_SIZE, "User-Agent: %s-%s %s [%s] (%s)\015\012", "ez-update", VERSION, OS, (options & OPT_DAEMON) ? "daemon" : "", "by Angus Mackay"); 288 output(buf); 289 snprintf(buf, BUFFER_SIZE, "Host: %s\015\012", server); 290 output(buf); 291 snprintf(buf, BUFFER_SIZE, "\015\012"); 292 output(buf); 293 294 memset (buf, 0, sizeof (buf)); 295 bp = buf; 296 bytes = 0; 297 btot = 0; 298 ret = 0; 299 while ((bytes = read_input(bp, BUFFER_SIZE - btot)) > 0) { 300 bp += bytes; 301 btot += bytes; 302 } 303 close(client_sockfd); 304 buf[btot] = '\0'; 305 //show_message("Asus Reg domain:: return: %s\n", buf); 306 if(btot) { // TODO: according to server response, parsing code have to rewrite 307 if (sscanf(buf, " HTTP/1.%*c %3d", &ret) != 1) { 308 ret = -1; 309 } 310 311 // looking for 2-th '|' 312 p = strchr (buf, '|'); 313 if (p != NULL) 314 p = strchr (p+1, '|'); 315 if (p == NULL) { 316 p = ""; 317 } 318 snprintf (ret_buf, sizeof (ret_buf), "%s,%d", "register", ret); 319 } 320 321 nvram_set ("ddns_return_code", ret_buf); 322 nvram_set ("ddns_return_code_chk", ret_buf); 323 switch (ret) { 324 case -1: 325 PRINT ("strange server response, are you connecting to the right server?\n"); 326 retval = REGISTERES_ERROR; 327 break; 328 329 case 200: 330 PRINT ("Registration success.\n"); 331 break; 332 333 case 203: 334 PRINT ("Registration failed. (203)\n"); 335 memset (sug_name, 0, sizeof (sug_name)); 336 sscanf (p, "|%[^|\r\n]c", sug_name); 337 nvram_set ("ddns_suggest_name", sug_name); 338 339 retval = REGISTERES_ERROR; 340 break; 341 342 case 220: 343 PRINT ("Registration same domain success.\n"); 344 break; 345 346 case 230: 347 PRINT ("Registration new domain success.\n"); 348 memset (old_name, 0, sizeof (old_name)); 349 sscanf (p, "|%[^|\r\n]c", old_name); 350 nvram_set ("ddns_old_name", old_name); 351 break; 352 353 case 233: 354 PRINT ("Registration failed. (233)\n"); 355 memset (old_name, 0, sizeof (old_name)); 356 sscanf (p, "|%[^|\r\n]c", old_name); 357 nvram_set ("ddns_old_name", old_name); 358 retval = REGISTERES_ERROR; 359 break; 360 361 case 297: 362 PRINT ("Invalid hostname.\n"); 363 retval = REGISTERES_ERROR; 364 break; 365 366 case 298: 367 PRINT ("Invalid domain name.\n"); 368 retval = REGISTERES_ERROR; 369 break; 370 371 case 299: 372 PRINT ("Invalid IP format.\n"); 373 retval = REGISTERES_ERROR; 374 break; 375 376 case 401: 377 PRINT ("authentication failure\n"); 378 retval = REGISTERES_SHUTDOWN; 379 break; 380 381 case 407: 382 PRINT ("Proxy authentication Required.\n"); 383 retval = REGISTERES_SHUTDOWN; 384 break; 385 386 default: 387 // reuse the auth buffer 388 *auth = '\0'; 389 sscanf(buf, " HTTP/1.%*c %*3d %255[^\r\n]", auth); 390 if (ret >= 500) { 391 retval = REGISTERES_SHUTDOWN; 392 nvram_set ("ddns_return_code","unknown_error"); 393 nvram_set ("ddns_return_code_chk","unknown_error"); 394 } else { 395 retval = REGISTERES_ERROR; 396 nvram_set ("ddns_return_code","Time-out"); 397 nvram_set ("ddns_return_code_chk","Time-out"); 398 } 399 retval = UPDATERES_SHUTDOWN; 400 break; 401 } 402 403 show_message("retval= %d, ddns_return_code (%s) ddns_suggest_name (%s) ddns_old_name (%s)", retval, nvram_safe_get ("ddns_return_code"), nvram_safe_get ("ddns_suggest_name"), nvram_safe_get ("ddns_old_name")); 404 return (retval); 405} 406 407 408int asus_update_entry(void) 409{ 410 char buf[BUFFER_SIZE + 1]; 411 char *p, *bp = buf; 412 char ret_buf[64]; 413 char sug_name[MAX_DOMAIN_LEN], old_name[MAX_DOMAIN_LEN]; 414 int bytes; 415 int btot; 416 int ret; 417 int retval = UPDATERES_OK; 418 419 buf[BUFFER_SIZE] = '\0'; 420 421 if (do_connect((int *) &client_sockfd, server, port) != 0) { 422 show_message("error connecting to %s:%s\n", server, port); 423 nvram_set ("ddns_return_code", "connect_fail"); 424 nvram_set ("ddns_return_code_chk", "connect_fail"); 425 return (UPDATERES_ERROR); 426 } 427 428 char *ddns_transfer; 429 char old_mac[13]; 430 memset(old_mac, 0, 13); 431 if(TransferMacAddr(nvram_safe_get("ddns_transfer"), old_mac)) { 432 snprintf(buf, BUFFER_SIZE, "GET /ddns/update.jsp?hostname=%s&myip=%s&oldmac=%s HTTP/1.0\015\012", 433 host, address, old_mac); 434 } 435 else { 436 snprintf(buf, BUFFER_SIZE, "GET /ddns/update.jsp?hostname=%s&myip=%s HTTP/1.0\015\012", host, address); 437 } 438 output(buf); 439 snprintf(buf, BUFFER_SIZE, "Authorization: Basic %s\015\012", auth); 440 output(buf); 441 snprintf(buf, BUFFER_SIZE, "User-Agent: %s-%s %s [%s] (%s)\015\012", "ez-update", VERSION, OS, (options & OPT_DAEMON) ? "daemon" : "", "by Angus Mackay"); 442 output(buf); 443 snprintf(buf, BUFFER_SIZE, "Host: %s\015\012", server); 444 output(buf); 445 snprintf(buf, BUFFER_SIZE, "\015\012"); 446 output(buf); 447 448 bp = buf; 449 bytes = 0; 450 btot = 0; 451 452 while ((bytes = read_input(bp, BUFFER_SIZE - btot)) > 0) { 453 bp += bytes; 454 btot += bytes; 455 } 456 close(client_sockfd); 457 buf[btot] = '\0'; 458 show_message("Asus update entry:: return: %s\n", buf); 459 if(btot) { // TODO: according to server response, parsing code have to rewrite 460 if (sscanf(buf, " HTTP/1.%*c %3d", &ret) != 1) { 461 ret = -1; 462 } 463 464 // looking for 2-th '|' 465 p = strchr (buf, '|'); 466 if (p != NULL) 467 p = strchr (p+1, '|'); 468 if (p == NULL) { 469 p = ""; 470 } 471 snprintf (ret_buf, sizeof (ret_buf), "%s,%d", "", ret); 472 } 473 474 nvram_set ("ddns_return_code", ret_buf); 475 nvram_set ("ddns_return_code_chk", ret_buf); 476 switch (ret) { 477 case -1: 478 PRINT("strange server response, are you connecting to the right server?\n"); 479 retval = UPDATERES_ERROR; 480 break; 481 482 case 200: 483 PRINT("Update IP successful\n"); 484 break; 485 486 case 203: 487 PRINT ("Update failed. (203)\n"); 488 memset (sug_name, 0, sizeof (sug_name)); 489 sscanf (p, "|%[^|\r\n]c", sug_name); 490 nvram_set ("ddns_suggest_name", sug_name); 491 492 retval = REGISTERES_ERROR; 493 break; 494 495 case 230: 496 PRINT ("Update new domain success.\n"); 497 memset (old_name, 0, sizeof (old_name)); 498 sscanf (p, "|%[^|\r\n]c", old_name); 499 nvram_set ("ddns_old_name", old_name); 500 break; 501 502 case 233: 503 PRINT ("Update failed. (233)\n"); 504 memset (old_name, 0, sizeof (old_name)); 505 sscanf (p, "|%[^|\r\n]c", old_name); 506 nvram_set ("ddns_old_name", old_name); 507 retval = REGISTERES_ERROR; 508 break; 509 510 case 220: 511 PRINT("Update same domain success.\n"); 512 break; 513 514 case 297: 515 PRINT("Invalid hostname\n"); 516 retval = UPDATERES_ERROR; 517 break; 518 519 case 298: 520 PRINT("Invalid domain name\n"); 521 retval = UPDATERES_ERROR; 522 break; 523 524 case 299: 525 PRINT("Invalid IP format\n"); 526 retval = UPDATERES_ERROR; 527 break; 528 529 case 401: 530 PRINT("Authentication failure\n"); 531 retval = UPDATERES_SHUTDOWN; 532 break; 533 534 case 407: 535 PRINT ("Proxy authentication Required.\n"); 536 retval = UPDATERES_SHUTDOWN; 537 break; 538 539 default: 540 // reuse the auth buffer 541 *auth = '\0'; 542 sscanf(buf, " HTTP/1.%*c %*3d %255[^\r\n]", auth); 543 if (ret >= 500) { 544 retval = UPDATERES_SHUTDOWN; 545 } else { 546 retval = UPDATERES_ERROR; 547 } 548 retval = UPDATERES_SHUTDOWN; 549 break; 550 } 551 552 show_message("retval= %d, ddns_return_code (%s)", retval, nvram_safe_get ("ddns_return_code")); 553 return (retval); 554} 555 556 557static int 558alnum_cpy (unsigned char *d, unsigned char *s, unsigned int max_dlen) 559{ 560 unsigned char *old_d, *max_d; 561 562 if (d == NULL || s == NULL || max_dlen == 0) 563 return 0; 564 565 old_d = d; 566 max_d = d + max_dlen; 567 while (*s != '\0' && d < max_d) { 568 if (isalnum (*s)) 569 *d++ = *s; 570 s++; 571 } 572 573 // out of range 574 if (d == max_d) { 575 *(d-1) = '\0'; 576 } 577 578 return (int) (d - old_d); 579} 580 581 582#ifdef DUMP_KEY 583static void dump (unsigned char *p, unsigned int l) 584{ 585 unsigned int i; 586 if (p == NULL || l == 0) 587 return; 588 589 printf ("0x"); 590 for (i = 0; i < l; ++i) 591 printf ("%02x", p[i]); 592 printf ("\n\n"); 593} 594#endif // DUMP_KEY 595 596 597static int 598wl_wscPincheck(char *pin_string) 599{ 600 unsigned long PIN = strtoul(pin_string, NULL, 10 );; 601 unsigned long int accum = 0; 602 603 accum += 3 * ((PIN / 10000000) % 10); 604 accum += 1 * ((PIN / 1000000) % 10); 605 accum += 3 * ((PIN / 100000) % 10); 606 accum += 1 * ((PIN / 10000) % 10); 607 accum += 3 * ((PIN / 1000) % 10); 608 accum += 1 * ((PIN / 100) % 10); 609 accum += 3 * ((PIN / 10) % 10); 610 accum += 1 * ((PIN / 1) % 10); 611 612 if (0 == (accum % 10)) 613 return 0; // The PIN code is Vaild. 614 else 615 return 1; // Invalid 616} 617 618 619// Generate password according to MAC address 620int asus_private(void) 621{ 622#define MAX_SECRET_CODE_LEN 8 623 int i, l, c; 624 unsigned long secret; 625 unsigned char *p, user[256], hwaddr[6], hwaddr_str[18], key[64], msg[256], ipbuf[20], bin_pwd[16]; 626 627 memset (hwaddr, 0, sizeof (hwaddr)); 628 memset (key, 0, sizeof (key)); 629 memset (msg, 0, sizeof (msg)); 630 memset (user, 0, sizeof (user)); 631 memset (bin_pwd, 0, sizeof (bin_pwd)); 632#ifdef RTCONFIG_RGMII_BRCM5301X 633 p = nvram_get ("et1macaddr"); 634#else 635 if (get_model() == MODEL_RTN56U) 636 p = nvram_get ("et1macaddr"); 637 else 638 p = nvram_get ("et0macaddr"); 639#endif 640#ifdef RTCONFIG_GMAC3 641 if(nvram_match("gmac3_enable", "1")) 642 p = nvram_safe_get ("et2macaddr"); 643#endif 644 if (p == NULL) { 645 PRINT ("ERROR: %s() can not take MAC address from et0macaddr\n"); 646 return -1; 647 } 648 strncpy (hwaddr_str, p, sizeof (hwaddr_str)); 649 p = hwaddr_str; 650 strtok (hwaddr_str, ":"); 651 for (i = 0; i < 6; ++i) { 652 if (p == NULL) { 653 PRINT ("ERROR: %s() can not convert MAC address\n", __FUNCTION__); 654 return -1; 655 } 656 hwaddr[i] = strtoul (p, NULL, 16); 657 p = strtok (NULL, ":"); 658 } 659 //DBG ("MAC %02X:%02X:%02X:%02X:%02X:%02X\n", hwaddr[0], hwaddr[1], hwaddr[2], hwaddr[3], hwaddr[4], hwaddr[5]); 660 661 p = nvram_get ("secret_code"); 662 if (p == NULL) { 663 PRINT ("ERROR: secret_code not found.\n"); 664 return -1; 665 } 666 strncpy (key, p, sizeof (key)); 667 c = wl_wscPincheck (key); 668 //DBG ("secret code (%s) is %s\n", key, (c == 0)?"valid":"INVALID"); 669 if (c) 670 PRINT ("WARNING: invalid secret code (%s)?\n", key); 671 672 DUMP (key); 673 674 // If address is invalid or ez-ipupdate is running as daemon, take IP address from interface. 675 if (address == NULL || *address == '\0' || options & OPT_DAEMON) { 676#ifdef IF_LOOKUP 677 struct sockaddr_in sin; 678 int sock; 679 680 if (interface == NULL) { 681 PRINT ("ERROR: %s() invalid address and interface\n", __FUNCTION__); 682 return -1; 683 } 684 685 sock = socket(AF_INET, SOCK_STREAM, 0); 686 if (get_if_addr(sock, interface, &sin) != 0) { 687 PRINT ("ERROR: %s() get IP address of interface fail\n", __FUNCTION__); 688 return -1; 689 } 690 close(sock); 691 snprintf(ipbuf, sizeof(ipbuf), "%s", inet_ntoa(sin.sin_addr)); 692 if (address) {free(address);} 693 address = strdup (ipbuf); 694#else 695#error interface lookup not enabled at compile time. 696#endif 697 } else { 698 snprintf(ipbuf, sizeof(ipbuf), "%s", address); 699 } 700 701 // generate m 702 i = alnum_cpy (msg, host, sizeof (msg)); 703 alnum_cpy (msg + i, ipbuf, sizeof (msg) - strlen (msg)); 704 //DBG ("%s(): m is (%s) len %d\n", __FUNCTION__, msg, strlen (msg)); 705 706 // generate password 707 hm(msg, strlen (msg), key, 64, bin_pwd); 708 709 //2007.03.19 Yau change snprintf -> sprintf 710 // This function is used to override "auth" 711 for (i = 0; i < 6; ++i) 712 //snprintf (user, sizeof (user), "%s%02X", user, hwaddr[i]); 713 sprintf (user, "%s%02X", user, hwaddr[i]); 714 //snprintf (user, sizeof (user), "%s:", user); 715 sprintf (user, "%s:", user); 716 717 for (i = 0; i < 16; ++i) 718 //snprintf (user, sizeof (user), "%s%02X", user, bin_pwd[i]); 719 sprintf (user, "%s%02X", user, bin_pwd[i]); 720 721 //DBG ("%s(): user and password (%s)\n", __FUNCTION__, user); 722 base64Encode(user, auth); 723 //PRINT("auth[] is overrode.\n"); 724 //DBG("new auth[] is (%s)\n", auth); 725 726 return 0; 727} 728#endif // TEST_HMAC_MD5 729